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

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