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

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

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