[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.2.2.1, Sat Jul 24 11:38:12 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
# Line 79  Line 47 
47          %endif          %endif
48  %endmacro  %endmacro
49    
50  mmx_one times 4 dw       1  ;=============================================================================
51    ; Local data (Read Only)
52  ;===========================================================================  ;=============================================================================
 ;  
 ; 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  
   
53    
54  ;===========================================================================  %ifdef FORMAT_COFF
55  ;  SECTION .rodata
56  ; intra matrix  %else
57  ;  SECTION .rodata align=16
58  ;===========================================================================  %endif
   
 cextern intra_matrix  
 cextern intra_matrix_fix  
59    
60  ;===========================================================================  mmx_one:
61  ;          times 4 dw       1
 ; inter matrix  
 ;  
 ;===========================================================================  
62    
63  cextern inter_matrix  ;-----------------------------------------------------------------------------
64  cextern inter_matrix_fix  ; divide by 2Q table
65    ;-----------------------------------------------------------------------------
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  %define VM18P 3  %define VM18P 3
80  %define VM18Q 4  %define VM18Q 4
81    
82    
83  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
84  ; quantd table  ; quantd table
85  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
86    
87  %macro MMX_QUANTD  1  quantd:
88  times 4 dw ((VM18P*%1) + (VM18Q/2)) / VM18Q  %assign quant 1
89  %endmacro  %rep 31
90            times 4 dw  ((VM18P*quant) + (VM18Q/2)) / VM18Q
91            %assign quant quant+1
92    %endrep
93    
94  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  ; multiple by 2Q table  ; multiple by 2Q table
96  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
   
 %macro MMX_MUL_QUANT  1  
 times 4   dw  %1  
 %endmacro  
97    
98  mmx_mul_quant  mmx_mul_quant:
99          MMX_MUL_QUANT 1  %assign quant 1
100          MMX_MUL_QUANT 2  %rep 31
101          MMX_MUL_QUANT 3          times 4 dw  quant
102          MMX_MUL_QUANT 4          %assign quant quant+1
103          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  
104    
105  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
106  ; saturation limits  ; saturation limits
107  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
108    
109  align 16  ALIGN 16
110    
111  mmx_32767_minus_2047                            times 4 dw (32767-2047)  mmx_32767_minus_2047:
112  mmx_32768_minus_2048                            times 4 dw (32768-2048)          times 4 dw (32767-2047)
113  mmx_2047 times 4 dw 2047  mmx_32768_minus_2048:
114  mmx_minus_2048 times 4 dw (-2048)          times 4 dw (32768-2048)
115  zero times 4 dw 0  mmx_2047:
116            times 4 dw 2047
117    mmx_minus_2048:
118            times 4 dw (-2048)
119    zero:
120            times 4 dw 0
121    
122    ;=============================================================================
123    ; Code
124    ;=============================================================================
125    
126  section .text  SECTION .text
127    
128  ;===========================================================================  cglobal quant_mpeg_intra_mmx
129    cglobal quant_mpeg_inter_mmx
130    cglobal dequant_mpeg_intra_mmx
131    cglobal dequant_mpeg_inter_mmx
132    
133    ;-----------------------------------------------------------------------------
134  ;  ;
135  ; void quant_intra4_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
136  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
137  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
138  ;                                       const uint32_t dcscalar);  ;                               const uint32_t dcscalar,
139    ;                               const uint16_t *mpeg_matrices);
140  ;  ;
141  ;===========================================================================  ;-----------------------------------------------------------------------------
142    
143  align ALIGN  ALIGN 16
 cglobal quant_mpeg_intra_mmx  
144  quant_mpeg_intra_mmx:  quant_mpeg_intra_mmx:
145    
146                  push    ecx                  push    ecx
147                  push    esi                  push    esi
148                  push    edi                  push    edi
149      push ebx
150    
151                  mov     edi, [esp + 12 + 4]             ; coeff    mov edi, [esp + 16 + 4]       ; coeff
152                  mov     esi, [esp + 12 + 8]             ; data    mov esi, [esp + 16 + 8]       ; data
153                  mov     eax, [esp + 12 + 12]    ; quant    mov eax, [esp + 16 + 12]      ; quant
154      mov ebx, [esp + 16 + 20]              ; mpeg_quant_matrices
155    
156                  movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5                  movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5
157    
# Line 284  Line 164 
164    
165                  movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7                  movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7
166    
167  align ALIGN  ALIGN 16
168  .loop  .loop
169                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
170                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
171                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
172                  pxor    mm4, mm4                  pxor    mm4, mm4
   
173                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
174                  pcmpgtw mm4, mm3                  pcmpgtw mm4, mm3
   
175                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
176                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
177                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
178                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
179                  psllw   mm0, 4                  ; level << 4                  psllw   mm0, 4                  ; level << 4
180                  psllw   mm3, 4                  ;    psllw mm3, 4
181      movq mm2, [ebx + 8*ecx]
                 movq    mm2, [intra_matrix + 8*ecx]  
182                  psrlw   mm2, 1                  ; intra_matrix[i]>>1                  psrlw   mm2, 1                  ; intra_matrix[i]>>1
183                  paddw   mm0, mm2                  paddw   mm0, mm2
184      movq mm2, [ebx + 256 + ecx*8]
                 movq    mm2, [intra_matrix_fix + ecx*8]  
185                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
186      movq mm2, [ebx + 8*ecx + 8]
                 movq    mm2, [intra_matrix + 8*ecx + 8]  
187                  psrlw   mm2, 1                  psrlw   mm2, 1
188                  paddw   mm3, mm2                  paddw   mm3, mm2
189      movq mm2, [ebx + 256 + ecx*8 + 8]
                 movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
190                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
191              paddw   mm0, mm5            ; + quantd              paddw   mm0, mm5            ; + quantd
192                  paddw   mm3, mm5                  paddw   mm3, mm5
   
193                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
194                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
195                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
196                  psrlw   mm3, 1                  psrlw   mm3, 1
   
197                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
198                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
199                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
# Line 339  Line 208 
208    
209  .done  .done
210                  ; caclulate  data[0] // (int32_t)dcscalar)                  ; caclulate  data[0] // (int32_t)dcscalar)
211      mov ecx, [esp + 16 + 16]  ; dcscalar
                 mov     ecx, [esp + 12 + 16]    ; dcscalar  
212                  mov     edx, ecx                  mov     edx, ecx
213                  movsx   eax, word [esi] ; data[0]                  movsx   eax, word [esi] ; data[0]
214                  shr     edx, 1                  ; edx = dcscalar /2                  shr     edx, 1                  ; edx = dcscalar /2
# Line 357  Line 225 
225    
226                  mov     [edi], ax               ; coeff[0] = ax                  mov     [edi], ax               ; coeff[0] = ax
227    
228      pop ebx
229                  pop     edi                  pop     edi
230                  pop     esi                  pop     esi
231                  pop     ecx                  pop     ecx
232    
233      xor eax, eax              ; return(0);
234                  ret                  ret
235    
236  align ALIGN  ALIGN 16
237  .q1loop  .q1loop
238                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
239                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
240                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
241                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
242                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
243                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
244                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
245                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
246                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
247                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
248                  psllw   mm0, 4                  psllw   mm0, 4
249                  psllw   mm3, 4                  psllw   mm3, 4
250      movq mm2, [ebx + 8*ecx]
                 movq    mm2, [intra_matrix + 8*ecx]  
251                  psrlw   mm2, 1                  psrlw   mm2, 1
252                  paddw   mm0, mm2                  paddw   mm0, mm2
253      movq mm2, [ebx + 256 + ecx*8]
                 movq    mm2, [intra_matrix_fix + ecx*8]  
254                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
255      movq mm2, [ebx + 8*ecx + 8]
                 movq    mm2, [intra_matrix + 8*ecx + 8]  
256                  psrlw   mm2, 1                  psrlw   mm2, 1
257                  paddw   mm3, mm2                  paddw   mm3, mm2
258      movq mm2, [ebx + 256 + ecx*8 + 8]
                 movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
259                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
260          paddw   mm0, mm5          paddw   mm0, mm5
261                  paddw   mm3, mm5                  paddw   mm3, mm5
   
262                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
263                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
264                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
265                  pxor    mm3, mm4        ;                  pxor    mm3, mm4        ;
266                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
267                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
268                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
269                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
270    
# Line 416  Line 274 
274                  jmp     near .done                  jmp     near .done
275    
276    
277  align ALIGN  ALIGN 16
278  .q2loop  .q2loop
279                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
280                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
281                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
282                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
283                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
284                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
285                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
286                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
287                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
288                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
289                  psllw   mm0, 4                  psllw   mm0, 4
290                  psllw   mm3, 4                  psllw   mm3, 4
291      movq mm2, [ebx + 8*ecx]
                 movq    mm2, [intra_matrix + 8*ecx]  
292                  psrlw   mm2, 1                  psrlw   mm2, 1
293                  paddw   mm0, mm2                  paddw   mm0, mm2
294      movq mm2, [ebx + 256 + ecx*8]
                 movq    mm2, [intra_matrix_fix + ecx*8]  
295                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
296      movq mm2, [ebx + 8*ecx + 8]
                 movq    mm2, [intra_matrix + 8*ecx + 8]  
297                  psrlw   mm2, 1                  psrlw   mm2, 1
298                  paddw   mm3, mm2                  paddw   mm3, mm2
299      movq mm2, [ebx + 256 + ecx*8 + 8]
                 movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
300                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
301          paddw   mm0, mm5          paddw   mm0, mm5
302                  paddw   mm3, mm5                  paddw   mm3, mm5
   
303                  psrlw   mm0, 2                  ; mm0 >>= 1   (/4)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/4)
304                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
305                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
306                  pxor    mm3, mm4        ;                  pxor    mm3, mm4        ;
307                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
308                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
309                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
310                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
311    
# Line 469  Line 315 
315                  jmp     near .done                  jmp     near .done
316    
317    
318  ;===========================================================================  ;-----------------------------------------------------------------------------
319  ;  ;
320  ; uint32_t quant4_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
321  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
322  ;                                       const uint32_t quant);  ;                               const uint32_t quant,
323    ;                               const uint16_t *mpeg_matrices);
324  ;  ;
325  ;===========================================================================  ;-----------------------------------------------------------------------------
326    
327  align ALIGN  ALIGN 16
 cglobal quant_mpeg_inter_mmx  
328  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
329    
330                  push    ecx                  push    ecx
331                  push    esi                  push    esi
332                  push    edi                  push    edi
333      push ebx
334    
335                  mov     edi, [esp + 12 + 4]             ; coeff    mov edi, [esp + 16 + 4]       ; coeff
336                  mov     esi, [esp + 12 + 8]             ; data    mov esi, [esp + 16 + 8]       ; data
337                  mov     eax, [esp + 12 + 12]    ; quant    mov eax, [esp + 16 + 12]  ; quant
338      mov ebx, [esp + 16 + 16]              ; mpeg_quant_matrices
339    
340                  xor ecx, ecx                  xor ecx, ecx
341    
# Line 501  Line 349 
349    
350                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider
351    
352  align ALIGN  ALIGN 16
353  .loop  .loop
354                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
355                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
# Line 513  Line 361 
361                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
362                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
363                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
364                  psllw   mm0, 4                  psllw   mm0, 4
365                  psllw   mm3, 4                  psllw   mm3, 4
366      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
367                  psrlw   mm2, 1                  psrlw   mm2, 1
368                  paddw   mm0, mm2                  paddw   mm0, mm2
369      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
370                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
371      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
372                  psrlw   mm2, 1                  psrlw   mm2, 1
373                  paddw   mm3, mm2                  paddw   mm3, mm2
374      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
375                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
376                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
377                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
378                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
379                  psrlw   mm3, 1                  psrlw   mm3, 1
   
380                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
381                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
382                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
# Line 556  Line 397 
397                  paddd   mm0, mm5                  paddd   mm0, mm5
398                  movd    eax, mm0                ; return sum                  movd    eax, mm0                ; return sum
399    
400      pop ebx
401                  pop     edi                  pop     edi
402                  pop     esi                  pop     esi
403                  pop ecx                  pop ecx
404    
405                  ret                  ret
406    
407  align ALIGN  ALIGN 16
408  .q1loop  .q1loop
409                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
410                  movq    mm3, [esi + 8*ecx+ 8]                  movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
411                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
412                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
413                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
414                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
415                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
416                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
417                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
418                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
419                  psllw   mm0, 4                  psllw   mm0, 4
420                  psllw   mm3, 4                  psllw   mm3, 4
421      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
422                  psrlw   mm2, 1                  psrlw   mm2, 1
423                  paddw   mm0, mm2                  paddw   mm0, mm2
424      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
425                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
426      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
427                  psrlw   mm2, 1                  psrlw   mm2, 1
428                  paddw   mm3, mm2                  paddw   mm3, mm2
429      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
430                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
431                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
432                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
433                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
434                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
435                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
436                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
437                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
438                  psubw   mm3, mm4                  psubw   mm3, mm4
   
439                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
440                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
441    
# Line 615  Line 446 
446                  jmp     .done                  jmp     .done
447    
448    
449  align ALIGN  ALIGN 16
450  .q2loop  .q2loop
451                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
452                  movq    mm3, [esi + 8*ecx+ 8]                  movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
453                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
454                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
455                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
456                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
457                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
458                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
459                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
460                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
461                  psllw   mm0, 4                  psllw   mm0, 4
462                  psllw   mm3, 4                  psllw   mm3, 4
463      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
464                  psrlw   mm2, 1                  psrlw   mm2, 1
465                  paddw   mm0, mm2                  paddw   mm0, mm2
466      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
467                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
468      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
469                  psrlw   mm2, 1                  psrlw   mm2, 1
470                  paddw   mm3, mm2                  paddw   mm3, mm2
471      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
472                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
473                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
474                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
475                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
476                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
477                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
478                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
479                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
480                  psubw   mm3, mm4                  psubw   mm3, mm4
   
481                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
482                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
483    
# Line 668  Line 488 
488                  jmp     .done                  jmp     .done
489    
490    
491  ;===========================================================================  ;-----------------------------------------------------------------------------
492  ;  ;
493  ; void dequant4_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
494  ;                    const int16_t const *coeff,  ;                    const int16_t const *coeff,
495  ;                    const uint32_t quant,  ;                    const uint32_t quant,
496  ;                    const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
497    ;                                 const uint16_t *mpeg_matrices);
498  ;  ;
499  ;===========================================================================  ;-----------------------------------------------------------------------------
500    
501    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
502    ; 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 517 
517    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
518    
519    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
520    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant.
521    
522    movq mm6, mm2    movq mm6, mm2
523    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 537 
537    
538    ;********************************************************************    ;********************************************************************
539    
540  align 16  ALIGN 16
 cglobal dequant_mpeg_intra_mmx  
541  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
542    
543    mov edx, [esp+4]  ; data    push ebx
544    mov ecx, [esp+8]  ; coeff  
545    mov eax, [esp+12] ; quant    mov edx, [esp + 4 + 4]  ; data
546      mov ecx, [esp + 4 + 8]  ; coeff
547      mov eax, [esp + 4 + 12] ; quant
548      mov ebx, [esp + 4 + 20] ; mpeg_quant_matrices
549    
550    movq mm7, [mmx_mul_quant  + eax*8 - 8]    movq mm7, [mmx_mul_quant  + eax*8 - 8]
551    mov eax, -16   ; to keep aligned, we regularly process coeff[0]    mov eax, -16      ; to keep ALIGNed, we regularly process coeff[0]
552    psllw mm7, 2   ; << 2. See comment.    psllw mm7, 2   ; << 2. See comment.
553    pxor mm6, mm6   ; this is a NOP    pxor mm6, mm6   ; this is a NOP
554    
555  align 16  ALIGN 16
556  .loop  .loop
557    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
558    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 562 
562    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
563    
564    pcmpgtw mm4, mm3  ; mm4 = sgn(c')    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
565    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant
566    
567    pxor mm0, mm1     ; negate if negative    pxor mm0, mm1     ; negate if negative
568    pxor mm3, mm4     ; negate if negative    pxor mm3, mm4     ; negate if negative
# Line 755  Line 578 
578    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
579    movq mm5, mm7     ; mm2 = quant    movq mm5, mm7     ; mm2 = quant
580    
581    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
582    
583    movq mm6, mm5    movq mm6, mm5
584    add eax,2   ; z-flag will be tested later    add eax,2   ; z-flag will be tested later
# Line 786  Line 609 
609    jnz near .loop    jnz near .loop
610    
611      ; deal with DC      ; deal with DC
   
612    movd mm0, [ecx]    movd mm0, [ecx]
613    pmullw mm0, [esp+16]  ; dcscalar    pmullw mm0, [esp + 4 + 16]  ; dcscalar
614    movq mm2, [mmx_32767_minus_2047]    movq mm2, [mmx_32767_minus_2047]
615    paddsw mm0, mm2    paddsw mm0, mm2
616    psubsw mm0, mm2    psubsw mm0, mm2
# Line 798  Line 620 
620    movd eax, mm0    movd eax, mm0
621    mov [edx], ax    mov [edx], ax
622    
623      xor eax, eax
624    
625      pop ebx
626    
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    ;                                 const uint16_t *mpeg_matrices);
635  ;  ;
636  ;===========================================================================  ;-----------------------------------------------------------------------------
637    
638      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
639      ; 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.
640      ; 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.
641      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
642    
643  align 16  ALIGN 16
 cglobal dequant_mpeg_inter_mmx  
644  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
645    
646    mov    edx, [esp+ 4]        ; data    push ebx
647    mov    ecx, [esp+ 8]        ; coeff  
648    mov    eax, [esp+12]        ; quant    mov edx, [esp + 4 + 4]        ; data
649      mov ecx, [esp + 4 + 8]        ; coeff
650      mov eax, [esp + 4 + 12]        ; quant
651      mov ebx, [esp + 4 + 16]                  ; mpeg_quant_matrices
652    
653    movq mm7, [mmx_mul_quant  + eax*8 - 8]    movq mm7, [mmx_mul_quant  + eax*8 - 8]
654    mov eax, -16    mov eax, -16
655    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
656    pxor mm6, mm6 ; mismatch sum    pxor mm6, mm6 ; mismatch sum
657    
658  align 16  ALIGN 16
659  .loop  .loop
660    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
661    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 684 
684      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
685    
686    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
687    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8]
688    movq mm5, mm4    movq mm5, mm4
689    pmulhw mm5, mm0   ; high of c*(matrix*quant)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
690    pmullw mm0, mm4   ; low  of c*(matrix*quant)    pmullw mm0, mm4   ; low  of c*(matrix*quant)
691    
692    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
693    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8 + 8]
694    
695    pcmpgtw mm5, [zero]    pcmpgtw mm5, [zero]
696    paddusw mm0, mm5    paddusw mm0, mm5
# Line 903  Line 733 
733    xor eax, 1    xor eax, 1
734    xor word [edx + 2*63], ax    xor word [edx + 2*63], ax
735    
736    ret    xor eax, eax
737    
738      pop ebx
739    
740      ret

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

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