[svn] / branches / dev-api-4 / xvidcore / src / quant / x86_asm / quantize_mpeg_xmm.asm Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/src/quant/x86_asm/quantize_mpeg_xmm.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1230 - (view) (download)

1 : edgomez 1192 ;/****************************************************************************
2 : edgomez 1174 ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 : edgomez 1176 ; * - 3dne Quantization/Dequantization -
5 : edgomez 1174 ; *
6 : edgomez 1176 ; * Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>
7 :     ; * 2002 Jaan Kalda
8 : edgomez 1174 ; *
9 :     ; * This program is free software ; you can redistribute it and/or modify
10 :     ; * it under the terms of the GNU General Public License as published by
11 :     ; * the Free Software Foundation ; either version 2 of the License, or
12 :     ; * (at your option) any later version.
13 :     ; *
14 :     ; * This program is distributed in the hope that it will be useful,
15 :     ; * but WITHOUT ANY WARRANTY ; without even the implied warranty of
16 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     ; * GNU General Public License for more details.
18 :     ; *
19 :     ; * You should have received a copy of the GNU General Public License
20 :     ; * along with this program ; if not, write to the Free Software
21 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 :     ; *
23 : edgomez 1230 ; * $Id: quantize_mpeg_xmm.asm,v 1.1.2.5 2003-11-30 16:13:16 edgomez Exp $
24 : edgomez 1174 ; *
25 : edgomez 1192 ; ***************************************************************************/
26 : edgomez 1176
27 : edgomez 1174 ; _3dne functions are compatible with iSSE, but are optimized specifically
28 :     ; for K7 pipelines
29 :    
30 :     %define SATURATE
31 :    
32 : edgomez 1192 BITS 32
33 : edgomez 1174
34 : edgomez 1192 %macro cglobal 1
35 : edgomez 1174 %ifdef PREFIX
36 : edgomez 1192 global _%1
37 : edgomez 1174 %define %1 _%1
38 :     %else
39 :     global %1
40 :     %endif
41 :     %endmacro
42 :    
43 : edgomez 1192 %macro cextern 1
44 : edgomez 1174 %ifdef PREFIX
45 : edgomez 1192 extern _%1
46 : edgomez 1174 %define %1 _%1
47 :     %else
48 :     extern %1
49 :     %endif
50 :     %endmacro
51 : edgomez 1176
52 : edgomez 1192 ;=============================================================================
53 : edgomez 1176 ; Local data
54 : edgomez 1192 ;=============================================================================
55 : edgomez 1176
56 : edgomez 1198 %ifdef FORMAT_COFF
57 :     SECTION .rodata data
58 :     %else
59 :     SECTION .rodata data align=16
60 :     %endif
61 : edgomez 1176
62 : edgomez 1192 ALIGN 8
63 : edgomez 1176 mmzero:
64 :     dd 0,0
65 :     mmx_one:
66 :     times 4 dw 1
67 : edgomez 1174
68 : edgomez 1192 ;-----------------------------------------------------------------------------
69 :     ; divide by 2Q table
70 :     ;-----------------------------------------------------------------------------
71 : edgomez 1174
72 : edgomez 1192 ALIGN 16
73 : edgomez 1176 mmx_divs: ;i>2
74 : edgomez 1174 %assign i 1
75 :     %rep 31
76 : edgomez 1192 times 4 dw ((1 << 15) / i + 1)
77 : edgomez 1174 %assign i i+1
78 :     %endrep
79 :    
80 : edgomez 1192 ALIGN 16
81 :     mmx_div: ;quant>2
82 :     times 4 dw 65535 ; the div by 2 formula will overflow for the case
83 :     ; quant=1 but we don't care much because quant=1
84 :     ; is handled by a different piece of code that
85 :     ; doesn't use this table.
86 :     %assign quant 2
87 : edgomez 1174 %rep 31
88 : edgomez 1192 times 4 dw ((1 << 16) / quant + 1)
89 :     %assign quant quant+1
90 : edgomez 1174 %endrep
91 :    
92 :     %macro FIXX 1
93 :     dw (1 << 16) / (%1) + 1
94 : edgomez 1192 %endmacro
95 : edgomez 1174
96 : edgomez 1176 %define nop4 db 08Dh, 074h, 026h,0
97 :     %define nop3 add esp, byte 0
98 :     %define nop2 mov esp, esp
99 :     %define nop7 db 08dh, 02ch, 02dh,0,0,0,0
100 :     %define nop6 add ebp, dword 0
101 : edgomez 1174
102 : edgomez 1192 ;-----------------------------------------------------------------------------
103 :     ; quantd table
104 :     ;-----------------------------------------------------------------------------
105 : edgomez 1174
106 : edgomez 1176 %define VM18P 3
107 :     %define VM18Q 4
108 : edgomez 1174
109 : edgomez 1192 ALIGN 16
110 : edgomez 1176 quantd:
111 : edgomez 1174 %assign i 1
112 :     %rep 31
113 :     times 4 dw (((VM18P*i) + (VM18Q/2)) / VM18Q)
114 :     %assign i i+1
115 :     %endrep
116 :    
117 : edgomez 1192 ;-----------------------------------------------------------------------------
118 : edgomez 1174 ; multiple by 2Q table
119 : edgomez 1192 ;-----------------------------------------------------------------------------
120 : edgomez 1174
121 : edgomez 1192 ALIGN 16
122 :     mmx_mul_quant:
123 : edgomez 1174 %assign i 1
124 :     %rep 31
125 :     times 4 dw i
126 :     %assign i i+1
127 :     %endrep
128 :    
129 : edgomez 1192 ;-----------------------------------------------------------------------------
130 :     ; saturation limits
131 :     ;-----------------------------------------------------------------------------
132 : edgomez 1174
133 : edgomez 1192 ALIGN 16
134 : edgomez 1176 mmx_32767_minus_2047:
135 : edgomez 1192 times 4 dw (32767-2047)
136 : edgomez 1176 mmx_32768_minus_2048:
137 :     times 4 dw (32768-2048)
138 :     mmx_2047:
139 :     times 4 dw 2047
140 :     mmx_minus_2048:
141 :     times 4 dw (-2048)
142 :     zero:
143 :     times 4 dw 0
144 : edgomez 1174
145 : edgomez 1176 int_div:
146 : edgomez 1174 dd 0
147 :     %assign i 1
148 : edgomez 1192 %rep 255
149 : edgomez 1174 dd (1 << 17) / ( i) + 1
150 :     %assign i i+1
151 :     %endrep
152 :    
153 : edgomez 1192 ;=============================================================================
154 : edgomez 1176 ; Code
155 : edgomez 1192 ;=============================================================================
156 : edgomez 1176
157 : edgomez 1192 SECTION .text
158 : edgomez 1174
159 : edgomez 1192 cglobal quant_mpeg_intra_xmm
160 :     cglobal quant_mpeg_inter_xmm
161 :     cglobal dequant_mpeg_intra_3dne
162 :     cglobal dequant_mpeg_inter_3dne
163 :    
164 :     ;-----------------------------------------------------------------------------
165 : edgomez 1174 ;
166 : edgomez 1192 ; uint32_t quant_mpeg_intra_xmm(int16_t * coeff,
167 : edgomez 1176 ; const int16_t const * data,
168 :     ; const uint32_t quant,
169 : edgomez 1230 ; const uint32_t dcscalar,
170 :     ; const uint16_t *mpeg_matrices);
171 : edgomez 1174 ;
172 : edgomez 1192 ;-----------------------------------------------------------------------------
173 : edgomez 1174
174 : edgomez 1192 ALIGN 16
175 : edgomez 1174 quant_mpeg_intra_xmm:
176 : edgomez 1192 mov eax, [esp + 8] ; data
177 :     mov ecx, [esp + 12] ; quant
178 :     mov edx, [esp + 4] ; coeff
179 :     push esi
180 :     push edi
181 :     push ebx
182 :     nop
183 : edgomez 1230 mov edi, [esp + 12 + 20] ; mpeg_quant_matrices
184 : edgomez 1192 mov esi, -14
185 :     pxor mm0, mm0
186 :     pxor mm3, mm3
187 :     cmp ecx, byte 1
188 :     je near .q1loop
189 :     cmp ecx, byte 19
190 :     jg near .lloop
191 :     nop6
192 :    
193 :     ALIGN 16
194 : edgomez 1174 .loop
195 : edgomez 1192 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
196 :     psubw mm0, mm1 ;-mm1
197 :     movq mm4, [eax + 8*esi + 120] ;
198 :     psubw mm3, mm4 ;-mm4
199 :     pmaxsw mm0, mm1 ;|src|
200 :     pmaxsw mm3,mm4
201 :     nop2
202 :     psraw mm1, 15 ;sign src
203 :     psraw mm4, 15
204 :     psllw mm0, 4 ;level << 4 ;
205 :     psllw mm3, 4
206 : edgomez 1230 paddw mm0, [edi + 128 + 8*esi+112]
207 :     paddw mm3, [edi + 128 + 8*esi+120]
208 :     movq mm5, [edi + 384 + 8*esi+112]
209 :     movq mm7, [edi + 384 + 8*esi+120]
210 : edgomez 1192 pmulhuw mm5, mm0
211 :     pmulhuw mm7, mm3
212 :     mov esp, esp
213 : edgomez 1230 movq mm2, [edi + 8*esi+112]
214 :     movq mm6, [edi + 8*esi+120]
215 : edgomez 1192 pmullw mm2, mm5
216 :     pmullw mm6, mm7
217 :     psubw mm0, mm2
218 :     psubw mm3, mm6
219 :     nop4
220 :     movq mm2, [quantd + ecx * 8 - 8]
221 :     movq mm6, [mmx_divs + ecx * 8 - 8]
222 :     paddw mm5, mm2
223 :     paddw mm7, mm2
224 :     mov esp, esp
225 : edgomez 1230 pmulhuw mm0, [edi + 256 + 8*esi+112]
226 :     pmulhuw mm3, [edi + 256 + 8*esi+120]
227 : edgomez 1192 paddw mm5, mm0
228 :     paddw mm7, mm3
229 : edgomez 1230 pxor mm0, mm0
230 :     pxor mm3, mm3
231 : edgomez 1192 pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
232 :     pmulhuw mm7, mm6 ; (level + quantd) / quant (0<quant<32)
233 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
234 :     pxor mm7, mm4 ;
235 :     psubw mm5, mm1 ; undisplace
236 :     psubw mm7, mm4 ;
237 :     movq [edx + 8*esi+112], mm5
238 :     movq [edx + 8*esi +120], mm7
239 :     add esi, byte 2
240 :     jng near .loop
241 : edgomez 1174
242 :     .done
243 :     ; calculate data[0] // (int32_t)dcscalar)
244 : edgomez 1192 mov esi, [esp + 12 + 16] ; dcscalar
245 :     movsx ecx, word [eax]
246 :     mov edi, ecx
247 :     mov edx, [esp + 12 + 16]
248 :     shr edx, 1 ; ebx = dcscalar /2
249 :     sar edi, 31 ; cdq is vectorpath
250 :     xor edx, edi ; ebx = eax V -eax -1
251 :     sub ecx, edi
252 :     add ecx, edx
253 :     mov edx, [dword esp + 12 + 4]
254 :     mov esi, [int_div+4*esi]
255 :     imul ecx, esi
256 :     sar ecx, 17
257 :     lea ebx, [byte ecx + 1]
258 :     cmovs ecx, ebx
259 :     ; idiv cx ; ecx = edi:ecx / dcscalar
260 : edgomez 1174
261 : edgomez 1192 mov ebx, [esp]
262 :     mov edi, [esp+4]
263 :     mov esi, [esp+8]
264 :     add esp, byte 12
265 :     mov [edx], cx ; coeff[0] = ax
266 : edgomez 1174
267 : edgomez 1192 xor eax, eax
268 :     ret
269 :    
270 :     ALIGN 16
271 : edgomez 1174 .q1loop
272 : edgomez 1192 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
273 :     psubw mm0, mm1 ;-mm1
274 :     movq mm4, [eax + 8*esi+120] ;
275 :     psubw mm3, mm4 ;-mm4
276 :     pmaxsw mm0, mm1 ;|src|
277 :     pmaxsw mm3, mm4
278 :     nop2
279 :     psraw mm1, 15 ;sign src
280 :     psraw mm4, 15
281 :     psllw mm0, 4 ; level << 4
282 :     psllw mm3, 4
283 : edgomez 1230 paddw mm0, [edi + 128 + 8*esi+112] ;mm0 is to be divided
284 :     paddw mm3, [edi + 128 + 8*esi+120] ;intra1 contains fix for division by 1
285 :     movq mm5, [edi + 384 + 8*esi+112] ;with rounding down
286 :     movq mm7, [edi + 384 + 8*esi+120]
287 : edgomez 1192 pmulhuw mm5, mm0
288 :     pmulhuw mm7, mm3 ;mm7: first approx of division
289 :     mov esp, esp
290 : edgomez 1230 movq mm2, [edi + 8*esi+112]
291 :     movq mm6, [edi + 8*esi+120] ; divs for q<=16
292 : edgomez 1192 pmullw mm2, mm5 ;test value <= original
293 :     pmullw mm6, mm7
294 :     psubw mm0, mm2 ;mismatch
295 :     psubw mm3, mm6
296 :     nop4
297 :     movq mm2, [quantd + ecx * 8 - 8]
298 :     paddw mm5, mm2 ;first approx with quantd
299 :     paddw mm7, mm2
300 :     mov esp, esp
301 : edgomez 1230 pmulhuw mm0, [edi + 256 + 8*esi+112] ;correction
302 :     pmulhuw mm3, [edi + 256 + 8*esi+120]
303 : edgomez 1192 paddw mm5, mm0 ;final result with quantd
304 :     paddw mm7, mm3
305 : edgomez 1230 pxor mm0, mm0
306 :     pxor mm3, mm3
307 : edgomez 1192 mov esp, esp
308 :     psrlw mm5, 1 ; (level + quantd) /2 (quant = 1)
309 :     psrlw mm7, 1
310 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
311 :     pxor mm7, mm4 ;
312 :     psubw mm5, mm1 ; undisplace
313 :     psubw mm7, mm4 ;
314 :     movq [edx + 8*esi+112], mm5
315 :     movq [edx + 8*esi +120], mm7
316 :     add esi, byte 2
317 :     jng near .q1loop
318 :     jmp near .done
319 : edgomez 1174
320 : edgomez 1192 ALIGN 8
321 : edgomez 1174 .lloop
322 : edgomez 1192 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
323 :     psubw mm0, mm1 ;-mm1
324 :     movq mm4, [eax + 8*esi+120]
325 :     psubw mm3, mm4 ;-mm4
326 :     pmaxsw mm0, mm1 ;|src|
327 :     pmaxsw mm3, mm4
328 :     nop2
329 :     psraw mm1, 15 ;sign src
330 :     psraw mm4, 15
331 :     psllw mm0, 4 ; level << 4
332 :     psllw mm3, 4 ;
333 : edgomez 1230 paddw mm0, [edi + 128 + 8*esi+112] ;mm0 is to be divided intra1 contains fix for division by 1
334 :     paddw mm3, [edi + 128 + 8*esi+120]
335 :     movq mm5, [edi + 384 + 8*esi+112]
336 :     movq mm7, [edi + 384 + 8*esi+120]
337 : edgomez 1192 pmulhuw mm5, mm0
338 :     pmulhuw mm7, mm3 ;mm7: first approx of division
339 :     mov esp, esp
340 : edgomez 1230 movq mm2, [edi + 8*esi+112]
341 :     movq mm6, [edi + 8*esi+120]
342 : edgomez 1192 pmullw mm2, mm5 ;test value <= original
343 :     pmullw mm6, mm7
344 :     psubw mm0, mm2 ;mismatch
345 :     psubw mm3, mm6
346 :     nop4
347 :     movq mm2, [quantd + ecx * 8 - 8]
348 :     movq mm6, [mmx_div + ecx * 8 - 8] ; divs for q<=16
349 :     paddw mm5, mm2 ;first approx with quantd
350 :     paddw mm7, mm2
351 :     mov esp, esp
352 : edgomez 1230 pmulhuw mm0, [edi + 256 + 8*esi+112] ;correction
353 :     pmulhuw mm3, [edi + 256 + 8*esi+120]
354 : edgomez 1192 paddw mm5, mm0 ;final result with quantd
355 :     paddw mm7, mm3
356 : edgomez 1230 pxor mm0, mm0
357 :     pxor mm3, mm3
358 : edgomez 1192 mov esp, esp
359 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
360 :     pmulhuw mm7, mm6 ; (level + quantd) / quant (0<quant<32)
361 :     psrlw mm5, 1 ; (level + quantd) / (2*quant)
362 :     psrlw mm7, 1
363 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
364 :     pxor mm7, mm4 ;
365 :     psubw mm5, mm1 ; undisplace
366 :     psubw mm7, mm4 ;
367 :     movq [edx + 8*esi+112], mm5
368 :     movq [edx + 8*esi +120], mm7
369 :     add esi,byte 2
370 :     jng near .lloop
371 :     jmp near .done
372 : edgomez 1174
373 : edgomez 1192 ;-----------------------------------------------------------------------------
374 : edgomez 1174 ;
375 : edgomez 1176 ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,
376 :     ; const int16_t const * data,
377 : edgomez 1230 ; const uint32_t quant,
378 :     ; const uint16_t *mpeg_matrices);
379 : edgomez 1174 ;
380 : edgomez 1192 ;-----------------------------------------------------------------------------
381 : edgomez 1174
382 : edgomez 1192 ALIGN 16
383 : edgomez 1174 quant_mpeg_inter_xmm:
384 : edgomez 1192 mov eax, [esp + 8] ; data
385 :     mov ecx, [esp + 12] ; quant
386 :     mov edx, [esp + 4] ; coeff
387 :     push esi
388 :     push edi
389 :     push ebx
390 :     nop
391 : edgomez 1230 mov edi, [esp + 12 + 16]
392 : edgomez 1192 mov esi, -14
393 :     mov ebx, esp
394 :     sub esp, byte 24
395 :     lea ebx, [esp+8]
396 :     and ebx, byte -8 ;ALIGN 8
397 :     pxor mm0, mm0
398 :     pxor mm3, mm3
399 :     movq [byte ebx],mm0
400 :     db 0Fh, 7Fh, 44h, 23h, 8 ;movq [ebx+8],mm0
401 :     cmp ecx, byte 1
402 :     je near .q1loop
403 :     cmp ecx, byte 19
404 :     jg near .lloop
405 :     nop
406 :    
407 :     ALIGN 16
408 : edgomez 1174 .loop
409 : edgomez 1192 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
410 :     psubw mm0, mm1 ;-mm1
411 :     movq mm4, [eax + 8*esi + 120] ;
412 :     psubw mm3, mm4 ;-mm4
413 :     pmaxsw mm0, mm1 ;|src|
414 :     pmaxsw mm3, mm4
415 :     nop2
416 :     psraw mm1, 15 ;sign src
417 :     psraw mm4, 15
418 :     psllw mm0, 4 ; level << 4
419 :     psllw mm3, 4 ;
420 : edgomez 1230 paddw mm0, [edi + 640 + 8*esi+112]
421 :     paddw mm3, [edi + 640 + 8*esi+120]
422 :     movq mm5, [edi + 896 + 8*esi+112]
423 :     movq mm7, [edi + 896 + 8*esi+120]
424 : edgomez 1192 pmulhuw mm5, mm0
425 :     pmulhuw mm7, mm3
426 :     mov esp, esp
427 : edgomez 1230 movq mm2, [edi + 512 + 8*esi+112]
428 :     movq mm6, [edi + 512 + 8*esi+120]
429 : edgomez 1192 pmullw mm2, mm5
430 :     pmullw mm6, mm7
431 :     psubw mm0, mm2
432 :     psubw mm3, mm6
433 :     movq mm2, [byte ebx]
434 :     movq mm6, [mmx_divs + ecx * 8 - 8]
435 : edgomez 1230 pmulhuw mm0, [edi + 768 + 8*esi+112]
436 :     pmulhuw mm3, [edi + 768 + 8*esi+120]
437 : edgomez 1192 paddw mm2, [ebx+8] ;sum
438 :     paddw mm5, mm0
439 :     paddw mm7, mm3
440 : edgomez 1230 pxor mm0, mm0
441 :     pxor mm3, mm3
442 : edgomez 1192 pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
443 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
444 :     add esi, byte 2
445 :     paddw mm2, mm5 ;sum += x1
446 :     movq [ebx], mm7 ;store x2
447 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
448 :     pxor mm7, mm4 ;
449 :     psubw mm5, mm1 ; undisplace
450 :     psubw mm7, mm4 ;
451 :     db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
452 :     movq [edx + 8*esi+112-16], mm5
453 :     movq [edx + 8*esi +120-16], mm7
454 :     jng near .loop
455 : edgomez 1174
456 :     .done
457 :     ; calculate data[0] // (int32_t)dcscalar)
458 : edgomez 1192 paddw mm2, [ebx]
459 :     mov ebx, [esp+24]
460 :     mov edi, [esp+4+24]
461 :     mov esi, [esp+8+24]
462 :     add esp, byte 12+24
463 :     pmaddwd mm2, [mmx_one]
464 :     punpckldq mm0, mm2 ;get low dw to mm0:high
465 :     paddd mm0,mm2
466 :     punpckhdq mm0, mm0 ;get result to low
467 :     movd eax, mm0
468 : edgomez 1174
469 : edgomez 1192 ret
470 : edgomez 1174
471 : edgomez 1192 ALIGN 16
472 : edgomez 1174 .q1loop
473 : edgomez 1192 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
474 :     psubw mm0, mm1 ;-mm1
475 :     movq mm4, [eax + 8*esi+120]
476 :     psubw mm3, mm4 ;-mm4
477 :     pmaxsw mm0, mm1 ;|src|
478 :     pmaxsw mm3, mm4
479 :     nop2
480 :     psraw mm1, 15 ; sign src
481 :     psraw mm4, 15
482 :     psllw mm0, 4 ; level << 4
483 :     psllw mm3, 4
484 : edgomez 1230 paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided
485 :     paddw mm3, [edi + 640 + 8*esi+120] ; inter1 contains fix for division by 1
486 :     movq mm5, [edi + 896 + 8*esi+112] ;with rounding down
487 :     movq mm7, [edi + 896 + 8*esi+120]
488 : edgomez 1192 pmulhuw mm5, mm0
489 :     pmulhuw mm7, mm3 ;mm7: first approx of division
490 :     mov esp, esp
491 : edgomez 1230 movq mm2, [edi + 512 + 8*esi+112]
492 :     movq mm6, [edi + 512 + 8*esi+120] ; divs for q<=16
493 : edgomez 1192 pmullw mm2, mm5 ;test value <= original
494 :     pmullw mm6, mm7
495 :     psubw mm0, mm2 ;mismatch
496 :     psubw mm3, mm6
497 :     movq mm2, [byte ebx]
498 : edgomez 1230 pmulhuw mm0, [edi + 768 + 8*esi+112] ;correction
499 :     pmulhuw mm3, [edi + 768 + 8*esi+120]
500 : edgomez 1192 paddw mm2, [ebx+8] ;sum
501 :     paddw mm5, mm0 ;final result
502 :     paddw mm7, mm3
503 : edgomez 1230 pxor mm0, mm0
504 :     pxor mm3, mm3
505 : edgomez 1192 psrlw mm5, 1 ; (level ) /2 (quant = 1)
506 :     psrlw mm7, 1
507 :     add esi, byte 2
508 :     paddw mm2, mm5 ;sum += x1
509 :     movq [ebx], mm7 ;store x2
510 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
511 :     pxor mm7, mm4 ;
512 :     psubw mm5, mm1 ; undisplace
513 :     psubw mm7, mm4 ;
514 :     movq [ebx+8], mm2 ;store sum
515 :     movq [edx + 8*esi+112-16], mm5
516 :     movq [edx + 8*esi +120-16], mm7
517 :     jng near .q1loop
518 :     jmp near .done
519 : edgomez 1174
520 : edgomez 1192 ALIGN 8
521 : edgomez 1174 .lloop
522 : edgomez 1192 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
523 :     psubw mm0,mm1 ;-mm1
524 :     movq mm4, [eax + 8*esi+120]
525 :     psubw mm3,mm4 ;-mm4
526 :     pmaxsw mm0,mm1 ;|src|
527 :     pmaxsw mm3,mm4
528 :     nop2
529 :     psraw mm1,15 ;sign src
530 :     psraw mm4,15
531 :     psllw mm0, 4 ; level << 4
532 :     psllw mm3, 4 ;
533 : edgomez 1230 paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1
534 :     paddw mm3, [edi + 640 + 8*esi+120]
535 :     movq mm5,[edi + 896 + 8*esi+112]
536 :     movq mm7,[edi + 896 + 8*esi+120]
537 : edgomez 1192 pmulhuw mm5,mm0
538 :     pmulhuw mm7,mm3 ;mm7: first approx of division
539 :     mov esp,esp
540 : edgomez 1230 movq mm2,[edi + 512 + 8*esi+112]
541 :     movq mm6,[edi + 512 + 8*esi+120]
542 : edgomez 1192 pmullw mm2,mm5 ;test value <= original
543 :     pmullw mm6,mm7
544 :     psubw mm0,mm2 ;mismatch
545 :     psubw mm3,mm6
546 :     movq mm2,[byte ebx]
547 :     movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16
548 : edgomez 1230 pmulhuw mm0,[edi + 768 + 8*esi+112] ;correction
549 :     pmulhuw mm3,[edi + 768 + 8*esi+120]
550 : edgomez 1192 paddw mm2,[ebx+8] ;sum
551 :     paddw mm5,mm0 ;final result
552 :     paddw mm7,mm3
553 : edgomez 1230 pxor mm0,mm0
554 :     pxor mm3,mm3
555 : edgomez 1192 pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
556 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
557 :     add esi,byte 2
558 :     psrlw mm5, 1 ; (level ) / (2*quant)
559 :     paddw mm2,mm5 ;sum += x1
560 :     psrlw mm7, 1
561 :     movq [ebx],mm7 ;store x2
562 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
563 :     pxor mm7, mm4 ;
564 :     psubw mm5, mm1 ; undisplace
565 :     psubw mm7, mm4 ;
566 :     db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
567 :     movq [edx + 8*esi+112-16], mm5
568 :     movq [edx + 8*esi +120-16], mm7
569 :     jng near .lloop
570 :     jmp near .done
571 : edgomez 1174
572 :    
573 : edgomez 1192 ;-----------------------------------------------------------------------------
574 : edgomez 1174 ;
575 : edgomez 1176 ; uint32_t dequant_mpeg_intra_3dne(int16_t *data,
576 :     ; const int16_t const *coeff,
577 :     ; const uint32_t quant,
578 : edgomez 1230 ; const uint32_t dcscalar,
579 :     ; const uint16_t *mpeg_matrices);
580 : edgomez 1174 ;
581 : edgomez 1192 ;-----------------------------------------------------------------------------
582 : edgomez 1174
583 :     ; Note: in order to saturate 'easily', we pre-shift the quantifier
584 :     ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
585 :     ; build a saturating mask. It is non-zero only when an overflow occured.
586 :     ; We thus avoid packing/unpacking toward double-word.
587 :     ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
588 :     ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
589 :     ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
590 : edgomez 1192 ; and quant in [1..31].
591 : edgomez 1174 ;
592 : edgomez 1176
593 : edgomez 1174 %macro DEQUANT4INTRAMMX 1
594 : edgomez 1192 movq mm1, [byte ecx+ 16 * %1] ; mm0 = c = coeff[i]
595 :     movq mm4, [ecx+ 16 * %1 +8] ; mm3 = c' = coeff[i+1]
596 :     psubw mm0, mm1
597 :     psubw mm3, mm4
598 :     pmaxsw mm0, mm1
599 :     pmaxsw mm3, mm4
600 :     psraw mm1, 15
601 :     psraw mm4, 15
602 :     %if %1
603 :     movq mm2, [eax+8] ;preshifted quant
604 :     movq mm7, [eax+8]
605 : edgomez 1174 %endif
606 : edgomez 1230 pmullw mm2, [edi + 16 * %1 ] ; matrix[i]*quant
607 :     pmullw mm7, [edi + 16 * %1 +8] ; matrix[i+1]*quant
608 : edgomez 1192 movq mm5, mm0
609 :     movq mm6, mm3
610 :     pmulhw mm0, mm2 ; high of coeff*(matrix*quant)
611 :     pmulhw mm3, mm7 ; high of coeff*(matrix*quant)
612 :     pmullw mm2, mm5 ; low of coeff*(matrix*quant)
613 :     pmullw mm7, mm6 ; low of coeff*(matrix*quant)
614 :     pcmpgtw mm0, [eax]
615 :     pcmpgtw mm3, [eax]
616 :     paddusw mm2, mm0
617 :     paddusw mm7, mm3
618 :     psrlw mm2, 5
619 :     psrlw mm7, 5
620 :     pxor mm2, mm1 ; start negating back
621 :     pxor mm7, mm4 ; start negating back
622 :     psubusw mm1, mm0
623 :     psubusw mm4, mm3
624 :     movq mm0, [eax] ;zero
625 :     movq mm3, [eax] ;zero
626 :     psubw mm2, mm1 ; finish negating back
627 :     psubw mm7, mm4 ; finish negating back
628 :     movq [byte edx + 16 * %1], mm2 ; data[i]
629 :     movq [edx + 16 * %1 +8], mm7 ; data[i+1]
630 : edgomez 1174 %endmacro
631 :    
632 : edgomez 1192 ALIGN 16
633 : edgomez 1174 dequant_mpeg_intra_3dne:
634 : edgomez 1192 mov eax, [esp+12] ; quant
635 :     mov ecx, [esp+8] ; coeff
636 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
637 :     psllw mm7, 2 ; << 2. See comment.
638 :     mov edx, [esp+4] ; data
639 :     push ebx
640 :     movsx ebx, word [ecx]
641 :     pxor mm0, mm0
642 :     pxor mm3, mm3
643 :     push esi
644 :     lea eax, [esp-28]
645 :     sub esp, byte 32
646 :     and eax, byte -8 ;points to qword ALIGNed space on stack
647 :     movq [eax], mm0
648 :     movq [eax+8], mm7
649 :     imul ebx, [esp+16+8+32] ; dcscalar
650 :     movq mm2, mm7
651 : edgomez 1230 push edi
652 :     mov edi, [esp + 32 + 12 + 20] ; mpeg_quant_matrices
653 : edgomez 1192 ALIGN 4
654 : edgomez 1174
655 : edgomez 1192 DEQUANT4INTRAMMX 0
656 : edgomez 1174
657 : edgomez 1192 mov esi, -2048
658 :     nop
659 :     cmp ebx, esi
660 : edgomez 1174
661 : edgomez 1192 DEQUANT4INTRAMMX 1
662 : edgomez 1174
663 : edgomez 1192 cmovl ebx, esi
664 :     neg esi
665 :     sub esi, byte 1 ;2047
666 : edgomez 1174
667 : edgomez 1192 DEQUANT4INTRAMMX 2
668 : edgomez 1174
669 : edgomez 1192 cmp ebx, esi
670 :     cmovg ebx, esi
671 :     lea ebp, [byte ebp]
672 : edgomez 1174
673 : edgomez 1192 DEQUANT4INTRAMMX 3
674 : edgomez 1174
675 : edgomez 1230 mov esi, [esp+36]
676 : edgomez 1192 mov [byte edx], bx
677 : edgomez 1230 mov ebx, [esp+36+4]
678 : edgomez 1174
679 : edgomez 1192 DEQUANT4INTRAMMX 4
680 :     DEQUANT4INTRAMMX 5
681 :     DEQUANT4INTRAMMX 6
682 :     DEQUANT4INTRAMMX 7
683 : edgomez 1174
684 : edgomez 1230 pop edi
685 :    
686 : edgomez 1192 add esp, byte 32+8
687 : edgomez 1174
688 : edgomez 1192 xor eax, eax
689 :     ret
690 :    
691 :     ;-----------------------------------------------------------------------------
692 : edgomez 1174 ;
693 : edgomez 1176 ; uint32_t dequant_mpeg_inter_3dne(int16_t * data,
694 :     ; const int16_t * const coeff,
695 : edgomez 1230 ; const uint32_t quant,
696 :     ; const uint16_t *mpeg_matrices);
697 : edgomez 1174 ;
698 : edgomez 1192 ;-----------------------------------------------------------------------------
699 : edgomez 1174
700 :     ; Note: We use (2*c + sgn(c) - sgn(-c)) as multiplier
701 :     ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
702 :     ; sgn(x) is the result of 'pcmpgtw 0,x': 0 if x>=0, -1 if x<0.
703 :     ; It's mixed with the extraction of the absolute value.
704 :    
705 : edgomez 1192 ALIGN 16
706 : edgomez 1174 dequant_mpeg_inter_3dne:
707 : edgomez 1192 mov edx, [esp+ 4] ; data
708 :     mov ecx, [esp+ 8] ; coeff
709 :     mov eax, [esp+12] ; quant
710 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
711 :     mov eax, -14
712 :     paddw mm7, mm7 ; << 1
713 :     pxor mm6, mm6 ; mismatch sum
714 :     push esi
715 : edgomez 1230 push edi
716 : edgomez 1192 mov esi, mmzero
717 :     pxor mm1, mm1
718 :     pxor mm3, mm3
719 : edgomez 1230 mov edi, [esp + 8 + 16] ; mpeg_quant_matrices
720 : edgomez 1192 nop
721 :     nop4
722 : edgomez 1174
723 : edgomez 1192 ALIGN 16
724 : edgomez 1174 .loop
725 : edgomez 1192 movq mm0, [ecx+8*eax + 7*16 ] ; mm0 = coeff[i]
726 :     pcmpgtw mm1, mm0 ; mm1 = sgn(c) (preserved)
727 :     movq mm2, [ecx+8*eax + 7*16 +8] ; mm2 = coeff[i+1]
728 :     pcmpgtw mm3, mm2 ; mm3 = sgn(c') (preserved)
729 :     paddsw mm0, mm1 ; c += sgn(c)
730 :     paddsw mm2, mm3 ; c += sgn(c')
731 :     paddw mm0, mm0 ; c *= 2
732 :     paddw mm2, mm2 ; c'*= 2
733 : edgomez 1174
734 : edgomez 1192 movq mm4, [esi]
735 :     movq mm5, [esi]
736 :     psubw mm4, mm0 ; -c
737 :     psubw mm5, mm2 ; -c'
738 : edgomez 1174
739 : edgomez 1192 psraw mm4, 16 ; mm4 = sgn(-c)
740 :     psraw mm5, 16 ; mm5 = sgn(-c')
741 :     psubsw mm0, mm4 ; c -= sgn(-c)
742 :     psubsw mm2, mm5 ; c' -= sgn(-c')
743 :     pxor mm0, mm1 ; finish changing sign if needed
744 :     pxor mm2, mm3 ; finish changing sign if needed
745 : edgomez 1174
746 : edgomez 1192 ; we're short on register, here. Poor pairing...
747 : edgomez 1174
748 : edgomez 1192 movq mm4, mm7 ; (matrix*quant)
749 :     nop
750 : edgomez 1230 pmullw mm4, [edi + 512 + 8*eax + 7*16]
751 : edgomez 1192 movq mm5, mm4
752 :     pmulhw mm5, mm0 ; high of c*(matrix*quant)
753 :     pmullw mm0, mm4 ; low of c*(matrix*quant)
754 : edgomez 1174
755 : edgomez 1192 movq mm4, mm7 ; (matrix*quant)
756 : edgomez 1230 pmullw mm4, [edi + 512 + 8*eax + 7*16 + 8]
757 : edgomez 1192 add eax, byte 2
758 : edgomez 1174
759 : edgomez 1192 pcmpgtw mm5, [esi]
760 :     paddusw mm0, mm5
761 :     psrlw mm0, 5
762 :     pxor mm0, mm1 ; start restoring sign
763 :     psubusw mm1, mm5
764 : edgomez 1174
765 : edgomez 1192 movq mm5, mm4
766 :     pmulhw mm5, mm2 ; high of c*(matrix*quant)
767 :     pmullw mm2, mm4 ; low of c*(matrix*quant)
768 :     psubw mm0, mm1 ; finish restoring sign
769 : edgomez 1174
770 : edgomez 1192 pcmpgtw mm5, [esi]
771 :     paddusw mm2, mm5
772 :     psrlw mm2, 5
773 :     pxor mm2, mm3 ; start restoring sign
774 :     psubusw mm3, mm5
775 :     psubw mm2, mm3 ; finish restoring sign
776 :     movq mm1, [esi]
777 :     movq mm3, [byte esi]
778 :     pxor mm6, mm0 ; mismatch control
779 :     movq [edx + 8*eax + 7*16 -2*8 ], mm0 ; data[i]
780 :     pxor mm6, mm2 ; mismatch control
781 :     movq [edx + 8*eax + 7*16 -2*8 +8], mm2 ; data[i+1]
782 : edgomez 1174
783 : edgomez 1192 jng .loop
784 :     nop
785 : edgomez 1174
786 : edgomez 1192 ; mismatch control
787 : edgomez 1174
788 : edgomez 1192 pshufw mm0, mm6, 01010101b
789 :     pshufw mm1, mm6, 10101010b
790 :     pshufw mm2, mm6, 11111111b
791 :     pxor mm6, mm0
792 :     pxor mm1, mm2
793 :     pxor mm6, mm1
794 :     movd eax, mm6
795 : edgomez 1230 pop edi
796 : edgomez 1192 and eax, byte 1
797 :     xor eax, byte 1
798 :     mov esi, [esp]
799 :     add esp, byte 4
800 :     xor word [edx + 2*63], ax
801 : edgomez 1174
802 : edgomez 1192 xor eax, eax
803 :     ret

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