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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1382 - (view) (download)

1 : edgomez 1382 ;/*****************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - MPEG4 Quantization H263 implementation / MMX optimized -
5 :     ; *
6 :     ; * Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
7 :     ; * 2002-2003 Pascal Massimino <skal@planet-d.net>
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 :     ; * $Id: quantize_h263_mmx.asm,v 1.2 2004-03-22 22:36:24 edgomez Exp $
24 :     ; *
25 :     ; ****************************************************************************/
26 :    
27 :     ; enable dequant saturate [-2048,2047], test purposes only.
28 :     %define SATURATE
29 :    
30 :     BITS 32
31 :    
32 :     %macro cglobal 1
33 :     %ifdef PREFIX
34 :     global _%1
35 :     %define %1 _%1
36 :     %else
37 :     global %1
38 :     %endif
39 :     %endmacro
40 :    
41 :     ;=============================================================================
42 :     ; Read only Local data
43 :     ;=============================================================================
44 :    
45 :     %ifdef FORMAT_COFF
46 :     SECTION .rodata data
47 :     %else
48 :     SECTION .rodata data align=16
49 :     %endif
50 :    
51 :     ALIGN 16
52 :     plus_one:
53 :     times 8 dw 1
54 :    
55 :     ;-----------------------------------------------------------------------------
56 :     ;
57 :     ; subtract by Q/2 table
58 :     ;
59 :     ;-----------------------------------------------------------------------------
60 :    
61 :     ALIGN 16
62 :     mmx_sub:
63 :     %assign quant 1
64 :     %rep 31
65 :     times 4 dw quant / 2
66 :     %assign quant quant+1
67 :     %endrep
68 :    
69 :     ;-----------------------------------------------------------------------------
70 :     ;
71 :     ; divide by 2Q table
72 :     ;
73 :     ; use a shift of 16 to take full advantage of _pmulhw_
74 :     ; for q=1, _pmulhw_ will overflow so it is treated seperately
75 :     ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
76 :     ;
77 :     ;-----------------------------------------------------------------------------
78 :    
79 :     ALIGN 16
80 :     mmx_div:
81 :     %assign quant 1
82 :     %rep 31
83 :     times 4 dw (1<<16) / (quant*2) + 1
84 :     %assign quant quant+1
85 :     %endrep
86 :    
87 :     ;-----------------------------------------------------------------------------
88 :     ;
89 :     ; add by (odd(Q) ? Q : Q - 1) table
90 :     ;
91 :     ;-----------------------------------------------------------------------------
92 :    
93 :     ALIGN 16
94 :     mmx_add:
95 :     %assign quant 1
96 :     %rep 31
97 :     %if quant % 2 != 0
98 :     times 4 dw quant
99 :     %else
100 :     times 4 dw quant - 1
101 :     %endif
102 :     %assign quant quant+1
103 :     %endrep
104 :    
105 :     ;-----------------------------------------------------------------------------
106 :     ;
107 :     ; multiple by 2Q table
108 :     ;
109 :     ;-----------------------------------------------------------------------------
110 :    
111 :     ALIGN 16
112 :     mmx_mul:
113 :     %assign quant 1
114 :     %rep 31
115 :     times 4 dw quant*2
116 :     %assign quant quant+1
117 :     %endrep
118 :    
119 :     ;-----------------------------------------------------------------------------
120 :     ;
121 :     ; saturation limits
122 :     ;
123 :     ;-----------------------------------------------------------------------------
124 :    
125 :     ALIGN 16
126 :     sse2_2047:
127 :     times 8 dw 2047
128 :    
129 :     ALIGN 16
130 :     mmx_2047:
131 :     times 4 dw 2047
132 :    
133 :     ALIGN 8
134 :     mmx_32768_minus_2048:
135 :     times 4 dw (32768-2048)
136 :    
137 :     mmx_32767_minus_2047:
138 :     times 4 dw (32767-2047)
139 :    
140 :    
141 :     ;=============================================================================
142 :     ; Code
143 :     ;=============================================================================
144 :    
145 :     SECTION .text
146 :    
147 :     cglobal quant_h263_intra_mmx
148 :     cglobal quant_h263_intra_sse2
149 :     cglobal quant_h263_inter_mmx
150 :     cglobal quant_h263_inter_sse2
151 :     cglobal dequant_h263_intra_mmx
152 :     cglobal dequant_h263_intra_xmm
153 :     cglobal dequant_h263_intra_sse2
154 :     cglobal dequant_h263_inter_mmx
155 :     cglobal dequant_h263_inter_xmm
156 :     cglobal dequant_h263_inter_sse2
157 :    
158 :     ;-----------------------------------------------------------------------------
159 :     ;
160 :     ; uint32_t quant_h263_intra_mmx(int16_t * coeff,
161 :     ; const int16_t const * data,
162 :     ; const uint32_t quant,
163 :     ; const uint32_t dcscalar,
164 :     ; const uint16_t *mpeg_matrices);
165 :     ;
166 :     ;-----------------------------------------------------------------------------
167 :    
168 :     ALIGN 16
169 :     quant_h263_intra_mmx:
170 :    
171 :     push ecx
172 :     push esi
173 :     push edi
174 :    
175 :     mov edi, [esp + 12 + 4] ; coeff
176 :     mov esi, [esp + 12 + 8] ; data
177 :     mov eax, [esp + 12 + 12] ; quant
178 :    
179 :     xor ecx, ecx
180 :     cmp al, 1
181 :     jz .q1loop
182 :    
183 :     movq mm7, [mmx_div + eax * 8 - 8]
184 :    
185 :     ALIGN 16
186 :     .loop
187 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
188 :     movq mm3, [esi + 8*ecx + 8]
189 :     pxor mm1, mm1 ; mm1 = 0
190 :     pxor mm4, mm4 ;
191 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
192 :     pcmpgtw mm4, mm3 ;
193 :     pxor mm0, mm1 ; mm0 = |mm0|
194 :     pxor mm3, mm4 ;
195 :     psubw mm0, mm1 ; displace
196 :     psubw mm3, mm4 ;
197 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
198 :     pmulhw mm3, mm7 ;
199 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
200 :     pxor mm3, mm4 ;
201 :     psubw mm0, mm1 ; undisplace
202 :     psubw mm3, mm4 ;
203 :     movq [edi + 8*ecx], mm0
204 :     movq [edi + 8*ecx + 8], mm3
205 :    
206 :     add ecx, 2
207 :     cmp ecx, 16
208 :     jnz .loop
209 :    
210 :     .done
211 :    
212 :     ; caclulate data[0] // (int32_t)dcscalar)
213 :     mov ecx, [esp + 12 + 16] ; dcscalar
214 :     mov edx, ecx
215 :     movsx eax, word [esi] ; data[0]
216 :     shr edx, 1 ; edx = dcscalar /2
217 :     cmp eax, 0
218 :     jg .gtzero
219 :    
220 :     sub eax, edx
221 :     jmp short .mul
222 :    
223 :     .gtzero
224 :     add eax, edx
225 :     .mul
226 :     cdq ; expand eax -> edx:eax
227 :     idiv ecx ; eax = edx:eax / dcscalar
228 :     mov [edi], ax ; coeff[0] = ax
229 :    
230 :     xor eax, eax ; return(0);
231 :     pop edi
232 :     pop esi
233 :     pop ecx
234 :    
235 :     ret
236 :    
237 :     ALIGN 16
238 :     .q1loop
239 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
240 :     movq mm3, [esi + 8*ecx + 8]
241 :     pxor mm1, mm1 ; mm1 = 0
242 :     pxor mm4, mm4 ;
243 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
244 :     pcmpgtw mm4, mm3 ;
245 :     pxor mm0, mm1 ; mm0 = |mm0|
246 :     pxor mm3, mm4 ;
247 :     psubw mm0, mm1 ; displace
248 :     psubw mm3, mm4 ;
249 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
250 :     psrlw mm3, 1 ;
251 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
252 :     pxor mm3, mm4
253 :     psubw mm0, mm1 ; undisplace
254 :     psubw mm3, mm4 ;
255 :     movq [edi + 8*ecx], mm0
256 :     movq [edi + 8*ecx + 8], mm3
257 :    
258 :     add ecx, 2
259 :     cmp ecx, 16
260 :     jnz .q1loop
261 :     jmp short .done
262 :    
263 :    
264 :    
265 :     ;-----------------------------------------------------------------------------
266 :     ;
267 :     ; uint32_t quant_h263_intra_sse2(int16_t * coeff,
268 :     ; const int16_t const * data,
269 :     ; const uint32_t quant,
270 :     ; const uint32_t dcscalar,
271 :     ; const uint16_t *mpeg_matrices);
272 :     ;
273 :     ;-----------------------------------------------------------------------------
274 :    
275 :     ALIGN 16
276 :     quant_h263_intra_sse2:
277 :    
278 :     push esi
279 :     push edi
280 :    
281 :     mov edi, [esp + 8 + 4] ; coeff
282 :     mov esi, [esp + 8 + 8] ; data
283 :     mov eax, [esp + 8 + 12] ; quant
284 :    
285 :     xor ecx, ecx
286 :     cmp al, 1
287 :     jz near .qas2_q1loop
288 :    
289 :     .qas2_not1
290 :     movq mm7, [mmx_div + eax*8 - 8]
291 :     movq2dq xmm7, mm7
292 :     movlhps xmm7, xmm7
293 :    
294 :     ALIGN 16
295 :     .qas2_loop
296 :     movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
297 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
298 :     pxor xmm1, xmm1
299 :     pxor xmm4, xmm4
300 :     pcmpgtw xmm1, xmm0
301 :     pcmpgtw xmm4, xmm3
302 :     pxor xmm0, xmm1
303 :     pxor xmm3, xmm4
304 :     psubw xmm0, xmm1
305 :     psubw xmm3, xmm4
306 :     pmulhw xmm0, xmm7
307 :     pmulhw xmm3, xmm7
308 :     pxor xmm0, xmm1
309 :     pxor xmm3, xmm4
310 :     psubw xmm0, xmm1
311 :     psubw xmm3, xmm4
312 :     movdqa [edi + ecx*8], xmm0
313 :     movdqa [edi + ecx*8 + 16], xmm3
314 :    
315 :     add ecx, 4
316 :     cmp ecx, 16
317 :     jnz .qas2_loop
318 :    
319 :     .qas2_done
320 :     mov ecx, [esp + 8 + 16] ; dcscalar
321 :     mov edx, ecx
322 :     movsx eax, word [esi]
323 :     shr edx, 1
324 :     cmp eax, 0
325 :     jg .qas2_gtzero
326 :    
327 :     sub eax, edx
328 :     jmp short .qas2_mul
329 :    
330 :     .qas2_gtzero
331 :     add eax, edx
332 :    
333 :     .qas2_mul
334 :     cdq
335 :     idiv ecx
336 :    
337 :     mov [edi], ax
338 :    
339 :     xor eax, eax ; return(0);
340 :     pop edi
341 :     pop esi
342 :    
343 :     ret
344 :    
345 :     ALIGN 16
346 :     .qas2_q1loop
347 :     movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
348 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
349 :     pxor xmm1, xmm1
350 :     pxor xmm4, xmm4
351 :     pcmpgtw xmm1, xmm0
352 :     pcmpgtw xmm4, xmm3
353 :     pxor xmm0, xmm1
354 :     pxor xmm3, xmm4
355 :     psubw xmm0, xmm1
356 :     psubw xmm3, xmm4
357 :     psrlw xmm0, 1
358 :     psrlw xmm3, 1
359 :     pxor xmm0, xmm1
360 :     pxor xmm3, xmm4
361 :     psubw xmm0, xmm1
362 :     psubw xmm3, xmm4
363 :     movdqa [edi + ecx*8], xmm0
364 :     movdqa [edi + ecx*8 + 16], xmm3
365 :    
366 :     add ecx, 4
367 :     cmp ecx, 16
368 :     jnz .qas2_q1loop
369 :     jmp near .qas2_done
370 :    
371 :    
372 :    
373 :     ;-----------------------------------------------------------------------------
374 :     ;
375 :     ; uint32_t quant_h263_inter_mmx(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_h263_inter_mmx:
384 :    
385 :     push ecx
386 :     push esi
387 :     push edi
388 :    
389 :     mov edi, [esp + 12 + 4] ; coeff
390 :     mov esi, [esp + 12 + 8] ; data
391 :     mov eax, [esp + 12 + 12] ; quant
392 :    
393 :     xor ecx, ecx
394 :    
395 :     pxor mm5, mm5 ; sum
396 :     movq mm6, [mmx_sub + eax * 8 - 8] ; sub
397 :    
398 :     cmp al, 1
399 :     jz .q1loop
400 :    
401 :     movq mm7, [mmx_div + eax * 8 - 8] ; divider
402 :    
403 :     ALIGN 8
404 :     .loop
405 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
406 :     movq mm3, [esi + 8*ecx + 8]
407 :     pxor mm1, mm1 ; mm1 = 0
408 :     pxor mm4, mm4 ;
409 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
410 :     pcmpgtw mm4, mm3 ;
411 :     pxor mm0, mm1 ; mm0 = |mm0|
412 :     pxor mm3, mm4 ;
413 :     psubw mm0, mm1 ; displace
414 :     psubw mm3, mm4 ;
415 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
416 :     psubusw mm3, mm6 ;
417 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
418 :     pmulhw mm3, mm7 ;
419 :     paddw mm5, mm0 ; sum += mm0
420 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
421 :     paddw mm5, mm3 ;
422 :     pxor mm3, mm4 ;
423 :     psubw mm0, mm1 ; undisplace
424 :     psubw mm3, mm4
425 :     movq [edi + 8*ecx], mm0
426 :     movq [edi + 8*ecx + 8], mm3
427 :    
428 :     add ecx, 2
429 :     cmp ecx, 16
430 :     jnz .loop
431 :    
432 :     .done
433 :     pmaddwd mm5, [plus_one]
434 :     movq mm0, mm5
435 :     psrlq mm5, 32
436 :     paddd mm0, mm5
437 :    
438 :     movd eax, mm0 ; return sum
439 :     pop edi
440 :     pop esi
441 :     pop ecx
442 :    
443 :     ret
444 :    
445 :     ALIGN 8
446 :     .q1loop
447 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
448 :     movq mm3, [esi + 8*ecx+ 8] ;
449 :     pxor mm1, mm1 ; mm1 = 0
450 :     pxor mm4, mm4 ;
451 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
452 :     pcmpgtw mm4, mm3 ;
453 :     pxor mm0, mm1 ; mm0 = |mm0|
454 :     pxor mm3, mm4 ;
455 :     psubw mm0, mm1 ; displace
456 :     psubw mm3, mm4 ;
457 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
458 :     psubusw mm3, mm6 ;
459 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
460 :     psrlw mm3, 1 ;
461 :     paddw mm5, mm0 ; sum += mm0
462 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
463 :     paddw mm5, mm3 ;
464 :     pxor mm3, mm4 ;
465 :     psubw mm0, mm1 ; undisplace
466 :     psubw mm3, mm4
467 :     movq [edi + 8*ecx], mm0
468 :     movq [edi + 8*ecx + 8], mm3
469 :    
470 :     add ecx, 2
471 :     cmp ecx, 16
472 :     jnz .q1loop
473 :    
474 :     jmp .done
475 :    
476 :    
477 :    
478 :     ;-----------------------------------------------------------------------------
479 :     ;
480 :     ; uint32_t quant_h263_inter_sse2(int16_t * coeff,
481 :     ; const int16_t const * data,
482 :     ; const uint32_t quant,
483 :     ; const uint16_t *mpeg_matrices);
484 :     ;
485 :     ;-----------------------------------------------------------------------------
486 :    
487 :     ALIGN 16
488 :     quant_h263_inter_sse2:
489 :    
490 :     push esi
491 :     push edi
492 :    
493 :     mov edi, [esp + 8 + 4] ; coeff
494 :     mov esi, [esp + 8 + 8] ; data
495 :     mov eax, [esp + 8 + 12] ; quant
496 :    
497 :     xor ecx, ecx
498 :    
499 :     pxor xmm5, xmm5 ; sum
500 :    
501 :     movq mm0, [mmx_sub + eax*8 - 8] ; sub
502 :     movq2dq xmm6, mm0 ; load into low 8 bytes
503 :     movlhps xmm6, xmm6 ; duplicate into high 8 bytes
504 :    
505 :     cmp al, 1
506 :     jz near .qes2_q1loop
507 :    
508 :     .qes2_not1
509 :     movq mm0, [mmx_div + eax*8 - 8] ; divider
510 :     movq2dq xmm7, mm0
511 :     movlhps xmm7, xmm7
512 :    
513 :     ALIGN 16
514 :     .qes2_loop
515 :     movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
516 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
517 :     pxor xmm1, xmm1
518 :     pxor xmm4, xmm4
519 :     pcmpgtw xmm1, xmm0
520 :     pcmpgtw xmm4, xmm3
521 :     pxor xmm0, xmm1
522 :     pxor xmm3, xmm4
523 :     psubw xmm0, xmm1
524 :     psubw xmm3, xmm4
525 :     psubusw xmm0, xmm6
526 :     psubusw xmm3, xmm6
527 :     pmulhw xmm0, xmm7
528 :     pmulhw xmm3, xmm7
529 :     paddw xmm5, xmm0
530 :     pxor xmm0, xmm1
531 :     paddw xmm5, xmm3
532 :     pxor xmm3, xmm4
533 :     psubw xmm0, xmm1
534 :     psubw xmm3, xmm4
535 :     movdqa [edi + ecx*8], xmm0
536 :     movdqa [edi + ecx*8 + 16], xmm3
537 :    
538 :     add ecx, 4
539 :     cmp ecx, 16
540 :     jnz .qes2_loop
541 :    
542 :     .qes2_done
543 :     movdqu xmm6, [plus_one]
544 :     pmaddwd xmm5, xmm6
545 :     movhlps xmm6, xmm5
546 :     paddd xmm5, xmm6
547 :     movdq2q mm0, xmm5
548 :    
549 :     movq mm5, mm0
550 :     psrlq mm5, 32
551 :     paddd mm0, mm5
552 :    
553 :     movd eax, mm0 ; return sum
554 :    
555 :     pop edi
556 :     pop esi
557 :    
558 :     ret
559 :    
560 :     ALIGN 16
561 :     .qes2_q1loop
562 :     movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
563 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
564 :     pxor xmm1, xmm1
565 :     pxor xmm4, xmm4
566 :     pcmpgtw xmm1, xmm0
567 :     pcmpgtw xmm4, xmm3
568 :     pxor xmm0, xmm1
569 :     pxor xmm3, xmm4
570 :     psubw xmm0, xmm1
571 :     psubw xmm3, xmm4
572 :     psubusw xmm0, xmm6
573 :     psubusw xmm3, xmm6
574 :     psrlw xmm0, 1
575 :     psrlw xmm3, 1
576 :     paddw xmm5, xmm0
577 :     pxor xmm0, xmm1
578 :     paddw xmm5, xmm3
579 :     pxor xmm3, xmm4
580 :     psubw xmm0, xmm1
581 :     psubw xmm3, xmm4
582 :     movdqa [edi + ecx*8], xmm0
583 :     movdqa [edi + ecx*8 + 16], xmm3
584 :    
585 :     add ecx, 4
586 :     cmp ecx, 16
587 :     jnz .qes2_q1loop
588 :     jmp .qes2_done
589 :    
590 :    
591 :     ;-----------------------------------------------------------------------------
592 :     ;
593 :     ; uint32_t dequant_h263_intra_mmx(int16_t *data,
594 :     ; const int16_t const *coeff,
595 :     ; const uint32_t quant,
596 :     ; const uint32_t dcscalar,
597 :     ; const uint16_t *mpeg_matrices);
598 :     ;
599 :     ;-----------------------------------------------------------------------------
600 :    
601 :     ; note: we only saturate to +2047 *before* restoring the sign.
602 :     ; Hence, final clamp really is [-2048,2047]
603 :    
604 :     ALIGN 16
605 :     dequant_h263_intra_mmx:
606 :    
607 :     mov edx, [esp+ 4] ; data
608 :     mov ecx, [esp+ 8] ; coeff
609 :     mov eax, [esp+12] ; quant
610 :     movq mm6, [mmx_add + eax*8 - 8] ; quant or quant-1
611 :     movq mm7, [mmx_mul + eax*8 - 8] ; 2*quant
612 :     mov eax, -16
613 :    
614 :     ALIGN 16
615 :     .loop
616 :     movq mm0, [ecx+8*eax+8*16] ; c = coeff[i]
617 :     movq mm3, [ecx+8*eax+8*16 + 8] ; c' = coeff[i+1]
618 :     pxor mm1, mm1
619 :     pxor mm4, mm4
620 :     pcmpgtw mm1, mm0 ; sign(c)
621 :     pcmpgtw mm4, mm3 ; sign(c')
622 :     pxor mm2, mm2
623 :     pxor mm5, mm5
624 :     pcmpeqw mm2, mm0 ; c is zero
625 :     pcmpeqw mm5, mm3 ; c' is zero
626 :     pandn mm2, mm6 ; offset = isZero ? 0 : quant_add
627 :     pandn mm5, mm6
628 :     pxor mm0, mm1 ; negate if negative
629 :     pxor mm3, mm4 ; negate if negative
630 :     psubw mm0, mm1
631 :     psubw mm3, mm4
632 :     pmullw mm0, mm7 ; *= 2Q
633 :     pmullw mm3, mm7 ; *= 2Q
634 :     paddw mm0, mm2 ; + offset
635 :     paddw mm3, mm5 ; + offset
636 :     paddw mm0, mm1 ; negate back
637 :     paddw mm3, mm4 ; negate back
638 :    
639 :     ; saturates to +2047
640 :     movq mm2, [mmx_32767_minus_2047]
641 :     add eax, 2
642 :     paddsw mm0, mm2
643 :     paddsw mm3, mm2
644 :     psubsw mm0, mm2
645 :     psubsw mm3, mm2
646 :    
647 :     pxor mm0, mm1
648 :     pxor mm3, mm4
649 :     movq [edx + 8*eax + 8*16 - 2*8], mm0
650 :     movq [edx + 8*eax + 8*16+8 - 2*8], mm3
651 :     jnz near .loop
652 :    
653 :     ; deal with DC
654 :     movd mm0, [ecx]
655 :     pmullw mm0, [esp+16] ; dcscalar
656 :     movq mm2, [mmx_32767_minus_2047]
657 :     paddsw mm0, mm2
658 :     psubsw mm0, mm2
659 :     movq mm3, [mmx_32768_minus_2048]
660 :     psubsw mm0, mm3
661 :     paddsw mm0, mm3
662 :     movd eax, mm0
663 :     mov [edx], ax
664 :    
665 :     xor eax, eax ; return(0);
666 :     ret
667 :    
668 :     ;-----------------------------------------------------------------------------
669 :     ;
670 :     ; uint32_t dequant_h263_intra_xmm(int16_t *data,
671 :     ; const int16_t const *coeff,
672 :     ; const uint32_t quant,
673 :     ; const uint32_t dcscalar,
674 :     ; const uint16_t *mpeg_matrices);
675 :     ;
676 :     ;-----------------------------------------------------------------------------
677 :    
678 :     ; this is the same as dequant_inter_mmx, except that we're
679 :     ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
680 :    
681 :     ALIGN 16
682 :     dequant_h263_intra_xmm:
683 :    
684 :     mov edx, [esp+ 4] ; data
685 :     mov ecx, [esp+ 8] ; coeff
686 :     mov eax, [esp+12] ; quant
687 :     movq mm6, [mmx_add + eax*8 - 8] ; quant or quant-1
688 :     movq mm7, [mmx_mul + eax*8 - 8] ; 2*quant
689 :     mov eax, -16
690 :    
691 :     ALIGN 16
692 :     .loop
693 :     movq mm0, [ecx+8*eax+8*16] ; c = coeff[i]
694 :     movq mm3, [ecx+8*eax+8*16 + 8] ; c' = coeff[i+1]
695 :     pxor mm1, mm1
696 :     pxor mm4, mm4
697 :     pcmpgtw mm1, mm0 ; sign(c)
698 :     pcmpgtw mm4, mm3 ; sign(c')
699 :     pxor mm2, mm2
700 :     pxor mm5, mm5
701 :     pcmpeqw mm2, mm0 ; c is zero
702 :     pcmpeqw mm5, mm3 ; c' is zero
703 :     pandn mm2, mm6 ; offset = isZero ? 0 : quant_add
704 :     pandn mm5, mm6
705 :     pxor mm0, mm1 ; negate if negative
706 :     pxor mm3, mm4 ; negate if negative
707 :     psubw mm0, mm1
708 :     psubw mm3, mm4
709 :     pmullw mm0, mm7 ; *= 2Q
710 :     pmullw mm3, mm7 ; *= 2Q
711 :     paddw mm0, mm2 ; + offset
712 :     paddw mm3, mm5 ; + offset
713 :     paddw mm0, mm1 ; negate back
714 :     paddw mm3, mm4 ; negate back
715 :    
716 :     ; saturates to +2047
717 :     movq mm2, [mmx_2047]
718 :     pminsw mm0, mm2
719 :     add eax, 2
720 :     pminsw mm3, mm2
721 :    
722 :     pxor mm0, mm1
723 :     pxor mm3, mm4
724 :     movq [edx + 8*eax + 8*16 - 2*8], mm0
725 :     movq [edx + 8*eax + 8*16+8 - 2*8], mm3
726 :     jnz near .loop
727 :    
728 :     ; deal with DC
729 :     movd mm0, [ecx]
730 :     pmullw mm0, [esp+16] ; dcscalar
731 :     movq mm2, [mmx_32767_minus_2047]
732 :     paddsw mm0, mm2
733 :     psubsw mm0, mm2
734 :     movq mm2, [mmx_32768_minus_2048]
735 :     psubsw mm0, mm2
736 :     paddsw mm0, mm2
737 :     movd eax, mm0
738 :     mov [edx], ax
739 :    
740 :     xor eax, eax
741 :     ret
742 :    
743 :    
744 :     ;-----------------------------------------------------------------------------
745 :     ;
746 :     ; uint32_t dequant_h263_intra_sse2(int16_t *data,
747 :     ; const int16_t const *coeff,
748 :     ; const uint32_t quant,
749 :     ; const uint32_t dcscalar,
750 :     ; const uint16_t *mpeg_matrices);
751 :     ;
752 :     ;-----------------------------------------------------------------------------
753 :    
754 :     ALIGN 16
755 :     dequant_h263_intra_sse2:
756 :     mov edx, [esp+ 4] ; data
757 :     mov ecx, [esp+ 8] ; coeff
758 :     mov eax, [esp+12] ; quant
759 :     movq mm6, [mmx_add + eax * 8 - 8]
760 :     movq mm7, [mmx_mul + eax * 8 - 8]
761 :     movq2dq xmm6, mm6
762 :     movq2dq xmm7, mm7
763 :     movlhps xmm6, xmm6
764 :     movlhps xmm7, xmm7
765 :     mov eax, -16
766 :    
767 :     ALIGN 16
768 :     .loop
769 :     movdqa xmm0, [ecx + 8*16 + 8*eax] ; c = coeff[i]
770 :     movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]
771 :     pxor xmm1, xmm1
772 :     pxor xmm4, xmm4
773 :     pcmpgtw xmm1, xmm0 ; sign(c)
774 :     pcmpgtw xmm4, xmm3
775 :     pxor xmm2, xmm2
776 :     pxor xmm5, xmm5
777 :     pcmpeqw xmm2, xmm0 ; c is zero
778 :     pcmpeqw xmm5, xmm3
779 :     pandn xmm2, xmm6 ; offset = isZero ? 0 : quant_add
780 :     pandn xmm5, xmm6
781 :     pxor xmm0, xmm1 ; negate if negative
782 :     pxor xmm3, xmm4
783 :     psubw xmm0, xmm1
784 :     psubw xmm3, xmm4
785 :     pmullw xmm0, xmm7 ; *= 2Q
786 :     pmullw xmm3, xmm7
787 :     paddw xmm0, xmm2 ; + offset
788 :     paddw xmm3, xmm5
789 :     paddw xmm0, xmm1 ; negate back
790 :     paddw xmm3, xmm4
791 :    
792 :     ; saturates to +2047
793 :     movdqa xmm2, [sse2_2047]
794 :     pminsw xmm0, xmm2
795 :     add eax, 4
796 :     pminsw xmm3, xmm2
797 :    
798 :     pxor xmm0, xmm1
799 :     pxor xmm3, xmm4
800 :     movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
801 :     movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
802 :     jnz near .loop
803 :    
804 :     ; deal with DC
805 :     movd mm0, [ecx]
806 :     pmullw mm0, [esp+16] ; dcscalar
807 :     movq mm2, [mmx_32767_minus_2047]
808 :     paddsw mm0, mm2
809 :     psubsw mm0, mm2
810 :     movq mm2, [mmx_32768_minus_2048]
811 :     psubsw mm0, mm2
812 :     paddsw mm0, mm2
813 :     movd eax, mm0
814 :     mov [edx], ax
815 :    
816 :     xor eax, eax
817 :     ret
818 :    
819 :     ;-----------------------------------------------------------------------------
820 :     ;
821 :     ; uint32t dequant_h263_inter_mmx(int16_t * data,
822 :     ; const int16_t * const coeff,
823 :     ; const uint32_t quant,
824 :     ; const uint16_t *mpeg_matrices);
825 :     ;
826 :     ;-----------------------------------------------------------------------------
827 :    
828 :     ALIGN 16
829 :     dequant_h263_inter_mmx:
830 :    
831 :     mov edx, [esp+ 4] ; data
832 :     mov ecx, [esp+ 8] ; coeff
833 :     mov eax, [esp+12] ; quant
834 :     movq mm6, [mmx_add + eax*8 - 8] ; quant or quant-1
835 :     movq mm7, [mmx_mul + eax*8 - 8] ; 2*quant
836 :     mov eax, -16
837 :    
838 :     ALIGN 16
839 :     .loop
840 :     movq mm0, [ecx+8*eax+8*16] ; c = coeff[i]
841 :     movq mm3, [ecx+8*eax+8*16 + 8] ; c' = coeff[i+1]
842 :     pxor mm1, mm1
843 :     pxor mm4, mm4
844 :     pcmpgtw mm1, mm0 ; sign(c)
845 :     pcmpgtw mm4, mm3 ; sign(c')
846 :     pxor mm2, mm2
847 :     pxor mm5, mm5
848 :     pcmpeqw mm2, mm0 ; c is zero
849 :     pcmpeqw mm5, mm3 ; c' is zero
850 :     pandn mm2, mm6 ; offset = isZero ? 0 : quant_add
851 :     pandn mm5, mm6
852 :     pxor mm0, mm1 ; negate if negative
853 :     pxor mm3, mm4 ; negate if negative
854 :     psubw mm0, mm1
855 :     psubw mm3, mm4
856 :     pmullw mm0, mm7 ; *= 2Q
857 :     pmullw mm3, mm7 ; *= 2Q
858 :     paddw mm0, mm2 ; + offset
859 :     paddw mm3, mm5 ; + offset
860 :     paddw mm0, mm1 ; negate back
861 :     paddw mm3, mm4 ; negate back
862 :     ; saturates to +2047
863 :     movq mm2, [mmx_32767_minus_2047]
864 :     add eax, 2
865 :     paddsw mm0, mm2
866 :     paddsw mm3, mm2
867 :     psubsw mm0, mm2
868 :     psubsw mm3, mm2
869 :    
870 :     pxor mm0, mm1
871 :     pxor mm3, mm4
872 :     movq [edx + 8*eax + 8*16 - 2*8], mm0
873 :     movq [edx + 8*eax + 8*16+8 - 2*8], mm3
874 :     jnz near .loop
875 :    
876 :     xor eax, eax
877 :     ret
878 :    
879 :     ;-----------------------------------------------------------------------------
880 :     ;
881 :     ; uint32_t dequant_h263_inter_xmm(int16_t * data,
882 :     ; const int16_t * const coeff,
883 :     ; const uint32_t quant,
884 :     ; const uint16_t *mpeg_matrices);
885 :     ;
886 :     ;-----------------------------------------------------------------------------
887 :    
888 :     ; this is the same as dequant_inter_mmx,
889 :     ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
890 :    
891 :     ALIGN 16
892 :     dequant_h263_inter_xmm:
893 :    
894 :     mov edx, [esp+ 4] ; data
895 :     mov ecx, [esp+ 8] ; coeff
896 :     mov eax, [esp+12] ; quant
897 :     movq mm6, [mmx_add + eax*8 - 8] ; quant or quant-1
898 :     movq mm7, [mmx_mul + eax*8 - 8] ; 2*quant
899 :     mov eax, -16
900 :    
901 :     ALIGN 16
902 :     .loop
903 :     movq mm0, [ecx+8*eax+8*16] ; c = coeff[i]
904 :     movq mm3, [ecx+8*eax+8*16 + 8] ; c' = coeff[i+1]
905 :     pxor mm1, mm1
906 :     pxor mm4, mm4
907 :     pcmpgtw mm1, mm0 ; sign(c)
908 :     pcmpgtw mm4, mm3 ; sign(c')
909 :     pxor mm2, mm2
910 :     pxor mm5, mm5
911 :     pcmpeqw mm2, mm0 ; c is zero
912 :     pcmpeqw mm5, mm3 ; c' is zero
913 :     pandn mm2, mm6 ; offset = isZero ? 0 : quant_add
914 :     pandn mm5, mm6
915 :     pxor mm0, mm1 ; negate if negative
916 :     pxor mm3, mm4 ; negate if negative
917 :     psubw mm0, mm1
918 :     psubw mm3, mm4
919 :     pmullw mm0, mm7 ; *= 2Q
920 :     pmullw mm3, mm7 ; *= 2Q
921 :     paddw mm0, mm2 ; + offset
922 :     paddw mm3, mm5 ; + offset
923 :     paddw mm0, mm1 ; start restoring sign
924 :     paddw mm3, mm4 ; start restoring sign
925 :     ; saturates to +2047
926 :     movq mm2, [mmx_2047]
927 :     pminsw mm0, mm2
928 :     add eax, 2
929 :     pminsw mm3, mm2
930 :    
931 :     pxor mm0, mm1 ; finish restoring sign
932 :     pxor mm3, mm4 ; finish restoring sign
933 :     movq [edx + 8*eax + 8*16 - 2*8], mm0
934 :     movq [edx + 8*eax + 8*16+8 - 2*8], mm3
935 :     jnz near .loop
936 :    
937 :     xor eax, eax
938 :     ret
939 :    
940 :     ;-----------------------------------------------------------------------------
941 :     ;
942 :     ; uint32_t dequant_h263_inter_sse2(int16_t * data,
943 :     ; const int16_t * const coeff,
944 :     ; const uint32_t quant,
945 :     ; const uint16_t *mpeg_matrices);
946 :     ;
947 :     ;-----------------------------------------------------------------------------
948 :    
949 :     ALIGN 16
950 :     dequant_h263_inter_sse2:
951 :     mov edx, [esp + 4] ; data
952 :     mov ecx, [esp + 8] ; coeff
953 :     mov eax, [esp + 12] ; quant
954 :     movq mm6, [mmx_add + eax * 8 - 8]
955 :     movq mm7, [mmx_mul + eax * 8 - 8]
956 :     movq2dq xmm6, mm6
957 :     movq2dq xmm7, mm7
958 :     movlhps xmm6, xmm6
959 :     movlhps xmm7, xmm7
960 :     mov eax, -16
961 :    
962 :     ALIGN 16
963 :     .loop
964 :     movdqa xmm0, [ecx + 8*16 + 8*eax] ; c = coeff[i]
965 :     movdqa xmm3, [ecx + 8*16 + 8*eax + 16]
966 :    
967 :     pxor xmm1, xmm1
968 :     pxor xmm4, xmm4
969 :     pcmpgtw xmm1, xmm0 ; sign(c)
970 :     pcmpgtw xmm4, xmm3
971 :     pxor xmm2, xmm2
972 :     pxor xmm5, xmm5
973 :     pcmpeqw xmm2, xmm0 ; c is zero
974 :     pcmpeqw xmm5, xmm3
975 :     pandn xmm2, xmm6
976 :     pandn xmm5, xmm6
977 :     pxor xmm0, xmm1 ; negate if negative
978 :     pxor xmm3, xmm4
979 :     psubw xmm0, xmm1
980 :     psubw xmm3, xmm4
981 :     pmullw xmm0, xmm7 ; *= 2Q
982 :     pmullw xmm3, xmm7
983 :     paddw xmm0, xmm2 ; + offset
984 :     paddw xmm3, xmm5
985 :    
986 :     paddw xmm0, xmm1 ; start restoring sign
987 :     paddw xmm3, xmm4
988 :    
989 :     ; saturates to +2047
990 :     movdqa xmm2, [sse2_2047]
991 :     pminsw xmm0, xmm2
992 :     add eax, 4
993 :     pminsw xmm3, xmm2
994 :    
995 :     pxor xmm0, xmm1 ; finish restoring sign
996 :     pxor xmm3, xmm4
997 :     movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
998 :     movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
999 :     jnz near .loop
1000 :    
1001 :     xor eax, eax
1002 :     ret

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