[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 269 - (view) (download)

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

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