[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.11, Wed Nov 26 01:04:34 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-2008 Michael Militzer <michael@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  %include "nasm.inc"
   
 %ifdef FORMAT_COFF  
 SECTION .data data  
 %else  
 SECTION .data data align=8  
 %endif  
   
31    
32  %macro cglobal 1  ;=============================================================================
33          %ifdef PREFIX  ; Local data (Read Only)
34                  global _%1  ;=============================================================================
                 %define %1 _%1  
         %else  
                 global %1  
         %endif  
 %endmacro  
35    
36  %macro cextern 1  DATA
         %ifdef PREFIX  
                 extern _%1  
                 %define %1 _%1  
         %else  
                 extern %1  
         %endif  
 %endmacro  
37    
38  mmx_one times 4 dw       1  mmx_one:
39            times 4 dw       1
40    
41  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
42  ; divide by 2Q table  ; divide by 2Q table
43  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
   
 %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  
 ;  
 ;===========================================================================  
   
 cextern intra_matrix  
 cextern intra_matrix_fix  
   
 ;===========================================================================  
 ;  
 ; inter matrix  
 ;  
 ;===========================================================================  
   
 cextern inter_matrix  
 cextern inter_matrix_fix  
44    
45    ALIGN SECTION_ALIGN
46    mmx_div:
47            times 4 dw 65535 ; the div by 2 formula will overflow for the case
48                             ; quant=1 but we don't care much because quant=1
49                             ; is handled by a different piece of code that
50                             ; doesn't use this table.
51    %assign quant 2
52    %rep 30
53            times 4 dw  (1<<17) / (quant*2) + 1
54            %assign quant quant+1
55    %endrep
56    
57  %define VM18P 3  %define VM18P 3
58  %define VM18Q 4  %define VM18Q 4
59    
60    
61  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
62  ; quantd table  ; quantd table
63  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
   
 %macro MMX_QUANTD  1  
 times 4 dw ((VM18P*%1) + (VM18Q/2)) / VM18Q  
 %endmacro  
64    
65  quantd  quantd:
66                  MMX_QUANTD 1  %assign quant 1
67                  MMX_QUANTD 2  %rep 31
68                  MMX_QUANTD 3          times 4 dw  ((VM18P*quant) + (VM18Q/2)) / VM18Q
69                  MMX_QUANTD 4          %assign quant quant+1
70                  MMX_QUANTD 5  %endrep
                 MMX_QUANTD 6  
                 MMX_QUANTD 7  
                 MMX_QUANTD 8  
                 MMX_QUANTD 9  
                 MMX_QUANTD 10  
                 MMX_QUANTD 11  
                 MMX_QUANTD 12  
                 MMX_QUANTD 13  
                 MMX_QUANTD 14  
                 MMX_QUANTD 15  
                 MMX_QUANTD 16  
                 MMX_QUANTD 17  
                 MMX_QUANTD 18  
                 MMX_QUANTD 19  
                 MMX_QUANTD 20  
                 MMX_QUANTD 21  
                 MMX_QUANTD 22  
                 MMX_QUANTD 23  
                 MMX_QUANTD 24  
                 MMX_QUANTD 25  
                 MMX_QUANTD 26  
                 MMX_QUANTD 27  
                 MMX_QUANTD 28  
                 MMX_QUANTD 29  
                 MMX_QUANTD 30  
                 MMX_QUANTD 31  
71    
72    ;-----------------------------------------------------------------------------
 ;===========================================================================  
 ;  
73  ; multiple by 2Q table  ; multiple by 2Q table
74  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
75    
76  %macro MMX_MUL_QUANT  1  mmx_mul_quant:
77  times 4   dw  %1  %assign quant 1
78  %endmacro  %rep 31
79            times 4 dw  quant
80  mmx_mul_quant          %assign quant quant+1
81          MMX_MUL_QUANT 1  %endrep
         MMX_MUL_QUANT 2  
         MMX_MUL_QUANT 3  
         MMX_MUL_QUANT 4  
         MMX_MUL_QUANT 5  
         MMX_MUL_QUANT 6  
         MMX_MUL_QUANT 7  
         MMX_MUL_QUANT 8  
         MMX_MUL_QUANT 9  
         MMX_MUL_QUANT 10  
         MMX_MUL_QUANT 11  
         MMX_MUL_QUANT 12  
         MMX_MUL_QUANT 13  
         MMX_MUL_QUANT 14  
         MMX_MUL_QUANT 15  
         MMX_MUL_QUANT 16  
         MMX_MUL_QUANT 17  
         MMX_MUL_QUANT 18  
         MMX_MUL_QUANT 19  
         MMX_MUL_QUANT 20  
         MMX_MUL_QUANT 21  
         MMX_MUL_QUANT 22  
         MMX_MUL_QUANT 23  
         MMX_MUL_QUANT 24  
         MMX_MUL_QUANT 25  
         MMX_MUL_QUANT 26  
         MMX_MUL_QUANT 27  
         MMX_MUL_QUANT 28  
         MMX_MUL_QUANT 29  
         MMX_MUL_QUANT 30  
         MMX_MUL_QUANT 31  
82    
83  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
84  ; saturation limits  ; saturation limits
85  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
86    
87  align 16  ALIGN SECTION_ALIGN
88    
89  mmx_32767_minus_2047                            times 4 dw (32767-2047)  mmx_32767_minus_2047:
90  mmx_32768_minus_2048                            times 4 dw (32768-2048)          times 4 dw (32767-2047)
91  mmx_2047 times 4 dw 2047  mmx_32768_minus_2048:
92  mmx_minus_2048 times 4 dw (-2048)          times 4 dw (32768-2048)
93  zero times 4 dw 0  mmx_2047:
94            times 4 dw 2047
95    mmx_minus_2048:
96            times 4 dw (-2048)
97    zero:
98            times 4 dw 0
99    
100    ;=============================================================================
101    ; rounding
102    ;=============================================================================
103    
104    ALIGN SECTION_ALIGN
105    
106    mmx_rounding:
107            dd (1<<13)
108            dd (1<<13)
109    
110    ;=============================================================================
111    ; Code
112    ;=============================================================================
113    
114  section .text  SECTION .rotext align=SECTION_ALIGN
115    
 ;===========================================================================  
 ;  
 ; void quant_intra4_mmx(int16_t * coeff,  
 ;                                       const int16_t const * data,  
 ;                                       const uint32_t quant,  
 ;                                       const uint32_t dcscalar);  
 ;  
 ;===========================================================================  
   
 align ALIGN  
116  cglobal quant_mpeg_intra_mmx  cglobal quant_mpeg_intra_mmx
117  quant_mpeg_intra_mmx:  cglobal quant_mpeg_inter_mmx
118    cglobal dequant_mpeg_intra_mmx
119                  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                  ;  
120    
                 movq    mm2, [intra_matrix + 8*ecx]  
                 psrlw   mm2, 1                  ; intra_matrix[i]>>1  
                 paddw   mm0, mm2  
121    
122                  movq    mm2, [intra_matrix_fix + ecx*8]  %macro QUANT_MMX        1
123                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]          movq    mm0, [_EAX + 16*(%1)]                   ; data
124            movq    mm2, [TMP0 + 16*(%1) + 128]             ; intra_matrix_rec
125            movq    mm4, [_EAX + 16*(%1) + 8]               ; data
126            movq    mm6, [TMP0 + 16*(%1) + 128 + 8] ; intra_matrix_rec
127    
128                  movq    mm2, [intra_matrix + 8*ecx + 8]          movq    mm1, mm0
129                  psrlw   mm2, 1          movq    mm5, mm4
                 paddw   mm3, mm2  
130    
131                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]          pmullw  mm0, mm2                                        ; low results
132                  pmulhw  mm3, mm2          pmulhw  mm1, mm2                                        ; high results
133            pmullw  mm4, mm6                                        ; low results
134            pmulhw  mm5, mm6                                        ; high results
135    
136            movq    mm2, mm0
137            movq    mm6, mm4
138    
139            punpckhwd mm0, mm1
140            punpcklwd mm2, mm1
141            punpckhwd mm4, mm5
142            punpcklwd mm6, mm5
143    
144            paddd   mm2, mm7
145            paddd   mm0, mm7
146            paddd   mm6, mm7
147            paddd   mm4, mm7
148    
149            psrad   mm2, 14
150            psrad   mm0, 14
151            psrad   mm6, 14
152            psrad   mm4, 14
153    
154              paddw   mm0, mm5            ; + quantd          packssdw mm2, mm0
155                  paddw   mm3, mm5          packssdw mm6, mm4
156    
157                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16          movq    [TMP1 + 16*(%1)], mm2
158                  pmulhw  mm3, mm7                ;          movq    [TMP1 + 16*(%1)+8], mm6
159                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17  %endmacro
                 psrlw   mm3, 1  
160    
161                  pxor    mm0, mm1                ; mm0 *= sign(mm0)  ;-----------------------------------------------------------------------------
162                  pxor    mm3, mm4                ;  ;
163                  psubw   mm0, mm1                ; undisplace  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
164                  psubw   mm3, mm4                ;  ;                               const int16_t const * data,
165    ;                               const uint32_t quant,
166    ;                               const uint32_t dcscalar,
167    ;                               const uint16_t *mpeg_matrices);
168    ;
169    ;-----------------------------------------------------------------------------
170    
171                  movq    [edi + 8*ecx], mm0  ALIGN SECTION_ALIGN
172                  movq    [edi + 8*ecx + 8], mm3  quant_mpeg_intra_mmx:
173    
174                  add ecx,2    mov _EAX, prm2                ; data
175                  cmp ecx,16    mov TMP0, prm5                ; mpeg_quant_matrices
176                  jnz     near .loop    mov TMP1, prm1                ; coeff
177    
178      movq mm7, [mmx_rounding]
179    
180    ;  QUANT_MMX(0)
181    ;  QUANT_MMX(1)
182    ;  QUANT_MMX(2)
183    ;  QUANT_MMX(3)
184    ;  QUANT_MMX(4)
185    ;  QUANT_MMX(5)
186    ;  QUANT_MMX(6)
187    ;  QUANT_MMX(7)
188    
189      ; calculate DC
190    ;  movsx _EAX, word [_EAX]   ; data[0]
191    ;  mov TMP0, prm4            ; dcscalar
192    ;  mov _EDX, _EAX
193    ;  shr TMP0, 1               ; TMP0 = dcscalar/2
194    ;  sar _EDX, 31              ; TMP1 = sign extend of _EAX (ready for division too)
195    ;  xor TMP0, _EDX            ; adjust TMP0 according to the sign of data[0]
196    ;  sub TMP0, _EDX
197    ;  add _EAX, TMP0
198    
199  .done  ;  mov TMP0, prm4           ; dcscalar
200                  ; caclulate  data[0] // (int32_t)dcscalar)  ;  idiv TMP0                 ; _EAX = _EDX:_EAX / dcscalar
201    
202                  mov     ecx, [esp + 12 + 16]    ; dcscalar  ;  mov _EDX, prm1            ; coeff again
203                  mov     edx, ecx  ;  mov word [_EDX], ax       ; coeff[0] = ax
                 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  
   
                 mov     [edi], ax               ; coeff[0] = ax  
   
                 pop     edi  
                 pop     esi  
                 pop     ecx  
204    
205      xor _EAX, _EAX            ; return(0);
206                  ret                  ret
207    ENDFUNC
208    
 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  
209    
210          paddw   mm0, mm5  ;-----------------------------------------------------------------------------
                 paddw   mm3, mm5  
   
                 psrlw   mm0, 2                  ; mm0 >>= 1   (/4)  
                 psrlw   mm3, 2                  ;  
   
                 pxor    mm0, mm1                ; mm0 *= sign(mm0)  
                 pxor    mm3, mm4        ;  
                 psubw   mm0, mm1                ; undisplace  
                 psubw   mm3, mm4                ;  
   
                 movq    [edi + 8*ecx], mm0  
                 movq    [edi + 8*ecx + 8], mm3  
   
                 add ecx,2  
                 cmp ecx,16  
                 jnz     near .q2loop  
                 jmp     near .done  
   
   
 ;===========================================================================  
211  ;  ;
212  ; uint32_t quant4_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
213  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
214  ;                                       const uint32_t quant);  ;                               const uint32_t quant,
215    ;                               const uint16_t *mpeg_matrices);
216  ;  ;
217  ;===========================================================================  ;-----------------------------------------------------------------------------
218    
219  align ALIGN  ALIGN SECTION_ALIGN
 cglobal quant_mpeg_inter_mmx  
220  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
221    
222                  push    ecx    mov TMP1, prm1           ; coeff
223                  push    esi    mov _EAX, prm3           ; quant
224                  push    edi    mov TMP0, prm4           ; mpeg_quant_matrices
225    
226                  mov     edi, [esp + 12 + 4]             ; coeff    push _ESI
227                  mov     esi, [esp + 12 + 8]             ; data  %ifdef ARCH_IS_X86_64
228                  mov     eax, [esp + 12 + 12]    ; quant    mov _ESI, prm2           ; data
229    %else
230      mov _ESI, [_ESP + 4 + 8] ; data
231    %endif
232    
233                  xor ecx, ecx    push _EBX
234      xor _EBX, _EBX
235    
236                  pxor mm5, mm5                                   ; sum                  pxor mm5, mm5                                   ; sum
237    
# Line 499  Line 241 
241                  cmp     al, 2                  cmp     al, 2
242                  jz  near .q2loop                  jz  near .q2loop
243    
244                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider  %ifdef ARCH_IS_X86_64
245      lea r9, [mmx_div]
246      movq mm7, [r9 + _EAX * 8 - 8]
247    %else
248      movq mm7, [mmx_div + _EAX * 8 - 8] ; divider
249    %endif
250    
251  align ALIGN  ALIGN SECTION_ALIGN
252  .loop  .loop:
253                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
254                  movq    mm3, [esi + 8*ecx + 8]  ;    movq mm3, [_ESI + 8*_EBX + 8]   ;
255                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
256                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
257                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
# Line 513  Line 260 
260                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
261                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
262                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
263                  psllw   mm0, 4                  psllw   mm0, 4
264                  psllw   mm3, 4                  psllw   mm3, 4
265      movq mm2, [TMP0 + 512 + 8*_EBX]
                 movq    mm2, [inter_matrix + 8*ecx]  
266                  psrlw   mm2, 1                  psrlw   mm2, 1
267                  paddw   mm0, mm2                  paddw   mm0, mm2
268      movq mm2, [TMP0 + 768 + _EBX*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
269                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
270      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
271                  psrlw   mm2, 1                  psrlw   mm2, 1
272                  paddw   mm3, mm2                  paddw   mm3, mm2
273      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
274                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
275                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
276                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
277                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
278                  psrlw   mm3, 1                  psrlw   mm3, 1
   
279                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
280                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
281                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
282                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
283                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
284                  psubw   mm3, mm4                  psubw   mm3, mm4
285                  movq    [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
286                  movq    [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
287    
288                  add ecx, 2    add _EBX, 2
289                  cmp ecx, 16    cmp _EBX, 16
290                  jnz near .loop                  jnz near .loop
291    
292  .done  .done:
293                  pmaddwd mm5, [mmx_one]                  pmaddwd mm5, [mmx_one]
294                  movq    mm0, mm5                  movq    mm0, mm5
295                  psrlq   mm5, 32                  psrlq   mm5, 32
296                  paddd   mm0, mm5                  paddd   mm0, mm5
297                  movd    eax, mm0                ; return sum                  movd    eax, mm0                ; return sum
298    
299                  pop     edi    pop _EBX
300                  pop     esi    pop _ESI
                 pop ecx  
301    
302                  ret                  ret
303    
304  align ALIGN  ALIGN SECTION_ALIGN
305  .q1loop  .q1loop:
306                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
307                  movq    mm3, [esi + 8*ecx+ 8]    movq mm3, [_ESI + 8*_EBX+ 8]
                                 ;  
308                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
309                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
310                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
311                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
312                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
313                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
314                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
315                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
316                  psllw   mm0, 4                  psllw   mm0, 4
317                  psllw   mm3, 4                  psllw   mm3, 4
318      movq mm2, [TMP0 + 512 + 8*_EBX]
                 movq    mm2, [inter_matrix + 8*ecx]  
319                  psrlw   mm2, 1                  psrlw   mm2, 1
320                  paddw   mm0, mm2                  paddw   mm0, mm2
321      movq mm2, [TMP0 + 768 + _EBX*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
322                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
323      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
324                  psrlw   mm2, 1                  psrlw   mm2, 1
325                  paddw   mm3, mm2                  paddw   mm3, mm2
326      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
327                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
328                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
329                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
330                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
331                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
332                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
333                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
334                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
335                  psubw   mm3, mm4                  psubw   mm3, mm4
336      movq [TMP1 + 8*_EBX], mm0
337      movq [TMP1 + 8*_EBX + 8], mm3
338    
339                  movq    [edi + 8*ecx], mm0    add _EBX, 2
340                  movq    [edi + 8*ecx + 8], mm3    cmp _EBX, 16
   
                 add ecx,2  
                 cmp ecx,16  
341                  jnz     near .q1loop                  jnz     near .q1loop
342    
343                  jmp     .done                  jmp     .done
344    
345    ALIGN SECTION_ALIGN
346  align ALIGN  .q2loop:
347  .q2loop    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
348                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm3, [_ESI + 8*_EBX+ 8]
                 movq    mm3, [esi + 8*ecx+ 8]  
                                 ;  
349                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
350                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
351                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
352                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
353                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
354                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
355                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
356                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
357                  psllw   mm0, 4                  psllw   mm0, 4
358                  psllw   mm3, 4                  psllw   mm3, 4
359      movq mm2, [TMP0 + 512 + 8*_EBX]
                 movq    mm2, [inter_matrix + 8*ecx]  
360                  psrlw   mm2, 1                  psrlw   mm2, 1
361                  paddw   mm0, mm2                  paddw   mm0, mm2
362      movq mm2, [TMP0 + 768 + _EBX*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
363                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
364      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
365                  psrlw   mm2, 1                  psrlw   mm2, 1
366                  paddw   mm3, mm2                  paddw   mm3, mm2
367      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
368                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
369                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
370                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
371                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
372                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
373                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
374                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
375                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
376                  psubw   mm3, mm4                  psubw   mm3, mm4
377      movq [TMP1 + 8*_EBX], mm0
378      movq [TMP1 + 8*_EBX + 8], mm3
379    
380                  movq    [edi + 8*ecx], mm0    add _EBX, 2
381                  movq    [edi + 8*ecx + 8], mm3    cmp _EBX, 16
   
                 add ecx,2  
                 cmp ecx,16  
382                  jnz     near .q2loop                  jnz     near .q2loop
383    
384                  jmp     .done                  jmp     .done
385    ENDFUNC
386    
387    
388  ;===========================================================================  ;-----------------------------------------------------------------------------
389  ;  ;
390  ; void dequant4_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
391  ;                    const int16_t const *coeff,  ;                    const int16_t const *coeff,
392  ;                    const uint32_t quant,  ;                    const uint32_t quant,
393  ;                    const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
394    ;                                 const uint16_t *mpeg_matrices);
395  ;  ;
396  ;===========================================================================  ;-----------------------------------------------------------------------------
397    
398    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
399    ; 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 689  Line 407 
407    ; The original loop is:    ; The original loop is:
408    ;    ;
409  %if 0  %if 0
410    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = coeff[i]
411    pxor mm1, mm1    pxor mm1, mm1
412    pcmpgtw mm1, mm0    pcmpgtw mm1, mm0
413    pxor mm0, mm1     ; change sign if negative    pxor mm0, mm1     ; change sign if negative
414    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
415    
416    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
417    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant.
418    
419    movq mm6, mm2    movq mm6, mm2
420    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 710  Line 428 
428    por mm0, mm2      ; saturate to 2047 if needed    por mm0, mm2      ; saturate to 2047 if needed
429    pxor mm0, mm1     ; finish negating back    pxor mm0, mm1     ; finish negating back
430    
431    movq [edx + 8*eax + 8*16], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16], mm0   ; data[i]
432    add eax, 1    add _EAX, 1
433  %endif  %endif
434    
435    ;********************************************************************    ;********************************************************************
436    
437  align 16  ALIGN SECTION_ALIGN
 cglobal dequant_mpeg_intra_mmx  
438  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
439    
440    mov edx, [esp+4]  ; data    mov TMP1, prm1  ; data
441    mov ecx, [esp+8]  ; coeff    mov TMP0, prm2  ; coeff
442    mov eax, [esp+12] ; quant    mov _EAX, prm5  ; mpeg_quant_matrices
443    
444      push _EBX
445      mov _EBX, _EAX
446    %ifdef ARCH_IS_X86_64
447      mov _EAX, prm3
448      lea r9, [mmx_mul_quant]
449      movq mm7, [r9 + _EAX*8 - 8]
450    %else
451      mov _EAX, [_ESP + 4 + 12] ; quant
452      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
453    %endif
454    
455    movq mm7, [mmx_mul_quant  + eax*8 - 8]    mov _EAX, -16      ; to keep ALIGNed, we regularly process coeff[0]
   mov eax, -16   ; to keep aligned, we regularly process coeff[0]  
456    psllw mm7, 2   ; << 2. See comment.    psllw mm7, 2   ; << 2. See comment.
457    pxor mm6, mm6   ; this is a NOP    pxor mm6, mm6   ; this is a NOP
458    
459  align 16  ALIGN SECTION_ALIGN
460  .loop  .loop:
461    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = c  = coeff[i]
462    movq mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]    movq mm3, [TMP0+8*_EAX + 8*16 +8]; mm3 = c' = coeff[i+1]
463    pxor mm1, mm1    pxor mm1, mm1
464    pxor mm4, mm4    pxor mm4, mm4
465    pcmpgtw mm1, mm0  ; mm1 = sgn(c)    pcmpgtw mm1, mm0  ; mm1 = sgn(c)
466    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
467    
468    pcmpgtw mm4, mm3  ; mm4 = sgn(c')    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
469    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant
470    
471    pxor mm0, mm1     ; negate if negative    pxor mm0, mm1     ; negate if negative
472    pxor mm3, mm4     ; negate if negative    pxor mm3, mm4     ; negate if negative
# Line 755  Line 482 
482    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
483    movq mm5, mm7     ; mm2 = quant    movq mm5, mm7     ; mm2 = quant
484    
485    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
486    
487    movq mm6, mm5    movq mm6, mm5
488    add eax,2   ; z-flag will be tested later    add _EAX,2   ; z-flag will be tested later
489    
490    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)
491    pmulhw mm3, mm5   ; high of coeff*(matrix*quant)    pmulhw mm3, mm5   ; high of coeff*(matrix*quant)
# Line 780  Line 507 
507    psubw mm2, mm1 ; finish negating back    psubw mm2, mm1 ; finish negating back
508    psubw mm6, mm4 ; finish negating back    psubw mm6, mm4 ; finish negating back
509    
510    movq [edx + 8*eax + 8*16   -2*8   ], mm2   ; data[i]    movq [TMP1 + 8*_EAX + 8*16   -2*8   ], mm2   ; data[i]
511    movq [edx + 8*eax + 8*16   -2*8 +8], mm6   ; data[i+1]    movq [TMP1 + 8*_EAX + 8*16   -2*8 +8], mm6   ; data[i+1]
512    
513    jnz near .loop    jnz near .loop
514    
515      ; deal with DC    pop _EBX
516    
517    movd mm0, [ecx]      ; deal with DC
518    pmullw mm0, [esp+16]  ; dcscalar    movd mm0, [TMP0]
519    %ifdef ARCH_IS_X86_64
520      movq mm6, prm4
521      pmullw mm0, mm6
522    %else
523      pmullw mm0, prm4  ; dcscalar
524    %endif
525    movq mm2, [mmx_32767_minus_2047]    movq mm2, [mmx_32767_minus_2047]
526    paddsw mm0, mm2    paddsw mm0, mm2
527    psubsw mm0, mm2    psubsw mm0, mm2
# Line 796  Line 529 
529    psubsw mm0, mm2    psubsw mm0, mm2
530    paddsw mm0, mm2    paddsw mm0, mm2
531    movd eax, mm0    movd eax, mm0
532    mov [edx], ax    mov [TMP1], ax
533    
534      xor _EAX, _EAX
535    
536    ret    ret
537    ENDFUNC
538    
539  ;===========================================================================  ;-----------------------------------------------------------------------------
540  ;  ;
541  ; void dequant4_inter_mmx(int16_t * data,  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,
542  ;                    const int16_t * const coeff,  ;                    const int16_t * const coeff,
543  ;                    const uint32_t quant);  ;                                 const uint32_t quant,
544    ;                                 const uint16_t *mpeg_matrices);
545  ;  ;
546  ;===========================================================================  ;-----------------------------------------------------------------------------
547    
548      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
549      ; 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.
550      ; 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.
551      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
552    
553  align 16  ALIGN SECTION_ALIGN
 cglobal dequant_mpeg_inter_mmx  
554  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
555    
556    mov    edx, [esp+ 4]        ; data  
557    mov    ecx, [esp+ 8]        ; coeff    mov TMP1, prm1        ; data
558    mov    eax, [esp+12]        ; quant    mov TMP0, prm2        ; coeff
559    movq mm7, [mmx_mul_quant  + eax*8 - 8]    mov _EAX, prm3        ; quant
560    mov eax, -16  
561      push _EBX
562    %ifdef ARCH_IS_X86_64
563      mov _EBX, prm4
564      lea r9, [mmx_mul_quant]
565      movq mm7, [r9 + _EAX*8 - 8]
566    %else
567      mov _EBX, [_ESP + 4 + 16]     ; mpeg_quant_matrices
568      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
569    %endif
570    
571      mov _EAX, -16
572    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
573    pxor mm6, mm6 ; mismatch sum    pxor mm6, mm6 ; mismatch sum
574    
575  align 16  ALIGN SECTION_ALIGN
576  .loop  .loop:
577    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16   ]   ; mm0 = coeff[i]
578    movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]    movq mm2, [TMP0+8*_EAX + 8*16 +8]   ; mm2 = coeff[i+1]
579    add eax,2    add _EAX, 2
580    
581    pxor mm1, mm1    pxor mm1, mm1
582    pxor mm3, mm3    pxor mm3, mm3
# Line 854  Line 601 
601      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
602    
603    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
604    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8]
605    movq mm5, mm4    movq mm5, mm4
606    pmulhw mm5, mm0   ; high of c*(matrix*quant)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
607    pmullw mm0, mm4   ; low  of c*(matrix*quant)    pmullw mm0, mm4   ; low  of c*(matrix*quant)
608    
609    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
610    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8 + 8]
611    
612    pcmpgtw mm5, [zero]    pcmpgtw mm5, [zero]
613    paddusw mm0, mm5    paddusw mm0, mm5
# Line 881  Line 628 
628    psubw mm2, mm3   ; finish restoring sign    psubw mm2, mm3   ; finish restoring sign
629    
630    pxor mm6, mm0     ; mismatch control    pxor mm6, mm0     ; mismatch control
631    movq [edx + 8*eax + 8*16 -2*8   ], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16 -2*8   ], mm0   ; data[i]
632    pxor mm6, mm2     ; mismatch control    pxor mm6, mm2     ; mismatch control
633    movq [edx + 8*eax + 8*16 -2*8 +8], mm2   ; data[i+1]    movq [TMP1 + 8*_EAX + 8*16 -2*8 +8], mm2   ; data[i+1]
634    
635    jnz near .loop    jnz near .loop
636    
# Line 899  Line 646 
646    pxor mm6, mm1    pxor mm6, mm1
647    pxor mm6, mm2    pxor mm6, mm2
648    movd eax, mm6    movd eax, mm6
649    and eax, 1    and _EAX, 1
650    xor eax, 1    xor _EAX, 1
651    xor word [edx + 2*63], ax    xor word [TMP1 + 2*63], ax
652    
653      xor _EAX, _EAX
654    
655      pop _EBX
656    
657    ret    ret
658    ENDFUNC
659    
660    
661    %ifidn __OUTPUT_FORMAT__,elf
662    section ".note.GNU-stack" noalloc noexec nowrite progbits
663    %endif
664    

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

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