[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.16, Wed Sep 16 17:07:58 2009 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  TEXT
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    
196      xor TMP0, _EDX           ; adjust TMP0 according to the sign of data[0]
197      sub TMP0, _EDX
198      add _EAX, TMP0
199    
200  .done    mov TMP0, prm4            ; dcscalar
201                  ; caclulate  data[0] // (int32_t)dcscalar)    idiv TMP0                 ; _EAX = _EDX:_EAX / dcscalar
202    
203                  mov     ecx, [esp + 12 + 16]    ; dcscalar    mov _EDX, prm1            ; coeff again
204                  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  
205    
206      xor _EAX, _EAX            ; return(0);
207                  ret                  ret
208    ENDFUNC
209    
 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]  
210    
211                  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                ;  
   
                 movq    [edi + 8*ecx], mm0  
                 movq    [edi + 8*ecx + 8], mm3  
   
                 add ecx,2  
                 cmp ecx,16  
                 jnz     near .q2loop  
                 jmp     near .done  
   
   
 ;===========================================================================  
212  ;  ;
213  ; uint32_t quant4_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
214  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
215  ;                                       const uint32_t quant);  ;                               const uint32_t quant,
216    ;                               const uint16_t *mpeg_matrices);
217  ;  ;
218  ;===========================================================================  ;-----------------------------------------------------------------------------
219    
220  align ALIGN  ALIGN SECTION_ALIGN
 cglobal quant_mpeg_inter_mmx  
221  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
222    
223                  push    ecx    mov TMP1, prm1           ; coeff
224                  push    esi    mov _EAX, prm3           ; quant
225                  push    edi    mov TMP0, prm4           ; mpeg_quant_matrices
226    
227                  mov     edi, [esp + 12 + 4]             ; coeff    push _ESI
228                  mov     esi, [esp + 12 + 8]             ; data  %ifdef ARCH_IS_X86_64
229                  mov     eax, [esp + 12 + 12]    ; quant    mov _ESI, prm2           ; data
230    %else
231      mov _ESI, [_ESP + 4 + 8] ; data
232    %endif
233    
234                  xor ecx, ecx    push _EBX
235      xor _EBX, _EBX
236    
237                  pxor mm5, mm5                                   ; sum                  pxor mm5, mm5                                   ; sum
238    
# Line 499  Line 242 
242                  cmp     al, 2                  cmp     al, 2
243                  jz  near .q2loop                  jz  near .q2loop
244    
245                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider  %ifdef ARCH_IS_X86_64
246      lea r9, [mmx_div]
247      movq mm7, [r9 + _EAX * 8 - 8]
248    %else
249      movq mm7, [mmx_div + _EAX * 8 - 8] ; divider
250    %endif
251    
252  align ALIGN  ALIGN SECTION_ALIGN
253  .loop  .loop:
254                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
255                  movq    mm3, [esi + 8*ecx + 8]  ;    movq mm3, [_ESI + 8*_EBX + 8]   ;
256                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
257                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
258                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
# Line 513  Line 261 
261                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
262                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
263                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
264                  psllw   mm0, 4                  psllw   mm0, 4
265                  psllw   mm3, 4                  psllw   mm3, 4
266      movq mm2, [TMP0 + 512 + 8*_EBX]
                 movq    mm2, [inter_matrix + 8*ecx]  
267                  psrlw   mm2, 1                  psrlw   mm2, 1
268                  paddw   mm0, mm2                  paddw   mm0, mm2
269      movq mm2, [TMP0 + 768 + _EBX*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
270                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
271      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
272                  psrlw   mm2, 1                  psrlw   mm2, 1
273                  paddw   mm3, mm2                  paddw   mm3, mm2
274      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
275                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
276                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
277                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
278                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
279                  psrlw   mm3, 1                  psrlw   mm3, 1
   
280                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
281                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
282                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
283                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
284                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
285                  psubw   mm3, mm4                  psubw   mm3, mm4
286                  movq    [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
287                  movq    [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
288    
289                  add ecx, 2    add _EBX, 2
290                  cmp ecx, 16    cmp _EBX, 16
291                  jnz near .loop                  jnz near .loop
292    
293  .done  .done:
294                  pmaddwd mm5, [mmx_one]                  pmaddwd mm5, [mmx_one]
295                  movq    mm0, mm5                  movq    mm0, mm5
296                  psrlq   mm5, 32                  psrlq   mm5, 32
297                  paddd   mm0, mm5                  paddd   mm0, mm5
298                  movd    eax, mm0                ; return sum                  movd    eax, mm0                ; return sum
299    
300                  pop     edi    pop _EBX
301                  pop     esi    pop _ESI
                 pop ecx  
302    
303                  ret                  ret
304    
305  align ALIGN  ALIGN SECTION_ALIGN
306  .q1loop  .q1loop:
307                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
308                  movq    mm3, [esi + 8*ecx+ 8]    movq mm3, [_ESI + 8*_EBX+ 8]
                                 ;  
309                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
310                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
311                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
312                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
313                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
314                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
315                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
316                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
317                  psllw   mm0, 4                  psllw   mm0, 4
318                  psllw   mm3, 4                  psllw   mm3, 4
319      movq mm2, [TMP0 + 512 + 8*_EBX]
                 movq    mm2, [inter_matrix + 8*ecx]  
320                  psrlw   mm2, 1                  psrlw   mm2, 1
321                  paddw   mm0, mm2                  paddw   mm0, mm2
322      movq mm2, [TMP0 + 768 + _EBX*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
323                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
324      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
325                  psrlw   mm2, 1                  psrlw   mm2, 1
326                  paddw   mm3, mm2                  paddw   mm3, mm2
327      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
328                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
329                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
330                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
331                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
332                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
333                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
334                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
335                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
336                  psubw   mm3, mm4                  psubw   mm3, mm4
337      movq [TMP1 + 8*_EBX], mm0
338      movq [TMP1 + 8*_EBX + 8], mm3
339    
340                  movq    [edi + 8*ecx], mm0    add _EBX, 2
341                  movq    [edi + 8*ecx + 8], mm3    cmp _EBX, 16
   
                 add ecx,2  
                 cmp ecx,16  
342                  jnz     near .q1loop                  jnz     near .q1loop
343    
344                  jmp     .done                  jmp     .done
345    
346    ALIGN SECTION_ALIGN
347  align ALIGN  .q2loop:
348  .q2loop    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
349                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm3, [_ESI + 8*_EBX+ 8]
                 movq    mm3, [esi + 8*ecx+ 8]  
                                 ;  
350                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
351                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
352                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
353                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
354                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
355                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
356                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
357                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
358                  psllw   mm0, 4                  psllw   mm0, 4
359                  psllw   mm3, 4                  psllw   mm3, 4
360      movq mm2, [TMP0 + 512 + 8*_EBX]
                 movq    mm2, [inter_matrix + 8*ecx]  
361                  psrlw   mm2, 1                  psrlw   mm2, 1
362                  paddw   mm0, mm2                  paddw   mm0, mm2
363      movq mm2, [TMP0 + 768 + _EBX*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
364                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
365      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
366                  psrlw   mm2, 1                  psrlw   mm2, 1
367                  paddw   mm3, mm2                  paddw   mm3, mm2
368      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
369                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
370                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
371                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
372                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
373                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
374                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
375                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
376                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
377                  psubw   mm3, mm4                  psubw   mm3, mm4
378      movq [TMP1 + 8*_EBX], mm0
379      movq [TMP1 + 8*_EBX + 8], mm3
380    
381                  movq    [edi + 8*ecx], mm0    add _EBX, 2
382                  movq    [edi + 8*ecx + 8], mm3    cmp _EBX, 16
   
                 add ecx,2  
                 cmp ecx,16  
383                  jnz     near .q2loop                  jnz     near .q2loop
384    
385                  jmp     .done                  jmp     .done
386    ENDFUNC
387    
388    
389  ;===========================================================================  ;-----------------------------------------------------------------------------
390  ;  ;
391  ; void dequant4_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
392  ;                    const int16_t const *coeff,  ;                    const int16_t const *coeff,
393  ;                    const uint32_t quant,  ;                    const uint32_t quant,
394  ;                    const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
395    ;                                 const uint16_t *mpeg_matrices);
396  ;  ;
397  ;===========================================================================  ;-----------------------------------------------------------------------------
398    
399    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
400    ; 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 408 
408    ; The original loop is:    ; The original loop is:
409    ;    ;
410  %if 0  %if 0
411    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = coeff[i]
412    pxor mm1, mm1    pxor mm1, mm1
413    pcmpgtw mm1, mm0    pcmpgtw mm1, mm0
414    pxor mm0, mm1     ; change sign if negative    pxor mm0, mm1     ; change sign if negative
415    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
416    
417    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
418    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant.
419    
420    movq mm6, mm2    movq mm6, mm2
421    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 429 
429    por mm0, mm2      ; saturate to 2047 if needed    por mm0, mm2      ; saturate to 2047 if needed
430    pxor mm0, mm1     ; finish negating back    pxor mm0, mm1     ; finish negating back
431    
432    movq [edx + 8*eax + 8*16], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16], mm0   ; data[i]
433    add eax, 1    add _EAX, 1
434  %endif  %endif
435    
436    ;********************************************************************    ;********************************************************************
437    
438  align 16  ALIGN SECTION_ALIGN
 cglobal dequant_mpeg_intra_mmx  
439  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
440    
441    mov edx, [esp+4]  ; data    mov TMP1, prm1  ; data
442    mov ecx, [esp+8]  ; coeff    mov TMP0, prm2  ; coeff
443    mov eax, [esp+12] ; quant    mov _EAX, prm5  ; mpeg_quant_matrices
444    
445      push _EBX
446      mov _EBX, _EAX
447    %ifdef ARCH_IS_X86_64
448      mov _EAX, prm3
449      lea prm1, [mmx_mul_quant]
450      movq mm7, [prm1 + _EAX*8 - 8]
451    %else
452      mov _EAX, [_ESP + 4 + 12] ; quant
453      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
454    %endif
455    
456    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]  
457    psllw mm7, 2   ; << 2. See comment.    psllw mm7, 2   ; << 2. See comment.
458    pxor mm6, mm6   ; this is a NOP    pxor mm6, mm6   ; this is a NOP
459    
460  align 16  ALIGN SECTION_ALIGN
461  .loop  .loop:
462    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = c  = coeff[i]
463    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]
464    pxor mm1, mm1    pxor mm1, mm1
465    pxor mm4, mm4    pxor mm4, mm4
466    pcmpgtw mm1, mm0  ; mm1 = sgn(c)    pcmpgtw mm1, mm0  ; mm1 = sgn(c)
467    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
468    
469    pcmpgtw mm4, mm3  ; mm4 = sgn(c')    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
470    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant
471    
472    pxor mm0, mm1     ; negate if negative    pxor mm0, mm1     ; negate if negative
473    pxor mm3, mm4     ; negate if negative    pxor mm3, mm4     ; negate if negative
# Line 755  Line 483 
483    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
484    movq mm5, mm7     ; mm2 = quant    movq mm5, mm7     ; mm2 = quant
485    
486    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
487    
488    movq mm6, mm5    movq mm6, mm5
489    add eax,2   ; z-flag will be tested later    add _EAX,2   ; z-flag will be tested later
490    
491    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)
492    pmulhw mm3, mm5   ; high of coeff*(matrix*quant)    pmulhw mm3, mm5   ; high of coeff*(matrix*quant)
# Line 780  Line 508 
508    psubw mm2, mm1 ; finish negating back    psubw mm2, mm1 ; finish negating back
509    psubw mm6, mm4 ; finish negating back    psubw mm6, mm4 ; finish negating back
510    
511    movq [edx + 8*eax + 8*16   -2*8   ], mm2   ; data[i]    movq [TMP1 + 8*_EAX + 8*16   -2*8   ], mm2   ; data[i]
512    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]
513    
514    jnz near .loop    jnz near .loop
515    
516      ; deal with DC    pop _EBX
517    
518    movd mm0, [ecx]      ; deal with DC
519    pmullw mm0, [esp+16]  ; dcscalar    movd mm0, [TMP0]
520    %ifdef ARCH_IS_X86_64
521      movq mm6, prm4
522      pmullw mm0, mm6
523    %else
524      pmullw mm0, prm4  ; dcscalar
525    %endif
526    movq mm2, [mmx_32767_minus_2047]    movq mm2, [mmx_32767_minus_2047]
527    paddsw mm0, mm2    paddsw mm0, mm2
528    psubsw mm0, mm2    psubsw mm0, mm2
# Line 796  Line 530 
530    psubsw mm0, mm2    psubsw mm0, mm2
531    paddsw mm0, mm2    paddsw mm0, mm2
532    movd eax, mm0    movd eax, mm0
533    mov [edx], ax    mov [TMP1], ax
534    
535      xor _EAX, _EAX
536    
537    ret    ret
538    ENDFUNC
539    
540  ;===========================================================================  ;-----------------------------------------------------------------------------
541  ;  ;
542  ; void dequant4_inter_mmx(int16_t * data,  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,
543  ;                    const int16_t * const coeff,  ;                    const int16_t * const coeff,
544  ;                    const uint32_t quant);  ;                                 const uint32_t quant,
545    ;                                 const uint16_t *mpeg_matrices);
546  ;  ;
547  ;===========================================================================  ;-----------------------------------------------------------------------------
548    
549      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
550      ; 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.
551      ; 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.
552      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
553    
554  align 16  ALIGN SECTION_ALIGN
 cglobal dequant_mpeg_inter_mmx  
555  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
556    
557    mov    edx, [esp+ 4]        ; data  
558    mov    ecx, [esp+ 8]        ; coeff    mov TMP1, prm1        ; data
559    mov    eax, [esp+12]        ; quant    mov TMP0, prm2        ; coeff
560    movq mm7, [mmx_mul_quant  + eax*8 - 8]    mov _EAX, prm3        ; quant
561    mov eax, -16  
562      push _EBX
563    %ifdef ARCH_IS_X86_64
564      mov _EBX, prm4
565      lea r9, [mmx_mul_quant]
566      movq mm7, [r9 + _EAX*8 - 8]
567    %else
568      mov _EBX, [_ESP + 4 + 16]     ; mpeg_quant_matrices
569      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
570    %endif
571    
572      mov _EAX, -16
573    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
574    pxor mm6, mm6 ; mismatch sum    pxor mm6, mm6 ; mismatch sum
575    
576  align 16  ALIGN SECTION_ALIGN
577  .loop  .loop:
578    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16   ]   ; mm0 = coeff[i]
579    movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]    movq mm2, [TMP0+8*_EAX + 8*16 +8]   ; mm2 = coeff[i+1]
580    add eax,2    add _EAX, 2
581    
582    pxor mm1, mm1    pxor mm1, mm1
583    pxor mm3, mm3    pxor mm3, mm3
# Line 854  Line 602 
602      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
603    
604    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
605    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8]
606    movq mm5, mm4    movq mm5, mm4
607    pmulhw mm5, mm0   ; high of c*(matrix*quant)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
608    pmullw mm0, mm4   ; low  of c*(matrix*quant)    pmullw mm0, mm4   ; low  of c*(matrix*quant)
609    
610    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
611    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8 + 8]
612    
613    pcmpgtw mm5, [zero]    pcmpgtw mm5, [zero]
614    paddusw mm0, mm5    paddusw mm0, mm5
# Line 881  Line 629 
629    psubw mm2, mm3   ; finish restoring sign    psubw mm2, mm3   ; finish restoring sign
630    
631    pxor mm6, mm0     ; mismatch control    pxor mm6, mm0     ; mismatch control
632    movq [edx + 8*eax + 8*16 -2*8   ], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16 -2*8   ], mm0   ; data[i]
633    pxor mm6, mm2     ; mismatch control    pxor mm6, mm2     ; mismatch control
634    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]
635    
636    jnz near .loop    jnz near .loop
637    
# Line 899  Line 647 
647    pxor mm6, mm1    pxor mm6, mm1
648    pxor mm6, mm2    pxor mm6, mm2
649    movd eax, mm6    movd eax, mm6
650    and eax, 1    and _EAX, 1
651    xor eax, 1    xor _EAX, 1
652    xor word [edx + 2*63], ax    xor word [TMP1 + 2*63], ax
653    
654      xor _EAX, _EAX
655    
656      pop _EBX
657    
658    ret    ret
659    ENDFUNC
660    
661    NON_EXEC_STACK

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

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