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

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