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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 653 - (view) (download)

1 : chl 463 ;/*****************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * mmx optimized MPEG quantization/dequantization
5 :     ; *
6 :     ; * 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 :     ; *
10 : edgomez 653 ; * This file is part of XviD, a free MPEG-4 video encoder/decoder
11 : chl 463 ; *
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 :     ; *
17 :     ; * 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 :     ; *
22 :     ; * 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 :     ; *
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: quantize4_mmx.asm,v 1.7 2002-11-17 00:41:20 edgomez Exp $
56 :     ; *
57 : chl 463 ; *************************************************************************/
58 : Isibaar 3
59 :     ; data/text alignment
60 :     %define ALIGN 8
61 :    
62 :     %define SATURATE
63 :    
64 :     bits 32
65 :    
66 :     section .data
67 :    
68 :     %macro cglobal 1
69 :     %ifdef PREFIX
70 :     global _%1
71 :     %define %1 _%1
72 :     %else
73 :     global %1
74 :     %endif
75 :     %endmacro
76 :    
77 : Isibaar 4 %macro cextern 1
78 :     %ifdef PREFIX
79 :     extern _%1
80 :     %define %1 _%1
81 :     %else
82 :     extern %1
83 :     %endif
84 :     %endmacro
85 :    
86 : Isibaar 3 mmx_one times 4 dw 1
87 :    
88 :     ;===========================================================================
89 :     ;
90 :     ; divide by 2Q table
91 :     ;
92 :     ;===========================================================================
93 :    
94 :     %macro MMX_DIV 1
95 :     times 4 dw (1 << 17) / (%1 * 2) + 1
96 :     %endmacro
97 :    
98 :     align ALIGN
99 :     mmx_div
100 :     MMX_DIV 1
101 :     MMX_DIV 2
102 :     MMX_DIV 3
103 :     MMX_DIV 4
104 :     MMX_DIV 5
105 :     MMX_DIV 6
106 :     MMX_DIV 7
107 :     MMX_DIV 8
108 :     MMX_DIV 9
109 :     MMX_DIV 10
110 :     MMX_DIV 11
111 :     MMX_DIV 12
112 :     MMX_DIV 13
113 :     MMX_DIV 14
114 :     MMX_DIV 15
115 :     MMX_DIV 16
116 :     MMX_DIV 17
117 :     MMX_DIV 18
118 :     MMX_DIV 19
119 :     MMX_DIV 20
120 :     MMX_DIV 21
121 :     MMX_DIV 22
122 :     MMX_DIV 23
123 :     MMX_DIV 24
124 :     MMX_DIV 25
125 :     MMX_DIV 26
126 :     MMX_DIV 27
127 :     MMX_DIV 28
128 :     MMX_DIV 29
129 :     MMX_DIV 30
130 :     MMX_DIV 31
131 :    
132 :    
133 :     ;===========================================================================
134 :     ;
135 : Isibaar 4 ; intra matrix
136 : Isibaar 3 ;
137 :     ;===========================================================================
138 :    
139 : Isibaar 4 cextern intra_matrix
140 :     cextern intra_matrix_fix
141 : Isibaar 3
142 :     ;===========================================================================
143 :     ;
144 : Isibaar 4 ; inter matrix
145 : Isibaar 3 ;
146 :     ;===========================================================================
147 :    
148 : Isibaar 4 cextern inter_matrix
149 :     cextern inter_matrix_fix
150 : Isibaar 3
151 :    
152 :     %define VM18P 3
153 :     %define VM18Q 4
154 :    
155 : Isibaar 4
156 : Isibaar 3 ;===========================================================================
157 :     ;
158 :     ; quantd table
159 :     ;
160 :     ;===========================================================================
161 :    
162 :     %macro MMX_QUANTD 1
163 :     times 4 dw ((VM18P*%1) + (VM18Q/2)) / VM18Q
164 :     %endmacro
165 :    
166 :     quantd
167 :     MMX_QUANTD 1
168 :     MMX_QUANTD 2
169 :     MMX_QUANTD 3
170 :     MMX_QUANTD 4
171 :     MMX_QUANTD 5
172 :     MMX_QUANTD 6
173 :     MMX_QUANTD 7
174 :     MMX_QUANTD 8
175 :     MMX_QUANTD 9
176 :     MMX_QUANTD 10
177 :     MMX_QUANTD 11
178 :     MMX_QUANTD 12
179 :     MMX_QUANTD 13
180 :     MMX_QUANTD 14
181 :     MMX_QUANTD 15
182 :     MMX_QUANTD 16
183 :     MMX_QUANTD 17
184 :     MMX_QUANTD 18
185 :     MMX_QUANTD 19
186 :     MMX_QUANTD 20
187 :     MMX_QUANTD 21
188 :     MMX_QUANTD 22
189 :     MMX_QUANTD 23
190 :     MMX_QUANTD 24
191 :     MMX_QUANTD 25
192 :     MMX_QUANTD 26
193 :     MMX_QUANTD 27
194 :     MMX_QUANTD 28
195 :     MMX_QUANTD 29
196 :     MMX_QUANTD 30
197 :     MMX_QUANTD 31
198 :    
199 :    
200 :     ;===========================================================================
201 :     ;
202 :     ; multiple by 2Q table
203 :     ;
204 :     ;===========================================================================
205 :    
206 :     %macro MMX_MUL_QUANT 1
207 :     times 4 dw %1
208 :     %endmacro
209 :    
210 :     mmx_mul_quant
211 :     MMX_MUL_QUANT 1
212 :     MMX_MUL_QUANT 2
213 :     MMX_MUL_QUANT 3
214 :     MMX_MUL_QUANT 4
215 :     MMX_MUL_QUANT 5
216 :     MMX_MUL_QUANT 6
217 :     MMX_MUL_QUANT 7
218 :     MMX_MUL_QUANT 8
219 :     MMX_MUL_QUANT 9
220 :     MMX_MUL_QUANT 10
221 :     MMX_MUL_QUANT 11
222 :     MMX_MUL_QUANT 12
223 :     MMX_MUL_QUANT 13
224 :     MMX_MUL_QUANT 14
225 :     MMX_MUL_QUANT 15
226 :     MMX_MUL_QUANT 16
227 :     MMX_MUL_QUANT 17
228 :     MMX_MUL_QUANT 18
229 :     MMX_MUL_QUANT 19
230 :     MMX_MUL_QUANT 20
231 :     MMX_MUL_QUANT 21
232 :     MMX_MUL_QUANT 22
233 :     MMX_MUL_QUANT 23
234 :     MMX_MUL_QUANT 24
235 :     MMX_MUL_QUANT 25
236 :     MMX_MUL_QUANT 26
237 :     MMX_MUL_QUANT 27
238 :     MMX_MUL_QUANT 28
239 :     MMX_MUL_QUANT 29
240 :     MMX_MUL_QUANT 30
241 :     MMX_MUL_QUANT 31
242 :    
243 :     ;===========================================================================
244 :     ;
245 :     ; saturation limits
246 :     ;
247 :     ;===========================================================================
248 :    
249 :     align 16
250 :    
251 : Isibaar 262 mmx_32767_minus_2047 times 4 dw (32767-2047)
252 :     mmx_32768_minus_2048 times 4 dw (32768-2048)
253 :     mmx_2047 times 4 dw 2047
254 :     mmx_minus_2048 times 4 dw (-2048)
255 :     zero times 4 dw 0
256 :    
257 : Isibaar 3 section .text
258 :    
259 :     ;===========================================================================
260 :     ;
261 :     ; void quant_intra4_mmx(int16_t * coeff,
262 :     ; const int16_t const * data,
263 :     ; const uint32_t quant,
264 :     ; const uint32_t dcscalar);
265 :     ;
266 :     ;===========================================================================
267 :    
268 :     align ALIGN
269 :     cglobal quant4_intra_mmx
270 :     quant4_intra_mmx
271 :    
272 :     push ecx
273 :     push esi
274 :     push edi
275 :    
276 :     mov edi, [esp + 12 + 4] ; coeff
277 :     mov esi, [esp + 12 + 8] ; data
278 :     mov eax, [esp + 12 + 12] ; quant
279 :    
280 :     movq mm5, [quantd + eax * 8 - 8] ; quantd -> mm5
281 :    
282 :     xor ecx, ecx
283 :     cmp al, 1
284 :     jz near .q1loop
285 :    
286 :     cmp al, 2
287 :     jz near .q2loop
288 :    
289 :     movq mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7
290 :    
291 :     align ALIGN
292 :     .loop
293 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
294 :     movq mm3, [esi + 8*ecx + 8] ;
295 :    
296 :     pxor mm1, mm1 ; mm1 = 0
297 :     pxor mm4, mm4
298 :    
299 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
300 :     pcmpgtw mm4, mm3
301 :    
302 :     pxor mm0, mm1 ; mm0 = |mm0|
303 :     pxor mm3, mm4 ;
304 :     psubw mm0, mm1 ; displace
305 :     psubw mm3, mm4 ;
306 :    
307 :     psllw mm0, 4 ; level << 4
308 :     psllw mm3, 4 ;
309 :    
310 : Isibaar 4 movq mm2, [intra_matrix + 8*ecx]
311 : Isibaar 3 psrlw mm2, 1 ; intra_matrix[i]>>1
312 :     paddw mm0, mm2
313 :    
314 : Isibaar 4 movq mm2, [intra_matrix_fix + ecx*8]
315 : Isibaar 3 pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
316 :    
317 : Isibaar 4 movq mm2, [intra_matrix + 8*ecx + 8]
318 : Isibaar 3 psrlw mm2, 1
319 :     paddw mm3, mm2
320 :    
321 : Isibaar 4 movq mm2, [intra_matrix_fix + ecx*8 + 8]
322 : Isibaar 3 pmulhw mm3, mm2
323 :    
324 :     paddw mm0, mm5 ; + quantd
325 :     paddw mm3, mm5
326 :    
327 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
328 :     pmulhw mm3, mm7 ;
329 :     psrlw mm0, 1 ; additional shift by 1 => 16 + 1 = 17
330 :     psrlw mm3, 1
331 :    
332 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
333 :     pxor mm3, mm4 ;
334 :     psubw mm0, mm1 ; undisplace
335 :     psubw mm3, mm4 ;
336 :    
337 :     movq [edi + 8*ecx], mm0
338 :     movq [edi + 8*ecx + 8], mm3
339 :    
340 :     add ecx,2
341 :     cmp ecx,16
342 :     jnz near .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 :    
375 :     pxor mm1, mm1 ; mm1 = 0
376 :     pxor mm4, mm4 ;
377 :    
378 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
379 :     pcmpgtw mm4, mm3 ;
380 :    
381 :     pxor mm0, mm1 ; mm0 = |mm0|
382 :     pxor mm3, mm4 ;
383 :     psubw mm0, mm1 ; displace
384 :     psubw mm3, mm4 ;
385 :    
386 :     psllw mm0, 4
387 :     psllw mm3, 4
388 :    
389 : Isibaar 4 movq mm2, [intra_matrix + 8*ecx]
390 : Isibaar 3 psrlw mm2, 1
391 :     paddw mm0, mm2
392 :    
393 : Isibaar 4 movq mm2, [intra_matrix_fix + ecx*8]
394 : Isibaar 3 pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
395 :    
396 : Isibaar 4 movq mm2, [intra_matrix + 8*ecx + 8]
397 : Isibaar 3 psrlw mm2, 1
398 :     paddw mm3, mm2
399 :    
400 : Isibaar 4 movq mm2, [intra_matrix_fix + ecx*8 + 8]
401 : Isibaar 3 pmulhw mm3, mm2
402 :    
403 :     paddw mm0, mm5
404 :     paddw mm3, mm5
405 :    
406 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
407 :     psrlw mm3, 1 ;
408 :    
409 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
410 :     pxor mm3, mm4 ;
411 :     psubw mm0, mm1 ; undisplace
412 :     psubw mm3, mm4 ;
413 :    
414 :     movq [edi + 8*ecx], mm0
415 :     movq [edi + 8*ecx + 8], mm3
416 :    
417 :     add ecx,2
418 :     cmp ecx,16
419 :     jnz near .q1loop
420 :     jmp near .done
421 :    
422 :    
423 :     align ALIGN
424 :     .q2loop
425 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
426 :     movq mm3, [esi + 8*ecx + 8] ;
427 :    
428 :     pxor mm1, mm1 ; mm1 = 0
429 :     pxor mm4, mm4 ;
430 :    
431 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
432 :     pcmpgtw mm4, mm3 ;
433 :    
434 :     pxor mm0, mm1 ; mm0 = |mm0|
435 :     pxor mm3, mm4 ;
436 :     psubw mm0, mm1 ; displace
437 :     psubw mm3, mm4 ;
438 :    
439 :     psllw mm0, 4
440 :     psllw mm3, 4
441 :    
442 : Isibaar 4 movq mm2, [intra_matrix + 8*ecx]
443 : Isibaar 3 psrlw mm2, 1
444 :     paddw mm0, mm2
445 :    
446 : Isibaar 4 movq mm2, [intra_matrix_fix + ecx*8]
447 : Isibaar 3 pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
448 :    
449 : Isibaar 4 movq mm2, [intra_matrix + 8*ecx + 8]
450 : Isibaar 3 psrlw mm2, 1
451 :     paddw mm3, mm2
452 :    
453 : Isibaar 4 movq mm2, [intra_matrix_fix + ecx*8 + 8]
454 : Isibaar 3 pmulhw mm3, mm2
455 :    
456 :     paddw mm0, mm5
457 :     paddw mm3, mm5
458 :    
459 :     psrlw mm0, 2 ; mm0 >>= 1 (/4)
460 :     psrlw mm3, 2 ;
461 :    
462 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
463 :     pxor mm3, mm4 ;
464 :     psubw mm0, mm1 ; undisplace
465 :     psubw mm3, mm4 ;
466 :    
467 :     movq [edi + 8*ecx], mm0
468 :     movq [edi + 8*ecx + 8], mm3
469 :    
470 :     add ecx,2
471 :     cmp ecx,16
472 :     jnz near .q2loop
473 :     jmp near .done
474 :    
475 :    
476 :     ;===========================================================================
477 :     ;
478 :     ; uint32_t quant4_inter_mmx(int16_t * coeff,
479 :     ; const int16_t const * data,
480 :     ; const uint32_t quant);
481 :     ;
482 :     ;===========================================================================
483 :    
484 :     align ALIGN
485 :     cglobal quant4_inter_mmx
486 :     quant4_inter_mmx
487 :    
488 :     push ecx
489 :     push esi
490 :     push edi
491 :    
492 :     mov edi, [esp + 12 + 4] ; coeff
493 :     mov esi, [esp + 12 + 8] ; data
494 :     mov eax, [esp + 12 + 12] ; quant
495 :    
496 :     xor ecx, ecx
497 :    
498 :     pxor mm5, mm5 ; sum
499 :    
500 :     cmp al, 1
501 :     jz near .q1loop
502 :    
503 :     cmp al, 2
504 :     jz near .q2loop
505 :    
506 :     movq mm7, [mmx_div + eax * 8 - 8] ; divider
507 :    
508 :     align ALIGN
509 :     .loop
510 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
511 :     movq mm3, [esi + 8*ecx + 8] ;
512 :     pxor mm1, mm1 ; mm1 = 0
513 :     pxor mm4, mm4 ;
514 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
515 :     pcmpgtw mm4, mm3 ;
516 :     pxor mm0, mm1 ; mm0 = |mm0|
517 :     pxor mm3, mm4 ;
518 :     psubw mm0, mm1 ; displace
519 :     psubw mm3, mm4 ;
520 :    
521 :     psllw mm0, 4
522 :     psllw mm3, 4
523 :    
524 : Isibaar 4 movq mm2, [inter_matrix + 8*ecx]
525 : Isibaar 3 psrlw mm2, 1
526 :     paddw mm0, mm2
527 :    
528 : Isibaar 4 movq mm2, [inter_matrix_fix + ecx*8]
529 : Isibaar 3 pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
530 :    
531 : Isibaar 4 movq mm2, [inter_matrix + 8*ecx + 8]
532 : Isibaar 3 psrlw mm2, 1
533 :     paddw mm3, mm2
534 :    
535 : Isibaar 4 movq mm2, [inter_matrix_fix + ecx*8 + 8]
536 : Isibaar 3 pmulhw mm3, mm2
537 :    
538 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
539 :     pmulhw mm3, mm7 ;
540 :     psrlw mm0, 1 ; additional shift by 1 => 16 + 1 = 17
541 :     psrlw mm3, 1
542 :    
543 :     paddw mm5, mm0 ; sum += mm0
544 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
545 :     paddw mm5, mm3 ;
546 :     pxor mm3, mm4 ;
547 :     psubw mm0, mm1 ; undisplace
548 :     psubw mm3, mm4
549 :     movq [edi + 8*ecx], mm0
550 :     movq [edi + 8*ecx + 8], mm3
551 :    
552 :     add ecx, 2
553 :     cmp ecx, 16
554 :     jnz near .loop
555 :    
556 :     .done
557 :     pmaddwd mm5, [mmx_one]
558 :     movq mm0, mm5
559 :     psrlq mm5, 32
560 :     paddd mm0, mm5
561 :     movd eax, mm0 ; return sum
562 :    
563 :     pop edi
564 :     pop esi
565 :     pop ecx
566 :    
567 :     ret
568 :    
569 :     align ALIGN
570 :     .q1loop
571 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
572 :     movq mm3, [esi + 8*ecx+ 8]
573 :     ;
574 :     pxor mm1, mm1 ; mm1 = 0
575 :     pxor mm4, mm4 ;
576 :    
577 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
578 :     pcmpgtw mm4, mm3 ;
579 :    
580 :     pxor mm0, mm1 ; mm0 = |mm0|
581 :     pxor mm3, mm4 ;
582 :     psubw mm0, mm1 ; displace
583 :     psubw mm3, mm4 ;
584 :    
585 :     psllw mm0, 4
586 :     psllw mm3, 4
587 :    
588 : Isibaar 4 movq mm2, [inter_matrix + 8*ecx]
589 : Isibaar 3 psrlw mm2, 1
590 :     paddw mm0, mm2
591 :    
592 : Isibaar 4 movq mm2, [inter_matrix_fix + ecx*8]
593 : Isibaar 3 pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
594 :    
595 : Isibaar 4 movq mm2, [inter_matrix + 8*ecx + 8]
596 : Isibaar 3 psrlw mm2, 1
597 :     paddw mm3, mm2
598 :    
599 : Isibaar 4 movq mm2, [inter_matrix_fix + ecx*8 + 8]
600 : Isibaar 3 pmulhw mm3, mm2
601 :    
602 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
603 :     psrlw mm3, 1 ;
604 :    
605 :     paddw mm5, mm0 ; sum += mm0
606 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
607 :     paddw mm5, mm3 ;
608 :     pxor mm3, mm4 ;
609 :     psubw mm0, mm1 ; undisplace
610 :     psubw mm3, mm4
611 :    
612 :     movq [edi + 8*ecx], mm0
613 :     movq [edi + 8*ecx + 8], mm3
614 :    
615 :     add ecx,2
616 :     cmp ecx,16
617 :     jnz near .q1loop
618 :    
619 :     jmp .done
620 :    
621 :    
622 :     align ALIGN
623 :     .q2loop
624 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
625 :     movq mm3, [esi + 8*ecx+ 8]
626 :     ;
627 :     pxor mm1, mm1 ; mm1 = 0
628 :     pxor mm4, mm4 ;
629 :    
630 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
631 :     pcmpgtw mm4, mm3 ;
632 :    
633 :     pxor mm0, mm1 ; mm0 = |mm0|
634 :     pxor mm3, mm4 ;
635 :     psubw mm0, mm1 ; displace
636 :     psubw mm3, mm4 ;
637 :    
638 :     psllw mm0, 4
639 :     psllw mm3, 4
640 :    
641 : Isibaar 4 movq mm2, [inter_matrix + 8*ecx]
642 : Isibaar 3 psrlw mm2, 1
643 :     paddw mm0, mm2
644 :    
645 : Isibaar 4 movq mm2, [inter_matrix_fix + ecx*8]
646 : Isibaar 3 pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
647 :    
648 : Isibaar 4 movq mm2, [inter_matrix + 8*ecx + 8]
649 : Isibaar 3 psrlw mm2, 1
650 :     paddw mm3, mm2
651 :    
652 : Isibaar 4 movq mm2, [inter_matrix_fix + ecx*8 + 8]
653 : Isibaar 3 pmulhw mm3, mm2
654 :    
655 :     psrlw mm0, 2 ; mm0 >>= 1 (/2)
656 :     psrlw mm3, 2 ;
657 :    
658 :     paddw mm5, mm0 ; sum += mm0
659 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
660 :     paddw mm5, mm3 ;
661 :     pxor mm3, mm4 ;
662 :     psubw mm0, mm1 ; undisplace
663 :     psubw mm3, mm4
664 :    
665 :     movq [edi + 8*ecx], mm0
666 :     movq [edi + 8*ecx + 8], mm3
667 :    
668 :     add ecx,2
669 :     cmp ecx,16
670 :     jnz near .q2loop
671 :    
672 :     jmp .done
673 :    
674 :    
675 :     ;===========================================================================
676 :     ;
677 :     ; void dequant4_intra_mmx(int16_t *data,
678 :     ; const int16_t const *coeff,
679 :     ; const uint32_t quant,
680 :     ; const uint32_t dcscalar);
681 :     ;
682 :     ;===========================================================================
683 :    
684 : Isibaar 262 ; Note: in order to saturate 'easily', we pre-shift the quantifier
685 :     ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
686 :     ; build a saturating mask. It is non-zero only when an overflow occured.
687 :     ; We thus avoid packing/unpacking toward double-word.
688 :     ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
689 :     ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
690 :     ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
691 :     ; and quant in [1..31].
692 :     ;
693 :     ; The original loop is:
694 :     ;
695 :     %if 0
696 :     movq mm0, [ecx+8*eax + 8*16] ; mm0 = coeff[i]
697 :     pxor mm1, mm1
698 :     pcmpgtw mm1, mm0
699 :     pxor mm0, mm1 ; change sign if negative
700 :     psubw mm0, mm1 ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
701 :    
702 :     movq mm2, mm7 ; mm2 = quant
703 :     pmullw mm2, [intra_matrix + 8*eax + 8*16 ] ; matrix[i]*quant.
704 :    
705 :     movq mm6, mm2
706 :     pmulhw mm2, mm0 ; high of coeff*(matrix*quant) (should be 0 if no overflow)
707 :     pmullw mm0, mm6 ; low of coeff*(matrix*quant)
708 :    
709 :     pxor mm5, mm5
710 :     pcmpgtw mm2, mm5 ; otherflow?
711 :     psrlw mm2, 5 ; =0 if no clamp, 2047 otherwise
712 :     psrlw mm0, 5
713 :     paddw mm0, mm1 ; start restoring sign
714 :     por mm0, mm2 ; saturate to 2047 if needed
715 :     pxor mm0, mm1 ; finish negating back
716 :    
717 :     movq [edx + 8*eax + 8*16], mm0 ; data[i]
718 :     add eax, 1
719 :     %endif
720 :    
721 :     ;********************************************************************
722 :    
723 : Isibaar 3 align 16
724 :     cglobal dequant4_intra_mmx
725 : Isibaar 262 dequant4_intra_mmx:
726 : Isibaar 3
727 : Isibaar 262 mov edx, [esp+4] ; data
728 :     mov ecx, [esp+8] ; coeff
729 :     mov eax, [esp+12] ; quant
730 : Isibaar 3
731 : Isibaar 262 movq mm7, [mmx_mul_quant + eax*8 - 8]
732 :     mov eax, -16 ; to keep aligned, we regularly process coeff[0]
733 :     psllw mm7, 2 ; << 2. See comment.
734 :     pxor mm6, mm6 ; this is a NOP
735 : Isibaar 3
736 : Isibaar 262 align 16
737 : Isibaar 3 .loop
738 : Isibaar 262 movq mm0, [ecx+8*eax + 8*16] ; mm0 = c = coeff[i]
739 :     movq mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]
740 :     pxor mm1, mm1
741 :     pxor mm4, mm4
742 :     pcmpgtw mm1, mm0 ; mm1 = sgn(c)
743 :     movq mm2, mm7 ; mm2 = quant
744 :    
745 :     pcmpgtw mm4, mm3 ; mm4 = sgn(c')
746 :     pmullw mm2, [intra_matrix + 8*eax + 8*16 ] ; matrix[i]*quant
747 : Isibaar 3
748 : Isibaar 262 pxor mm0, mm1 ; negate if negative
749 :     pxor mm3, mm4 ; negate if negative
750 :    
751 :     psubw mm0, mm1
752 :     psubw mm3, mm4
753 :    
754 :     ; we're short on register, here. Poor pairing...
755 : Isibaar 3
756 : Isibaar 262 movq mm5, mm2
757 :     pmullw mm2, mm0 ; low of coeff*(matrix*quant)
758 : Isibaar 3
759 : Isibaar 262 pmulhw mm0, mm5 ; high of coeff*(matrix*quant)
760 :     movq mm5, mm7 ; mm2 = quant
761 : Isibaar 3
762 : Isibaar 262 pmullw mm5, [intra_matrix + 8*eax + 8*16 +8] ; matrix[i+1]*quant
763 : Isibaar 3
764 : Isibaar 262 movq mm6, mm5
765 :     add eax,2 ; z-flag will be tested later
766 : Isibaar 3
767 : Isibaar 262 pmullw mm6, mm3 ; low of coeff*(matrix*quant)
768 :     pmulhw mm3, mm5 ; high of coeff*(matrix*quant)
769 : Isibaar 3
770 : Isibaar 262 pcmpgtw mm0, [zero]
771 :     paddusw mm2, mm0
772 :     psrlw mm2, 5
773 : Isibaar 3
774 : Isibaar 262 pcmpgtw mm3, [zero]
775 :     paddusw mm6, mm3
776 :     psrlw mm6, 5
777 : Isibaar 3
778 : Isibaar 262 pxor mm2, mm1 ; start negating back
779 :     pxor mm6, mm4 ; start negating back
780 : Isibaar 3
781 : Isibaar 262 psubusw mm1, mm0
782 :     psubusw mm4, mm3
783 : Isibaar 3
784 : Isibaar 262 psubw mm2, mm1 ; finish negating back
785 :     psubw mm6, mm4 ; finish negating back
786 : Isibaar 3
787 : Isibaar 262 movq [edx + 8*eax + 8*16 -2*8 ], mm2 ; data[i]
788 :     movq [edx + 8*eax + 8*16 -2*8 +8], mm6 ; data[i+1]
789 : Isibaar 3
790 : Isibaar 268 jnz near .loop
791 : Isibaar 3
792 : Isibaar 262 ; deal with DC
793 : Isibaar 3
794 : Isibaar 262 movd mm0, [ecx]
795 :     pmullw mm0, [esp+16] ; dcscalar
796 :     movq mm2, [mmx_32767_minus_2047]
797 :     paddsw mm0, mm2
798 :     psubsw mm0, mm2
799 :     movq mm2, [mmx_32768_minus_2048]
800 :     psubsw mm0, mm2
801 :     paddsw mm0, mm2
802 :     movd eax, mm0
803 :     mov [edx], ax
804 : Isibaar 3
805 : Isibaar 262 ret
806 :    
807 : Isibaar 3 ;===========================================================================
808 :     ;
809 :     ; void dequant4_inter_mmx(int16_t * data,
810 :     ; const int16_t * const coeff,
811 :     ; const uint32_t quant);
812 :     ;
813 :     ;===========================================================================
814 :    
815 : Isibaar 262 ; Note: We use (2*c + sgn(c) - sgn(-c)) as multiplier
816 :     ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
817 :     ; sgn(x) is the result of 'pcmpgtw 0,x': 0 if x>=0, -1 if x<0.
818 :     ; It's mixed with the extraction of the absolute value.
819 :    
820 : Isibaar 3 align 16
821 :     cglobal dequant4_inter_mmx
822 : Isibaar 262 dequant4_inter_mmx:
823 : Isibaar 3
824 : Isibaar 262 mov edx, [esp+ 4] ; data
825 :     mov ecx, [esp+ 8] ; coeff
826 :     mov eax, [esp+12] ; quant
827 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
828 :     mov eax, -16
829 :     paddw mm7, mm7 ; << 1
830 :     pxor mm6, mm6 ; mismatch sum
831 : Isibaar 3
832 : Isibaar 262 align 16
833 : Isibaar 3 .loop
834 : Isibaar 262 movq mm0, [ecx+8*eax + 8*16 ] ; mm0 = coeff[i]
835 :     movq mm2, [ecx+8*eax + 8*16 +8] ; mm2 = coeff[i+1]
836 :     add eax,2
837 : Isibaar 3
838 : Isibaar 262 pxor mm1, mm1
839 :     pxor mm3, mm3
840 :     pcmpgtw mm1, mm0 ; mm1 = sgn(c) (preserved)
841 :     pcmpgtw mm3, mm2 ; mm3 = sgn(c') (preserved)
842 :     paddsw mm0, mm1 ; c += sgn(c)
843 :     paddsw mm2, mm3 ; c += sgn(c')
844 :     paddw mm0, mm0 ; c *= 2
845 :     paddw mm2, mm2 ; c'*= 2
846 : Isibaar 3
847 : Isibaar 262 pxor mm4, mm4
848 :     pxor mm5, mm5
849 :     psubw mm4, mm0 ; -c
850 :     psubw mm5, mm2 ; -c'
851 :     psraw mm4, 16 ; mm4 = sgn(-c)
852 :     psraw mm5, 16 ; mm5 = sgn(-c')
853 :     psubsw mm0, mm4 ; c -= sgn(-c)
854 :     psubsw mm2, mm5 ; c' -= sgn(-c')
855 :     pxor mm0, mm1 ; finish changing sign if needed
856 :     pxor mm2, mm3 ; finish changing sign if needed
857 : Isibaar 3
858 : Isibaar 262 ; we're short on register, here. Poor pairing...
859 : Isibaar 3
860 : Isibaar 262 movq mm4, mm7 ; (matrix*quant)
861 :     pmullw mm4, [inter_matrix + 8*eax + 8*16 -2*8]
862 :     movq mm5, mm4
863 :     pmulhw mm5, mm0 ; high of c*(matrix*quant)
864 :     pmullw mm0, mm4 ; low of c*(matrix*quant)
865 : Isibaar 3
866 : Isibaar 262 movq mm4, mm7 ; (matrix*quant)
867 :     pmullw mm4, [inter_matrix + 8*eax + 8*16 -2*8 + 8]
868 : Isibaar 3
869 : Isibaar 262 pcmpgtw mm5, [zero]
870 :     paddusw mm0, mm5
871 :     psrlw mm0, 5
872 :     pxor mm0, mm1 ; start restoring sign
873 :     psubusw mm1, mm5
874 : Isibaar 3
875 : Isibaar 262 movq mm5, mm4
876 :     pmulhw mm5, mm2 ; high of c*(matrix*quant)
877 :     pmullw mm2, mm4 ; low of c*(matrix*quant)
878 :     psubw mm0, mm1 ; finish restoring sign
879 : Isibaar 3
880 : Isibaar 262 pcmpgtw mm5, [zero]
881 :     paddusw mm2, mm5
882 :     psrlw mm2, 5
883 :     pxor mm2, mm3 ; start restoring sign
884 :     psubusw mm3, mm5
885 :     psubw mm2, mm3 ; finish restoring sign
886 : Isibaar 3
887 : Isibaar 262 pxor mm6, mm0 ; mismatch control
888 :     movq [edx + 8*eax + 8*16 -2*8 ], mm0 ; data[i]
889 :     pxor mm6, mm2 ; mismatch control
890 :     movq [edx + 8*eax + 8*16 -2*8 +8], mm2 ; data[i+1]
891 : Isibaar 3
892 : Isibaar 268 jnz near .loop
893 : Isibaar 3
894 : Isibaar 262 ; mismatch control
895 : Isibaar 3
896 : Isibaar 262 movq mm0, mm6
897 :     psrlq mm0, 48
898 :     movq mm1, mm6
899 :     movq mm2, mm6
900 :     psrlq mm1, 32
901 :     pxor mm6, mm0
902 :     psrlq mm2, 16
903 :     pxor mm6, mm1
904 :     pxor mm6, mm2
905 :     movd eax, mm6
906 :     and eax, 1
907 :     xor eax, 1
908 :     xor word [edx + 2*63], ax
909 : Isibaar 3
910 : Isibaar 262 ret
911 : Isibaar 3

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