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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1793 - (view) (download)

1 : edgomez 1382 ;/****************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - 3dne Quantization/Dequantization -
5 :     ; *
6 :     ; * Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>
7 :     ; * 2002 Jaan Kalda
8 :     ; *
9 :     ; * This program is free software ; you can redistribute it and/or modify
10 :     ; * it under the terms of the GNU General Public License as published by
11 :     ; * the Free Software Foundation ; either version 2 of the License, or
12 :     ; * (at your option) any later version.
13 :     ; *
14 :     ; * This program is distributed in the hope that it will be useful,
15 :     ; * but WITHOUT ANY WARRANTY ; without even the implied warranty of
16 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     ; * GNU General Public License for more details.
18 :     ; *
19 :     ; * You should have received a copy of the GNU General Public License
20 :     ; * along with this program ; if not, write to the Free Software
21 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 :     ; *
23 : Isibaar 1793 ; * $Id: quantize_mpeg_xmm.asm,v 1.8 2008-11-11 20:46:24 Isibaar Exp $
24 : edgomez 1382 ; *
25 :     ; ***************************************************************************/
26 :    
27 :     ; _3dne functions are compatible with iSSE, but are optimized specifically
28 :     ; for K7 pipelines
29 :    
30 :     %define SATURATE
31 :    
32 :     BITS 32
33 :    
34 :     %macro cglobal 1
35 :     %ifdef PREFIX
36 : edgomez 1535 %ifdef MARK_FUNCS
37 : edgomez 1540 global _%1:function %1.endfunc-%1
38 :     %define %1 _%1:function %1.endfunc-%1
39 : Isibaar 1793 %define ENDFUNC .endfunc
40 : edgomez 1535 %else
41 :     global _%1
42 :     %define %1 _%1
43 : Isibaar 1793 %define ENDFUNC
44 : edgomez 1535 %endif
45 : edgomez 1382 %else
46 : edgomez 1535 %ifdef MARK_FUNCS
47 : edgomez 1540 global %1:function %1.endfunc-%1
48 : Isibaar 1793 %define ENDFUNC .endfunc
49 : edgomez 1535 %else
50 :     global %1
51 : Isibaar 1793 %define ENDFUNC
52 : edgomez 1535 %endif
53 : edgomez 1382 %endif
54 :     %endmacro
55 :    
56 :     %macro cextern 1
57 :     %ifdef PREFIX
58 :     extern _%1
59 :     %define %1 _%1
60 :     %else
61 :     extern %1
62 :     %endif
63 :     %endmacro
64 :    
65 :     ;=============================================================================
66 :     ; Local data
67 :     ;=============================================================================
68 :    
69 :     %ifdef FORMAT_COFF
70 : edgomez 1519 SECTION .rodata
71 : edgomez 1382 %else
72 : edgomez 1519 SECTION .rodata align=16
73 : edgomez 1382 %endif
74 :    
75 :     ALIGN 8
76 :     mmzero:
77 :     dd 0,0
78 :     mmx_one:
79 :     times 4 dw 1
80 :    
81 :     ;-----------------------------------------------------------------------------
82 :     ; divide by 2Q table
83 :     ;-----------------------------------------------------------------------------
84 :    
85 :     ALIGN 16
86 :     mmx_divs: ;i>2
87 :     %assign i 1
88 :     %rep 31
89 :     times 4 dw ((1 << 15) / i + 1)
90 :     %assign i i+1
91 :     %endrep
92 :    
93 :     ALIGN 16
94 :     mmx_div: ;quant>2
95 :     times 4 dw 65535 ; the div by 2 formula will overflow for the case
96 :     ; quant=1 but we don't care much because quant=1
97 :     ; is handled by a different piece of code that
98 :     ; doesn't use this table.
99 :     %assign quant 2
100 :     %rep 31
101 :     times 4 dw ((1 << 16) / quant + 1)
102 :     %assign quant quant+1
103 :     %endrep
104 :    
105 :     %macro FIXX 1
106 :     dw (1 << 16) / (%1) + 1
107 :     %endmacro
108 :    
109 :     %define nop4 db 08Dh, 074h, 026h,0
110 :     %define nop3 add esp, byte 0
111 :     %define nop2 mov esp, esp
112 :     %define nop7 db 08dh, 02ch, 02dh,0,0,0,0
113 :     %define nop6 add ebp, dword 0
114 :    
115 :     ;-----------------------------------------------------------------------------
116 :     ; quantd table
117 :     ;-----------------------------------------------------------------------------
118 :    
119 :     %define VM18P 3
120 :     %define VM18Q 4
121 :    
122 :     ALIGN 16
123 :     quantd:
124 :     %assign i 1
125 :     %rep 31
126 :     times 4 dw (((VM18P*i) + (VM18Q/2)) / VM18Q)
127 :     %assign i i+1
128 :     %endrep
129 :    
130 :     ;-----------------------------------------------------------------------------
131 :     ; multiple by 2Q table
132 :     ;-----------------------------------------------------------------------------
133 :    
134 :     ALIGN 16
135 :     mmx_mul_quant:
136 :     %assign i 1
137 :     %rep 31
138 :     times 4 dw i
139 :     %assign i i+1
140 :     %endrep
141 :    
142 :     ;-----------------------------------------------------------------------------
143 :     ; saturation limits
144 :     ;-----------------------------------------------------------------------------
145 :    
146 :     ALIGN 16
147 :     mmx_32767_minus_2047:
148 :     times 4 dw (32767-2047)
149 :     mmx_32768_minus_2048:
150 :     times 4 dw (32768-2048)
151 :     mmx_2047:
152 :     times 4 dw 2047
153 :     mmx_minus_2048:
154 :     times 4 dw (-2048)
155 :     zero:
156 :     times 4 dw 0
157 :    
158 :     int_div:
159 :     dd 0
160 :     %assign i 1
161 :     %rep 255
162 :     dd (1 << 17) / ( i) + 1
163 :     %assign i i+1
164 :     %endrep
165 :    
166 :     ;=============================================================================
167 :     ; Code
168 :     ;=============================================================================
169 :    
170 :     SECTION .text
171 :    
172 :     cglobal quant_mpeg_inter_xmm
173 :     cglobal dequant_mpeg_intra_3dne
174 :     cglobal dequant_mpeg_inter_3dne
175 :    
176 :     ;-----------------------------------------------------------------------------
177 :     ;
178 :     ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,
179 :     ; const int16_t const * data,
180 :     ; const uint32_t quant,
181 :     ; const uint16_t *mpeg_matrices);
182 :     ;
183 :     ;-----------------------------------------------------------------------------
184 :    
185 :     ALIGN 16
186 :     quant_mpeg_inter_xmm:
187 :     mov eax, [esp + 8] ; data
188 :     mov ecx, [esp + 12] ; quant
189 :     mov edx, [esp + 4] ; coeff
190 :     push esi
191 :     push edi
192 :     push ebx
193 :     nop
194 :     mov edi, [esp + 12 + 16]
195 :     mov esi, -14
196 :     mov ebx, esp
197 :     sub esp, byte 24
198 :     lea ebx, [esp+8]
199 :     and ebx, byte -8 ;ALIGN 8
200 :     pxor mm0, mm0
201 :     pxor mm3, mm3
202 :     movq [byte ebx],mm0
203 :     db 0Fh, 7Fh, 44h, 23h, 8 ;movq [ebx+8],mm0
204 :     cmp ecx, byte 1
205 :     je near .q1loop
206 :     cmp ecx, byte 19
207 :     jg near .lloop
208 :     nop
209 :    
210 :     ALIGN 16
211 : Isibaar 1793 .loop:
212 : edgomez 1382 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
213 :     psubw mm0, mm1 ;-mm1
214 :     movq mm4, [eax + 8*esi + 120] ;
215 :     psubw mm3, mm4 ;-mm4
216 :     pmaxsw mm0, mm1 ;|src|
217 :     pmaxsw mm3, mm4
218 :     nop2
219 :     psraw mm1, 15 ;sign src
220 :     psraw mm4, 15
221 :     psllw mm0, 4 ; level << 4
222 :     psllw mm3, 4 ;
223 :     paddw mm0, [edi + 640 + 8*esi+112]
224 :     paddw mm3, [edi + 640 + 8*esi+120]
225 :     movq mm5, [edi + 896 + 8*esi+112]
226 :     movq mm7, [edi + 896 + 8*esi+120]
227 :     pmulhuw mm5, mm0
228 :     pmulhuw mm7, mm3
229 :     mov esp, esp
230 :     movq mm2, [edi + 512 + 8*esi+112]
231 :     movq mm6, [edi + 512 + 8*esi+120]
232 :     pmullw mm2, mm5
233 :     pmullw mm6, mm7
234 :     psubw mm0, mm2
235 :     psubw mm3, mm6
236 :     movq mm2, [byte ebx]
237 :     movq mm6, [mmx_divs + ecx * 8 - 8]
238 :     pmulhuw mm0, [edi + 768 + 8*esi+112]
239 :     pmulhuw mm3, [edi + 768 + 8*esi+120]
240 :     paddw mm2, [ebx+8] ;sum
241 :     paddw mm5, mm0
242 :     paddw mm7, mm3
243 :     pxor mm0, mm0
244 :     pxor mm3, mm3
245 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
246 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
247 :     add esi, byte 2
248 :     paddw mm2, mm5 ;sum += x1
249 :     movq [ebx], mm7 ;store x2
250 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
251 :     pxor mm7, mm4 ;
252 :     psubw mm5, mm1 ; undisplace
253 :     psubw mm7, mm4 ;
254 :     db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
255 :     movq [edx + 8*esi+112-16], mm5
256 :     movq [edx + 8*esi +120-16], mm7
257 :     jng near .loop
258 :    
259 : Isibaar 1793 .done:
260 : edgomez 1382 ; calculate data[0] // (int32_t)dcscalar)
261 :     paddw mm2, [ebx]
262 :     mov ebx, [esp+24]
263 :     mov edi, [esp+4+24]
264 :     mov esi, [esp+8+24]
265 :     add esp, byte 12+24
266 :     pmaddwd mm2, [mmx_one]
267 :     punpckldq mm0, mm2 ;get low dw to mm0:high
268 :     paddd mm0,mm2
269 :     punpckhdq mm0, mm0 ;get result to low
270 :     movd eax, mm0
271 :    
272 :     ret
273 :    
274 :     ALIGN 16
275 : Isibaar 1793 .q1loop:
276 : edgomez 1382 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
277 :     psubw mm0, mm1 ;-mm1
278 :     movq mm4, [eax + 8*esi+120]
279 :     psubw mm3, mm4 ;-mm4
280 :     pmaxsw mm0, mm1 ;|src|
281 :     pmaxsw mm3, mm4
282 :     nop2
283 :     psraw mm1, 15 ; sign src
284 :     psraw mm4, 15
285 :     psllw mm0, 4 ; level << 4
286 :     psllw mm3, 4
287 :     paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided
288 :     paddw mm3, [edi + 640 + 8*esi+120] ; inter1 contains fix for division by 1
289 :     movq mm5, [edi + 896 + 8*esi+112] ;with rounding down
290 :     movq mm7, [edi + 896 + 8*esi+120]
291 :     pmulhuw mm5, mm0
292 :     pmulhuw mm7, mm3 ;mm7: first approx of division
293 :     mov esp, esp
294 :     movq mm2, [edi + 512 + 8*esi+112]
295 :     movq mm6, [edi + 512 + 8*esi+120] ; divs for q<=16
296 :     pmullw mm2, mm5 ;test value <= original
297 :     pmullw mm6, mm7
298 :     psubw mm0, mm2 ;mismatch
299 :     psubw mm3, mm6
300 :     movq mm2, [byte ebx]
301 :     pmulhuw mm0, [edi + 768 + 8*esi+112] ;correction
302 :     pmulhuw mm3, [edi + 768 + 8*esi+120]
303 :     paddw mm2, [ebx+8] ;sum
304 :     paddw mm5, mm0 ;final result
305 :     paddw mm7, mm3
306 :     pxor mm0, mm0
307 :     pxor mm3, mm3
308 :     psrlw mm5, 1 ; (level ) /2 (quant = 1)
309 :     psrlw mm7, 1
310 :     add esi, byte 2
311 :     paddw mm2, mm5 ;sum += x1
312 :     movq [ebx], mm7 ;store x2
313 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
314 :     pxor mm7, mm4 ;
315 :     psubw mm5, mm1 ; undisplace
316 :     psubw mm7, mm4 ;
317 :     movq [ebx+8], mm2 ;store sum
318 :     movq [edx + 8*esi+112-16], mm5
319 :     movq [edx + 8*esi +120-16], mm7
320 :     jng near .q1loop
321 :     jmp near .done
322 :    
323 :     ALIGN 8
324 : Isibaar 1793 .lloop:
325 : edgomez 1382 movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
326 :     psubw mm0,mm1 ;-mm1
327 :     movq mm4, [eax + 8*esi+120]
328 :     psubw mm3,mm4 ;-mm4
329 :     pmaxsw mm0,mm1 ;|src|
330 :     pmaxsw mm3,mm4
331 :     nop2
332 :     psraw mm1,15 ;sign src
333 :     psraw mm4,15
334 :     psllw mm0, 4 ; level << 4
335 :     psllw mm3, 4 ;
336 :     paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1
337 :     paddw mm3, [edi + 640 + 8*esi+120]
338 :     movq mm5,[edi + 896 + 8*esi+112]
339 :     movq mm7,[edi + 896 + 8*esi+120]
340 :     pmulhuw mm5,mm0
341 :     pmulhuw mm7,mm3 ;mm7: first approx of division
342 :     mov esp,esp
343 :     movq mm2,[edi + 512 + 8*esi+112]
344 :     movq mm6,[edi + 512 + 8*esi+120]
345 :     pmullw mm2,mm5 ;test value <= original
346 :     pmullw mm6,mm7
347 :     psubw mm0,mm2 ;mismatch
348 :     psubw mm3,mm6
349 :     movq mm2,[byte ebx]
350 :     movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16
351 :     pmulhuw mm0,[edi + 768 + 8*esi+112] ;correction
352 :     pmulhuw mm3,[edi + 768 + 8*esi+120]
353 :     paddw mm2,[ebx+8] ;sum
354 :     paddw mm5,mm0 ;final result
355 :     paddw mm7,mm3
356 :     pxor mm0,mm0
357 :     pxor mm3,mm3
358 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
359 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
360 :     add esi,byte 2
361 :     psrlw mm5, 1 ; (level ) / (2*quant)
362 :     paddw mm2,mm5 ;sum += x1
363 :     psrlw mm7, 1
364 :     movq [ebx],mm7 ;store x2
365 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
366 :     pxor mm7, mm4 ;
367 :     psubw mm5, mm1 ; undisplace
368 :     psubw mm7, mm4 ;
369 :     db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
370 :     movq [edx + 8*esi+112-16], mm5
371 :     movq [edx + 8*esi +120-16], mm7
372 :     jng near .lloop
373 :     jmp near .done
374 : Isibaar 1793 ENDFUNC
375 : edgomez 1382
376 :    
377 :     ;-----------------------------------------------------------------------------
378 :     ;
379 :     ; uint32_t dequant_mpeg_intra_3dne(int16_t *data,
380 :     ; const int16_t const *coeff,
381 :     ; const uint32_t quant,
382 :     ; const uint32_t dcscalar,
383 :     ; const uint16_t *mpeg_matrices);
384 :     ;
385 :     ;-----------------------------------------------------------------------------
386 :    
387 :     ; Note: in order to saturate 'easily', we pre-shift the quantifier
388 :     ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
389 :     ; build a saturating mask. It is non-zero only when an overflow occured.
390 :     ; We thus avoid packing/unpacking toward double-word.
391 :     ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
392 :     ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
393 :     ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
394 :     ; and quant in [1..31].
395 :     ;
396 :    
397 :     %macro DEQUANT4INTRAMMX 1
398 :     movq mm1, [byte ecx+ 16 * %1] ; mm0 = c = coeff[i]
399 :     movq mm4, [ecx+ 16 * %1 +8] ; mm3 = c' = coeff[i+1]
400 :     psubw mm0, mm1
401 :     psubw mm3, mm4
402 :     pmaxsw mm0, mm1
403 :     pmaxsw mm3, mm4
404 :     psraw mm1, 15
405 :     psraw mm4, 15
406 :     %if %1
407 :     movq mm2, [eax+8] ;preshifted quant
408 :     movq mm7, [eax+8]
409 :     %endif
410 :     pmullw mm2, [edi + 16 * %1 ] ; matrix[i]*quant
411 :     pmullw mm7, [edi + 16 * %1 +8] ; matrix[i+1]*quant
412 :     movq mm5, mm0
413 :     movq mm6, mm3
414 :     pmulhw mm0, mm2 ; high of coeff*(matrix*quant)
415 :     pmulhw mm3, mm7 ; high of coeff*(matrix*quant)
416 :     pmullw mm2, mm5 ; low of coeff*(matrix*quant)
417 :     pmullw mm7, mm6 ; low of coeff*(matrix*quant)
418 :     pcmpgtw mm0, [eax]
419 :     pcmpgtw mm3, [eax]
420 :     paddusw mm2, mm0
421 :     paddusw mm7, mm3
422 :     psrlw mm2, 5
423 :     psrlw mm7, 5
424 :     pxor mm2, mm1 ; start negating back
425 :     pxor mm7, mm4 ; start negating back
426 :     psubusw mm1, mm0
427 :     psubusw mm4, mm3
428 :     movq mm0, [eax] ;zero
429 :     movq mm3, [eax] ;zero
430 :     psubw mm2, mm1 ; finish negating back
431 :     psubw mm7, mm4 ; finish negating back
432 :     movq [byte edx + 16 * %1], mm2 ; data[i]
433 :     movq [edx + 16 * %1 +8], mm7 ; data[i+1]
434 :     %endmacro
435 :    
436 :     ALIGN 16
437 :     dequant_mpeg_intra_3dne:
438 :     mov eax, [esp+12] ; quant
439 :     mov ecx, [esp+8] ; coeff
440 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
441 :     psllw mm7, 2 ; << 2. See comment.
442 :     mov edx, [esp+4] ; data
443 :     push ebx
444 :     movsx ebx, word [ecx]
445 :     pxor mm0, mm0
446 :     pxor mm3, mm3
447 :     push esi
448 :     lea eax, [esp-28]
449 :     sub esp, byte 32
450 :     and eax, byte -8 ;points to qword ALIGNed space on stack
451 :     movq [eax], mm0
452 :     movq [eax+8], mm7
453 :     imul ebx, [esp+16+8+32] ; dcscalar
454 :     movq mm2, mm7
455 :     push edi
456 :     mov edi, [esp + 32 + 12 + 20] ; mpeg_quant_matrices
457 :     ALIGN 4
458 :    
459 :     DEQUANT4INTRAMMX 0
460 :    
461 :     mov esi, -2048
462 :     nop
463 :     cmp ebx, esi
464 :    
465 :     DEQUANT4INTRAMMX 1
466 :    
467 :     cmovl ebx, esi
468 :     neg esi
469 :     sub esi, byte 1 ;2047
470 :    
471 :     DEQUANT4INTRAMMX 2
472 :    
473 :     cmp ebx, esi
474 :     cmovg ebx, esi
475 :     lea ebp, [byte ebp]
476 :    
477 :     DEQUANT4INTRAMMX 3
478 :    
479 :     mov esi, [esp+36]
480 :     mov [byte edx], bx
481 :     mov ebx, [esp+36+4]
482 :    
483 :     DEQUANT4INTRAMMX 4
484 :     DEQUANT4INTRAMMX 5
485 :     DEQUANT4INTRAMMX 6
486 :     DEQUANT4INTRAMMX 7
487 :    
488 :     pop edi
489 :    
490 :     add esp, byte 32+8
491 :    
492 :     xor eax, eax
493 :     ret
494 : Isibaar 1793 ENDFUNC
495 : edgomez 1382
496 :     ;-----------------------------------------------------------------------------
497 :     ;
498 :     ; uint32_t dequant_mpeg_inter_3dne(int16_t * data,
499 :     ; const int16_t * const coeff,
500 :     ; const uint32_t quant,
501 :     ; const uint16_t *mpeg_matrices);
502 :     ;
503 :     ;-----------------------------------------------------------------------------
504 :    
505 :     ; Note: We use (2*c + sgn(c) - sgn(-c)) as multiplier
506 :     ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
507 :     ; sgn(x) is the result of 'pcmpgtw 0,x': 0 if x>=0, -1 if x<0.
508 :     ; It's mixed with the extraction of the absolute value.
509 :    
510 :     ALIGN 16
511 :     dequant_mpeg_inter_3dne:
512 :     mov edx, [esp+ 4] ; data
513 :     mov ecx, [esp+ 8] ; coeff
514 :     mov eax, [esp+12] ; quant
515 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
516 :     mov eax, -14
517 :     paddw mm7, mm7 ; << 1
518 :     pxor mm6, mm6 ; mismatch sum
519 :     push esi
520 :     push edi
521 :     mov esi, mmzero
522 :     pxor mm1, mm1
523 :     pxor mm3, mm3
524 :     mov edi, [esp + 8 + 16] ; mpeg_quant_matrices
525 :     nop
526 :     nop4
527 :    
528 :     ALIGN 16
529 : Isibaar 1793 .loop:
530 : edgomez 1382 movq mm0, [ecx+8*eax + 7*16 ] ; mm0 = coeff[i]
531 :     pcmpgtw mm1, mm0 ; mm1 = sgn(c) (preserved)
532 :     movq mm2, [ecx+8*eax + 7*16 +8] ; mm2 = coeff[i+1]
533 :     pcmpgtw mm3, mm2 ; mm3 = sgn(c') (preserved)
534 :     paddsw mm0, mm1 ; c += sgn(c)
535 :     paddsw mm2, mm3 ; c += sgn(c')
536 :     paddw mm0, mm0 ; c *= 2
537 :     paddw mm2, mm2 ; c'*= 2
538 :    
539 :     movq mm4, [esi]
540 :     movq mm5, [esi]
541 :     psubw mm4, mm0 ; -c
542 :     psubw mm5, mm2 ; -c'
543 :    
544 :     psraw mm4, 16 ; mm4 = sgn(-c)
545 :     psraw mm5, 16 ; mm5 = sgn(-c')
546 :     psubsw mm0, mm4 ; c -= sgn(-c)
547 :     psubsw mm2, mm5 ; c' -= sgn(-c')
548 :     pxor mm0, mm1 ; finish changing sign if needed
549 :     pxor mm2, mm3 ; finish changing sign if needed
550 :    
551 :     ; we're short on register, here. Poor pairing...
552 :    
553 :     movq mm4, mm7 ; (matrix*quant)
554 :     nop
555 :     pmullw mm4, [edi + 512 + 8*eax + 7*16]
556 :     movq mm5, mm4
557 :     pmulhw mm5, mm0 ; high of c*(matrix*quant)
558 :     pmullw mm0, mm4 ; low of c*(matrix*quant)
559 :    
560 :     movq mm4, mm7 ; (matrix*quant)
561 :     pmullw mm4, [edi + 512 + 8*eax + 7*16 + 8]
562 :     add eax, byte 2
563 :    
564 :     pcmpgtw mm5, [esi]
565 :     paddusw mm0, mm5
566 :     psrlw mm0, 5
567 :     pxor mm0, mm1 ; start restoring sign
568 :     psubusw mm1, mm5
569 :    
570 :     movq mm5, mm4
571 :     pmulhw mm5, mm2 ; high of c*(matrix*quant)
572 :     pmullw mm2, mm4 ; low of c*(matrix*quant)
573 :     psubw mm0, mm1 ; finish restoring sign
574 :    
575 :     pcmpgtw mm5, [esi]
576 :     paddusw mm2, mm5
577 :     psrlw mm2, 5
578 :     pxor mm2, mm3 ; start restoring sign
579 :     psubusw mm3, mm5
580 :     psubw mm2, mm3 ; finish restoring sign
581 :     movq mm1, [esi]
582 :     movq mm3, [byte esi]
583 :     pxor mm6, mm0 ; mismatch control
584 :     movq [edx + 8*eax + 7*16 -2*8 ], mm0 ; data[i]
585 :     pxor mm6, mm2 ; mismatch control
586 :     movq [edx + 8*eax + 7*16 -2*8 +8], mm2 ; data[i+1]
587 :    
588 :     jng .loop
589 :     nop
590 :    
591 :     ; mismatch control
592 :    
593 :     pshufw mm0, mm6, 01010101b
594 :     pshufw mm1, mm6, 10101010b
595 :     pshufw mm2, mm6, 11111111b
596 :     pxor mm6, mm0
597 :     pxor mm1, mm2
598 :     pxor mm6, mm1
599 :     movd eax, mm6
600 :     pop edi
601 :     and eax, byte 1
602 :     xor eax, byte 1
603 :     mov esi, [esp]
604 :     add esp, byte 4
605 :     xor word [edx + 2*63], ax
606 :    
607 :     xor eax, eax
608 :     ret
609 : Isibaar 1793 ENDFUNC
610 : edgomez 1540
611 : Isibaar 1790
612 :     %ifidn __OUTPUT_FORMAT__,elf
613 :     section ".note.GNU-stack" noalloc noexec nowrite progbits
614 :     %endif
615 :    

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