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

Annotation of /trunk/xvidcore/src/quant/x86_asm/quantize_mpeg_xmm.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1535 - (view) (download)

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

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