[cvs] / xvidcore / src / quant / x86_asm / quantize_mpeg_xmm.asm Repository:
ViewVC logotype

Diff of /xvidcore/src/quant/x86_asm/quantize_mpeg_xmm.asm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.2.5, Sun Nov 30 16:13:16 2003 UTC revision 1.13, Wed Sep 16 17:07:58 2009 UTC
# Line 29  Line 29 
29    
30  %define SATURATE  %define SATURATE
31    
32  BITS 32  %include "nasm.inc"
   
 %macro cglobal 1  
         %ifdef PREFIX  
                 global _%1  
                 %define %1 _%1  
         %else  
                 global %1  
         %endif  
 %endmacro  
   
 %macro cextern 1  
         %ifdef PREFIX  
                 extern _%1  
                 %define %1 _%1  
         %else  
                 extern %1  
         %endif  
 %endmacro  
33    
34  ;=============================================================================  ;=============================================================================
35  ; Local data  ; Local data
36  ;=============================================================================  ;=============================================================================
37    
38  %ifdef FORMAT_COFF  DATA
 SECTION .rodata data  
 %else  
 SECTION .rodata data align=16  
 %endif  
39    
40  ALIGN 8  ALIGN SECTION_ALIGN
41  mmzero:  mmzero:
42          dd 0,0          dd 0,0
43  mmx_one:  mmx_one:
# Line 69  Line 47 
47  ; divide by 2Q table  ; divide by 2Q table
48  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
49    
50  ALIGN 16  ALIGN SECTION_ALIGN
51  mmx_divs:               ;i>2  mmx_divs:               ;i>2
52  %assign i 1  %assign i 1
53  %rep 31  %rep 31
# Line 77  Line 55 
55          %assign i i+1          %assign i i+1
56  %endrep  %endrep
57    
58  ALIGN 16  ALIGN SECTION_ALIGN
59  mmx_div:                ;quant>2  mmx_div:                ;quant>2
60          times 4 dw 65535 ; the div by 2 formula will overflow for the case          times 4 dw 65535 ; the div by 2 formula will overflow for the case
61                           ; quant=1 but we don't care much because quant=1                           ; quant=1 but we don't care much because quant=1
# Line 93  Line 71 
71  dw (1 << 16) / (%1) + 1  dw (1 << 16) / (%1) + 1
72  %endmacro  %endmacro
73    
74    %ifndef ARCH_IS_X86_64
75  %define nop4    db      08Dh, 074h, 026h,0  %define nop4    db      08Dh, 074h, 026h,0
 %define nop3    add     esp, byte 0  
 %define nop2    mov     esp, esp  
76  %define nop7    db      08dh, 02ch, 02dh,0,0,0,0  %define nop7    db      08dh, 02ch, 02dh,0,0,0,0
77  %define nop6    add     ebp, dword 0  %else
78    %define nop4
79    %define nop7
80    %endif
81    %define nop3    add     _ESP, byte 0
82    %define nop2    mov     _ESP, _ESP
83    %define nop6    add     _EBP, dword 0
84    
85  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
86  ; quantd table  ; quantd table
# Line 106  Line 89 
89  %define VM18P   3  %define VM18P   3
90  %define VM18Q   4  %define VM18Q   4
91    
92  ALIGN 16  ALIGN SECTION_ALIGN
93  quantd:  quantd:
94  %assign i 1  %assign i 1
95  %rep 31  %rep 31
# Line 118  Line 101 
101  ; multiple by 2Q table  ; multiple by 2Q table
102  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
103    
104  ALIGN 16  ALIGN SECTION_ALIGN
105  mmx_mul_quant:  mmx_mul_quant:
106  %assign i 1  %assign i 1
107  %rep 31  %rep 31
# Line 130  Line 113 
113  ; saturation limits  ; saturation limits
114  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
115    
116  ALIGN 16  ALIGN SECTION_ALIGN
117  mmx_32767_minus_2047:  mmx_32767_minus_2047:
118          times 4 dw (32767-2047)          times 4 dw (32767-2047)
119  mmx_32768_minus_2048:  mmx_32768_minus_2048:
# Line 154  Line 137 
137  ; Code  ; Code
138  ;=============================================================================  ;=============================================================================
139    
140  SECTION .text  TEXT
141    
 cglobal quant_mpeg_intra_xmm  
142  cglobal quant_mpeg_inter_xmm  cglobal quant_mpeg_inter_xmm
143  cglobal dequant_mpeg_intra_3dne  cglobal dequant_mpeg_intra_3dne
144  cglobal dequant_mpeg_inter_3dne  cglobal dequant_mpeg_inter_3dne
145    
146  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
147  ;  ;
 ; uint32_t quant_mpeg_intra_xmm(int16_t * coeff,  
 ;                               const int16_t const * data,  
 ;                               const uint32_t quant,  
 ;                               const uint32_t dcscalar,  
 ;                               const uint16_t *mpeg_matrices);  
 ;  
 ;-----------------------------------------------------------------------------  
   
 ALIGN 16  
 quant_mpeg_intra_xmm:  
   mov eax, [esp  + 8]       ; data  
   mov ecx, [esp  + 12]      ; quant  
   mov edx, [esp  + 4]       ; coeff  
   push esi  
   push edi  
   push ebx  
   nop  
   mov edi, [esp + 12 + 20]              ; mpeg_quant_matrices  
   mov esi, -14  
   pxor mm0, mm0  
   pxor mm3, mm3  
   cmp ecx, byte 1  
   je near .q1loop  
   cmp ecx, byte 19  
   jg near .lloop  
   nop6  
   
 ALIGN 16  
 .loop  
   movq mm1, [eax + 8*esi+112]   ; mm0 = [1st]  
   psubw mm0, mm1                ;-mm1  
   movq mm4, [eax + 8*esi + 120] ;  
   psubw mm3, mm4                ;-mm4  
   pmaxsw mm0, mm1               ;|src|  
   pmaxsw mm3,mm4  
   nop2  
   psraw mm1, 15     ;sign src  
   psraw mm4, 15  
   psllw mm0, 4      ;level << 4 ;  
   psllw mm3, 4  
   paddw mm0, [edi + 128 + 8*esi+112]  
   paddw mm3, [edi + 128 + 8*esi+120]  
   movq mm5, [edi + 384 + 8*esi+112]  
   movq mm7, [edi + 384 + 8*esi+120]  
   pmulhuw mm5, mm0  
   pmulhuw mm7, mm3  
   mov esp, esp  
   movq mm2, [edi + 8*esi+112]  
   movq mm6, [edi + 8*esi+120]  
   pmullw mm2, mm5  
   pmullw mm6, mm7  
   psubw mm0, mm2  
   psubw mm3, mm6  
   nop4  
   movq mm2, [quantd + ecx * 8 - 8]  
   movq mm6, [mmx_divs + ecx * 8 - 8]  
   paddw mm5, mm2  
   paddw mm7, mm2  
   mov esp, esp  
   pmulhuw mm0, [edi + 256 + 8*esi+112]  
   pmulhuw mm3, [edi + 256 + 8*esi+120]  
   paddw mm5, mm0  
   paddw mm7, mm3  
   pxor mm0, mm0  
   pxor mm3, mm3  
   pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16  
   pmulhuw mm7, mm6      ;  (level + quantd) / quant (0<quant<32)  
   pxor mm5, mm1         ; mm0 *= sign(mm0)  
   pxor mm7, mm4         ;  
   psubw mm5, mm1        ; undisplace  
   psubw mm7, mm4        ;  
   movq [edx + 8*esi+112], mm5  
   movq [edx + 8*esi +120], mm7  
   add esi, byte 2  
   jng near .loop  
   
 .done  
 ; calculate  data[0] // (int32_t)dcscalar)  
   mov esi, [esp + 12 + 16]  ; dcscalar  
   movsx ecx, word [eax]  
   mov edi, ecx  
   mov edx, [esp + 12 + 16]  
   shr edx, 1            ; ebx = dcscalar /2  
   sar edi, 31           ; cdq is vectorpath  
   xor edx, edi          ; ebx = eax V -eax -1  
   sub ecx, edi  
   add ecx, edx  
   mov edx, [dword esp + 12 + 4]  
   mov esi, [int_div+4*esi]  
   imul ecx, esi  
   sar ecx, 17  
   lea ebx, [byte ecx + 1]  
   cmovs ecx, ebx  
   ; idiv    cx          ; ecx = edi:ecx / dcscalar  
   
   mov ebx, [esp]  
   mov edi, [esp+4]  
   mov esi, [esp+8]  
   add esp, byte 12  
   mov [edx], cx     ; coeff[0] = ax  
   
   xor eax, eax  
   ret  
   
 ALIGN 16  
 .q1loop  
   movq mm1, [eax + 8*esi+112]               ; mm0 = [1st]  
   psubw mm0, mm1                            ;-mm1  
   movq mm4, [eax + 8*esi+120]               ;  
   psubw mm3, mm4                            ;-mm4  
   pmaxsw mm0, mm1                           ;|src|  
   pmaxsw mm3, mm4  
   nop2  
   psraw mm1, 15                             ;sign src  
   psraw mm4, 15  
   psllw mm0, 4                              ; level << 4  
   psllw mm3, 4  
   paddw mm0, [edi + 128 + 8*esi+112]    ;mm0 is to be divided  
   paddw mm3, [edi + 128 + 8*esi+120]    ;intra1 contains fix for division by 1  
   movq mm5, [edi + 384 + 8*esi+112] ;with rounding down  
   movq mm7, [edi + 384 + 8*esi+120]  
   pmulhuw mm5, mm0  
   pmulhuw mm7, mm3      ;mm7: first approx of division  
   mov esp, esp  
   movq mm2, [edi + 8*esi+112]  
   movq mm6, [edi + 8*esi+120]      ; divs for q<=16  
   pmullw mm2, mm5       ;test value <= original  
   pmullw mm6, mm7  
   psubw mm0, mm2        ;mismatch  
   psubw mm3, mm6  
   nop4  
   movq mm2, [quantd + ecx * 8 - 8]  
   paddw mm5, mm2        ;first approx with quantd  
   paddw mm7, mm2  
   mov esp, esp  
   pmulhuw mm0, [edi + 256 + 8*esi+112]   ;correction  
   pmulhuw mm3, [edi + 256 + 8*esi+120]  
   paddw mm5, mm0        ;final result with quantd  
   paddw mm7, mm3  
   pxor mm0, mm0  
   pxor mm3, mm3  
   mov esp, esp  
   psrlw mm5, 1          ;  (level + quantd) /2  (quant = 1)  
   psrlw mm7, 1  
   pxor mm5, mm1         ; mm0 *= sign(mm0)  
   pxor mm7, mm4         ;  
   psubw mm5, mm1        ; undisplace  
   psubw mm7, mm4        ;  
   movq [edx + 8*esi+112], mm5  
   movq [edx + 8*esi +120], mm7  
   add esi, byte 2  
   jng near .q1loop  
   jmp near .done  
   
 ALIGN 8  
 .lloop  
   movq mm1, [eax + 8*esi+112]       ; mm0 = [1st]  
   psubw mm0, mm1        ;-mm1  
   movq mm4, [eax + 8*esi+120]  
   psubw mm3, mm4        ;-mm4  
   pmaxsw mm0, mm1       ;|src|  
   pmaxsw mm3, mm4  
   nop2  
   psraw mm1, 15         ;sign src  
   psraw mm4, 15  
   psllw mm0, 4          ; level << 4  
   psllw mm3, 4          ;  
   paddw mm0, [edi + 128 + 8*esi+112] ;mm0 is to be divided intra1 contains fix for division by 1  
   paddw mm3, [edi + 128 + 8*esi+120]  
   movq mm5, [edi + 384 + 8*esi+112]  
   movq mm7, [edi + 384 + 8*esi+120]  
   pmulhuw mm5, mm0  
   pmulhuw mm7, mm3      ;mm7: first approx of division  
   mov esp, esp  
   movq mm2, [edi + 8*esi+112]  
   movq mm6, [edi + 8*esi+120]  
   pmullw mm2, mm5       ;test value <= original  
   pmullw mm6, mm7  
   psubw mm0, mm2        ;mismatch  
   psubw mm3, mm6  
   nop4  
   movq mm2, [quantd + ecx * 8 - 8]  
   movq mm6, [mmx_div + ecx * 8 - 8] ; divs for q<=16  
   paddw mm5, mm2        ;first approx with quantd  
   paddw mm7, mm2  
   mov esp, esp  
   pmulhuw mm0, [edi + 256 + 8*esi+112] ;correction  
   pmulhuw mm3, [edi + 256 + 8*esi+120]  
   paddw mm5, mm0        ;final result with quantd  
   paddw mm7, mm3  
   pxor mm0, mm0  
   pxor mm3, mm3  
   mov esp, esp  
   pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16  
   pmulhuw mm7, mm6      ;  (level + quantd) / quant (0<quant<32)  
   psrlw mm5, 1          ; (level + quantd) / (2*quant)  
   psrlw mm7, 1  
   pxor mm5, mm1         ; mm0 *= sign(mm0)  
   pxor mm7, mm4         ;  
   psubw mm5, mm1        ; undisplace  
   psubw mm7, mm4        ;  
   movq [edx + 8*esi+112], mm5  
   movq [edx + 8*esi +120], mm7  
   add esi,byte 2  
   jng near .lloop  
   jmp near .done  
   
 ;-----------------------------------------------------------------------------  
 ;  
148  ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,  ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,
149  ;                               const int16_t const * data,  ;                               const int16_t const * data,
150  ;                               const uint32_t quant,  ;                               const uint32_t quant,
# Line 379  Line 152 
152  ;  ;
153  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
154    
155  ALIGN 16  ALIGN SECTION_ALIGN
156  quant_mpeg_inter_xmm:  quant_mpeg_inter_xmm:
157    mov eax, [esp  + 8]       ; data    mov _EAX, prm2       ; data
158    mov ecx, [esp  + 12]      ; quant    mov TMP0, prm3       ; quant
159    mov edx, [esp  + 4]       ; coeff    mov TMP1, prm1       ; coeff
160    push esi    push _ESI
161    push edi    push _EDI
162    push ebx    push _EBX
163    nop    nop
164    mov edi, [esp + 12 + 16]  %ifdef ARCH_IS_X86_64
165    mov esi, -14    mov _EDI, prm4
166    mov ebx, esp  %else
167    sub esp, byte 24    mov _EDI, [_ESP + 12 + 16]
168    lea ebx, [esp+8]  %endif
169    and ebx, byte -8 ;ALIGN 8  
170      mov _ESI, -14
171      mov _EBX, _ESP
172      sub _ESP, byte 24
173      lea _EBX, [_ESP+8]
174      and _EBX, byte -8 ;ALIGN 8
175    pxor mm0, mm0    pxor mm0, mm0
176    pxor mm3, mm3    pxor mm3, mm3
177    movq [byte ebx],mm0    movq [byte _EBX],mm0
178    db 0Fh, 7Fh, 44h, 23h, 8 ;movq [ebx+8],mm0    movq [_EBX+8],mm0
179    cmp ecx, byte 1  
180      cmp TMP0, byte 1
181    je near .q1loop    je near .q1loop
182    cmp ecx, byte 19    cmp TMP0, byte 19
183    jg near .lloop    jg near .lloop
184    nop    nop
185    
186  ALIGN 16  ALIGN SECTION_ALIGN
187  .loop  .loop:
188    movq mm1, [eax + 8*esi+112]       ; mm0 = [1st]    movq mm1, [_EAX + 8*_ESI+112]       ; mm0 = [1st]
189    psubw mm0, mm1 ;-mm1    psubw mm0, mm1 ;-mm1
190    movq mm4, [eax + 8*esi + 120] ;    movq mm4, [_EAX + 8*_ESI + 120] ;
191    psubw mm3, mm4 ;-mm4    psubw mm3, mm4 ;-mm4
192    pmaxsw mm0, mm1 ;|src|    pmaxsw mm0, mm1 ;|src|
193    pmaxsw mm3, mm4    pmaxsw mm3, mm4
# Line 417  Line 196 
196    psraw mm4, 15    psraw mm4, 15
197    psllw mm0, 4          ; level << 4    psllw mm0, 4          ; level << 4
198    psllw mm3, 4          ;    psllw mm3, 4          ;
199    paddw mm0, [edi + 640 + 8*esi+112]    paddw mm0, [_EDI + 640 + 8*_ESI+112]
200    paddw mm3, [edi + 640 + 8*esi+120]    paddw mm3, [_EDI + 640 + 8*_ESI+120]
201    movq mm5, [edi + 896 + 8*esi+112]    movq mm5, [_EDI + 896 + 8*_ESI+112]
202    movq mm7, [edi + 896 + 8*esi+120]    movq mm7, [_EDI + 896 + 8*_ESI+120]
203    pmulhuw mm5, mm0    pmulhuw mm5, mm0
204    pmulhuw mm7, mm3    pmulhuw mm7, mm3
205    mov esp, esp    mov _ESP, _ESP
206    movq mm2, [edi + 512 + 8*esi+112]    movq mm2, [_EDI + 512 + 8*_ESI+112]
207    movq mm6, [edi + 512 + 8*esi+120]    movq mm6, [_EDI + 512 + 8*_ESI+120]
208    pmullw mm2, mm5    pmullw mm2, mm5
209    pmullw mm6, mm7    pmullw mm6, mm7
210    psubw mm0, mm2    psubw mm0, mm2
211    psubw mm3, mm6    psubw mm3, mm6
212    movq mm2, [byte ebx]    movq mm2, [byte _EBX]
213    movq mm6, [mmx_divs + ecx * 8 - 8]  %ifdef ARCH_IS_X86_64
214    pmulhuw mm0, [edi + 768 + 8*esi+112]    lea r9, [mmx_divs]
215    pmulhuw mm3, [edi + 768 + 8*esi+120]    movq mm6, [r9 + TMP0 * 8 - 8]
216    paddw mm2, [ebx+8]    ;sum  %else
217      movq mm6, [mmx_divs + TMP0 * 8 - 8]
218    %endif
219      pmulhuw mm0, [_EDI + 768 + 8*_ESI+112]
220      pmulhuw mm3, [_EDI + 768 + 8*_ESI+120]
221      paddw mm2, [_EBX+8]    ;sum
222    paddw mm5, mm0    paddw mm5, mm0
223    paddw mm7, mm3    paddw mm7, mm3
224    pxor mm0, mm0    pxor mm0, mm0
225    pxor mm3, mm3    pxor mm3, mm3
226    pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16    pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16
227    pmulhuw mm7, mm6      ;  (level ) / quant (0<quant<32)    pmulhuw mm7, mm6      ;  (level ) / quant (0<quant<32)
228    add esi, byte 2    add _ESI, byte 2
229    paddw mm2, mm5        ;sum += x1    paddw mm2, mm5        ;sum += x1
230    movq [ebx], mm7       ;store x2    movq [_EBX], mm7       ;store x2
231    pxor mm5, mm1         ; mm0 *= sign(mm0)    pxor mm5, mm1         ; mm0 *= sign(mm0)
232    pxor mm7, mm4         ;    pxor mm7, mm4         ;
233    psubw mm5, mm1        ; undisplace    psubw mm5, mm1        ; undisplace
234    psubw mm7, mm4        ;    psubw mm7, mm4        ;
235    db 0Fh, 7Fh, 54h, 23h, 08 ;movq   [ebx+8],mm2 ;store sum    movq [_EBX+8],mm2 ;store sum
236    movq [edx + 8*esi+112-16], mm5    movq [TMP1 + 8*_ESI+112-16], mm5
237    movq [edx + 8*esi +120-16], mm7    movq [TMP1 + 8*_ESI +120-16], mm7
238    jng near .loop    jng near .loop
239    
240  .done  .done:
241  ; calculate  data[0] // (int32_t)dcscalar)  ; calculate  data[0] // (int32_t)dcscalar)
242    paddw mm2, [ebx]    paddw mm2, [_EBX]
243    mov ebx, [esp+24]    mov _EBX, [_ESP+24]
244    mov edi, [esp+4+24]    mov _EDI, [_ESP+PTR_SIZE+24]
245    mov esi, [esp+8+24]    mov _ESI, [_ESP+2*PTR_SIZE+24]
246    add esp, byte 12+24    add _ESP, byte 3*PTR_SIZE+24
247    pmaddwd mm2, [mmx_one]    pmaddwd mm2, [mmx_one]
248    punpckldq mm0, mm2 ;get low dw to mm0:high    punpckldq mm0, mm2 ;get low dw to mm0:high
249    paddd mm0,mm2    paddd mm0,mm2
# Line 468  Line 252 
252    
253    ret    ret
254    
255  ALIGN 16  ALIGN SECTION_ALIGN
256  .q1loop  .q1loop:
257    movq mm1, [eax + 8*esi+112]       ; mm0 = [1st]    movq mm1, [_EAX + 8*_ESI+112]       ; mm0 = [1st]
258    psubw mm0, mm1                    ;-mm1    psubw mm0, mm1                    ;-mm1
259    movq mm4, [eax + 8*esi+120]    movq mm4, [_EAX + 8*_ESI+120]
260    psubw mm3, mm4                    ;-mm4    psubw mm3, mm4                    ;-mm4
261    pmaxsw mm0, mm1                   ;|src|    pmaxsw mm0, mm1                   ;|src|
262    pmaxsw mm3, mm4    pmaxsw mm3, mm4
# Line 481  Line 265 
265    psraw mm4, 15    psraw mm4, 15
266    psllw mm0, 4                              ; level << 4    psllw mm0, 4                              ; level << 4
267    psllw mm3, 4    psllw mm3, 4
268    paddw mm0, [edi + 640 + 8*esi+112]    ;mm0 is to be divided    paddw mm0, [_EDI + 640 + 8*_ESI+112]    ;mm0 is to be divided
269    paddw mm3, [edi + 640 + 8*esi+120]    ; inter1 contains fix for division by 1    paddw mm3, [_EDI + 640 + 8*_ESI+120]    ; inter1 contains fix for division by 1
270    movq mm5, [edi + 896 + 8*esi+112] ;with rounding down    movq mm5, [_EDI + 896 + 8*_ESI+112] ;with rounding down
271    movq mm7, [edi + 896 + 8*esi+120]    movq mm7, [_EDI + 896 + 8*_ESI+120]
272    pmulhuw mm5, mm0    pmulhuw mm5, mm0
273    pmulhuw mm7, mm3                          ;mm7: first approx of division    pmulhuw mm7, mm3                          ;mm7: first approx of division
274    mov esp, esp    mov _ESP, _ESP
275    movq mm2, [edi + 512 + 8*esi+112]    movq mm2, [_EDI + 512 + 8*_ESI+112]
276    movq mm6, [edi + 512 + 8*esi+120]      ; divs for q<=16    movq mm6, [_EDI + 512 + 8*_ESI+120]      ; divs for q<=16
277    pmullw mm2, mm5                           ;test value <= original    pmullw mm2, mm5                           ;test value <= original
278    pmullw mm6, mm7    pmullw mm6, mm7
279    psubw mm0, mm2                            ;mismatch    psubw mm0, mm2                            ;mismatch
280    psubw mm3, mm6    psubw mm3, mm6
281    movq mm2, [byte ebx]    movq mm2, [byte _EBX]
282    pmulhuw mm0, [edi + 768 + 8*esi+112]  ;correction    pmulhuw mm0, [_EDI + 768 + 8*_ESI+112]  ;correction
283    pmulhuw mm3, [edi + 768 + 8*esi+120]    pmulhuw mm3, [_EDI + 768 + 8*_ESI+120]
284    paddw mm2, [ebx+8]    ;sum    paddw mm2, [_EBX+8]    ;sum
285    paddw mm5, mm0        ;final result    paddw mm5, mm0        ;final result
286    paddw mm7, mm3    paddw mm7, mm3
287    pxor mm0, mm0    pxor mm0, mm0
288    pxor mm3, mm3    pxor mm3, mm3
289    psrlw mm5, 1          ;  (level ) /2  (quant = 1)    psrlw mm5, 1          ;  (level ) /2  (quant = 1)
290    psrlw mm7, 1    psrlw mm7, 1
291    add esi, byte 2    add _ESI, byte 2
292    paddw mm2, mm5        ;sum += x1    paddw mm2, mm5        ;sum += x1
293    movq [ebx], mm7       ;store x2    movq [_EBX], mm7      ;store x2
294    pxor mm5, mm1         ; mm0 *= sign(mm0)    pxor mm5, mm1         ; mm0 *= sign(mm0)
295    pxor mm7, mm4         ;    pxor mm7, mm4         ;
296    psubw mm5, mm1        ; undisplace    psubw mm5, mm1        ; undisplace
297    psubw mm7, mm4        ;    psubw mm7, mm4        ;
298    movq [ebx+8], mm2     ;store sum    movq [_EBX+8], mm2    ;store sum
299    movq [edx + 8*esi+112-16], mm5    movq [TMP1 + 8*_ESI+112-16], mm5
300    movq [edx + 8*esi +120-16], mm7    movq [TMP1 + 8*_ESI +120-16], mm7
301    jng near .q1loop    jng near .q1loop
302    jmp near .done    jmp near .done
303    
304  ALIGN 8  ALIGN SECTION_ALIGN
305  .lloop  .lloop:
306    movq mm1, [eax + 8*esi+112]       ; mm0 = [1st]    movq mm1, [_EAX + 8*_ESI+112]       ; mm0 = [1st]
307    psubw mm0,mm1         ;-mm1    psubw mm0,mm1         ;-mm1
308    movq mm4, [eax + 8*esi+120]    movq mm4, [_EAX + 8*_ESI+120]
309    psubw mm3,mm4         ;-mm4    psubw mm3,mm4         ;-mm4
310    pmaxsw mm0,mm1        ;|src|    pmaxsw mm0,mm1        ;|src|
311    pmaxsw mm3,mm4    pmaxsw mm3,mm4
# Line 530  Line 314 
314    psraw mm4,15    psraw mm4,15
315    psllw mm0, 4          ; level << 4    psllw mm0, 4          ; level << 4
316    psllw mm3, 4          ;    psllw mm3, 4          ;
317    paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1    paddw mm0, [_EDI + 640 + 8*_ESI+112] ;mm0 is to be divided inter1 contains fix for division by 1
318    paddw mm3, [edi + 640 + 8*esi+120]    paddw mm3, [_EDI + 640 + 8*_ESI+120]
319    movq mm5,[edi + 896 + 8*esi+112]    movq mm5,[_EDI + 896 + 8*_ESI+112]
320    movq mm7,[edi + 896 + 8*esi+120]    movq mm7,[_EDI + 896 + 8*_ESI+120]
321    pmulhuw mm5,mm0    pmulhuw mm5,mm0
322    pmulhuw mm7,mm3       ;mm7: first approx of division    pmulhuw mm7,mm3       ;mm7: first approx of division
323    mov esp,esp    mov _ESP,_ESP
324    movq mm2,[edi + 512 + 8*esi+112]    movq mm2,[_EDI + 512 + 8*_ESI+112]
325    movq mm6,[edi + 512 + 8*esi+120]    movq mm6,[_EDI + 512 + 8*_ESI+120]
326    pmullw mm2,mm5        ;test value <= original    pmullw mm2,mm5        ;test value <= original
327    pmullw mm6,mm7    pmullw mm6,mm7
328    psubw mm0,mm2         ;mismatch    psubw mm0,mm2         ;mismatch
329    psubw mm3,mm6    psubw mm3,mm6
330    movq mm2,[byte ebx]    movq mm2,[byte _EBX]
331    movq mm6,[mmx_div + ecx * 8 - 8]  ; divs for q<=16  %ifdef ARCH_IS_X86_64
332    pmulhuw mm0,[edi + 768 + 8*esi+112] ;correction    lea r9, [mmx_div]
333    pmulhuw mm3,[edi + 768 + 8*esi+120]    movq mm6, [r9 + TMP0 * 8 - 8]
334    paddw mm2,[ebx+8]     ;sum  %else
335      movq mm6,[mmx_div + TMP0 * 8 - 8]  ; divs for q<=16
336    %endif
337      pmulhuw mm0,[_EDI + 768 + 8*_ESI+112] ;correction
338      pmulhuw mm3,[_EDI + 768 + 8*_ESI+120]
339      paddw mm2,[_EBX+8]    ;sum
340    paddw mm5,mm0         ;final result    paddw mm5,mm0         ;final result
341    paddw mm7,mm3    paddw mm7,mm3
342    pxor mm0,mm0    pxor mm0,mm0
343    pxor mm3,mm3    pxor mm3,mm3
344    pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16    pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16
345    pmulhuw mm7, mm6      ;  (level ) / quant (0<quant<32)    pmulhuw mm7, mm6      ;  (level ) / quant (0<quant<32)
346    add esi,byte 2    add _ESI,byte 2
347    psrlw mm5, 1          ; (level ) / (2*quant)    psrlw mm5, 1          ; (level ) / (2*quant)
348    paddw mm2,mm5         ;sum += x1    paddw mm2,mm5         ;sum += x1
349    psrlw mm7, 1    psrlw mm7, 1
350    movq [ebx],mm7        ;store x2    movq [_EBX],mm7       ;store x2
351    pxor mm5, mm1         ; mm0 *= sign(mm0)    pxor mm5, mm1         ; mm0 *= sign(mm0)
352    pxor mm7, mm4         ;    pxor mm7, mm4         ;
353    psubw mm5, mm1        ; undisplace    psubw mm5, mm1        ; undisplace
354    psubw mm7, mm4        ;    psubw mm7, mm4        ;
355    db 0Fh, 7Fh, 54h, 23h, 08 ;movq   [ebx+8],mm2 ;store sum    movq [_EBX+8], mm2    ;store sum
356    movq [edx + 8*esi+112-16], mm5    movq [TMP1 + 8*_ESI+112-16], mm5
357    movq [edx + 8*esi +120-16], mm7    movq [TMP1 + 8*_ESI +120-16], mm7
358    jng near .lloop    jng near .lloop
359    jmp near .done    jmp near .done
360    ENDFUNC
361    
362    
363  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 591  Line 381 
381    ;    ;
382    
383  %macro DEQUANT4INTRAMMX 1  %macro DEQUANT4INTRAMMX 1
384    movq mm1, [byte ecx+ 16 * %1] ; mm0 = c  = coeff[i]    movq mm1, [byte TMP0+ 16 * %1] ; mm0 = c  = coeff[i]
385    movq mm4, [ecx+ 16 * %1 +8]   ; mm3 = c' = coeff[i+1]    movq mm4, [TMP0+ 16 * %1 +8]   ; mm3 = c' = coeff[i+1]
386    psubw mm0, mm1    psubw mm0, mm1
387    psubw mm3, mm4    psubw mm3, mm4
388    pmaxsw mm0, mm1    pmaxsw mm0, mm1
# Line 600  Line 390 
390    psraw mm1, 15    psraw mm1, 15
391    psraw mm4, 15    psraw mm4, 15
392  %if %1  %if %1
393    movq mm2, [eax+8] ;preshifted quant    movq mm2, [_EAX+8] ;preshifted quant
394    movq mm7, [eax+8]    movq mm7, [_EAX+8]
395  %endif  %endif
396    pmullw mm2, [edi + 16 * %1 ]     ; matrix[i]*quant    pmullw mm2, [TMP1 + 16 * %1 ]     ; matrix[i]*quant
397    pmullw mm7, [edi + 16 * %1 +8]   ; matrix[i+1]*quant    pmullw mm7, [TMP1 + 16 * %1 +8]   ; matrix[i+1]*quant
398    movq mm5, mm0    movq mm5, mm0
399    movq mm6, mm3    movq mm6, mm3
400    pmulhw mm0, mm2   ; high of coeff*(matrix*quant)    pmulhw mm0, mm2   ; high of coeff*(matrix*quant)
401    pmulhw mm3, mm7   ; high of coeff*(matrix*quant)    pmulhw mm3, mm7   ; high of coeff*(matrix*quant)
402    pmullw mm2, mm5   ; low  of coeff*(matrix*quant)    pmullw mm2, mm5   ; low  of coeff*(matrix*quant)
403    pmullw mm7, mm6   ; low  of coeff*(matrix*quant)    pmullw mm7, mm6   ; low  of coeff*(matrix*quant)
404    pcmpgtw mm0, [eax]    pcmpgtw mm0, [_EAX]
405    pcmpgtw mm3, [eax]    pcmpgtw mm3, [_EAX]
406    paddusw mm2, mm0    paddusw mm2, mm0
407    paddusw mm7, mm3    paddusw mm7, mm3
408    psrlw mm2, 5    psrlw mm2, 5
# Line 621  Line 411 
411    pxor mm7, mm4     ; start negating back    pxor mm7, mm4     ; start negating back
412    psubusw mm1, mm0    psubusw mm1, mm0
413    psubusw mm4, mm3    psubusw mm4, mm3
414    movq mm0, [eax]   ;zero    movq mm0, [_EAX]   ;zero
415    movq mm3, [eax]   ;zero    movq mm3, [_EAX]   ;zero
416    psubw mm2, mm1    ; finish negating back    psubw mm2, mm1    ; finish negating back
417    psubw mm7, mm4    ; finish negating back    psubw mm7, mm4    ; finish negating back
418    movq [byte edx + 16 * %1], mm2   ; data[i]    movq [byte _EDI + 16 * %1], mm2   ; data[i]
419    movq [edx + 16 * %1  +8], mm7   ; data[i+1]    movq [_EDI + 16 * %1  +8], mm7   ; data[i+1]
420  %endmacro  %endmacro
421    
422  ALIGN 16  ALIGN SECTION_ALIGN
423  dequant_mpeg_intra_3dne:  dequant_mpeg_intra_3dne:
424    mov eax, [esp+12] ; quant    mov _EAX, prm3  ; quant
425    mov ecx, [esp+8]  ; coeff  %ifdef ARCH_IS_X86_64
426    movq mm7, [mmx_mul_quant  + eax*8 - 8]    lea TMP0, [mmx_mul_quant]
427      movq mm7, [TMP0 + _EAX*8 - 8]
428    %else
429      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
430    %endif
431      mov TMP0, prm2  ; coeff
432    psllw mm7, 2      ; << 2. See comment.    psllw mm7, 2      ; << 2. See comment.
433    mov edx, [esp+4]  ; data    mov TMP1, prm5 ; mpeg_quant_matrices
434    push ebx    push _EBX
435    movsx ebx, word [ecx]    movsx _EBX, word [TMP0]
436    pxor mm0, mm0    pxor mm0, mm0
437    pxor mm3, mm3    pxor mm3, mm3
438    push esi    push _ESI
439    lea eax, [esp-28]    lea _EAX, [_ESP-28]
440    sub esp, byte 32    sub _ESP, byte 32
441    and eax, byte -8  ;points to qword ALIGNed space on stack    and _EAX, byte -8  ;points to qword ALIGNed space on stack
442    movq [eax], mm0    movq [_EAX], mm0
443    movq [eax+8], mm7    movq [_EAX+8], mm7
444    imul ebx, [esp+16+8+32]    ; dcscalar  %ifdef ARCH_IS_X86_64
445      imul _EBX, prm4    ; dcscalar
446    %else
447      imul _EBX, [_ESP+16+8+32]    ; dcscalar
448    %endif
449    movq mm2, mm7    movq mm2, mm7
450    push edi    push _EDI
451    mov edi, [esp + 32 + 12 + 20] ; mpeg_quant_matrices  
452  ALIGN 4  %ifdef ARCH_IS_X86_64
453      mov _EDI, prm1  ; data
454    %else
455      mov _EDI, [_ESP+4+12+32]
456    %endif
457    
458    ALIGN SECTION_ALIGN
459    
460    DEQUANT4INTRAMMX 0    DEQUANT4INTRAMMX 0
461    
462    mov esi, -2048    mov _ESI, -2048
463    nop    nop
464    cmp ebx, esi    cmp _EBX, _ESI
465    
466    DEQUANT4INTRAMMX 1    DEQUANT4INTRAMMX 1
467    
468    cmovl ebx, esi    cmovl _EBX, _ESI
469    neg esi    neg _ESI
470    sub esi, byte 1 ;2047    sub _ESI, byte 1 ;2047
471    
472    DEQUANT4INTRAMMX 2    DEQUANT4INTRAMMX 2
473    
474    cmp ebx, esi    cmp _EBX, _ESI
475    cmovg ebx, esi    cmovg _EBX, _ESI
476    lea ebp, [byte ebp]    lea _EBP, [byte _EBP]
477    
478    DEQUANT4INTRAMMX 3    DEQUANT4INTRAMMX 3
479    
480    mov esi, [esp+36]    mov _ESI, [_ESP+32+PTR_SIZE]
481    mov [byte edx], bx    mov [byte _EDI], bx
482    mov ebx, [esp+36+4]    mov _EBX, [_ESP+32+2*PTR_SIZE]
483    
484    DEQUANT4INTRAMMX 4    DEQUANT4INTRAMMX 4
485    DEQUANT4INTRAMMX 5    DEQUANT4INTRAMMX 5
486    DEQUANT4INTRAMMX 6    DEQUANT4INTRAMMX 6
487    DEQUANT4INTRAMMX 7    DEQUANT4INTRAMMX 7
488    
489    pop edi    pop _EDI
490    
491    add esp, byte 32+8    add _ESP, byte 32+2*PTR_SIZE
492    
493    xor eax, eax    xor _EAX, _EAX
494    ret    ret
495    ENDFUNC
496    
497  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
498  ;  ;
# Line 702  Line 508 
508      ; 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.
509      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
510    
511  ALIGN 16  ALIGN SECTION_ALIGN
512  dequant_mpeg_inter_3dne:  dequant_mpeg_inter_3dne:
513    mov edx, [esp+ 4]        ; data    mov _EAX, prm3        ; quant
514    mov ecx, [esp+ 8]        ; coeff  %ifdef ARCH_IS_X86_64
515    mov eax, [esp+12]        ; quant    lea TMP0, [mmx_mul_quant]
516    movq mm7, [mmx_mul_quant  + eax*8 - 8]    movq mm7, [TMP0  + _EAX*8 - 8]
517    mov eax, -14  %else
518      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
519    %endif
520      mov TMP1, prm1        ; data
521      mov TMP0, prm2        ; coeff
522      mov _EAX, -14
523    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
524    pxor mm6, mm6     ; mismatch sum    pxor mm6, mm6     ; mismatch sum
525    push esi    push _ESI
526    push edi    push _EDI
527    mov esi, mmzero    lea _ESI, [mmzero]
528    pxor mm1, mm1    pxor mm1, mm1
529    pxor mm3, mm3    pxor mm3, mm3
530    mov edi, [esp + 8 + 16] ; mpeg_quant_matrices  %ifdef ARCH_IS_X86_64
531      mov _EDI, prm4
532    %else
533      mov _EDI, [_ESP + 8 + 16] ; mpeg_quant_matrices
534    %endif
535    nop    nop
536    nop4    nop4
537    
538  ALIGN 16  ALIGN SECTION_ALIGN
539  .loop  .loop:
540    movq mm0, [ecx+8*eax + 7*16   ]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 7*16   ]   ; mm0 = coeff[i]
541    pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)    pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)
542    movq mm2, [ecx+8*eax + 7*16 +8]   ; mm2 = coeff[i+1]    movq mm2, [TMP0+8*_EAX + 7*16 +8]   ; mm2 = coeff[i+1]
543    pcmpgtw mm3, mm2  ; mm3 = sgn(c')   (preserved)    pcmpgtw mm3, mm2  ; mm3 = sgn(c')   (preserved)
544    paddsw mm0, mm1   ; c += sgn(c)    paddsw mm0, mm1   ; c += sgn(c)
545    paddsw mm2, mm3   ; c += sgn(c')    paddsw mm2, mm3   ; c += sgn(c')
546    paddw mm0, mm0    ; c *= 2    paddw mm0, mm0    ; c *= 2
547    paddw mm2, mm2    ; c'*= 2    paddw mm2, mm2    ; c'*= 2
548    
549    movq mm4, [esi]    movq mm4, [_ESI]
550    movq mm5, [esi]    movq mm5, [_ESI]
551    psubw mm4, mm0    ; -c    psubw mm4, mm0    ; -c
552    psubw mm5, mm2    ; -c'    psubw mm5, mm2    ; -c'
553    
# Line 747  Line 562 
562    
563    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
564    nop    nop
565    pmullw mm4, [edi + 512 + 8*eax + 7*16]    pmullw mm4, [_EDI + 512 + 8*_EAX + 7*16]
566    movq mm5, mm4    movq mm5, mm4
567    pmulhw mm5, mm0   ; high of c*(matrix*quant)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
568    pmullw mm0, mm4   ; low  of c*(matrix*quant)    pmullw mm0, mm4   ; low  of c*(matrix*quant)
569    
570    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
571    pmullw mm4, [edi + 512 + 8*eax + 7*16 + 8]    pmullw mm4, [_EDI + 512 + 8*_EAX + 7*16 + 8]
572    add eax, byte 2    add _EAX, byte 2
573    
574    pcmpgtw mm5, [esi]    pcmpgtw mm5, [_ESI]
575    paddusw mm0, mm5    paddusw mm0, mm5
576    psrlw mm0, 5    psrlw mm0, 5
577    pxor mm0, mm1     ; start restoring sign    pxor mm0, mm1     ; start restoring sign
# Line 767  Line 582 
582    pmullw mm2, mm4   ; low  of c*(matrix*quant)    pmullw mm2, mm4   ; low  of c*(matrix*quant)
583    psubw mm0, mm1    ; finish restoring sign    psubw mm0, mm1    ; finish restoring sign
584    
585    pcmpgtw mm5, [esi]    pcmpgtw mm5, [_ESI]
586    paddusw mm2, mm5    paddusw mm2, mm5
587    psrlw mm2, 5    psrlw mm2, 5
588    pxor mm2, mm3     ; start restoring sign    pxor mm2, mm3     ; start restoring sign
589    psubusw mm3, mm5    psubusw mm3, mm5
590    psubw mm2, mm3    ; finish restoring sign    psubw mm2, mm3    ; finish restoring sign
591    movq mm1, [esi]    movq mm1, [_ESI]
592    movq mm3, [byte esi]    movq mm3, [byte _ESI]
593    pxor mm6, mm0                             ; mismatch control    pxor mm6, mm0                             ; mismatch control
594    movq [edx + 8*eax + 7*16 -2*8   ], mm0    ; data[i]    movq [TMP1 + 8*_EAX + 7*16 -2*8   ], mm0    ; data[i]
595    pxor mm6, mm2                             ; mismatch control    pxor mm6, mm2                             ; mismatch control
596    movq [edx + 8*eax + 7*16 -2*8 +8], mm2    ; data[i+1]    movq [TMP1 + 8*_EAX + 7*16 -2*8 +8], mm2    ; data[i+1]
597    
598    jng .loop    jng .loop
599    nop    nop
# Line 792  Line 607 
607    pxor mm1, mm2    pxor mm1, mm2
608    pxor mm6, mm1    pxor mm6, mm1
609    movd eax, mm6    movd eax, mm6
610    pop edi    pop _EDI
611    and eax, byte 1    and _EAX, byte 1
612    xor eax, byte 1    xor _EAX, byte 1
613    mov esi, [esp]    mov _ESI, [_ESP]
614    add esp, byte 4    add _ESP, byte PTR_SIZE
615    xor word [edx + 2*63], ax    xor word [TMP1 + 2*63], ax
616    
617    xor eax, eax    xor _EAX, _EAX
618    ret    ret
619    ENDFUNC
620    
621    NON_EXEC_STACK

Legend:
Removed from v.1.1.2.5  
changed lines
  Added in v.1.13

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