[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 126 - (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 :     ; * 26.12.2001 minor bug fixes, dequant saturate, further optimization
36 :     ; * 19.11.2001 quant_inter_mmx now returns sum of abs. coefficient values
37 :     ; * 04.11.2001 nasm version; (c)2001 peter ross <pross@cs.rmit.edu.au>
38 :     ; *
39 :     ; *************************************************************************/
40 :    
41 :     ; enable dequant saturate [-2048,2047], test purposes only.
42 :     %define SATURATE
43 :    
44 :     ; data/text alignment
45 :     %define ALIGN 8
46 :    
47 :     bits 32
48 :    
49 :     section .data
50 :    
51 :    
52 :     %macro cglobal 1
53 :     %ifdef PREFIX
54 :     global _%1
55 :     %define %1 _%1
56 :     %else
57 :     global %1
58 :     %endif
59 :     %endmacro
60 :    
61 : h 126 align 16
62 : Isibaar 3
63 : h 126 plus_one times 8 dw 1
64 :    
65 : Isibaar 3 ;===========================================================================
66 :     ;
67 :     ; subtract by Q/2 table
68 :     ;
69 :     ;===========================================================================
70 :    
71 :     %macro MMX_SUB 1
72 :     times 4 dw %1 / 2
73 :     %endmacro
74 :    
75 : h 126 align 16
76 : Isibaar 3 mmx_sub
77 :     MMX_SUB 1
78 :     MMX_SUB 2
79 :     MMX_SUB 3
80 :     MMX_SUB 4
81 :     MMX_SUB 5
82 :     MMX_SUB 6
83 :     MMX_SUB 7
84 :     MMX_SUB 8
85 :     MMX_SUB 9
86 :     MMX_SUB 10
87 :     MMX_SUB 11
88 :     MMX_SUB 12
89 :     MMX_SUB 13
90 :     MMX_SUB 14
91 :     MMX_SUB 15
92 :     MMX_SUB 16
93 :     MMX_SUB 17
94 :     MMX_SUB 18
95 :     MMX_SUB 19
96 :     MMX_SUB 20
97 :     MMX_SUB 21
98 :     MMX_SUB 22
99 :     MMX_SUB 23
100 :     MMX_SUB 24
101 :     MMX_SUB 25
102 :     MMX_SUB 26
103 :     MMX_SUB 27
104 :     MMX_SUB 28
105 :     MMX_SUB 29
106 :     MMX_SUB 30
107 :     MMX_SUB 31
108 :    
109 :    
110 :    
111 :     ;===========================================================================
112 :     ;
113 :     ; divide by 2Q table
114 :     ;
115 :     ; use a shift of 16 to take full advantage of _pmulhw_
116 :     ; for q=1, _pmulhw_ will overflow so it is treated seperately
117 :     ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
118 :     ;
119 :     ;===========================================================================
120 :    
121 :     %macro MMX_DIV 1
122 :     times 4 dw (1 << 16) / (%1 * 2) + 1
123 :     %endmacro
124 :    
125 : h 126 align 16
126 : Isibaar 3 mmx_div
127 :     MMX_DIV 1
128 :     MMX_DIV 2
129 :     MMX_DIV 3
130 :     MMX_DIV 4
131 :     MMX_DIV 5
132 :     MMX_DIV 6
133 :     MMX_DIV 7
134 :     MMX_DIV 8
135 :     MMX_DIV 9
136 :     MMX_DIV 10
137 :     MMX_DIV 11
138 :     MMX_DIV 12
139 :     MMX_DIV 13
140 :     MMX_DIV 14
141 :     MMX_DIV 15
142 :     MMX_DIV 16
143 :     MMX_DIV 17
144 :     MMX_DIV 18
145 :     MMX_DIV 19
146 :     MMX_DIV 20
147 :     MMX_DIV 21
148 :     MMX_DIV 22
149 :     MMX_DIV 23
150 :     MMX_DIV 24
151 :     MMX_DIV 25
152 :     MMX_DIV 26
153 :     MMX_DIV 27
154 :     MMX_DIV 28
155 :     MMX_DIV 29
156 :     MMX_DIV 30
157 :     MMX_DIV 31
158 :    
159 :    
160 :    
161 :     ;===========================================================================
162 :     ;
163 :     ; add by (odd(Q) ? Q : Q - 1) table
164 :     ;
165 :     ;===========================================================================
166 :    
167 :     %macro MMX_ADD 1
168 :     %if %1 % 2 != 0
169 :     times 4 dw %1
170 :     %else
171 :     times 4 dw %1 - 1
172 :     %endif
173 :     %endmacro
174 :    
175 : h 126 align 16
176 : Isibaar 3 mmx_add
177 :     MMX_ADD 1
178 :     MMX_ADD 2
179 :     MMX_ADD 3
180 :     MMX_ADD 4
181 :     MMX_ADD 5
182 :     MMX_ADD 6
183 :     MMX_ADD 7
184 :     MMX_ADD 8
185 :     MMX_ADD 9
186 :     MMX_ADD 10
187 :     MMX_ADD 11
188 :     MMX_ADD 12
189 :     MMX_ADD 13
190 :     MMX_ADD 14
191 :     MMX_ADD 15
192 :     MMX_ADD 16
193 :     MMX_ADD 17
194 :     MMX_ADD 18
195 :     MMX_ADD 19
196 :     MMX_ADD 20
197 :     MMX_ADD 21
198 :     MMX_ADD 22
199 :     MMX_ADD 23
200 :     MMX_ADD 24
201 :     MMX_ADD 25
202 :     MMX_ADD 26
203 :     MMX_ADD 27
204 :     MMX_ADD 28
205 :     MMX_ADD 29
206 :     MMX_ADD 30
207 :     MMX_ADD 31
208 :    
209 :    
210 :     ;===========================================================================
211 :     ;
212 :     ; multiple by 2Q table
213 :     ;
214 :     ;===========================================================================
215 :    
216 :     %macro MMX_MUL 1
217 :     times 4 dw %1 * 2
218 :     %endmacro
219 :    
220 : h 126 align 16
221 : Isibaar 3 mmx_mul
222 :     MMX_MUL 1
223 :     MMX_MUL 2
224 :     MMX_MUL 3
225 :     MMX_MUL 4
226 :     MMX_MUL 5
227 :     MMX_MUL 6
228 :     MMX_MUL 7
229 :     MMX_MUL 8
230 :     MMX_MUL 9
231 :     MMX_MUL 10
232 :     MMX_MUL 11
233 :     MMX_MUL 12
234 :     MMX_MUL 13
235 :     MMX_MUL 14
236 :     MMX_MUL 15
237 :     MMX_MUL 16
238 :     MMX_MUL 17
239 :     MMX_MUL 18
240 :     MMX_MUL 19
241 :     MMX_MUL 20
242 :     MMX_MUL 21
243 :     MMX_MUL 22
244 :     MMX_MUL 23
245 :     MMX_MUL 24
246 :     MMX_MUL 25
247 :     MMX_MUL 26
248 :     MMX_MUL 27
249 :     MMX_MUL 28
250 :     MMX_MUL 29
251 :     MMX_MUL 30
252 :     MMX_MUL 31
253 :    
254 :    
255 :     ;===========================================================================
256 :     ;
257 :     ; saturation limits
258 :     ;
259 :     ;===========================================================================
260 :    
261 :     align ALIGN
262 :     mmx_32768_minus_2048 times 4 dw (32768-2048)
263 :     mmx_32767_minus_2047 times 4 dw (32767-2047)
264 :    
265 : h 126 align 16
266 :     sse2_pos_2047 times 8 dw 2047
267 :     sse2_neg_2048 times 8 dw -2048
268 : Isibaar 3
269 : h 126
270 : Isibaar 3 section .text
271 :    
272 :    
273 :     ;===========================================================================
274 :     ;
275 :     ; void quant_intra_mmx(int16_t * coeff,
276 :     ; const int16_t const * data,
277 :     ; const uint32_t quant,
278 :     ; const uint32_t dcscalar);
279 :     ;
280 :     ;===========================================================================
281 :    
282 :     align ALIGN
283 :     cglobal quant_intra_mmx
284 :     quant_intra_mmx
285 :    
286 :     push ecx
287 :     push esi
288 :     push edi
289 :    
290 :     mov edi, [esp + 12 + 4] ; coeff
291 :     mov esi, [esp + 12 + 8] ; data
292 :     mov eax, [esp + 12 + 12] ; quant
293 :    
294 :     xor ecx, ecx
295 :     cmp al, 1
296 :     jz .q1loop
297 :    
298 :     movq mm7, [mmx_div + eax * 8 - 8]
299 :     align ALIGN
300 :     .loop
301 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
302 :     movq mm3, [esi + 8*ecx + 8] ;
303 :     pxor mm1, mm1 ; mm1 = 0
304 :     pxor mm4, mm4 ;
305 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
306 :     pcmpgtw mm4, mm3 ;
307 :     pxor mm0, mm1 ; mm0 = |mm0|
308 :     pxor mm3, mm4 ;
309 :     psubw mm0, mm1 ; displace
310 :     psubw mm3, mm4 ;
311 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
312 :     pmulhw mm3, mm7 ;
313 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
314 :     pxor mm3, mm4 ;
315 :     psubw mm0, mm1 ; undisplace
316 :     psubw mm3, mm4 ;
317 :     movq [edi + 8*ecx], mm0
318 :     movq [edi + 8*ecx + 8], mm3
319 :    
320 :     add ecx,2
321 :     cmp ecx,16
322 :     jnz .loop
323 :    
324 :     .done
325 :     ; caclulate data[0] // (int32_t)dcscalar)
326 :    
327 :     mov ecx, [esp + 12 + 16] ; dcscalar
328 :     mov edx, ecx
329 :     movsx eax, word [esi] ; data[0]
330 :     shr edx, 1 ; edx = dcscalar /2
331 :     cmp eax, 0
332 :     jg .gtzero
333 :    
334 :     sub eax, edx
335 :     jmp short .mul
336 :     .gtzero
337 :     add eax, edx
338 :     .mul
339 :     cdq ; expand eax -> edx:eax
340 :     idiv ecx ; eax = edx:eax / dcscalar
341 :    
342 :     mov [edi], ax ; coeff[0] = ax
343 :    
344 :     pop edi
345 :     pop esi
346 :     pop ecx
347 :    
348 :     ret
349 :    
350 :     align ALIGN
351 :     .q1loop
352 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
353 :     movq mm3, [esi + 8*ecx + 8] ;
354 :     pxor mm1, mm1 ; mm1 = 0
355 :     pxor mm4, mm4 ;
356 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
357 :     pcmpgtw mm4, mm3 ;
358 :     pxor mm0, mm1 ; mm0 = |mm0|
359 :     pxor mm3, mm4 ;
360 :     psubw mm0, mm1 ; displace
361 :     psubw mm3, mm4 ;
362 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
363 :     psrlw mm3, 1 ;
364 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
365 :     pxor mm3, mm4 ;
366 :     psubw mm0, mm1 ; undisplace
367 :     psubw mm3, mm4 ;
368 :     movq [edi + 8*ecx], mm0
369 :     movq [edi + 8*ecx + 8], mm3
370 :    
371 :     add ecx,2
372 :     cmp ecx,16
373 :     jnz .q1loop
374 :     jmp short .done
375 :    
376 :    
377 :    
378 :     ;===========================================================================
379 :     ;
380 :     ; uint32_t quant_inter_mmx(int16_t * coeff,
381 :     ; const int16_t const * data,
382 :     ; const uint32_t quant);
383 :     ;
384 :     ;===========================================================================
385 :    
386 :     align ALIGN
387 :     cglobal quant_inter_mmx
388 :     quant_inter_mmx
389 :    
390 :     push ecx
391 :     push esi
392 :     push edi
393 :    
394 :     mov edi, [esp + 12 + 4] ; coeff
395 :     mov esi, [esp + 12 + 8] ; data
396 :     mov eax, [esp + 12 + 12] ; quant
397 :    
398 :     xor ecx, ecx
399 :    
400 :     pxor mm5, mm5 ; sum
401 :     movq mm6, [mmx_sub + eax * 8 - 8] ; sub
402 :    
403 :     cmp al, 1
404 :     jz .q1loop
405 :    
406 :     movq mm7, [mmx_div + eax * 8 - 8] ; divider
407 :    
408 :     align ALIGN
409 :     .loop
410 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
411 :     movq mm3, [esi + 8*ecx + 8] ;
412 :     pxor mm1, mm1 ; mm1 = 0
413 :     pxor mm4, mm4 ;
414 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
415 :     pcmpgtw mm4, mm3 ;
416 :     pxor mm0, mm1 ; mm0 = |mm0|
417 :     pxor mm3, mm4 ;
418 :     psubw mm0, mm1 ; displace
419 :     psubw mm3, mm4 ;
420 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
421 :     psubusw mm3, mm6 ;
422 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
423 :     pmulhw mm3, mm7 ;
424 :     paddw mm5, mm0 ; sum += mm0
425 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
426 :     paddw mm5, mm3 ;
427 :     pxor mm3, mm4 ;
428 :     psubw mm0, mm1 ; undisplace
429 :     psubw mm3, mm4
430 :     movq [edi + 8*ecx], mm0
431 :     movq [edi + 8*ecx + 8], mm3
432 :    
433 :     add ecx, 2
434 :     cmp ecx, 16
435 :     jnz .loop
436 :    
437 :     .done
438 :     pmaddwd mm5, [plus_one]
439 :     movq mm0, mm5
440 :     psrlq mm5, 32
441 :     paddd mm0, mm5
442 :     movd eax, mm0 ; return sum
443 :    
444 :     pop edi
445 :     pop esi
446 :     pop ecx
447 :    
448 :     ret
449 :    
450 :     align ALIGN
451 :     .q1loop
452 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
453 :     movq mm3, [esi + 8*ecx+ 8] ;
454 :     pxor mm1, mm1 ; mm1 = 0
455 :     pxor mm4, mm4 ;
456 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
457 :     pcmpgtw mm4, mm3 ;
458 :     pxor mm0, mm1 ; mm0 = |mm0|
459 :     pxor mm3, mm4 ;
460 :     psubw mm0, mm1 ; displace
461 :     psubw mm3, mm4 ;
462 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
463 :     psubusw mm3, mm6 ;
464 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
465 :     psrlw mm3, 1 ;
466 :     paddw mm5, mm0 ; sum += mm0
467 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
468 :     paddw mm5, mm3 ;
469 :     pxor mm3, mm4 ;
470 :     psubw mm0, mm1 ; undisplace
471 :     psubw mm3, mm4
472 :     movq [edi + 8*ecx], mm0
473 :     movq [edi + 8*ecx + 8], mm3
474 :    
475 :     add ecx,2
476 :     cmp ecx,16
477 :     jnz .q1loop
478 :    
479 :     jmp .done
480 :    
481 :    
482 :    
483 :     ;===========================================================================
484 :     ;
485 : h 126 ; uint32_t quant_inter_sse2(int16_t * coeff,
486 :     ; const int16_t const * data,
487 :     ; const uint32_t quant);
488 :     ;
489 :     ;===========================================================================
490 :    
491 :     align 16
492 :     cglobal quant_inter_sse2
493 :     quant_inter_sse2
494 :    
495 :     push esi
496 :     push edi
497 :    
498 :     mov edi, [esp + 8 + 4] ; coeff
499 :     mov esi, [esp + 8 + 8] ; data
500 :     mov eax, [esp + 8 + 12] ; quant
501 :    
502 :     xor ecx, ecx
503 :    
504 :     pxor xmm5, xmm5 ; sum
505 :    
506 :     movq mm0, [mmx_sub + eax*8 - 8] ; sub
507 :     movq2dq xmm6, mm0 ; load into low 8 bytes
508 :     movlhps xmm6, xmm6 ; duplicate into high 8 bytes
509 :    
510 :     cmp al, 1
511 :     jnz .not1
512 :     jmp .q1loop
513 :    
514 :     .not1
515 :     movq mm0, [mmx_div + eax*8 - 8] ; divider
516 :     movq2dq xmm7, mm0
517 :     movlhps xmm7, xmm7
518 :    
519 :     align 16
520 :     .loop
521 :     movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
522 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
523 :     pxor xmm1, xmm1 ; xmm1 = 0
524 :     pxor xmm4, xmm4
525 :     pcmpgtw xmm1, xmm0 ; xmm1 = (0 > xmm0)
526 :     pcmpgtw xmm4, xmm3
527 :     pxor xmm0, xmm1 ; xmm0 = |xmm0|
528 :     pxor xmm3, xmm4
529 :     psubw xmm0, xmm1 ; displace
530 :     psubw xmm3, xmm4
531 :     psubusw xmm0, xmm6 ; xmm0 -= sub (unsigned, dont go < 0)
532 :     psubusw xmm3, xmm6
533 :     pmulhw xmm0, xmm7 ; xmm0 = (xmm0 / 2Q) >> 16
534 :     pmulhw xmm3, xmm7
535 :     paddw xmm5, xmm0 ; sum += xmm0
536 :     pxor xmm0, xmm1 ; xmm0 *= sign(xmm0)
537 :     paddw xmm5, xmm3
538 :     pxor xmm3, xmm4
539 :     psubw xmm0, xmm1 ; undisplace
540 :     psubw xmm3, xmm4
541 :     movdqa [edi + ecx*8], xmm0
542 :     movdqa [edi + ecx*8 + 16], xmm3
543 :    
544 :     add ecx, 4
545 :     cmp ecx, 16
546 :     jnz .loop
547 :    
548 :     .done
549 :     pmaddwd xmm5, [plus_one]
550 :     movhlps xmm6, xmm5
551 :     paddd xmm5, xmm6
552 :     movdq2q mm0, xmm5
553 :    
554 :     movq mm5, mm0
555 :     psrlq mm5, 32
556 :     paddd mm0, mm5
557 :     movd eax, mm0 ; return sum
558 :    
559 :     pop edi
560 :     pop esi
561 :    
562 :     ret
563 :    
564 :     align 16
565 :     .q1loop
566 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
567 :     movq mm3, [esi + 8*ecx+ 8] ;
568 :     pxor mm1, mm1 ; mm1 = 0
569 :     pxor mm4, mm4 ;
570 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
571 :     pcmpgtw mm4, mm3 ;
572 :     pxor mm0, mm1 ; mm0 = |mm0|
573 :     pxor mm3, mm4 ;
574 :     psubw mm0, mm1 ; displace
575 :     psubw mm3, mm4 ;
576 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
577 :     psubusw mm3, mm6 ;
578 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
579 :     psrlw mm3, 1 ;
580 :     paddw mm5, mm0 ; sum += mm0
581 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
582 :     paddw mm5, mm3 ;
583 :     pxor mm3, mm4 ;
584 :     psubw mm0, mm1 ; undisplace
585 :     psubw mm3, mm4
586 :     movq [edi + 8*ecx], mm0
587 :     movq [edi + 8*ecx + 8], mm3
588 :    
589 :     add ecx,2
590 :     cmp ecx,16
591 :     jnz .q1loop
592 :    
593 :     jmp .done
594 :    
595 :    
596 :    
597 :     ;===========================================================================
598 :     ;
599 : Isibaar 3 ; void dequant_intra_mmx(int16_t *data,
600 :     ; const int16_t const *coeff,
601 :     ; const uint32_t quant,
602 :     ; const uint32_t dcscalar);
603 :     ;
604 :     ;===========================================================================
605 :    
606 :     align ALIGN
607 :     cglobal dequant_intra_mmx
608 :     dequant_intra_mmx
609 :    
610 :     push esi
611 :     push edi
612 :    
613 :     mov edi, [esp + 8 + 4] ; data
614 :     mov esi, [esp + 8 + 8] ; coeff
615 :     mov eax, [esp + 8 + 12] ; quant
616 :    
617 :     movq mm6, [mmx_add + eax * 8 - 8]
618 :     movq mm7, [mmx_mul + eax * 8 - 8]
619 :     xor eax, eax
620 :    
621 :     align ALIGN
622 :     .loop
623 :     movq mm0, [esi + 8*eax] ; mm0 = [coeff]
624 :     movq mm3, [esi + 8*eax + 8] ;
625 :     pxor mm1, mm1 ; mm1 = 0
626 :     pxor mm4, mm4 ;
627 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
628 :     pcmpgtw mm4, mm3 ;
629 :     pxor mm2, mm2 ; mm2 = 0
630 :     pxor mm5, mm5 ;
631 :     pcmpeqw mm2, mm0 ; mm2 = (0 == mm0)
632 :     pcmpeqw mm5, mm3 ;
633 :     pandn mm2, mm6 ; mm2 = (iszero ? 0 : add)
634 :     pandn mm5, mm6 ;
635 :     pxor mm0, mm1 ; mm0 = |mm0|
636 :     pxor mm3, mm4 ;
637 :     psubw mm0, mm1 ; displace
638 :     psubw mm3, mm4 ;
639 :     pmullw mm0, mm7 ; mm0 *= 2Q
640 :     pmullw mm3, mm7 ;
641 :     paddw mm0, mm2 ; mm0 += mm2 (add)
642 :     paddw mm3, mm5 ;
643 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
644 :     pxor mm3, mm4 ;
645 :     psubw mm0, mm1 ; undisplace
646 :     psubw mm3, mm4
647 :    
648 :     %ifdef SATURATE
649 :     movq mm2, [mmx_32767_minus_2047]
650 :     movq mm4, [mmx_32768_minus_2048]
651 :     paddsw mm0, mm2
652 :     paddsw mm3, mm2
653 :     psubsw mm0, mm2
654 :     psubsw mm3, mm2
655 :     psubsw mm0, mm4
656 :     psubsw mm3, mm4
657 :     paddsw mm0, mm4
658 :     paddsw mm3, mm4
659 :     %endif
660 :    
661 :     movq [edi + 8*eax], mm0 ; [data] = mm0
662 :     movq [edi + 8*eax + 8], mm3
663 :    
664 :     add eax, 2
665 :     cmp eax, 16
666 :     jnz near .loop
667 :    
668 :     mov ax, [esi] ; ax = data[0]
669 :     imul ax, [esp + 8 + 16] ; eax = data[0] * dcscalar
670 :    
671 :     %ifdef SATURATE
672 :     cmp ax, -2048
673 :     jl .set_n2048
674 :     cmp ax, 2047
675 :     jg .set_2047
676 :     %endif
677 :     mov [edi], ax
678 :    
679 :     pop edi
680 :     pop esi
681 :     ret
682 :    
683 :     %ifdef SATURATE
684 :     align ALIGN
685 :     .set_n2048
686 :     mov word [edi], -2048
687 :     pop edi
688 :     pop esi
689 :     ret
690 :    
691 :     align ALIGN
692 :     .set_2047
693 :     mov word [edi], 2047
694 :     pop edi
695 :     pop esi
696 :     ret
697 :     %endif
698 :    
699 :     ;===========================================================================
700 :     ;
701 :     ; void dequant_inter_mmx(int16_t * data,
702 :     ; const int16_t * const coeff,
703 :     ; const uint32_t quant);
704 :     ;
705 :     ;===========================================================================
706 :    
707 :     align ALIGN
708 :     cglobal dequant_inter_mmx
709 :     dequant_inter_mmx
710 :    
711 :     push esi
712 :     push edi
713 :    
714 :     mov edi, [esp + 8 + 4] ; data
715 :     mov esi, [esp + 8 + 8] ; coeff
716 :     mov eax, [esp + 8 + 12] ; quant
717 :     movq mm6, [mmx_add + eax * 8 - 8]
718 :     movq mm7, [mmx_mul + eax * 8 - 8]
719 :    
720 :     xor eax, eax
721 :    
722 :     align ALIGN
723 :     .loop
724 :     movq mm0, [esi + 8*eax] ; mm0 = [coeff]
725 :     movq mm3, [esi + 8*eax + 8] ;
726 :     pxor mm1, mm1 ; mm1 = 0
727 :     pxor mm4, mm4 ;
728 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
729 :     pcmpgtw mm4, mm3 ;
730 :     pxor mm2, mm2 ; mm2 = 0
731 :     pxor mm5, mm5 ;
732 :     pcmpeqw mm2, mm0 ; mm2 = (0 == mm0)
733 :     pcmpeqw mm5, mm3 ;
734 :     pandn mm2, mm6 ; mm2 = (iszero ? 0 : add)
735 :     pandn mm5, mm6 ;
736 :     pxor mm0, mm1 ; mm0 = |mm0|
737 :     pxor mm3, mm4 ;
738 :     psubw mm0, mm1 ; displace
739 :     psubw mm3, mm4 ;
740 :     pmullw mm0, mm7 ; mm0 *= 2Q
741 :     pmullw mm3, mm7 ;
742 :     paddw mm0, mm2 ; mm0 += mm2 (add)
743 :     paddw mm3, mm5 ;
744 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
745 :     pxor mm3, mm4 ;
746 :     psubw mm0, mm1 ; undisplace
747 :     psubw mm3, mm4
748 :    
749 :     %ifdef SATURATE
750 :     movq mm2, [mmx_32767_minus_2047]
751 :     movq mm4, [mmx_32768_minus_2048]
752 :     paddsw mm0, mm2
753 :     paddsw mm3, mm2
754 :     psubsw mm0, mm2
755 :     psubsw mm3, mm2
756 :     psubsw mm0, mm4
757 :     psubsw mm3, mm4
758 :     paddsw mm0, mm4
759 :     paddsw mm3, mm4
760 :     %endif
761 :    
762 :     movq [edi + 8*eax], mm0
763 :     movq [edi + 8*eax + 8], mm3
764 :    
765 :     add eax, 2
766 :     cmp eax, 16
767 :     jnz near .loop
768 :    
769 :     pop edi
770 :     pop esi
771 :    
772 : h 126 ret
773 :    
774 :    
775 :     ;===========================================================================
776 :     ;
777 :     ; void dequant_inter_sse2(int16_t * data,
778 :     ; const int16_t * const coeff,
779 :     ; const uint32_t quant);
780 :     ;
781 :     ;===========================================================================
782 :    
783 :     align 16
784 :     cglobal dequant_inter_sse2
785 :     dequant_inter_sse2
786 :    
787 :     push esi
788 :     push edi
789 :    
790 :     mov edi, [esp + 8 + 4] ; data
791 :     mov esi, [esp + 8 + 8] ; coeff
792 :     mov eax, [esp + 8 + 12] ; quant
793 :     movq mm6, [mmx_add + eax * 8 - 8]
794 :     movq mm7, [mmx_mul + eax * 8 - 8]
795 :    
796 :     movq2dq xmm6, mm6
797 :     movq2dq xmm7, mm7
798 :     movlhps xmm6, xmm6
799 :     movlhps xmm7, xmm7
800 :    
801 :     xor eax, eax
802 :    
803 :     align 16
804 :     .loop
805 :     movdqa xmm0, [esi + eax*8] ; xmm0 = [coeff]
806 :     movdqa xmm3, [esi + eax*8 + 16]
807 :     pxor xmm1, xmm1
808 :     pxor xmm4, xmm4
809 :     pcmpgtw xmm1, xmm0
810 :     pcmpgtw xmm4, xmm3
811 :     pxor xmm2, xmm2
812 :     pxor xmm5, xmm5
813 :     pcmpeqw xmm2, xmm0
814 :     pcmpeqw xmm5, xmm3
815 :     pandn xmm2, xmm6
816 :     pandn xmm5, xmm6
817 :     pxor xmm0, xmm1
818 :     pxor xmm3, xmm4
819 :     psubw xmm0, xmm1
820 :     psubw xmm3, xmm4
821 :     pmullw xmm0, xmm7
822 :     pmullw xmm3, xmm7
823 :     paddw xmm0, xmm2
824 :     paddw xmm3, xmm5
825 :     pxor xmm0, xmm1
826 :     pxor xmm3, xmm4
827 :     psubw xmm0, xmm1
828 :     psubw xmm3, xmm4
829 :    
830 :     %ifdef SATURATE
831 :     movdqa xmm2, [sse2_pos_2047]
832 :     movdqa xmm4, [sse2_neg_2048]
833 :     pminsw xmm0, xmm2
834 :     pminsw xmm3, xmm2
835 :     pmaxsw xmm0, xmm4
836 :     pmaxsw xmm3, xmm4
837 :     %endif
838 :    
839 :     movdqa [edi + eax*8], xmm0
840 :     movdqa [edi + eax*8 + 16], xmm3
841 :    
842 :     add eax, 4
843 :     cmp eax, 16
844 :     jnz near .loop
845 :    
846 :     pop edi
847 :     pop esi
848 :    
849 :     ret

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