[svn] / branches / dev-api-4 / xvidcore / src / quant / x86_asm / quantize4_mmx.asm Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/src/quant/x86_asm/quantize4_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 886 - (view) (download)

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

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