[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 1519 - (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 1519 ; * $Id: quantize_mpeg_xmm.asm,v 1.3 2004-07-24 11:46:08 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 :     global _%1
37 :     %define %1 _%1
38 :     %else
39 :     global %1
40 :     %endif
41 :     %endmacro
42 :    
43 :     %macro cextern 1
44 :     %ifdef PREFIX
45 :     extern _%1
46 :     %define %1 _%1
47 :     %else
48 :     extern %1
49 :     %endif
50 :     %endmacro
51 :    
52 :     ;=============================================================================
53 :     ; Local data
54 :     ;=============================================================================
55 :    
56 :     %ifdef FORMAT_COFF
57 : edgomez 1519 SECTION .rodata
58 : edgomez 1382 %else
59 : edgomez 1519 SECTION .rodata align=16
60 : edgomez 1382 %endif
61 :    
62 :     ALIGN 8
63 :     mmzero:
64 :     dd 0,0
65 :     mmx_one:
66 :     times 4 dw 1
67 :    
68 :     ;-----------------------------------------------------------------------------
69 :     ; divide by 2Q table
70 :     ;-----------------------------------------------------------------------------
71 :    
72 :     ALIGN 16
73 :     mmx_divs: ;i>2
74 :     %assign i 1
75 :     %rep 31
76 :     times 4 dw ((1 << 15) / i + 1)
77 :     %assign i i+1
78 :     %endrep
79 :    
80 :     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 :     %rep 31
88 :     times 4 dw ((1 << 16) / quant + 1)
89 :     %assign quant quant+1
90 :     %endrep
91 :    
92 :     %macro FIXX 1
93 :     dw (1 << 16) / (%1) + 1
94 :     %endmacro
95 :    
96 :     %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 :    
102 :     ;-----------------------------------------------------------------------------
103 :     ; quantd table
104 :     ;-----------------------------------------------------------------------------
105 :    
106 :     %define VM18P 3
107 :     %define VM18Q 4
108 :    
109 :     ALIGN 16
110 :     quantd:
111 :     %assign i 1
112 :     %rep 31
113 :     times 4 dw (((VM18P*i) + (VM18Q/2)) / VM18Q)
114 :     %assign i i+1
115 :     %endrep
116 :    
117 :     ;-----------------------------------------------------------------------------
118 :     ; multiple by 2Q table
119 :     ;-----------------------------------------------------------------------------
120 :    
121 :     ALIGN 16
122 :     mmx_mul_quant:
123 :     %assign i 1
124 :     %rep 31
125 :     times 4 dw i
126 :     %assign i i+1
127 :     %endrep
128 :    
129 :     ;-----------------------------------------------------------------------------
130 :     ; saturation limits
131 :     ;-----------------------------------------------------------------------------
132 :    
133 :     ALIGN 16
134 :     mmx_32767_minus_2047:
135 :     times 4 dw (32767-2047)
136 :     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 :    
145 :     int_div:
146 :     dd 0
147 :     %assign i 1
148 :     %rep 255
149 :     dd (1 << 17) / ( i) + 1
150 :     %assign i i+1
151 :     %endrep
152 :    
153 :     ;=============================================================================
154 :     ; Code
155 :     ;=============================================================================
156 :    
157 :     SECTION .text
158 :    
159 :     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 :     ;
166 :     ; uint32_t quant_mpeg_intra_xmm(int16_t * coeff,
167 :     ; const int16_t const * data,
168 :     ; const uint32_t quant,
169 :     ; const uint32_t dcscalar,
170 :     ; const uint16_t *mpeg_matrices);
171 :     ;
172 :     ;-----------------------------------------------------------------------------
173 :    
174 :     ALIGN 16
175 :     quant_mpeg_intra_xmm:
176 :     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 :     mov edi, [esp + 12 + 20] ; mpeg_quant_matrices
184 :     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 :     .loop
195 :     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 :     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 :     pmulhuw mm5, mm0
211 :     pmulhuw mm7, mm3
212 :     mov esp, esp
213 :     movq mm2, [edi + 8*esi+112]
214 :     movq mm6, [edi + 8*esi+120]
215 :     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 :     pmulhuw mm0, [edi + 256 + 8*esi+112]
226 :     pmulhuw mm3, [edi + 256 + 8*esi+120]
227 :     paddw mm5, mm0
228 :     paddw mm7, mm3
229 :     pxor mm0, mm0
230 :     pxor mm3, mm3
231 :     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 :    
242 :     .done
243 :     ; calculate data[0] // (int32_t)dcscalar)
244 :     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 :    
261 :     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 :    
267 :     xor eax, eax
268 :     ret
269 :    
270 :     ALIGN 16
271 :     .q1loop
272 :     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 :     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 :     pmulhuw mm5, mm0
288 :     pmulhuw mm7, mm3 ;mm7: first approx of division
289 :     mov esp, esp
290 :     movq mm2, [edi + 8*esi+112]
291 :     movq mm6, [edi + 8*esi+120] ; divs for q<=16
292 :     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 :     pmulhuw mm0, [edi + 256 + 8*esi+112] ;correction
302 :     pmulhuw mm3, [edi + 256 + 8*esi+120]
303 :     paddw mm5, mm0 ;final result with quantd
304 :     paddw mm7, mm3
305 :     pxor mm0, mm0
306 :     pxor mm3, mm3
307 :     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 :    
320 :     ALIGN 8
321 :     .lloop
322 :     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 :     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 :     pmulhuw mm5, mm0
338 :     pmulhuw mm7, mm3 ;mm7: first approx of division
339 :     mov esp, esp
340 :     movq mm2, [edi + 8*esi+112]
341 :     movq mm6, [edi + 8*esi+120]
342 :     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 :     pmulhuw mm0, [edi + 256 + 8*esi+112] ;correction
353 :     pmulhuw mm3, [edi + 256 + 8*esi+120]
354 :     paddw mm5, mm0 ;final result with quantd
355 :     paddw mm7, mm3
356 :     pxor mm0, mm0
357 :     pxor mm3, mm3
358 :     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 :    
373 :     ;-----------------------------------------------------------------------------
374 :     ;
375 :     ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,
376 :     ; const int16_t const * data,
377 :     ; const uint32_t quant,
378 :     ; const uint16_t *mpeg_matrices);
379 :     ;
380 :     ;-----------------------------------------------------------------------------
381 :    
382 :     ALIGN 16
383 :     quant_mpeg_inter_xmm:
384 :     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 :     mov edi, [esp + 12 + 16]
392 :     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 :     .loop
409 :     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 :     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 :     pmulhuw mm5, mm0
425 :     pmulhuw mm7, mm3
426 :     mov esp, esp
427 :     movq mm2, [edi + 512 + 8*esi+112]
428 :     movq mm6, [edi + 512 + 8*esi+120]
429 :     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 :     pmulhuw mm0, [edi + 768 + 8*esi+112]
436 :     pmulhuw mm3, [edi + 768 + 8*esi+120]
437 :     paddw mm2, [ebx+8] ;sum
438 :     paddw mm5, mm0
439 :     paddw mm7, mm3
440 :     pxor mm0, mm0
441 :     pxor mm3, mm3
442 :     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 :    
456 :     .done
457 :     ; calculate data[0] // (int32_t)dcscalar)
458 :     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 :    
469 :     ret
470 :    
471 :     ALIGN 16
472 :     .q1loop
473 :     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 :     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 :     pmulhuw mm5, mm0
489 :     pmulhuw mm7, mm3 ;mm7: first approx of division
490 :     mov esp, esp
491 :     movq mm2, [edi + 512 + 8*esi+112]
492 :     movq mm6, [edi + 512 + 8*esi+120] ; divs for q<=16
493 :     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 :     pmulhuw mm0, [edi + 768 + 8*esi+112] ;correction
499 :     pmulhuw mm3, [edi + 768 + 8*esi+120]
500 :     paddw mm2, [ebx+8] ;sum
501 :     paddw mm5, mm0 ;final result
502 :     paddw mm7, mm3
503 :     pxor mm0, mm0
504 :     pxor mm3, mm3
505 :     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 :    
520 :     ALIGN 8
521 :     .lloop
522 :     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 :     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 :     pmulhuw mm5,mm0
538 :     pmulhuw mm7,mm3 ;mm7: first approx of division
539 :     mov esp,esp
540 :     movq mm2,[edi + 512 + 8*esi+112]
541 :     movq mm6,[edi + 512 + 8*esi+120]
542 :     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 :     pmulhuw mm0,[edi + 768 + 8*esi+112] ;correction
549 :     pmulhuw mm3,[edi + 768 + 8*esi+120]
550 :     paddw mm2,[ebx+8] ;sum
551 :     paddw mm5,mm0 ;final result
552 :     paddw mm7,mm3
553 :     pxor mm0,mm0
554 :     pxor mm3,mm3
555 :     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 :    
572 :    
573 :     ;-----------------------------------------------------------------------------
574 :     ;
575 :     ; uint32_t dequant_mpeg_intra_3dne(int16_t *data,
576 :     ; const int16_t const *coeff,
577 :     ; const uint32_t quant,
578 :     ; const uint32_t dcscalar,
579 :     ; const uint16_t *mpeg_matrices);
580 :     ;
581 :     ;-----------------------------------------------------------------------------
582 :    
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 :     ; and quant in [1..31].
591 :     ;
592 :    
593 :     %macro DEQUANT4INTRAMMX 1
594 :     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 :     %endif
606 :     pmullw mm2, [edi + 16 * %1 ] ; matrix[i]*quant
607 :     pmullw mm7, [edi + 16 * %1 +8] ; matrix[i+1]*quant
608 :     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 :     %endmacro
631 :    
632 :     ALIGN 16
633 :     dequant_mpeg_intra_3dne:
634 :     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 :     push edi
652 :     mov edi, [esp + 32 + 12 + 20] ; mpeg_quant_matrices
653 :     ALIGN 4
654 :    
655 :     DEQUANT4INTRAMMX 0
656 :    
657 :     mov esi, -2048
658 :     nop
659 :     cmp ebx, esi
660 :    
661 :     DEQUANT4INTRAMMX 1
662 :    
663 :     cmovl ebx, esi
664 :     neg esi
665 :     sub esi, byte 1 ;2047
666 :    
667 :     DEQUANT4INTRAMMX 2
668 :    
669 :     cmp ebx, esi
670 :     cmovg ebx, esi
671 :     lea ebp, [byte ebp]
672 :    
673 :     DEQUANT4INTRAMMX 3
674 :    
675 :     mov esi, [esp+36]
676 :     mov [byte edx], bx
677 :     mov ebx, [esp+36+4]
678 :    
679 :     DEQUANT4INTRAMMX 4
680 :     DEQUANT4INTRAMMX 5
681 :     DEQUANT4INTRAMMX 6
682 :     DEQUANT4INTRAMMX 7
683 :    
684 :     pop edi
685 :    
686 :     add esp, byte 32+8
687 :    
688 :     xor eax, eax
689 :     ret
690 :    
691 :     ;-----------------------------------------------------------------------------
692 :     ;
693 :     ; uint32_t dequant_mpeg_inter_3dne(int16_t * data,
694 :     ; const int16_t * const coeff,
695 :     ; const uint32_t quant,
696 :     ; const uint16_t *mpeg_matrices);
697 :     ;
698 :     ;-----------------------------------------------------------------------------
699 :    
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 :     ALIGN 16
706 :     dequant_mpeg_inter_3dne:
707 :     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 :     push edi
716 :     mov esi, mmzero
717 :     pxor mm1, mm1
718 :     pxor mm3, mm3
719 :     mov edi, [esp + 8 + 16] ; mpeg_quant_matrices
720 :     nop
721 :     nop4
722 :    
723 :     ALIGN 16
724 :     .loop
725 :     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 :    
734 :     movq mm4, [esi]
735 :     movq mm5, [esi]
736 :     psubw mm4, mm0 ; -c
737 :     psubw mm5, mm2 ; -c'
738 :    
739 :     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 :    
746 :     ; we're short on register, here. Poor pairing...
747 :    
748 :     movq mm4, mm7 ; (matrix*quant)
749 :     nop
750 :     pmullw mm4, [edi + 512 + 8*eax + 7*16]
751 :     movq mm5, mm4
752 :     pmulhw mm5, mm0 ; high of c*(matrix*quant)
753 :     pmullw mm0, mm4 ; low of c*(matrix*quant)
754 :    
755 :     movq mm4, mm7 ; (matrix*quant)
756 :     pmullw mm4, [edi + 512 + 8*eax + 7*16 + 8]
757 :     add eax, byte 2
758 :    
759 :     pcmpgtw mm5, [esi]
760 :     paddusw mm0, mm5
761 :     psrlw mm0, 5
762 :     pxor mm0, mm1 ; start restoring sign
763 :     psubusw mm1, mm5
764 :    
765 :     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 :    
770 :     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 :    
783 :     jng .loop
784 :     nop
785 :    
786 :     ; mismatch control
787 :    
788 :     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 :     pop edi
796 :     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 :    
802 :     xor eax, eax
803 :     ret

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