[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 1540 - (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 1540 ; * $Id: quantize_mpeg_xmm.asm,v 1.5 2004-08-29 10:02:38 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 : edgomez 1540 global _%1:function %1.endfunc-%1
38 :     %define %1 _%1:function %1.endfunc-%1
39 : edgomez 1535 %else
40 :     global _%1
41 :     %define %1 _%1
42 :     %endif
43 : edgomez 1382 %else
44 : edgomez 1535 %ifdef MARK_FUNCS
45 : edgomez 1540 global %1:function %1.endfunc-%1
46 : edgomez 1535 %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 : edgomez 1540 .endfunc
382 : edgomez 1382
383 :     ;-----------------------------------------------------------------------------
384 :     ;
385 :     ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,
386 :     ; const int16_t const * data,
387 :     ; const uint32_t quant,
388 :     ; const uint16_t *mpeg_matrices);
389 :     ;
390 :     ;-----------------------------------------------------------------------------
391 :    
392 :     ALIGN 16
393 :     quant_mpeg_inter_xmm:
394 :     mov eax, [esp + 8] ; data
395 :     mov ecx, [esp + 12] ; quant
396 :     mov edx, [esp + 4] ; coeff
397 :     push esi
398 :     push edi
399 :     push ebx
400 :     nop
401 :     mov edi, [esp + 12 + 16]
402 :     mov esi, -14
403 :     mov ebx, esp
404 :     sub esp, byte 24
405 :     lea ebx, [esp+8]
406 :     and ebx, byte -8 ;ALIGN 8
407 :     pxor mm0, mm0
408 :     pxor mm3, mm3
409 :     movq [byte ebx],mm0
410 :     db 0Fh, 7Fh, 44h, 23h, 8 ;movq [ebx+8],mm0
411 :     cmp ecx, byte 1
412 :     je near .q1loop
413 :     cmp ecx, byte 19
414 :     jg near .lloop
415 :     nop
416 :    
417 :     ALIGN 16
418 :     .loop
419 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
420 :     psubw mm0, mm1 ;-mm1
421 :     movq mm4, [eax + 8*esi + 120] ;
422 :     psubw mm3, mm4 ;-mm4
423 :     pmaxsw mm0, mm1 ;|src|
424 :     pmaxsw mm3, mm4
425 :     nop2
426 :     psraw mm1, 15 ;sign src
427 :     psraw mm4, 15
428 :     psllw mm0, 4 ; level << 4
429 :     psllw mm3, 4 ;
430 :     paddw mm0, [edi + 640 + 8*esi+112]
431 :     paddw mm3, [edi + 640 + 8*esi+120]
432 :     movq mm5, [edi + 896 + 8*esi+112]
433 :     movq mm7, [edi + 896 + 8*esi+120]
434 :     pmulhuw mm5, mm0
435 :     pmulhuw mm7, mm3
436 :     mov esp, esp
437 :     movq mm2, [edi + 512 + 8*esi+112]
438 :     movq mm6, [edi + 512 + 8*esi+120]
439 :     pmullw mm2, mm5
440 :     pmullw mm6, mm7
441 :     psubw mm0, mm2
442 :     psubw mm3, mm6
443 :     movq mm2, [byte ebx]
444 :     movq mm6, [mmx_divs + ecx * 8 - 8]
445 :     pmulhuw mm0, [edi + 768 + 8*esi+112]
446 :     pmulhuw mm3, [edi + 768 + 8*esi+120]
447 :     paddw mm2, [ebx+8] ;sum
448 :     paddw mm5, mm0
449 :     paddw mm7, mm3
450 :     pxor mm0, mm0
451 :     pxor mm3, mm3
452 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
453 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
454 :     add esi, byte 2
455 :     paddw mm2, mm5 ;sum += x1
456 :     movq [ebx], mm7 ;store x2
457 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
458 :     pxor mm7, mm4 ;
459 :     psubw mm5, mm1 ; undisplace
460 :     psubw mm7, mm4 ;
461 :     db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
462 :     movq [edx + 8*esi+112-16], mm5
463 :     movq [edx + 8*esi +120-16], mm7
464 :     jng near .loop
465 :    
466 :     .done
467 :     ; calculate data[0] // (int32_t)dcscalar)
468 :     paddw mm2, [ebx]
469 :     mov ebx, [esp+24]
470 :     mov edi, [esp+4+24]
471 :     mov esi, [esp+8+24]
472 :     add esp, byte 12+24
473 :     pmaddwd mm2, [mmx_one]
474 :     punpckldq mm0, mm2 ;get low dw to mm0:high
475 :     paddd mm0,mm2
476 :     punpckhdq mm0, mm0 ;get result to low
477 :     movd eax, mm0
478 :    
479 :     ret
480 :    
481 :     ALIGN 16
482 :     .q1loop
483 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
484 :     psubw mm0, mm1 ;-mm1
485 :     movq mm4, [eax + 8*esi+120]
486 :     psubw mm3, mm4 ;-mm4
487 :     pmaxsw mm0, mm1 ;|src|
488 :     pmaxsw mm3, mm4
489 :     nop2
490 :     psraw mm1, 15 ; sign src
491 :     psraw mm4, 15
492 :     psllw mm0, 4 ; level << 4
493 :     psllw mm3, 4
494 :     paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided
495 :     paddw mm3, [edi + 640 + 8*esi+120] ; inter1 contains fix for division by 1
496 :     movq mm5, [edi + 896 + 8*esi+112] ;with rounding down
497 :     movq mm7, [edi + 896 + 8*esi+120]
498 :     pmulhuw mm5, mm0
499 :     pmulhuw mm7, mm3 ;mm7: first approx of division
500 :     mov esp, esp
501 :     movq mm2, [edi + 512 + 8*esi+112]
502 :     movq mm6, [edi + 512 + 8*esi+120] ; divs for q<=16
503 :     pmullw mm2, mm5 ;test value <= original
504 :     pmullw mm6, mm7
505 :     psubw mm0, mm2 ;mismatch
506 :     psubw mm3, mm6
507 :     movq mm2, [byte ebx]
508 :     pmulhuw mm0, [edi + 768 + 8*esi+112] ;correction
509 :     pmulhuw mm3, [edi + 768 + 8*esi+120]
510 :     paddw mm2, [ebx+8] ;sum
511 :     paddw mm5, mm0 ;final result
512 :     paddw mm7, mm3
513 :     pxor mm0, mm0
514 :     pxor mm3, mm3
515 :     psrlw mm5, 1 ; (level ) /2 (quant = 1)
516 :     psrlw mm7, 1
517 :     add esi, byte 2
518 :     paddw mm2, mm5 ;sum += x1
519 :     movq [ebx], mm7 ;store x2
520 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
521 :     pxor mm7, mm4 ;
522 :     psubw mm5, mm1 ; undisplace
523 :     psubw mm7, mm4 ;
524 :     movq [ebx+8], mm2 ;store sum
525 :     movq [edx + 8*esi+112-16], mm5
526 :     movq [edx + 8*esi +120-16], mm7
527 :     jng near .q1loop
528 :     jmp near .done
529 :    
530 :     ALIGN 8
531 :     .lloop
532 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
533 :     psubw mm0,mm1 ;-mm1
534 :     movq mm4, [eax + 8*esi+120]
535 :     psubw mm3,mm4 ;-mm4
536 :     pmaxsw mm0,mm1 ;|src|
537 :     pmaxsw mm3,mm4
538 :     nop2
539 :     psraw mm1,15 ;sign src
540 :     psraw mm4,15
541 :     psllw mm0, 4 ; level << 4
542 :     psllw mm3, 4 ;
543 :     paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1
544 :     paddw mm3, [edi + 640 + 8*esi+120]
545 :     movq mm5,[edi + 896 + 8*esi+112]
546 :     movq mm7,[edi + 896 + 8*esi+120]
547 :     pmulhuw mm5,mm0
548 :     pmulhuw mm7,mm3 ;mm7: first approx of division
549 :     mov esp,esp
550 :     movq mm2,[edi + 512 + 8*esi+112]
551 :     movq mm6,[edi + 512 + 8*esi+120]
552 :     pmullw mm2,mm5 ;test value <= original
553 :     pmullw mm6,mm7
554 :     psubw mm0,mm2 ;mismatch
555 :     psubw mm3,mm6
556 :     movq mm2,[byte ebx]
557 :     movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16
558 :     pmulhuw mm0,[edi + 768 + 8*esi+112] ;correction
559 :     pmulhuw mm3,[edi + 768 + 8*esi+120]
560 :     paddw mm2,[ebx+8] ;sum
561 :     paddw mm5,mm0 ;final result
562 :     paddw mm7,mm3
563 :     pxor mm0,mm0
564 :     pxor mm3,mm3
565 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
566 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
567 :     add esi,byte 2
568 :     psrlw mm5, 1 ; (level ) / (2*quant)
569 :     paddw mm2,mm5 ;sum += x1
570 :     psrlw mm7, 1
571 :     movq [ebx],mm7 ;store x2
572 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
573 :     pxor mm7, mm4 ;
574 :     psubw mm5, mm1 ; undisplace
575 :     psubw mm7, mm4 ;
576 :     db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
577 :     movq [edx + 8*esi+112-16], mm5
578 :     movq [edx + 8*esi +120-16], mm7
579 :     jng near .lloop
580 :     jmp near .done
581 : edgomez 1540 .endfunc
582 : edgomez 1382
583 :    
584 :     ;-----------------------------------------------------------------------------
585 :     ;
586 :     ; uint32_t dequant_mpeg_intra_3dne(int16_t *data,
587 :     ; const int16_t const *coeff,
588 :     ; const uint32_t quant,
589 :     ; const uint32_t dcscalar,
590 :     ; const uint16_t *mpeg_matrices);
591 :     ;
592 :     ;-----------------------------------------------------------------------------
593 :    
594 :     ; Note: in order to saturate 'easily', we pre-shift the quantifier
595 :     ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
596 :     ; build a saturating mask. It is non-zero only when an overflow occured.
597 :     ; We thus avoid packing/unpacking toward double-word.
598 :     ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
599 :     ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
600 :     ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
601 :     ; and quant in [1..31].
602 :     ;
603 :    
604 :     %macro DEQUANT4INTRAMMX 1
605 :     movq mm1, [byte ecx+ 16 * %1] ; mm0 = c = coeff[i]
606 :     movq mm4, [ecx+ 16 * %1 +8] ; mm3 = c' = coeff[i+1]
607 :     psubw mm0, mm1
608 :     psubw mm3, mm4
609 :     pmaxsw mm0, mm1
610 :     pmaxsw mm3, mm4
611 :     psraw mm1, 15
612 :     psraw mm4, 15
613 :     %if %1
614 :     movq mm2, [eax+8] ;preshifted quant
615 :     movq mm7, [eax+8]
616 :     %endif
617 :     pmullw mm2, [edi + 16 * %1 ] ; matrix[i]*quant
618 :     pmullw mm7, [edi + 16 * %1 +8] ; matrix[i+1]*quant
619 :     movq mm5, mm0
620 :     movq mm6, mm3
621 :     pmulhw mm0, mm2 ; high of coeff*(matrix*quant)
622 :     pmulhw mm3, mm7 ; high of coeff*(matrix*quant)
623 :     pmullw mm2, mm5 ; low of coeff*(matrix*quant)
624 :     pmullw mm7, mm6 ; low of coeff*(matrix*quant)
625 :     pcmpgtw mm0, [eax]
626 :     pcmpgtw mm3, [eax]
627 :     paddusw mm2, mm0
628 :     paddusw mm7, mm3
629 :     psrlw mm2, 5
630 :     psrlw mm7, 5
631 :     pxor mm2, mm1 ; start negating back
632 :     pxor mm7, mm4 ; start negating back
633 :     psubusw mm1, mm0
634 :     psubusw mm4, mm3
635 :     movq mm0, [eax] ;zero
636 :     movq mm3, [eax] ;zero
637 :     psubw mm2, mm1 ; finish negating back
638 :     psubw mm7, mm4 ; finish negating back
639 :     movq [byte edx + 16 * %1], mm2 ; data[i]
640 :     movq [edx + 16 * %1 +8], mm7 ; data[i+1]
641 :     %endmacro
642 :    
643 :     ALIGN 16
644 :     dequant_mpeg_intra_3dne:
645 :     mov eax, [esp+12] ; quant
646 :     mov ecx, [esp+8] ; coeff
647 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
648 :     psllw mm7, 2 ; << 2. See comment.
649 :     mov edx, [esp+4] ; data
650 :     push ebx
651 :     movsx ebx, word [ecx]
652 :     pxor mm0, mm0
653 :     pxor mm3, mm3
654 :     push esi
655 :     lea eax, [esp-28]
656 :     sub esp, byte 32
657 :     and eax, byte -8 ;points to qword ALIGNed space on stack
658 :     movq [eax], mm0
659 :     movq [eax+8], mm7
660 :     imul ebx, [esp+16+8+32] ; dcscalar
661 :     movq mm2, mm7
662 :     push edi
663 :     mov edi, [esp + 32 + 12 + 20] ; mpeg_quant_matrices
664 :     ALIGN 4
665 :    
666 :     DEQUANT4INTRAMMX 0
667 :    
668 :     mov esi, -2048
669 :     nop
670 :     cmp ebx, esi
671 :    
672 :     DEQUANT4INTRAMMX 1
673 :    
674 :     cmovl ebx, esi
675 :     neg esi
676 :     sub esi, byte 1 ;2047
677 :    
678 :     DEQUANT4INTRAMMX 2
679 :    
680 :     cmp ebx, esi
681 :     cmovg ebx, esi
682 :     lea ebp, [byte ebp]
683 :    
684 :     DEQUANT4INTRAMMX 3
685 :    
686 :     mov esi, [esp+36]
687 :     mov [byte edx], bx
688 :     mov ebx, [esp+36+4]
689 :    
690 :     DEQUANT4INTRAMMX 4
691 :     DEQUANT4INTRAMMX 5
692 :     DEQUANT4INTRAMMX 6
693 :     DEQUANT4INTRAMMX 7
694 :    
695 :     pop edi
696 :    
697 :     add esp, byte 32+8
698 :    
699 :     xor eax, eax
700 :     ret
701 : edgomez 1540 .endfunc
702 : edgomez 1382
703 :     ;-----------------------------------------------------------------------------
704 :     ;
705 :     ; uint32_t dequant_mpeg_inter_3dne(int16_t * data,
706 :     ; const int16_t * const coeff,
707 :     ; const uint32_t quant,
708 :     ; const uint16_t *mpeg_matrices);
709 :     ;
710 :     ;-----------------------------------------------------------------------------
711 :    
712 :     ; Note: We use (2*c + sgn(c) - sgn(-c)) as multiplier
713 :     ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
714 :     ; sgn(x) is the result of 'pcmpgtw 0,x': 0 if x>=0, -1 if x<0.
715 :     ; It's mixed with the extraction of the absolute value.
716 :    
717 :     ALIGN 16
718 :     dequant_mpeg_inter_3dne:
719 :     mov edx, [esp+ 4] ; data
720 :     mov ecx, [esp+ 8] ; coeff
721 :     mov eax, [esp+12] ; quant
722 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
723 :     mov eax, -14
724 :     paddw mm7, mm7 ; << 1
725 :     pxor mm6, mm6 ; mismatch sum
726 :     push esi
727 :     push edi
728 :     mov esi, mmzero
729 :     pxor mm1, mm1
730 :     pxor mm3, mm3
731 :     mov edi, [esp + 8 + 16] ; mpeg_quant_matrices
732 :     nop
733 :     nop4
734 :    
735 :     ALIGN 16
736 :     .loop
737 :     movq mm0, [ecx+8*eax + 7*16 ] ; mm0 = coeff[i]
738 :     pcmpgtw mm1, mm0 ; mm1 = sgn(c) (preserved)
739 :     movq mm2, [ecx+8*eax + 7*16 +8] ; mm2 = coeff[i+1]
740 :     pcmpgtw mm3, mm2 ; mm3 = sgn(c') (preserved)
741 :     paddsw mm0, mm1 ; c += sgn(c)
742 :     paddsw mm2, mm3 ; c += sgn(c')
743 :     paddw mm0, mm0 ; c *= 2
744 :     paddw mm2, mm2 ; c'*= 2
745 :    
746 :     movq mm4, [esi]
747 :     movq mm5, [esi]
748 :     psubw mm4, mm0 ; -c
749 :     psubw mm5, mm2 ; -c'
750 :    
751 :     psraw mm4, 16 ; mm4 = sgn(-c)
752 :     psraw mm5, 16 ; mm5 = sgn(-c')
753 :     psubsw mm0, mm4 ; c -= sgn(-c)
754 :     psubsw mm2, mm5 ; c' -= sgn(-c')
755 :     pxor mm0, mm1 ; finish changing sign if needed
756 :     pxor mm2, mm3 ; finish changing sign if needed
757 :    
758 :     ; we're short on register, here. Poor pairing...
759 :    
760 :     movq mm4, mm7 ; (matrix*quant)
761 :     nop
762 :     pmullw mm4, [edi + 512 + 8*eax + 7*16]
763 :     movq mm5, mm4
764 :     pmulhw mm5, mm0 ; high of c*(matrix*quant)
765 :     pmullw mm0, mm4 ; low of c*(matrix*quant)
766 :    
767 :     movq mm4, mm7 ; (matrix*quant)
768 :     pmullw mm4, [edi + 512 + 8*eax + 7*16 + 8]
769 :     add eax, byte 2
770 :    
771 :     pcmpgtw mm5, [esi]
772 :     paddusw mm0, mm5
773 :     psrlw mm0, 5
774 :     pxor mm0, mm1 ; start restoring sign
775 :     psubusw mm1, mm5
776 :    
777 :     movq mm5, mm4
778 :     pmulhw mm5, mm2 ; high of c*(matrix*quant)
779 :     pmullw mm2, mm4 ; low of c*(matrix*quant)
780 :     psubw mm0, mm1 ; finish restoring sign
781 :    
782 :     pcmpgtw mm5, [esi]
783 :     paddusw mm2, mm5
784 :     psrlw mm2, 5
785 :     pxor mm2, mm3 ; start restoring sign
786 :     psubusw mm3, mm5
787 :     psubw mm2, mm3 ; finish restoring sign
788 :     movq mm1, [esi]
789 :     movq mm3, [byte esi]
790 :     pxor mm6, mm0 ; mismatch control
791 :     movq [edx + 8*eax + 7*16 -2*8 ], mm0 ; data[i]
792 :     pxor mm6, mm2 ; mismatch control
793 :     movq [edx + 8*eax + 7*16 -2*8 +8], mm2 ; data[i+1]
794 :    
795 :     jng .loop
796 :     nop
797 :    
798 :     ; mismatch control
799 :    
800 :     pshufw mm0, mm6, 01010101b
801 :     pshufw mm1, mm6, 10101010b
802 :     pshufw mm2, mm6, 11111111b
803 :     pxor mm6, mm0
804 :     pxor mm1, mm2
805 :     pxor mm6, mm1
806 :     movd eax, mm6
807 :     pop edi
808 :     and eax, byte 1
809 :     xor eax, byte 1
810 :     mov esi, [esp]
811 :     add esp, byte 4
812 :     xor word [edx + 2*63], ax
813 :    
814 :     xor eax, eax
815 :     ret
816 : edgomez 1540 .endfunc
817 :    

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