[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.1.2.4, Mon Nov 3 15:51:50 2003 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
# Line 79  Line 47 
47          %endif          %endif
48  %endmacro  %endmacro
49    
50  mmx_one times 4 dw       1  ;=============================================================================
51    ; Local data (Read Only)
52    ;=============================================================================
53    
54  ;===========================================================================  %ifdef FORMAT_COFF
55  ;  SECTION .rodata data
56  ; divide by 2Q table  %else
57  ;  SECTION .rodata data align=16
58  ;===========================================================================  %endif
59    
60  %macro MMX_DIV  1  mmx_one:
61  times 4 dw  (1 << 17) / (%1 * 2) + 1          times 4 dw       1
 %endmacro  
62    
63  align ALIGN  ;-----------------------------------------------------------------------------
64  mmx_div  ; divide by 2Q table
65                  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  
66    
67    ALIGN 16
68    mmx_div:
69            times 4 dw 65535 ; the div by 2 formula will overflow for the case
70                             ; quant=1 but we don't care much because quant=1
71                             ; is handled by a different piece of code that
72                             ; doesn't use this table.
73    %assign quant 2
74    %rep 30
75            times 4 dw  (1<<17) / (quant*2) + 1
76            %assign quant quant+1
77    %endrep
78    
79  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
80  ; intra matrix  ; intra matrix
81  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
82    
83  cextern intra_matrix  cextern intra_matrix
84  cextern intra_matrix_fix  cextern intra_matrix_fix
85    
86  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
87  ; inter matrix  ; inter matrix
88  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
89    
90  cextern inter_matrix  cextern inter_matrix
91  cextern inter_matrix_fix  cextern inter_matrix_fix
# Line 149  Line 95 
95  %define VM18Q 4  %define VM18Q 4
96    
97    
98  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
99  ; quantd table  ; quantd table
100  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
   
 %macro MMX_QUANTD  1  
 times 4 dw ((VM18P*%1) + (VM18Q/2)) / VM18Q  
 %endmacro  
101    
102  quantd  quantd:
103                  MMX_QUANTD 1  %assign quant 1
104                  MMX_QUANTD 2  %rep 31
105                  MMX_QUANTD 3          times 4 dw  ((VM18P*quant) + (VM18Q/2)) / VM18Q
106                  MMX_QUANTD 4          %assign quant quant+1
107                  MMX_QUANTD 5  %endrep
                 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  
108    
109    ;-----------------------------------------------------------------------------
 ;===========================================================================  
 ;  
110  ; multiple by 2Q table  ; multiple by 2Q table
111  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
112    
113  %macro MMX_MUL_QUANT  1  mmx_mul_quant:
114  times 4   dw  %1  %assign quant 1
115  %endmacro  %rep 31
116            times 4 dw  quant
117  mmx_mul_quant          %assign quant quant+1
118          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  
119    
120  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
121  ; saturation limits  ; saturation limits
122  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
123    
124  align 16  ALIGN 16
125    
126  mmx_32767_minus_2047                            times 4 dw (32767-2047)  mmx_32767_minus_2047:
127  mmx_32768_minus_2048                            times 4 dw (32768-2048)          times 4 dw (32767-2047)
128  mmx_2047 times 4 dw 2047  mmx_32768_minus_2048:
129  mmx_minus_2048 times 4 dw (-2048)          times 4 dw (32768-2048)
130  zero times 4 dw 0  mmx_2047:
131            times 4 dw 2047
132    mmx_minus_2048:
133            times 4 dw (-2048)
134    zero:
135            times 4 dw 0
136    
137    ;=============================================================================
138    ; Code
139    ;=============================================================================
140    
141  section .text  SECTION .text
142    
143    cglobal quant_mpeg_intra_mmx
144    cglobal quant_mpeg_inter_mmx
145    cglobal dequant_mpeg_intra_mmx
146    cglobal dequant_mpeg_inter_mmx
147    
148  ;===========================================================================  ;-----------------------------------------------------------------------------
149  ;  ;
150  ; void quant_intra4_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
151  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
152  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
153  ;                                       const uint32_t dcscalar);  ;                                       const uint32_t dcscalar);
154  ;  ;
155  ;===========================================================================  ;-----------------------------------------------------------------------------
156    
157  align ALIGN  ALIGN 16
 cglobal quant_mpeg_intra_mmx  
158  quant_mpeg_intra_mmx:  quant_mpeg_intra_mmx:
159    
160                  push    ecx                  push    ecx
# Line 284  Line 176 
176    
177                  movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7                  movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7
178    
179  align ALIGN  ALIGN 16
180  .loop  .loop
181                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
182                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
183                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
184                  pxor    mm4, mm4                  pxor    mm4, mm4
   
185                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
186                  pcmpgtw mm4, mm3                  pcmpgtw mm4, mm3
   
187                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
188                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
189                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
190                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
191                  psllw   mm0, 4                  ; level << 4                  psllw   mm0, 4                  ; level << 4
192                  psllw   mm3, 4                  ;    psllw mm3, 4
   
193                  movq    mm2, [intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
194                  psrlw   mm2, 1                  ; intra_matrix[i]>>1                  psrlw   mm2, 1                  ; intra_matrix[i]>>1
195                  paddw   mm0, mm2                  paddw   mm0, mm2
   
196                  movq    mm2, [intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
197                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
   
198                  movq    mm2, [intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
199                  psrlw   mm2, 1                  psrlw   mm2, 1
200                  paddw   mm3, mm2                  paddw   mm3, mm2
   
201                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
202                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
203              paddw   mm0, mm5            ; + quantd              paddw   mm0, mm5            ; + quantd
204                  paddw   mm3, mm5                  paddw   mm3, mm5
   
205                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
206                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
207                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
208                  psrlw   mm3, 1                  psrlw   mm3, 1
   
209                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
210                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
211                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
# Line 339  Line 220 
220    
221  .done  .done
222                  ; caclulate  data[0] // (int32_t)dcscalar)                  ; caclulate  data[0] // (int32_t)dcscalar)
   
223                  mov     ecx, [esp + 12 + 16]    ; dcscalar                  mov     ecx, [esp + 12 + 16]    ; dcscalar
224                  mov     edx, ecx                  mov     edx, ecx
225                  movsx   eax, word [esi] ; data[0]                  movsx   eax, word [esi] ; data[0]
# Line 361  Line 241 
241                  pop     esi                  pop     esi
242                  pop     ecx                  pop     ecx
243    
244      xor eax, eax              ; return(0);
245                  ret                  ret
246    
247  align ALIGN  ALIGN 16
248  .q1loop  .q1loop
249                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
250                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
251                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
252                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
253                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
254                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
255                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
256                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
257                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
258                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
259                  psllw   mm0, 4                  psllw   mm0, 4
260                  psllw   mm3, 4                  psllw   mm3, 4
   
261                  movq    mm2, [intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
262                  psrlw   mm2, 1                  psrlw   mm2, 1
263                  paddw   mm0, mm2                  paddw   mm0, mm2
   
264                  movq    mm2, [intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
265                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
   
266                  movq    mm2, [intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
267                  psrlw   mm2, 1                  psrlw   mm2, 1
268                  paddw   mm3, mm2                  paddw   mm3, mm2
   
269                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
270                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
271          paddw   mm0, mm5          paddw   mm0, mm5
272                  paddw   mm3, mm5                  paddw   mm3, mm5
   
273                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
274                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
275                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
276                  pxor    mm3, mm4        ;                  pxor    mm3, mm4        ;
277                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
278                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
279                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
280                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
281    
# Line 416  Line 285 
285                  jmp     near .done                  jmp     near .done
286    
287    
288  align ALIGN  ALIGN 16
289  .q2loop  .q2loop
290                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
291                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
292                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
293                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
294                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
295                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
296                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
297                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
298                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
299                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
300                  psllw   mm0, 4                  psllw   mm0, 4
301                  psllw   mm3, 4                  psllw   mm3, 4
   
302                  movq    mm2, [intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
303                  psrlw   mm2, 1                  psrlw   mm2, 1
304                  paddw   mm0, mm2                  paddw   mm0, mm2
   
305                  movq    mm2, [intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
306                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
   
307                  movq    mm2, [intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
308                  psrlw   mm2, 1                  psrlw   mm2, 1
309                  paddw   mm3, mm2                  paddw   mm3, mm2
   
310                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
311                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
312          paddw   mm0, mm5          paddw   mm0, mm5
313                  paddw   mm3, mm5                  paddw   mm3, mm5
   
314                  psrlw   mm0, 2                  ; mm0 >>= 1   (/4)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/4)
315                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
316                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
317                  pxor    mm3, mm4        ;                  pxor    mm3, mm4        ;
318                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
319                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
320                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
321                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
322    
# Line 469  Line 326 
326                  jmp     near .done                  jmp     near .done
327    
328    
329  ;===========================================================================  ;-----------------------------------------------------------------------------
330  ;  ;
331  ; uint32_t quant4_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
332  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
333  ;                                       const uint32_t quant);  ;                                       const uint32_t quant);
334  ;  ;
335  ;===========================================================================  ;-----------------------------------------------------------------------------
336    
337  align ALIGN  ALIGN 16
 cglobal quant_mpeg_inter_mmx  
338  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
339    
340                  push    ecx                  push    ecx
# Line 501  Line 357 
357    
358                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider
359    
360  align ALIGN  ALIGN 16
361  .loop  .loop
362                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
363                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
# Line 513  Line 369 
369                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
370                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
371                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
372                  psllw   mm0, 4                  psllw   mm0, 4
373                  psllw   mm3, 4                  psllw   mm3, 4
   
374                  movq    mm2, [inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
375                  psrlw   mm2, 1                  psrlw   mm2, 1
376                  paddw   mm0, mm2                  paddw   mm0, mm2
   
377                  movq    mm2, [inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
378                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
   
379                  movq    mm2, [inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
380                  psrlw   mm2, 1                  psrlw   mm2, 1
381                  paddw   mm3, mm2                  paddw   mm3, mm2
   
382                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
383                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
384                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
385                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
386                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
387                  psrlw   mm3, 1                  psrlw   mm3, 1
   
388                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
389                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
390                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
# Line 562  Line 411 
411    
412                  ret                  ret
413    
414  align ALIGN  ALIGN 16
415  .q1loop  .q1loop
416                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
417                  movq    mm3, [esi + 8*ecx+ 8]                  movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
418                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
419                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
420                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
421                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
422                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
423                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
424                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
425                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
426                  psllw   mm0, 4                  psllw   mm0, 4
427                  psllw   mm3, 4                  psllw   mm3, 4
   
428                  movq    mm2, [inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
429                  psrlw   mm2, 1                  psrlw   mm2, 1
430                  paddw   mm0, mm2                  paddw   mm0, mm2
   
431                  movq    mm2, [inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
432                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
   
433                  movq    mm2, [inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
434                  psrlw   mm2, 1                  psrlw   mm2, 1
435                  paddw   mm3, mm2                  paddw   mm3, mm2
   
436                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
437                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
438                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
439                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
440                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
441                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
442                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
443                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
444                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
445                  psubw   mm3, mm4                  psubw   mm3, mm4
   
446                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
447                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
448    
# Line 615  Line 453 
453                  jmp     .done                  jmp     .done
454    
455    
456  align ALIGN  ALIGN 16
457  .q2loop  .q2loop
458                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
459                  movq    mm3, [esi + 8*ecx+ 8]                  movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
460                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
461                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
462                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
463                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
464                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
465                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
466                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
467                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
468                  psllw   mm0, 4                  psllw   mm0, 4
469                  psllw   mm3, 4                  psllw   mm3, 4
   
470                  movq    mm2, [inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
471                  psrlw   mm2, 1                  psrlw   mm2, 1
472                  paddw   mm0, mm2                  paddw   mm0, mm2
   
473                  movq    mm2, [inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
474                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
   
475                  movq    mm2, [inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
476                  psrlw   mm2, 1                  psrlw   mm2, 1
477                  paddw   mm3, mm2                  paddw   mm3, mm2
   
478                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
479                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
480                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
481                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
482                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
483                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
484                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
485                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
486                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
487                  psubw   mm3, mm4                  psubw   mm3, mm4
   
488                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
489                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
490    
# Line 668  Line 495 
495                  jmp     .done                  jmp     .done
496    
497    
498  ;===========================================================================  ;-----------------------------------------------------------------------------
499  ;  ;
500  ; void dequant4_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
501  ;                    const int16_t const *coeff,  ;                    const int16_t const *coeff,
502  ;                    const uint32_t quant,  ;                    const uint32_t quant,
503  ;                    const uint32_t dcscalar);  ;                    const uint32_t dcscalar);
504  ;  ;
505  ;===========================================================================  ;-----------------------------------------------------------------------------
506    
507    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
508    ; 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 716  Line 543 
543    
544    ;********************************************************************    ;********************************************************************
545    
546  align 16  ALIGN 16
 cglobal dequant_mpeg_intra_mmx  
547  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
548    
549    mov edx, [esp+4]  ; data    mov edx, [esp+4]  ; data
# Line 725  Line 551 
551    mov eax, [esp+12] ; quant    mov eax, [esp+12] ; quant
552    
553    movq mm7, [mmx_mul_quant  + eax*8 - 8]    movq mm7, [mmx_mul_quant  + eax*8 - 8]
554    mov eax, -16   ; to keep aligned, we regularly process coeff[0]    mov eax, -16      ; to keep ALIGNed, we regularly process coeff[0]
555    psllw mm7, 2   ; << 2. See comment.    psllw mm7, 2   ; << 2. See comment.
556    pxor mm6, mm6   ; this is a NOP    pxor mm6, mm6   ; this is a NOP
557    
558  align 16  ALIGN 16
559  .loop  .loop
560    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
561    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 786  Line 612 
612    jnz near .loop    jnz near .loop
613    
614      ; deal with DC      ; deal with DC
   
615    movd mm0, [ecx]    movd mm0, [ecx]
616    pmullw mm0, [esp+16]  ; dcscalar    pmullw mm0, [esp+16]  ; dcscalar
617    movq mm2, [mmx_32767_minus_2047]    movq mm2, [mmx_32767_minus_2047]
# Line 798  Line 623 
623    movd eax, mm0    movd eax, mm0
624    mov [edx], ax    mov [edx], ax
625    
626      xor eax, eax
627    ret    ret
628    
629  ;===========================================================================  ;-----------------------------------------------------------------------------
630  ;  ;
631  ; void dequant4_inter_mmx(int16_t * data,  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,
632  ;                    const int16_t * const coeff,  ;                    const int16_t * const coeff,
633  ;                    const uint32_t quant);  ;                    const uint32_t quant);
634  ;  ;
635  ;===========================================================================  ;-----------------------------------------------------------------------------
636    
637      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
638      ; 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.
639      ; 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.
640      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
641    
642  align 16  ALIGN 16
 cglobal dequant_mpeg_inter_mmx  
643  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
644    
645    mov    edx, [esp+ 4]        ; data    mov    edx, [esp+ 4]        ; data
# Line 825  Line 650 
650    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
651    pxor mm6, mm6 ; mismatch sum    pxor mm6, mm6 ; mismatch sum
652    
653  align 16  ALIGN 16
654  .loop  .loop
655    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
656    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 903  Line 728 
728    xor eax, 1    xor eax, 1
729    xor word [edx + 2*63], ax    xor word [edx + 2*63], ax
730    
731      xor eax, eax
732    ret    ret
   

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

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