[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 135 - (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 : h 135 ; * 24.02.2002 sse2 quant_intra / dequant_intra (have to use movdqu ???)
36 :     ; * 17.04.2002 sse2 quant_inter / dequant_inter
37 : Isibaar 3 ; * 26.12.2001 minor bug fixes, dequant saturate, further optimization
38 :     ; * 19.11.2001 quant_inter_mmx now returns sum of abs. coefficient values
39 :     ; * 04.11.2001 nasm version; (c)2001 peter ross <pross@cs.rmit.edu.au>
40 :     ; *
41 :     ; *************************************************************************/
42 :    
43 :     ; enable dequant saturate [-2048,2047], test purposes only.
44 :     %define SATURATE
45 :    
46 :     ; data/text alignment
47 :     %define ALIGN 8
48 :    
49 :     bits 32
50 :    
51 :     section .data
52 :    
53 :    
54 :     %macro cglobal 1
55 :     %ifdef PREFIX
56 :     global _%1
57 :     %define %1 _%1
58 :     %else
59 :     global %1
60 :     %endif
61 :     %endmacro
62 :    
63 : h 126 align 16
64 : Isibaar 3
65 : h 126 plus_one times 8 dw 1
66 :    
67 : h 135
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 :     align ALIGN
265 :     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 :     sse2_pos_2047 times 8 dw 2047
270 :     sse2_neg_2048 times 8 dw -2048
271 : Isibaar 3
272 : h 126
273 : Isibaar 3 section .text
274 :    
275 :    
276 :     ;===========================================================================
277 :     ;
278 :     ; void quant_intra_mmx(int16_t * coeff,
279 :     ; const int16_t const * data,
280 :     ; const uint32_t quant,
281 :     ; const uint32_t dcscalar);
282 :     ;
283 :     ;===========================================================================
284 :    
285 :     align ALIGN
286 :     cglobal quant_intra_mmx
287 :     quant_intra_mmx
288 :    
289 :     push ecx
290 :     push esi
291 :     push edi
292 :    
293 :     mov edi, [esp + 12 + 4] ; coeff
294 :     mov esi, [esp + 12 + 8] ; data
295 :     mov eax, [esp + 12 + 12] ; quant
296 :    
297 :     xor ecx, ecx
298 :     cmp al, 1
299 :     jz .q1loop
300 :    
301 :     movq mm7, [mmx_div + eax * 8 - 8]
302 :     align ALIGN
303 :     .loop
304 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
305 :     movq mm3, [esi + 8*ecx + 8] ;
306 :     pxor mm1, mm1 ; mm1 = 0
307 :     pxor mm4, mm4 ;
308 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
309 :     pcmpgtw mm4, mm3 ;
310 :     pxor mm0, mm1 ; mm0 = |mm0|
311 :     pxor mm3, mm4 ;
312 :     psubw mm0, mm1 ; displace
313 :     psubw mm3, mm4 ;
314 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
315 :     pmulhw mm3, mm7 ;
316 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
317 :     pxor mm3, mm4 ;
318 :     psubw mm0, mm1 ; undisplace
319 :     psubw mm3, mm4 ;
320 :     movq [edi + 8*ecx], mm0
321 :     movq [edi + 8*ecx + 8], mm3
322 :    
323 :     add ecx,2
324 :     cmp ecx,16
325 :     jnz .loop
326 :    
327 :     .done
328 :     ; caclulate data[0] // (int32_t)dcscalar)
329 :    
330 :     mov ecx, [esp + 12 + 16] ; dcscalar
331 :     mov edx, ecx
332 :     movsx eax, word [esi] ; data[0]
333 :     shr edx, 1 ; edx = dcscalar /2
334 :     cmp eax, 0
335 :     jg .gtzero
336 :    
337 :     sub eax, edx
338 :     jmp short .mul
339 :     .gtzero
340 :     add eax, edx
341 :     .mul
342 :     cdq ; expand eax -> edx:eax
343 :     idiv ecx ; eax = edx:eax / dcscalar
344 :    
345 :     mov [edi], ax ; coeff[0] = ax
346 :    
347 :     pop edi
348 :     pop esi
349 :     pop ecx
350 :    
351 :     ret
352 :    
353 :     align ALIGN
354 :     .q1loop
355 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
356 :     movq mm3, [esi + 8*ecx + 8] ;
357 :     pxor mm1, mm1 ; mm1 = 0
358 :     pxor mm4, mm4 ;
359 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
360 :     pcmpgtw mm4, mm3 ;
361 :     pxor mm0, mm1 ; mm0 = |mm0|
362 :     pxor mm3, mm4 ;
363 :     psubw mm0, mm1 ; displace
364 :     psubw mm3, mm4 ;
365 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
366 :     psrlw mm3, 1 ;
367 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
368 :     pxor mm3, mm4 ;
369 :     psubw mm0, mm1 ; undisplace
370 :     psubw mm3, mm4 ;
371 :     movq [edi + 8*ecx], mm0
372 :     movq [edi + 8*ecx + 8], mm3
373 :    
374 :     add ecx,2
375 :     cmp ecx,16
376 :     jnz .q1loop
377 :     jmp short .done
378 :    
379 :    
380 :    
381 :     ;===========================================================================
382 :     ;
383 : h 135 ; void quant_intra_sse2(int16_t * coeff,
384 :     ; const int16_t const * data,
385 :     ; const uint32_t quant,
386 :     ; const uint32_t dcscalar);
387 :     ;
388 :     ;===========================================================================
389 :    
390 :     align ALIGN
391 :     cglobal quant_intra_sse2
392 :     quant_intra_sse2
393 :    
394 :     push esi
395 :     push edi
396 :    
397 :     mov edi, [esp + 8 + 4] ; coeff
398 :     mov esi, [esp + 8 + 8] ; data
399 :     mov eax, [esp + 8 + 12] ; quant
400 :    
401 :     xor ecx, ecx
402 :     cmp al, 1
403 :     jz near .qas2_q1loop
404 :    
405 :     .qas2_not1
406 :     movq mm7, [mmx_div + eax*8 - 8]
407 :     movq2dq xmm7, mm7
408 :     movlhps xmm7, xmm7
409 :    
410 :     align 16
411 :     .qas2_loop
412 :     movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
413 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
414 :     pxor xmm1, xmm1
415 :     pxor xmm4, xmm4
416 :     pcmpgtw xmm1, xmm0
417 :     pcmpgtw xmm4, xmm3
418 :     pxor xmm0, xmm1
419 :     pxor xmm3, xmm4
420 :     psubw xmm0, xmm1
421 :     psubw xmm3, xmm4
422 :     pmulhw xmm0, xmm7
423 :     pmulhw xmm3, xmm7
424 :     pxor xmm0, xmm1
425 :     pxor xmm3, xmm4
426 :     psubw xmm0, xmm1
427 :     psubw xmm3, xmm4
428 :     movdqa [edi + ecx*8], xmm0
429 :     movdqa [edi + ecx*8 + 16], xmm3
430 :    
431 :     add ecx, 4
432 :     cmp ecx, 16
433 :     jnz .qas2_loop
434 :    
435 :     .qas2_done
436 :     mov ecx, [esp + 8 + 16] ; dcscalar
437 :     mov edx, ecx
438 :     movsx eax, word [esi]
439 :     shr edx, 1
440 :     cmp eax, 0
441 :     jg .qas2_gtzero
442 :    
443 :     sub eax, edx
444 :     jmp short .qas2_mul
445 :     .qas2_gtzero
446 :     add eax, edx
447 :     .qas2_mul
448 :     cdq
449 :     idiv ecx
450 :    
451 :     mov [edi], ax
452 :    
453 :     pop edi
454 :     pop esi
455 :    
456 :     ret
457 :    
458 :     align 16
459 :     .qas2_q1loop
460 :     movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
461 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
462 :     pxor xmm1, xmm1
463 :     pxor xmm4, xmm4
464 :     pcmpgtw xmm1, xmm0
465 :     pcmpgtw xmm4, xmm3
466 :     pxor xmm0, xmm1
467 :     pxor xmm3, xmm4
468 :     psubw xmm0, xmm1
469 :     psubw xmm3, xmm4
470 :     psrlw xmm0, 1
471 :     psrlw xmm3, 1
472 :     pxor xmm0, xmm1
473 :     pxor xmm3, xmm4
474 :     psubw xmm0, xmm1
475 :     psubw xmm3, xmm4
476 :     movdqa [edi + ecx*8], xmm0
477 :     movdqa [edi + ecx*8 + 16], xmm3
478 :    
479 :     add ecx, 4
480 :     cmp ecx, 16
481 :     jnz .qas2_q1loop
482 :     jmp near .qas2_done
483 :    
484 :    
485 :    
486 :     ;===========================================================================
487 :     ;
488 : Isibaar 3 ; uint32_t quant_inter_mmx(int16_t * coeff,
489 :     ; const int16_t const * data,
490 :     ; const uint32_t quant);
491 :     ;
492 :     ;===========================================================================
493 :    
494 :     align ALIGN
495 :     cglobal quant_inter_mmx
496 :     quant_inter_mmx
497 :    
498 :     push ecx
499 :     push esi
500 :     push edi
501 :    
502 :     mov edi, [esp + 12 + 4] ; coeff
503 :     mov esi, [esp + 12 + 8] ; data
504 :     mov eax, [esp + 12 + 12] ; quant
505 :    
506 :     xor ecx, ecx
507 :    
508 :     pxor mm5, mm5 ; sum
509 :     movq mm6, [mmx_sub + eax * 8 - 8] ; sub
510 :    
511 :     cmp al, 1
512 :     jz .q1loop
513 :    
514 :     movq mm7, [mmx_div + eax * 8 - 8] ; divider
515 :    
516 :     align ALIGN
517 :     .loop
518 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
519 :     movq mm3, [esi + 8*ecx + 8] ;
520 :     pxor mm1, mm1 ; mm1 = 0
521 :     pxor mm4, mm4 ;
522 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
523 :     pcmpgtw mm4, mm3 ;
524 :     pxor mm0, mm1 ; mm0 = |mm0|
525 :     pxor mm3, mm4 ;
526 :     psubw mm0, mm1 ; displace
527 :     psubw mm3, mm4 ;
528 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
529 :     psubusw mm3, mm6 ;
530 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
531 :     pmulhw mm3, mm7 ;
532 :     paddw mm5, mm0 ; sum += mm0
533 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
534 :     paddw mm5, mm3 ;
535 :     pxor mm3, mm4 ;
536 :     psubw mm0, mm1 ; undisplace
537 :     psubw mm3, mm4
538 :     movq [edi + 8*ecx], mm0
539 :     movq [edi + 8*ecx + 8], mm3
540 :    
541 :     add ecx, 2
542 :     cmp ecx, 16
543 :     jnz .loop
544 :    
545 :     .done
546 :     pmaddwd mm5, [plus_one]
547 :     movq mm0, mm5
548 :     psrlq mm5, 32
549 :     paddd mm0, mm5
550 :     movd eax, mm0 ; return sum
551 :    
552 :     pop edi
553 :     pop esi
554 :     pop ecx
555 :    
556 :     ret
557 :    
558 :     align ALIGN
559 :     .q1loop
560 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
561 :     movq mm3, [esi + 8*ecx+ 8] ;
562 :     pxor mm1, mm1 ; mm1 = 0
563 :     pxor mm4, mm4 ;
564 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
565 :     pcmpgtw mm4, mm3 ;
566 :     pxor mm0, mm1 ; mm0 = |mm0|
567 :     pxor mm3, mm4 ;
568 :     psubw mm0, mm1 ; displace
569 :     psubw mm3, mm4 ;
570 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
571 :     psubusw mm3, mm6 ;
572 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
573 :     psrlw mm3, 1 ;
574 :     paddw mm5, mm0 ; sum += mm0
575 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
576 :     paddw mm5, mm3 ;
577 :     pxor mm3, mm4 ;
578 :     psubw mm0, mm1 ; undisplace
579 :     psubw mm3, mm4
580 :     movq [edi + 8*ecx], mm0
581 :     movq [edi + 8*ecx + 8], mm3
582 :    
583 :     add ecx,2
584 :     cmp ecx,16
585 :     jnz .q1loop
586 :    
587 :     jmp .done
588 :    
589 :    
590 :    
591 :     ;===========================================================================
592 :     ;
593 : h 126 ; uint32_t quant_inter_sse2(int16_t * coeff,
594 :     ; const int16_t const * data,
595 :     ; const uint32_t quant);
596 :     ;
597 :     ;===========================================================================
598 :    
599 :     align 16
600 :     cglobal quant_inter_sse2
601 :     quant_inter_sse2
602 :    
603 :     push esi
604 :     push edi
605 :    
606 :     mov edi, [esp + 8 + 4] ; coeff
607 :     mov esi, [esp + 8 + 8] ; data
608 :     mov eax, [esp + 8 + 12] ; quant
609 :    
610 :     xor ecx, ecx
611 :    
612 :     pxor xmm5, xmm5 ; sum
613 :    
614 :     movq mm0, [mmx_sub + eax*8 - 8] ; sub
615 :     movq2dq xmm6, mm0 ; load into low 8 bytes
616 :     movlhps xmm6, xmm6 ; duplicate into high 8 bytes
617 :    
618 :     cmp al, 1
619 : h 135 jz near .qes2_q1loop
620 : h 126
621 : h 135 .qes2_not1
622 : h 126 movq mm0, [mmx_div + eax*8 - 8] ; divider
623 :     movq2dq xmm7, mm0
624 :     movlhps xmm7, xmm7
625 :    
626 :     align 16
627 : h 135 .qes2_loop
628 : h 126 movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
629 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
630 : h 135 pxor xmm1, xmm1
631 : h 126 pxor xmm4, xmm4
632 : h 135 pcmpgtw xmm1, xmm0
633 : h 126 pcmpgtw xmm4, xmm3
634 : h 135 pxor xmm0, xmm1
635 : h 126 pxor xmm3, xmm4
636 : h 135 psubw xmm0, xmm1
637 : h 126 psubw xmm3, xmm4
638 : h 135 psubusw xmm0, xmm6
639 : h 126 psubusw xmm3, xmm6
640 : h 135 pmulhw xmm0, xmm7
641 : h 126 pmulhw xmm3, xmm7
642 : h 135 paddw xmm5, xmm0
643 :     pxor xmm0, xmm1
644 : h 126 paddw xmm5, xmm3
645 :     pxor xmm3, xmm4
646 : h 135 psubw xmm0, xmm1
647 : h 126 psubw xmm3, xmm4
648 :     movdqa [edi + ecx*8], xmm0
649 :     movdqa [edi + ecx*8 + 16], xmm3
650 :    
651 :     add ecx, 4
652 :     cmp ecx, 16
653 : h 135 jnz .qes2_loop
654 : h 126
655 : h 135 .qes2_done
656 :     movdqu xmm6, [plus_one]
657 :     pmaddwd xmm5, xmm6
658 : h 126 movhlps xmm6, xmm5
659 :     paddd xmm5, xmm6
660 :     movdq2q mm0, xmm5
661 :    
662 :     movq mm5, mm0
663 :     psrlq mm5, 32
664 :     paddd mm0, mm5
665 :     movd eax, mm0 ; return sum
666 :    
667 :     pop edi
668 :     pop esi
669 :    
670 :     ret
671 :    
672 :     align 16
673 : h 135 .qes2_q1loop
674 :     movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
675 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
676 :     pxor xmm1, xmm1
677 :     pxor xmm4, xmm4
678 :     pcmpgtw xmm1, xmm0
679 :     pcmpgtw xmm4, xmm3
680 :     pxor xmm0, xmm1
681 :     pxor xmm3, xmm4
682 :     psubw xmm0, xmm1
683 :     psubw xmm3, xmm4
684 :     psubusw xmm0, xmm6
685 :     psubusw xmm3, xmm6
686 :     psrlw xmm0, 1
687 :     psrlw xmm3, 1
688 :     paddw xmm5, xmm0
689 :     pxor xmm0, xmm1
690 :     paddw xmm5, xmm3
691 :     pxor xmm3, xmm4
692 :     psubw xmm0, xmm1
693 :     psubw xmm3, xmm4
694 :     movdqa [edi + ecx*8], xmm0
695 :     movdqa [edi + ecx*8 + 16], xmm3
696 : h 126
697 : h 135 add ecx,4
698 :     cmp ecx,16
699 :     jnz .qes2_q1loop
700 :     jmp .qes2_done
701 : h 126
702 :    
703 :    
704 :     ;===========================================================================
705 :     ;
706 : Isibaar 3 ; void dequant_intra_mmx(int16_t *data,
707 :     ; const int16_t const *coeff,
708 :     ; const uint32_t quant,
709 :     ; const uint32_t dcscalar);
710 :     ;
711 :     ;===========================================================================
712 :    
713 :     align ALIGN
714 :     cglobal dequant_intra_mmx
715 :     dequant_intra_mmx
716 :    
717 :     push esi
718 :     push edi
719 :    
720 :     mov edi, [esp + 8 + 4] ; data
721 :     mov esi, [esp + 8 + 8] ; coeff
722 :     mov eax, [esp + 8 + 12] ; quant
723 :    
724 :     movq mm6, [mmx_add + eax * 8 - 8]
725 :     movq mm7, [mmx_mul + eax * 8 - 8]
726 :     xor eax, eax
727 :    
728 :     align ALIGN
729 :     .loop
730 :     movq mm0, [esi + 8*eax] ; mm0 = [coeff]
731 :     movq mm3, [esi + 8*eax + 8] ;
732 :     pxor mm1, mm1 ; mm1 = 0
733 :     pxor mm4, mm4 ;
734 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
735 :     pcmpgtw mm4, mm3 ;
736 :     pxor mm2, mm2 ; mm2 = 0
737 :     pxor mm5, mm5 ;
738 :     pcmpeqw mm2, mm0 ; mm2 = (0 == mm0)
739 :     pcmpeqw mm5, mm3 ;
740 :     pandn mm2, mm6 ; mm2 = (iszero ? 0 : add)
741 :     pandn mm5, mm6 ;
742 :     pxor mm0, mm1 ; mm0 = |mm0|
743 :     pxor mm3, mm4 ;
744 :     psubw mm0, mm1 ; displace
745 :     psubw mm3, mm4 ;
746 :     pmullw mm0, mm7 ; mm0 *= 2Q
747 :     pmullw mm3, mm7 ;
748 :     paddw mm0, mm2 ; mm0 += mm2 (add)
749 :     paddw mm3, mm5 ;
750 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
751 :     pxor mm3, mm4 ;
752 :     psubw mm0, mm1 ; undisplace
753 :     psubw mm3, mm4
754 :    
755 :     %ifdef SATURATE
756 :     movq mm2, [mmx_32767_minus_2047]
757 :     movq mm4, [mmx_32768_minus_2048]
758 :     paddsw mm0, mm2
759 :     paddsw mm3, mm2
760 :     psubsw mm0, mm2
761 :     psubsw mm3, mm2
762 :     psubsw mm0, mm4
763 :     psubsw mm3, mm4
764 :     paddsw mm0, mm4
765 :     paddsw mm3, mm4
766 :     %endif
767 :    
768 :     movq [edi + 8*eax], mm0 ; [data] = mm0
769 :     movq [edi + 8*eax + 8], mm3
770 :    
771 :     add eax, 2
772 :     cmp eax, 16
773 :     jnz near .loop
774 :    
775 :     mov ax, [esi] ; ax = data[0]
776 :     imul ax, [esp + 8 + 16] ; eax = data[0] * dcscalar
777 :    
778 :     %ifdef SATURATE
779 :     cmp ax, -2048
780 :     jl .set_n2048
781 :     cmp ax, 2047
782 :     jg .set_2047
783 :     %endif
784 :     mov [edi], ax
785 :    
786 :     pop edi
787 :     pop esi
788 :     ret
789 :    
790 :     %ifdef SATURATE
791 :     align ALIGN
792 :     .set_n2048
793 :     mov word [edi], -2048
794 :     pop edi
795 :     pop esi
796 :     ret
797 :    
798 :     align ALIGN
799 :     .set_2047
800 :     mov word [edi], 2047
801 :     pop edi
802 :     pop esi
803 :     ret
804 :     %endif
805 :    
806 : h 135
807 :    
808 : Isibaar 3 ;===========================================================================
809 :     ;
810 : h 135 ; void dequant_intra_sse2(int16_t *data,
811 :     ; const int16_t const *coeff,
812 :     ; const uint32_t quant,
813 :     ; const uint32_t dcscalar);
814 :     ;
815 :     ;===========================================================================
816 :    
817 :     align 16
818 :     cglobal dequant_intra_sse2
819 :     dequant_intra_sse2
820 :    
821 :     push esi
822 :     push edi
823 :    
824 :     mov edi, [esp + 8 + 4] ; data
825 :     mov esi, [esp + 8 + 8] ; coeff
826 :     mov eax, [esp + 8 + 12] ; quant
827 :    
828 :     movq mm6, [mmx_add + eax*8 - 8]
829 :     movq mm7, [mmx_mul + eax*8 - 8]
830 :     movq2dq xmm6, mm6
831 :     movq2dq xmm7, mm7
832 :     movlhps xmm6, xmm6
833 :     movlhps xmm7, xmm7
834 :    
835 :     xor eax, eax
836 :    
837 :     align 16
838 :     .das2_loop
839 :     movdqa xmm0, [esi + eax*8]
840 :     movdqa xmm3, [esi + eax*8 + 16]
841 :     pxor xmm1, xmm1
842 :     pxor xmm4, xmm4
843 :     pcmpgtw xmm1, xmm0
844 :     pcmpgtw xmm4, xmm3
845 :     pxor xmm2, xmm2
846 :     pxor xmm5, xmm5
847 :     pcmpeqw xmm2, xmm0
848 :     pcmpeqw xmm5, xmm3
849 :     pandn xmm2, xmm6
850 :     pandn xmm5, xmm6
851 :     pxor xmm0, xmm1
852 :     pxor xmm3, xmm4
853 :     psubw xmm0, xmm1
854 :     psubw xmm3, xmm4
855 :     pmullw xmm0, xmm7
856 :     pmullw xmm3, xmm7
857 :     paddw xmm0, xmm2
858 :     paddw xmm3, xmm5
859 :     pxor xmm0, xmm1
860 :     pxor xmm3, xmm4
861 :     psubw xmm0, xmm1
862 :     psubw xmm3, xmm4
863 :    
864 :     %ifdef SATURATE
865 :     movdqu xmm2, [sse2_pos_2047]
866 :     movdqu xmm4, [sse2_neg_2048]
867 :     pminsw xmm0, xmm2
868 :     pminsw xmm3, xmm2
869 :     pmaxsw xmm0, xmm4
870 :     pmaxsw xmm3, xmm4
871 :     %endif
872 :    
873 :     movdqa [edi + eax*8], xmm0
874 :     movdqa [edi + eax*8 + 16], xmm3
875 :    
876 :     add eax, 4
877 :     cmp eax, 16
878 :     jnz near .das2_loop
879 :    
880 :     mov ax, [esi] ; ax = data[0]
881 :     imul ax, [esp + 8 + 16] ; eax = data[0] * dcscalar
882 :    
883 :     %ifdef SATURATE
884 :     cmp ax, -2048
885 :     jl .das2_set_n2048
886 :     cmp ax, 2047
887 :     jg .das2_set_2047
888 :     %endif
889 :     mov [edi], ax
890 :    
891 :     pop edi
892 :     pop esi
893 :     ret
894 :    
895 :     %ifdef SATURATE
896 :     align 16
897 :     .das2_set_n2048
898 :     mov word [edi], -2048
899 :     pop edi
900 :     pop esi
901 :     ret
902 :    
903 :     align 16
904 :     .das2_set_2047
905 :     mov word [edi], 2047
906 :     pop edi
907 :     pop esi
908 :     ret
909 :     %endif
910 :    
911 :    
912 :    
913 :     ;===========================================================================
914 :     ;
915 : Isibaar 3 ; void dequant_inter_mmx(int16_t * data,
916 :     ; const int16_t * const coeff,
917 :     ; const uint32_t quant);
918 :     ;
919 :     ;===========================================================================
920 :    
921 :     align ALIGN
922 :     cglobal dequant_inter_mmx
923 :     dequant_inter_mmx
924 :    
925 :     push esi
926 :     push edi
927 :    
928 :     mov edi, [esp + 8 + 4] ; data
929 :     mov esi, [esp + 8 + 8] ; coeff
930 :     mov eax, [esp + 8 + 12] ; quant
931 :     movq mm6, [mmx_add + eax * 8 - 8]
932 :     movq mm7, [mmx_mul + eax * 8 - 8]
933 :    
934 :     xor eax, eax
935 :    
936 :     align ALIGN
937 :     .loop
938 :     movq mm0, [esi + 8*eax] ; mm0 = [coeff]
939 :     movq mm3, [esi + 8*eax + 8] ;
940 :     pxor mm1, mm1 ; mm1 = 0
941 :     pxor mm4, mm4 ;
942 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
943 :     pcmpgtw mm4, mm3 ;
944 :     pxor mm2, mm2 ; mm2 = 0
945 :     pxor mm5, mm5 ;
946 :     pcmpeqw mm2, mm0 ; mm2 = (0 == mm0)
947 :     pcmpeqw mm5, mm3 ;
948 :     pandn mm2, mm6 ; mm2 = (iszero ? 0 : add)
949 :     pandn mm5, mm6 ;
950 :     pxor mm0, mm1 ; mm0 = |mm0|
951 :     pxor mm3, mm4 ;
952 :     psubw mm0, mm1 ; displace
953 :     psubw mm3, mm4 ;
954 :     pmullw mm0, mm7 ; mm0 *= 2Q
955 :     pmullw mm3, mm7 ;
956 :     paddw mm0, mm2 ; mm0 += mm2 (add)
957 :     paddw mm3, mm5 ;
958 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
959 :     pxor mm3, mm4 ;
960 :     psubw mm0, mm1 ; undisplace
961 :     psubw mm3, mm4
962 :    
963 :     %ifdef SATURATE
964 :     movq mm2, [mmx_32767_minus_2047]
965 :     movq mm4, [mmx_32768_minus_2048]
966 :     paddsw mm0, mm2
967 :     paddsw mm3, mm2
968 :     psubsw mm0, mm2
969 :     psubsw mm3, mm2
970 :     psubsw mm0, mm4
971 :     psubsw mm3, mm4
972 :     paddsw mm0, mm4
973 :     paddsw mm3, mm4
974 :     %endif
975 :    
976 :     movq [edi + 8*eax], mm0
977 :     movq [edi + 8*eax + 8], mm3
978 :    
979 :     add eax, 2
980 :     cmp eax, 16
981 :     jnz near .loop
982 :    
983 :     pop edi
984 :     pop esi
985 :    
986 : h 126 ret
987 :    
988 :    
989 :     ;===========================================================================
990 :     ;
991 :     ; void dequant_inter_sse2(int16_t * data,
992 :     ; const int16_t * const coeff,
993 :     ; const uint32_t quant);
994 :     ;
995 :     ;===========================================================================
996 :    
997 :     align 16
998 :     cglobal dequant_inter_sse2
999 :     dequant_inter_sse2
1000 :    
1001 :     push esi
1002 :     push edi
1003 :    
1004 :     mov edi, [esp + 8 + 4] ; data
1005 :     mov esi, [esp + 8 + 8] ; coeff
1006 :     mov eax, [esp + 8 + 12] ; quant
1007 :     movq mm6, [mmx_add + eax * 8 - 8]
1008 :     movq mm7, [mmx_mul + eax * 8 - 8]
1009 :    
1010 :     movq2dq xmm6, mm6
1011 :     movq2dq xmm7, mm7
1012 :     movlhps xmm6, xmm6
1013 :     movlhps xmm7, xmm7
1014 :    
1015 :     xor eax, eax
1016 :    
1017 :     align 16
1018 : h 135 .des2_loop
1019 : h 126 movdqa xmm0, [esi + eax*8] ; xmm0 = [coeff]
1020 :     movdqa xmm3, [esi + eax*8 + 16]
1021 :     pxor xmm1, xmm1
1022 :     pxor xmm4, xmm4
1023 :     pcmpgtw xmm1, xmm0
1024 :     pcmpgtw xmm4, xmm3
1025 :     pxor xmm2, xmm2
1026 :     pxor xmm5, xmm5
1027 :     pcmpeqw xmm2, xmm0
1028 :     pcmpeqw xmm5, xmm3
1029 :     pandn xmm2, xmm6
1030 :     pandn xmm5, xmm6
1031 :     pxor xmm0, xmm1
1032 :     pxor xmm3, xmm4
1033 :     psubw xmm0, xmm1
1034 :     psubw xmm3, xmm4
1035 :     pmullw xmm0, xmm7
1036 :     pmullw xmm3, xmm7
1037 :     paddw xmm0, xmm2
1038 :     paddw xmm3, xmm5
1039 :     pxor xmm0, xmm1
1040 :     pxor xmm3, xmm4
1041 :     psubw xmm0, xmm1
1042 :     psubw xmm3, xmm4
1043 :    
1044 :     %ifdef SATURATE
1045 : h 135 movdqu xmm2, [sse2_pos_2047]
1046 :     movdqu xmm4, [sse2_neg_2048]
1047 : h 126 pminsw xmm0, xmm2
1048 :     pminsw xmm3, xmm2
1049 :     pmaxsw xmm0, xmm4
1050 :     pmaxsw xmm3, xmm4
1051 :     %endif
1052 :    
1053 :     movdqa [edi + eax*8], xmm0
1054 :     movdqa [edi + eax*8 + 16], xmm3
1055 :    
1056 :     add eax, 4
1057 :     cmp eax, 16
1058 : h 135 jnz near .des2_loop
1059 : h 126
1060 :     pop edi
1061 :     pop esi
1062 :    
1063 :     ret

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