[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 3 - (view) (download)

1 : Isibaar 3 ;/******************************************************************************
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 :     ; * 22.01.2002 initial version *
46 :     ; * *
47 :     ; ******************************************************************************/
48 :    
49 :     ; data/text alignment
50 :     %define ALIGN 8
51 :    
52 :     %define SATURATE
53 :    
54 :     bits 32
55 :    
56 :     section .data
57 :    
58 :     %macro cglobal 1
59 :     %ifdef PREFIX
60 :     global _%1
61 :     %define %1 _%1
62 :     %else
63 :     global %1
64 :     %endif
65 :     %endmacro
66 :    
67 :     mmx_one times 4 dw 1
68 :    
69 :     ;===========================================================================
70 :     ;
71 :     ; divide by 2Q table
72 :     ;
73 :     ;===========================================================================
74 :    
75 :     %macro MMX_DIV 1
76 :     times 4 dw (1 << 17) / (%1 * 2) + 1
77 :     %endmacro
78 :    
79 :     align ALIGN
80 :     mmx_div
81 :     MMX_DIV 1
82 :     MMX_DIV 2
83 :     MMX_DIV 3
84 :     MMX_DIV 4
85 :     MMX_DIV 5
86 :     MMX_DIV 6
87 :     MMX_DIV 7
88 :     MMX_DIV 8
89 :     MMX_DIV 9
90 :     MMX_DIV 10
91 :     MMX_DIV 11
92 :     MMX_DIV 12
93 :     MMX_DIV 13
94 :     MMX_DIV 14
95 :     MMX_DIV 15
96 :     MMX_DIV 16
97 :     MMX_DIV 17
98 :     MMX_DIV 18
99 :     MMX_DIV 19
100 :     MMX_DIV 20
101 :     MMX_DIV 21
102 :     MMX_DIV 22
103 :     MMX_DIV 23
104 :     MMX_DIV 24
105 :     MMX_DIV 25
106 :     MMX_DIV 26
107 :     MMX_DIV 27
108 :     MMX_DIV 28
109 :     MMX_DIV 29
110 :     MMX_DIV 30
111 :     MMX_DIV 31
112 :    
113 :    
114 :     ;===========================================================================
115 :     ;
116 :     ; default intra matrix
117 :     ;
118 :     ;===========================================================================
119 :    
120 :     mmx_intra_matrix
121 :     dw 8, 17, 18, 19
122 :     dw 21, 23, 25, 27
123 :     dw 17, 18, 19, 21
124 :     dw 23, 25, 27, 28
125 :     dw 20, 21, 22, 23
126 :     dw 24, 26, 28, 30
127 :     dw 21, 22, 23, 24
128 :     dw 26, 28, 30, 32
129 :     dw 22, 23, 24, 26
130 :     dw 28, 30, 32, 35
131 :     dw 23, 24, 26, 28
132 :     dw 30, 32, 35, 38
133 :     dw 25, 26, 28, 30
134 :     dw 32, 35, 38, 41
135 :     dw 27, 28, 30, 32
136 :     dw 35, 38, 41, 45
137 :    
138 :     %macro MMX_FIX 4
139 :     dw (1 << 16) / (%1) + 1, (1 << 16) / (%2) + 1, (1 << 16) / (%3) + 1, (1 << 16) / (%4) + 1
140 :     %endmacro
141 :    
142 :     mmx_intra_matrix_fix
143 :     MMX_FIX 8, 17, 18, 19
144 :     MMX_FIX 21, 23, 25, 27
145 :     MMX_FIX 17, 18, 19, 21
146 :     MMX_FIX 23, 25, 27, 28
147 :     MMX_FIX 20, 21, 22, 23
148 :     MMX_FIX 24, 26, 28, 30
149 :     MMX_FIX 21, 22, 23, 24
150 :     MMX_FIX 26, 28, 30, 32
151 :     MMX_FIX 22, 23, 24, 26
152 :     MMX_FIX 28, 30, 32, 35
153 :     MMX_FIX 23, 24, 26, 28
154 :     MMX_FIX 30, 32, 35, 38
155 :     MMX_FIX 25, 26, 28, 30
156 :     MMX_FIX 32, 35, 38, 41
157 :     MMX_FIX 27, 28, 30, 32
158 :     MMX_FIX 35, 38, 41, 45
159 :    
160 :    
161 :     ;===========================================================================
162 :     ;
163 :     ; default inter matrix
164 :     ;
165 :     ;===========================================================================
166 :    
167 :     mmx_inter_matrix
168 :     dw 16,17,18,19
169 :     dw 20,21,22,23
170 :     dw 17,18,19,20
171 :     dw 21,22,23,24
172 :     dw 18,19,20,21
173 :     dw 22,23,24,25
174 :     dw 19,20,21,22
175 :     dw 23,24,26,27
176 :     dw 20,21,22,23
177 :     dw 25,26,27,28
178 :     dw 21,22,23,24
179 :     dw 26,27,28,30
180 :     dw 22,23,24,26
181 :     dw 27,28,30,31
182 :     dw 23,24,25,27
183 :     dw 28,30,31,33
184 :    
185 :    
186 :     mmx_inter_matrix_fix
187 :     MMX_FIX 16,17,18,19
188 :     MMX_FIX 20,21,22,23
189 :     MMX_FIX 17,18,19,20
190 :     MMX_FIX 21,22,23,24
191 :     MMX_FIX 18,19,20,21
192 :     MMX_FIX 22,23,24,25
193 :     MMX_FIX 19,20,21,22
194 :     MMX_FIX 23,24,26,27
195 :     MMX_FIX 20,21,22,23
196 :     MMX_FIX 25,26,27,28
197 :     MMX_FIX 21,22,23,24
198 :     MMX_FIX 26,27,28,30
199 :     MMX_FIX 22,23,24,26
200 :     MMX_FIX 27,28,30,31
201 :     MMX_FIX 23,24,25,27
202 :     MMX_FIX 28,30,31,33
203 :    
204 :     %define VM18P 3
205 :     %define VM18Q 4
206 :    
207 :     ;===========================================================================
208 :     ;
209 :     ; quantd table
210 :     ;
211 :     ;===========================================================================
212 :    
213 :     %macro MMX_QUANTD 1
214 :     times 4 dw ((VM18P*%1) + (VM18Q/2)) / VM18Q
215 :     %endmacro
216 :    
217 :     quantd
218 :     MMX_QUANTD 1
219 :     MMX_QUANTD 2
220 :     MMX_QUANTD 3
221 :     MMX_QUANTD 4
222 :     MMX_QUANTD 5
223 :     MMX_QUANTD 6
224 :     MMX_QUANTD 7
225 :     MMX_QUANTD 8
226 :     MMX_QUANTD 9
227 :     MMX_QUANTD 10
228 :     MMX_QUANTD 11
229 :     MMX_QUANTD 12
230 :     MMX_QUANTD 13
231 :     MMX_QUANTD 14
232 :     MMX_QUANTD 15
233 :     MMX_QUANTD 16
234 :     MMX_QUANTD 17
235 :     MMX_QUANTD 18
236 :     MMX_QUANTD 19
237 :     MMX_QUANTD 20
238 :     MMX_QUANTD 21
239 :     MMX_QUANTD 22
240 :     MMX_QUANTD 23
241 :     MMX_QUANTD 24
242 :     MMX_QUANTD 25
243 :     MMX_QUANTD 26
244 :     MMX_QUANTD 27
245 :     MMX_QUANTD 28
246 :     MMX_QUANTD 29
247 :     MMX_QUANTD 30
248 :     MMX_QUANTD 31
249 :    
250 :    
251 :     ;===========================================================================
252 :     ;
253 :     ; multiple by matrix table
254 :     ;
255 :     ;===========================================================================
256 :    
257 :     %macro MMX_MUL 4
258 :     dw %1
259 :     dw %2
260 :     dw %3
261 :     dw %4
262 :     %endmacro
263 :    
264 :     default_inter_matrix_mul
265 :     MMX_MUL 16,17,18,19
266 :     MMX_MUL 20,21,22,23
267 :     MMX_MUL 17,18,19,20
268 :     MMX_MUL 21,22,23,24
269 :     MMX_MUL 18,19,20,21
270 :     MMX_MUL 22,23,24,25
271 :     MMX_MUL 19,20,21,22
272 :     MMX_MUL 23,24,26,27
273 :     MMX_MUL 20,21,22,23
274 :     MMX_MUL 25,26,27,28
275 :     MMX_MUL 21,22,23,24
276 :     MMX_MUL 26,27,28,30
277 :     MMX_MUL 22,23,24,26
278 :     MMX_MUL 27,28,30,31
279 :     MMX_MUL 23,24,25,27
280 :     MMX_MUL 28,30,31,33
281 :    
282 :    
283 :     default_intra_matrix_mul
284 :     MMX_MUL 8,17,18,19
285 :     MMX_MUL 21,23,25,27
286 :     MMX_MUL 17,18,19,21
287 :     MMX_MUL 23,25,27,28
288 :     MMX_MUL 20,21,22,23
289 :     MMX_MUL 24,26,28,30
290 :     MMX_MUL 21,22,23,24
291 :     MMX_MUL 26,28,30,32
292 :     MMX_MUL 22,23,24,26
293 :     MMX_MUL 28,30,32,35
294 :     MMX_MUL 23,24,26,28
295 :     MMX_MUL 30,32,35,38
296 :     MMX_MUL 25,26,28,30
297 :     MMX_MUL 32,35,38,41
298 :     MMX_MUL 27,28,30,32
299 :     MMX_MUL 35,38,41,45
300 :    
301 :    
302 :     ;===========================================================================
303 :     ;
304 :     ; multiple by 2Q table
305 :     ;
306 :     ;===========================================================================
307 :    
308 :     %macro MMX_MUL_QUANT 1
309 :     times 4 dw %1
310 :     %endmacro
311 :    
312 :     mmx_mul_quant
313 :     MMX_MUL_QUANT 1
314 :     MMX_MUL_QUANT 2
315 :     MMX_MUL_QUANT 3
316 :     MMX_MUL_QUANT 4
317 :     MMX_MUL_QUANT 5
318 :     MMX_MUL_QUANT 6
319 :     MMX_MUL_QUANT 7
320 :     MMX_MUL_QUANT 8
321 :     MMX_MUL_QUANT 9
322 :     MMX_MUL_QUANT 10
323 :     MMX_MUL_QUANT 11
324 :     MMX_MUL_QUANT 12
325 :     MMX_MUL_QUANT 13
326 :     MMX_MUL_QUANT 14
327 :     MMX_MUL_QUANT 15
328 :     MMX_MUL_QUANT 16
329 :     MMX_MUL_QUANT 17
330 :     MMX_MUL_QUANT 18
331 :     MMX_MUL_QUANT 19
332 :     MMX_MUL_QUANT 20
333 :     MMX_MUL_QUANT 21
334 :     MMX_MUL_QUANT 22
335 :     MMX_MUL_QUANT 23
336 :     MMX_MUL_QUANT 24
337 :     MMX_MUL_QUANT 25
338 :     MMX_MUL_QUANT 26
339 :     MMX_MUL_QUANT 27
340 :     MMX_MUL_QUANT 28
341 :     MMX_MUL_QUANT 29
342 :     MMX_MUL_QUANT 30
343 :     MMX_MUL_QUANT 31
344 :    
345 :     ;===========================================================================
346 :     ;
347 :     ; saturation limits
348 :     ;
349 :     ;===========================================================================
350 :    
351 :     align 16
352 :     mmx_32768_minus_2048 times 4 dw (32768-2048)
353 :     mmx_32767_minus_2047 times 4 dw (32767-2047)
354 :    
355 :     section .text
356 :    
357 :     ;===========================================================================
358 :     ;
359 :     ; void quant_intra4_mmx(int16_t * coeff,
360 :     ; const int16_t const * data,
361 :     ; const uint32_t quant,
362 :     ; const uint32_t dcscalar);
363 :     ;
364 :     ;===========================================================================
365 :    
366 :     align ALIGN
367 :     cglobal quant4_intra_mmx
368 :     quant4_intra_mmx
369 :    
370 :     push ecx
371 :     push esi
372 :     push edi
373 :    
374 :     mov edi, [esp + 12 + 4] ; coeff
375 :     mov esi, [esp + 12 + 8] ; data
376 :     mov eax, [esp + 12 + 12] ; quant
377 :    
378 :     movq mm5, [quantd + eax * 8 - 8] ; quantd -> mm5
379 :    
380 :     xor ecx, ecx
381 :     cmp al, 1
382 :     jz near .q1loop
383 :    
384 :     cmp al, 2
385 :     jz near .q2loop
386 :    
387 :     movq mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7
388 :    
389 :     align ALIGN
390 :     .loop
391 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
392 :     movq mm3, [esi + 8*ecx + 8] ;
393 :    
394 :     pxor mm1, mm1 ; mm1 = 0
395 :     pxor mm4, mm4
396 :    
397 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
398 :     pcmpgtw mm4, mm3
399 :    
400 :     pxor mm0, mm1 ; mm0 = |mm0|
401 :     pxor mm3, mm4 ;
402 :     psubw mm0, mm1 ; displace
403 :     psubw mm3, mm4 ;
404 :    
405 :     psllw mm0, 4 ; level << 4
406 :     psllw mm3, 4 ;
407 :    
408 :     movq mm2, [mmx_intra_matrix + 8*ecx]
409 :     psrlw mm2, 1 ; intra_matrix[i]>>1
410 :     paddw mm0, mm2
411 :    
412 :     movq mm2, [mmx_intra_matrix_fix + ecx*8]
413 :     pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
414 :    
415 :     movq mm2, [mmx_intra_matrix + 8*ecx + 8]
416 :     psrlw mm2, 1
417 :     paddw mm3, mm2
418 :    
419 :     movq mm2, [mmx_intra_matrix_fix + ecx*8 + 8]
420 :     pmulhw mm3, mm2
421 :    
422 :     paddw mm0, mm5 ; + quantd
423 :     paddw mm3, mm5
424 :    
425 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
426 :     pmulhw mm3, mm7 ;
427 :     psrlw mm0, 1 ; additional shift by 1 => 16 + 1 = 17
428 :     psrlw mm3, 1
429 :    
430 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
431 :     pxor mm3, mm4 ;
432 :     psubw mm0, mm1 ; undisplace
433 :     psubw mm3, mm4 ;
434 :    
435 :     movq [edi + 8*ecx], mm0
436 :     movq [edi + 8*ecx + 8], mm3
437 :    
438 :     add ecx,2
439 :     cmp ecx,16
440 :     jnz near .loop
441 :    
442 :     .done
443 :     ; caclulate data[0] // (int32_t)dcscalar)
444 :    
445 :     mov ecx, [esp + 12 + 16] ; dcscalar
446 :     mov edx, ecx
447 :     movsx eax, word [esi] ; data[0]
448 :     shr edx, 1 ; edx = dcscalar /2
449 :     cmp eax, 0
450 :     jg .gtzero
451 :    
452 :     sub eax, edx
453 :     jmp short .mul
454 :     .gtzero
455 :     add eax, edx
456 :     .mul
457 :     cdq ; expand eax -> edx:eax
458 :     idiv ecx ; eax = edx:eax / dcscalar
459 :    
460 :     mov [edi], ax ; coeff[0] = ax
461 :    
462 :     pop edi
463 :     pop esi
464 :     pop ecx
465 :    
466 :     ret
467 :    
468 :     align ALIGN
469 :     .q1loop
470 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
471 :     movq mm3, [esi + 8*ecx + 8] ;
472 :    
473 :     pxor mm1, mm1 ; mm1 = 0
474 :     pxor mm4, mm4 ;
475 :    
476 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
477 :     pcmpgtw mm4, mm3 ;
478 :    
479 :     pxor mm0, mm1 ; mm0 = |mm0|
480 :     pxor mm3, mm4 ;
481 :     psubw mm0, mm1 ; displace
482 :     psubw mm3, mm4 ;
483 :    
484 :     psllw mm0, 4
485 :     psllw mm3, 4
486 :    
487 :     movq mm2, [mmx_intra_matrix + 8*ecx]
488 :     psrlw mm2, 1
489 :     paddw mm0, mm2
490 :    
491 :     movq mm2, [mmx_intra_matrix_fix + ecx*8]
492 :     pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
493 :    
494 :     movq mm2, [mmx_intra_matrix + 8*ecx + 8]
495 :     psrlw mm2, 1
496 :     paddw mm3, mm2
497 :    
498 :     movq mm2, [mmx_intra_matrix_fix + ecx*8 + 8]
499 :     pmulhw mm3, mm2
500 :    
501 :     paddw mm0, mm5
502 :     paddw mm3, mm5
503 :    
504 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
505 :     psrlw mm3, 1 ;
506 :    
507 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
508 :     pxor mm3, mm4 ;
509 :     psubw mm0, mm1 ; undisplace
510 :     psubw mm3, mm4 ;
511 :    
512 :     movq [edi + 8*ecx], mm0
513 :     movq [edi + 8*ecx + 8], mm3
514 :    
515 :     add ecx,2
516 :     cmp ecx,16
517 :     jnz near .q1loop
518 :     jmp near .done
519 :    
520 :    
521 :     align ALIGN
522 :     .q2loop
523 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
524 :     movq mm3, [esi + 8*ecx + 8] ;
525 :    
526 :     pxor mm1, mm1 ; mm1 = 0
527 :     pxor mm4, mm4 ;
528 :    
529 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
530 :     pcmpgtw mm4, mm3 ;
531 :    
532 :     pxor mm0, mm1 ; mm0 = |mm0|
533 :     pxor mm3, mm4 ;
534 :     psubw mm0, mm1 ; displace
535 :     psubw mm3, mm4 ;
536 :    
537 :     psllw mm0, 4
538 :     psllw mm3, 4
539 :    
540 :     movq mm2, [mmx_intra_matrix + 8*ecx]
541 :     psrlw mm2, 1
542 :     paddw mm0, mm2
543 :    
544 :     movq mm2, [mmx_intra_matrix_fix + ecx*8]
545 :     pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
546 :    
547 :     movq mm2, [mmx_intra_matrix + 8*ecx + 8]
548 :     psrlw mm2, 1
549 :     paddw mm3, mm2
550 :    
551 :     movq mm2, [mmx_intra_matrix_fix + ecx*8 + 8]
552 :     pmulhw mm3, mm2
553 :    
554 :     paddw mm0, mm5
555 :     paddw mm3, mm5
556 :    
557 :     psrlw mm0, 2 ; mm0 >>= 1 (/4)
558 :     psrlw mm3, 2 ;
559 :    
560 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
561 :     pxor mm3, mm4 ;
562 :     psubw mm0, mm1 ; undisplace
563 :     psubw mm3, mm4 ;
564 :    
565 :     movq [edi + 8*ecx], mm0
566 :     movq [edi + 8*ecx + 8], mm3
567 :    
568 :     add ecx,2
569 :     cmp ecx,16
570 :     jnz near .q2loop
571 :     jmp near .done
572 :    
573 :    
574 :     ;===========================================================================
575 :     ;
576 :     ; uint32_t quant4_inter_mmx(int16_t * coeff,
577 :     ; const int16_t const * data,
578 :     ; const uint32_t quant);
579 :     ;
580 :     ;===========================================================================
581 :    
582 :     align ALIGN
583 :     cglobal quant4_inter_mmx
584 :     quant4_inter_mmx
585 :    
586 :     push ecx
587 :     push esi
588 :     push edi
589 :    
590 :     mov edi, [esp + 12 + 4] ; coeff
591 :     mov esi, [esp + 12 + 8] ; data
592 :     mov eax, [esp + 12 + 12] ; quant
593 :    
594 :     xor ecx, ecx
595 :    
596 :     pxor mm5, mm5 ; sum
597 :    
598 :     cmp al, 1
599 :     jz near .q1loop
600 :    
601 :     cmp al, 2
602 :     jz near .q2loop
603 :    
604 :     movq mm7, [mmx_div + eax * 8 - 8] ; divider
605 :    
606 :     align ALIGN
607 :     .loop
608 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
609 :     movq mm3, [esi + 8*ecx + 8] ;
610 :     pxor mm1, mm1 ; mm1 = 0
611 :     pxor mm4, mm4 ;
612 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
613 :     pcmpgtw mm4, mm3 ;
614 :     pxor mm0, mm1 ; mm0 = |mm0|
615 :     pxor mm3, mm4 ;
616 :     psubw mm0, mm1 ; displace
617 :     psubw mm3, mm4 ;
618 :    
619 :     psllw mm0, 4
620 :     psllw mm3, 4
621 :    
622 :     movq mm2, [mmx_inter_matrix + 8*ecx]
623 :     psrlw mm2, 1
624 :     paddw mm0, mm2
625 :    
626 :     movq mm2, [mmx_inter_matrix_fix + ecx*8]
627 :     pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
628 :    
629 :     movq mm2, [mmx_inter_matrix + 8*ecx + 8]
630 :     psrlw mm2, 1
631 :     paddw mm3, mm2
632 :    
633 :     movq mm2, [mmx_inter_matrix_fix + ecx*8 + 8]
634 :     pmulhw mm3, mm2
635 :    
636 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
637 :     pmulhw mm3, mm7 ;
638 :     psrlw mm0, 1 ; additional shift by 1 => 16 + 1 = 17
639 :     psrlw mm3, 1
640 :    
641 :     paddw mm5, mm0 ; sum += mm0
642 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
643 :     paddw mm5, mm3 ;
644 :     pxor mm3, mm4 ;
645 :     psubw mm0, mm1 ; undisplace
646 :     psubw mm3, mm4
647 :     movq [edi + 8*ecx], mm0
648 :     movq [edi + 8*ecx + 8], mm3
649 :    
650 :     add ecx, 2
651 :     cmp ecx, 16
652 :     jnz near .loop
653 :    
654 :     .done
655 :     pmaddwd mm5, [mmx_one]
656 :     movq mm0, mm5
657 :     psrlq mm5, 32
658 :     paddd mm0, mm5
659 :     movd eax, mm0 ; return sum
660 :    
661 :     pop edi
662 :     pop esi
663 :     pop ecx
664 :    
665 :     ret
666 :    
667 :     align ALIGN
668 :     .q1loop
669 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
670 :     movq mm3, [esi + 8*ecx+ 8]
671 :     ;
672 :     pxor mm1, mm1 ; mm1 = 0
673 :     pxor mm4, mm4 ;
674 :    
675 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
676 :     pcmpgtw mm4, mm3 ;
677 :    
678 :     pxor mm0, mm1 ; mm0 = |mm0|
679 :     pxor mm3, mm4 ;
680 :     psubw mm0, mm1 ; displace
681 :     psubw mm3, mm4 ;
682 :    
683 :     psllw mm0, 4
684 :     psllw mm3, 4
685 :    
686 :     movq mm2, [mmx_inter_matrix + 8*ecx]
687 :     psrlw mm2, 1
688 :     paddw mm0, mm2
689 :    
690 :     movq mm2, [mmx_inter_matrix_fix + ecx*8]
691 :     pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
692 :    
693 :     movq mm2, [mmx_inter_matrix + 8*ecx + 8]
694 :     psrlw mm2, 1
695 :     paddw mm3, mm2
696 :    
697 :     movq mm2, [mmx_inter_matrix_fix + ecx*8 + 8]
698 :     pmulhw mm3, mm2
699 :    
700 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
701 :     psrlw mm3, 1 ;
702 :    
703 :     paddw mm5, mm0 ; sum += mm0
704 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
705 :     paddw mm5, mm3 ;
706 :     pxor mm3, mm4 ;
707 :     psubw mm0, mm1 ; undisplace
708 :     psubw mm3, mm4
709 :    
710 :     movq [edi + 8*ecx], mm0
711 :     movq [edi + 8*ecx + 8], mm3
712 :    
713 :     add ecx,2
714 :     cmp ecx,16
715 :     jnz near .q1loop
716 :    
717 :     jmp .done
718 :    
719 :    
720 :     align ALIGN
721 :     .q2loop
722 :     movq mm0, [esi + 8*ecx] ; mm0 = [1st]
723 :     movq mm3, [esi + 8*ecx+ 8]
724 :     ;
725 :     pxor mm1, mm1 ; mm1 = 0
726 :     pxor mm4, mm4 ;
727 :    
728 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
729 :     pcmpgtw mm4, mm3 ;
730 :    
731 :     pxor mm0, mm1 ; mm0 = |mm0|
732 :     pxor mm3, mm4 ;
733 :     psubw mm0, mm1 ; displace
734 :     psubw mm3, mm4 ;
735 :    
736 :     psllw mm0, 4
737 :     psllw mm3, 4
738 :    
739 :     movq mm2, [mmx_inter_matrix + 8*ecx]
740 :     psrlw mm2, 1
741 :     paddw mm0, mm2
742 :    
743 :     movq mm2, [mmx_inter_matrix_fix + ecx*8]
744 :     pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
745 :    
746 :     movq mm2, [mmx_inter_matrix + 8*ecx + 8]
747 :     psrlw mm2, 1
748 :     paddw mm3, mm2
749 :    
750 :     movq mm2, [mmx_inter_matrix_fix + ecx*8 + 8]
751 :     pmulhw mm3, mm2
752 :    
753 :     psrlw mm0, 2 ; mm0 >>= 1 (/2)
754 :     psrlw mm3, 2 ;
755 :    
756 :     paddw mm5, mm0 ; sum += mm0
757 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
758 :     paddw mm5, mm3 ;
759 :     pxor mm3, mm4 ;
760 :     psubw mm0, mm1 ; undisplace
761 :     psubw mm3, mm4
762 :    
763 :     movq [edi + 8*ecx], mm0
764 :     movq [edi + 8*ecx + 8], mm3
765 :    
766 :     add ecx,2
767 :     cmp ecx,16
768 :     jnz near .q2loop
769 :    
770 :     jmp .done
771 :    
772 :    
773 :     ;===========================================================================
774 :     ;
775 :     ; void dequant4_intra_mmx(int16_t *data,
776 :     ; const int16_t const *coeff,
777 :     ; const uint32_t quant,
778 :     ; const uint32_t dcscalar);
779 :     ;
780 :     ;===========================================================================
781 :    
782 :     align 16
783 :     cglobal dequant4_intra_mmx
784 :     dequant4_intra_mmx
785 :    
786 :     push esi
787 :     push edi
788 :    
789 :     mov edi, [esp + 8 + 4] ; data
790 :     mov esi, [esp + 8 + 8] ; coeff
791 :     mov eax, [esp + 8 + 12] ; quant
792 :    
793 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
794 :    
795 :     xor eax, eax
796 :    
797 :    
798 :     align 16
799 :     .loop
800 :     movq mm0, [esi + 8*eax] ; mm0 = [coeff]
801 :    
802 :     pxor mm1, mm1 ; mm1 = 0
803 :     pcmpeqw mm1, mm0 ; mm1 = (0 == mm0)
804 :    
805 :     pxor mm2, mm2 ; mm2 = 0
806 :     pcmpgtw mm2, mm0 ; mm2 = (0 > mm0)
807 :     pxor mm0, mm2 ; mm0 = |mm0|
808 :     psubw mm0, mm2 ; displace
809 :    
810 :     pmullw mm0, mm7 ; mm0 *= quant
811 :    
812 :     movq mm3, [default_intra_matrix_mul + 8*eax]
813 :    
814 :     movq mm4, mm0 ;
815 :     pmullw mm0, mm3 ; mm0 = low(mm0 * mm3)
816 :     pmulhw mm3, mm4 ; mm3 = high(mm0 * mm3)
817 :    
818 :     movq mm4, mm0 ; mm0,mm4 = unpack(mm3, mm0)
819 :     punpcklwd mm0, mm3 ;
820 :     punpckhwd mm4, mm3 ;
821 :     psrld mm0, 3 ; mm0,mm4 /= 8
822 :     psrld mm4, 3 ;
823 :     packssdw mm0, mm4 ; mm0 = pack(mm4, mm0)
824 :    
825 :     pxor mm0, mm2 ; mm0 *= sign(mm0)
826 :     psubw mm0, mm2 ; undisplace
827 :     pandn mm1, mm0 ; mm1 = ~(iszero) & mm0
828 :    
829 :     %ifdef SATURATE
830 :     movq mm2, [mmx_32767_minus_2047]
831 :     movq mm6, [mmx_32768_minus_2048]
832 :     paddsw mm1, mm2
833 :     psubsw mm1, mm2
834 :     psubsw mm1, mm6
835 :     paddsw mm1, mm6
836 :     %endif
837 :    
838 :     movq [edi + 8*eax], mm1 ; [data] = mm0
839 :    
840 :     add eax, 1
841 :     cmp eax, 16
842 :     jnz near .loop
843 :    
844 :     mov ax, [esi] ; ax = data[0]
845 :     imul ax, [esp + 8 + 16] ; eax = data[0] * dcscalar
846 :     mov [edi], ax ; data[0] = ax
847 :    
848 :     %ifdef SATURATE
849 :     cmp ax, -2048
850 :     jl .set_n2048
851 :     cmp ax, 2047
852 :     jg .set_2047
853 :     %endif
854 :    
855 :     pop edi
856 :     pop esi
857 :     ret
858 :    
859 :     %ifdef SATURATE
860 :     .set_n2048
861 :     mov word [edi], -2048
862 :     pop edi
863 :     pop esi
864 :     ret
865 :    
866 :     .set_2047
867 :     mov word [edi], 2047
868 :     pop edi
869 :     pop esi
870 :    
871 :     ret
872 :     %endif
873 :    
874 :    
875 :    
876 :     ;===========================================================================
877 :     ;
878 :     ; void dequant4_inter_mmx(int16_t * data,
879 :     ; const int16_t * const coeff,
880 :     ; const uint32_t quant);
881 :     ;
882 :     ;===========================================================================
883 :    
884 :     align 16
885 :     cglobal dequant4_inter_mmx
886 :     dequant4_inter_mmx
887 :    
888 :     push esi
889 :     push edi
890 :    
891 :     mov edi, [esp + 8 + 4] ; data
892 :     mov esi, [esp + 8 + 8] ; coeff
893 :     mov eax, [esp + 8 + 12] ; quant
894 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
895 :     movq mm6, [mmx_one]
896 :     xor eax, eax
897 :     pxor mm5, mm5 ; mismatch sum
898 :    
899 :    
900 :     align 16
901 :     .loop
902 :     movq mm0, [esi + 8*eax] ; mm0 = [coeff]
903 :    
904 :     pxor mm1, mm1 ; mm1 = 0
905 :     pcmpeqw mm1, mm0 ; mm1 = (0 == mm0)
906 :    
907 :     pxor mm2, mm2 ; mm2 = 0
908 :     pcmpgtw mm2, mm0 ; mm2 = (0 > mm0)
909 :     pxor mm0, mm2 ; mm0 = |mm0|
910 :     psubw mm0, mm2 ; displace
911 :    
912 :     psllw mm0, 1 ;
913 :     paddsw mm0, mm6 ; mm0 = 2*mm0 + 1
914 :     pmullw mm0, mm7 ; mm0 *= quant
915 :    
916 :     movq mm3, [default_inter_matrix_mul + 8*eax]
917 :    
918 :     movq mm4, mm0
919 :     pmullw mm0, mm3 ; mm0 = low(mm0 * mm3)
920 :     pmulhw mm3, mm4 ; mm3 = high(mm0 * mm3)
921 :    
922 :     movq mm4, mm0 ; mm0,mm4 = unpack(mm3, mm0)
923 :     punpcklwd mm0, mm3 ;
924 :     punpckhwd mm4, mm3 ;
925 :    
926 :     psrad mm0, 4 ; mm0,mm4 /= 16
927 :     psrad mm4, 4 ;
928 :     packssdw mm0, mm4 ; mm0 = pack(mm4, mm0)
929 :    
930 :     pxor mm0, mm2 ; mm0 *= sign(mm0)
931 :     psubw mm0, mm2 ; undisplace
932 :     pandn mm1, mm0 ; mm1 = ~(iszero) & mm0
933 :    
934 :    
935 :     ;%ifdef SATURATE
936 :     movq mm2, [mmx_32767_minus_2047]
937 :     movq mm4, [mmx_32768_minus_2048]
938 :     paddsw mm1, mm2
939 :     psubsw mm1, mm2
940 :     psubsw mm1, mm4
941 :     paddsw mm1, mm4
942 :     ;%endif
943 :    
944 :     pxor mm5, mm1 ; mismatch
945 :    
946 :     movq [edi + 8*eax], mm1 ; [data] = mm0
947 :    
948 :     add eax, 1
949 :     cmp eax, 16
950 :     jnz near .loop
951 :    
952 :     ; mismatch control
953 :    
954 :     movq mm0, mm5
955 :     movq mm1, mm5
956 :     movq mm2, mm5
957 :     psrlq mm0, 48
958 :     psrlq mm1, 32
959 :     psrlq mm2, 16
960 :     pxor mm5, mm0
961 :     pxor mm5, mm1
962 :     pxor mm5, mm2
963 :    
964 :     movd eax, mm5
965 :     test eax, 0x1
966 :     jnz .done
967 :    
968 :     xor word [edi + 2*63], 1
969 :    
970 :     .done
971 :     pop edi
972 :     pop esi
973 :    
974 :     ret

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