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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 463 - (view) (download)

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

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