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

Annotation of /branches/dev-api-3/xvidcore/src/quant/x86_asm/quantize4_xmm.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 730 - (view) (download)

1 : Isibaar 730 ;/******************************************************************************
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 :     ; * quant4 bugs have been fixed: (a) overflow bug for matrix elements *
32 :     ; * equal to 1 or 2 is fixed by substituting pmulhw with pmulhuw (iSSE) *
33 :     ; * and using multiplier 0ffffh instead of 10001h (for matrix element = 1; *
34 :     ; * in that case, 1 is added before multiplying, that additional 1 comes *
35 :     ; * from intra_matrix1; (b) rounding error for large coefficients and matrix *
36 :     ; * elements is fixed by two-step approach: first approximation (rounded *
37 :     ; * down) is found as usual; the result is multiplied by the matrix element *
38 :     ; * and mismatch is used to calculate the correction. *
39 :     ; ******************************************************************************/
40 :     ;
41 :     ; _3dne functions are compatible with iSSE, but are optimized specifically for
42 :     ; K7 pipelines
43 :     ;
44 :     ;------------------------------------------------------------------------------
45 :     ; 09.12.2002 Athlon optimizations contributed by Jaan Kalda
46 :     ;------------------------------------------------------------------------------
47 :    
48 :    
49 :     ; data/text alignment
50 :     %define ALIGN 8
51 :     %define SATURATE
52 :    
53 :     bits 32
54 :    
55 :     section .data data align=8
56 :    
57 :     %macro cglobal 1
58 :     %ifdef PREFIX
59 :     global _%1
60 :     %define %1 _%1
61 :     %else
62 :     global %1
63 :     %endif
64 :     %endmacro
65 :    
66 :     %macro cextern 1
67 :     %ifdef PREFIX
68 :     extern _%1
69 :     %define %1 _%1
70 :     %else
71 :     extern %1
72 :     %endif
73 :     %endmacro
74 :     align 8
75 :     mmzero dd 0,0
76 :    
77 :     mmx_one times 4 dw 1
78 :    
79 :     ;===========================================================================
80 :     ;
81 :     ; divide by 2Q table
82 :     ;
83 :     ;===========================================================================
84 :    
85 :     align ALIGN
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 ALIGN
94 :     mmx_div ;i>2
95 :     %assign i 1
96 :     %rep 31
97 :     times 4 dw ((1 << 16) / i + 1)
98 :     %assign i i+1
99 :     %endrep
100 :    
101 :    
102 :     ;===========================================================================
103 :     ;
104 :     ; intra matrix
105 :     ;
106 :     ;===========================================================================
107 :    
108 :     %macro FIXX 1
109 :     dw (1 << 16) / (%1) + 1
110 :     %endmacro
111 :    
112 :     cextern intra_matrix_fixl
113 :     cextern intra_matrix_fix
114 :     cextern intra_matrix1
115 :     cextern intra_matrix
116 :    
117 :     ;===========================================================================
118 :     ;
119 :     ; inter matrix
120 :     ;
121 :     ;===========================================================================
122 :    
123 :     cextern inter_matrix1
124 :     cextern inter_matrix
125 :     cextern inter_matrix_fix
126 :     cextern inter_matrix_fixl
127 :    
128 :    
129 :     %define VM18P 3
130 :     %define VM18Q 4
131 :     %define nop4 DB 08Dh,074h,026h,0
132 :     %define nop3 add esp,byte 0
133 :     %define nop2 mov esp,esp
134 :     %define nop7 db 08dh,02ch,02dh,0,0,0,0
135 :     %define nop6 add ebp,dword 0
136 :     ;===========================================================================
137 :     ;
138 :     ; quantd table
139 :     ;
140 :     ;===========================================================================
141 :    
142 :    
143 :     quantd
144 :     %assign i 1
145 :     %rep 31
146 :     times 4 dw (((VM18P*i) + (VM18Q/2)) / VM18Q)
147 :     %assign i i+1
148 :     %endrep
149 :    
150 :     ;===========================================================================
151 :     ;
152 :     ; multiple by 2Q table
153 :     ;
154 :     ;===========================================================================
155 :    
156 :    
157 :     mmx_mul_quant
158 :     %assign i 1
159 :     %rep 31
160 :     times 4 dw i
161 :     %assign i i+1
162 :     %endrep
163 :    
164 :     ;===========================================================================
165 :     ;
166 :     ; saturation limits
167 :     ;
168 :     ;===========================================================================
169 :    
170 :     align 16
171 :    
172 :     mmx_32767_minus_2047 times 4 dw (32767-2047)
173 :     mmx_32768_minus_2048 times 4 dw (32768-2048)
174 :     mmx_2047 times 4 dw 2047
175 :     mmx_minus_2048 times 4 dw (-2048)
176 :     zero times 4 dw 0
177 :    
178 :     int_div
179 :     dd 0
180 :     %assign i 1
181 :     %rep 255
182 :     dd (1 << 17) / ( i) + 1
183 :     %assign i i+1
184 :     %endrep
185 :    
186 :     section .text
187 :    
188 :     ;===========================================================================
189 :     ;
190 :     ; void quant_intra4_xmm(int16_t * coeff,
191 :     ; const int16_t const * data,
192 :     ; const uint32_t quant,
193 :     ; const uint32_t dcscalar);
194 :     ;
195 :     ;===========================================================================
196 :    
197 :     align ALIGN
198 :     cglobal quant4_intra_xmm
199 :     quant4_intra_xmm
200 :    
201 :     mov eax, [esp + 8] ; data
202 :     mov ecx, [esp + 12] ; quant
203 :     mov edx, [esp + 4] ; coeff
204 :     push esi
205 :     push edi
206 :     push ebx
207 :     nop
208 :     mov edi,mmzero
209 :     mov esi,-14
210 :     pxor mm0,mm0
211 :     pxor mm3,mm3
212 :     cmp ecx,byte 1
213 :     je near .q1loop
214 :     cmp ecx,byte 19
215 :     jg near .lloop
216 :     nop6
217 :    
218 :    
219 :     align ALIGN
220 :     .loop
221 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
222 :     psubw mm0,mm1 ;-mm1
223 :     movq mm4, [eax + 8*esi + 120] ;
224 :     psubw mm3,mm4 ;-mm4
225 :     pmaxsw mm0,mm1 ;|src|
226 :     pmaxsw mm3,mm4
227 :     nop2
228 :     psraw mm1,15 ;sign src
229 :     psraw mm4,15
230 :     psllw mm0, 4 ; level << 4
231 :     psllw mm3, 4 ;
232 :     paddw mm0, [intra_matrix1 + 8*esi+112]
233 :     paddw mm3, [intra_matrix1 + 8*esi+120]
234 :     movq mm5,[intra_matrix_fixl + 8*esi+112]
235 :     movq mm7,[intra_matrix_fixl + 8*esi+120]
236 :     pmulhuw mm5,mm0
237 :     pmulhuw mm7,mm3
238 :     mov esp,esp
239 :     movq mm2,[intra_matrix + 8*esi+112]
240 :     movq mm6,[intra_matrix + 8*esi+120]
241 :     pmullw mm2,mm5
242 :     pmullw mm6,mm7
243 :     psubw mm0,mm2
244 :     psubw mm3,mm6
245 :     nop4
246 :     movq mm2,[quantd + ecx * 8 - 8]
247 :     movq mm6,[mmx_divs + ecx * 8 - 8]
248 :     paddw mm5,mm2
249 :     paddw mm7,mm2
250 :     mov esp,esp
251 :     pmulhuw mm0,[intra_matrix_fix + 8*esi+112]
252 :     pmulhuw mm3,[intra_matrix_fix + 8*esi+120]
253 :     paddw mm5,mm0
254 :     paddw mm7,mm3
255 :     movq mm0,[edi]
256 :     movq mm3,[edi]
257 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
258 :     pmulhuw mm7, mm6 ; (level + quantd) / quant (0<quant<32)
259 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
260 :     pxor mm7, mm4 ;
261 :     psubw mm5, mm1 ; undisplace
262 :     psubw mm7, mm4 ;
263 :     movq [edx + 8*esi+112], mm5
264 :     movq [edx + 8*esi +120], mm7
265 :     add esi,byte 2
266 :     jng near .loop
267 :     .done
268 :     ; caclulate data[0] // (int32_t)dcscalar)
269 :    
270 :    
271 :     mov esi, [esp + 12 + 16] ; dcscalar
272 :     movsx ecx, word [eax]
273 :     mov edi,ecx
274 :     mov edx,[esp + 12 + 16]
275 :     shr edx, 1 ; ebx = dcscalar /2
276 :     sar edi,31 ;cdq is vectorpath
277 :     xor edx,edi ; ebx = eax V -eax -1
278 :     sub ecx,edi
279 :     add ecx,edx
280 :     mov edx,[dword esp + 12 + 4]
281 :     mov esi,[int_div+4*esi]
282 :     imul ecx,esi
283 :     sar ecx,17
284 :     ; idiv cx ; ecx = edi:ecx / dcscalar
285 :    
286 :     mov ebx,[esp]
287 :     mov edi,[esp+4]
288 :     mov esi,[esp+8]
289 :     add esp,byte 12
290 :     mov [edx], cx ; coeff[0] = ax
291 :    
292 :     ret
293 :    
294 :     align ALIGN
295 :     .q1loop
296 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
297 :     psubw mm0,mm1 ;-mm1
298 :     movq mm4, [eax + 8*esi+120] ;
299 :     psubw mm3,mm4 ;-mm4
300 :     pmaxsw mm0,mm1 ;|src|
301 :     pmaxsw mm3,mm4
302 :     nop2
303 :     psraw mm1,15 ;sign src
304 :     psraw mm4,15
305 :     psllw mm0, 4 ; level << 4
306 :     psllw mm3, 4
307 :     paddw mm0, [intra_matrix1 + 8*esi+112] ;mm0 is to be divided
308 :     paddw mm3, [intra_matrix1 + 8*esi+120] ; intra1 contains fix for division by 1
309 :     movq mm5,[intra_matrix_fixl + 8*esi+112] ;with rounding down
310 :     movq mm7,[intra_matrix_fixl + 8*esi+120]
311 :     pmulhuw mm5,mm0
312 :     pmulhuw mm7,mm3 ;mm7: first approx of division
313 :     mov esp,esp
314 :     movq mm2,[intra_matrix + 8*esi+112]
315 :     movq mm6,[intra_matrix + 8*esi+120] ; divs for q<=16
316 :     pmullw mm2,mm5 ;test value <= original
317 :     pmullw mm6,mm7
318 :     psubw mm0,mm2 ;mismatch
319 :     psubw mm3,mm6
320 :     nop4
321 :     movq mm2,[quantd + ecx * 8 - 8]
322 :     paddw mm5,mm2 ;first approx with quantd
323 :     paddw mm7,mm2
324 :     mov esp,esp
325 :     pmulhuw mm0,[intra_matrix_fix + 8*esi+112] ;correction
326 :     pmulhuw mm3,[intra_matrix_fix + 8*esi+120]
327 :     paddw mm5,mm0 ;final result with quantd
328 :     paddw mm7,mm3
329 :     movq mm0,[edi]
330 :     movq mm3,[edi]
331 :     mov esp,esp
332 :     psrlw mm5, 1 ; (level + quantd) /2 (quant = 1)
333 :     psrlw mm7, 1
334 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
335 :     pxor mm7, mm4 ;
336 :     psubw mm5, mm1 ; undisplace
337 :     psubw mm7, mm4 ;
338 :     movq [edx + 8*esi+112], mm5
339 :     movq [edx + 8*esi +120], mm7
340 :     add esi,byte 2
341 :     jng near .q1loop
342 :     jmp near .done
343 :    
344 :     align 8
345 :     .lloop
346 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
347 :     psubw mm0,mm1 ;-mm1
348 :     movq mm4, [eax + 8*esi+120] ;
349 :     psubw mm3,mm4 ;-mm4
350 :     pmaxsw mm0,mm1 ;|src|
351 :     pmaxsw mm3,mm4
352 :     nop2
353 :     psraw mm1,15 ;sign src
354 :     psraw mm4,15
355 :     psllw mm0, 4 ; level << 4
356 :     psllw mm3, 4 ;
357 :     paddw mm0, [intra_matrix1 + 8*esi+112] ;mm0 is to be divided intra1 contains fix for division by 1
358 :     paddw mm3, [intra_matrix1 + 8*esi+120]
359 :     movq mm5,[intra_matrix_fixl + 8*esi+112]
360 :     movq mm7,[intra_matrix_fixl + 8*esi+120]
361 :     pmulhuw mm5,mm0
362 :     pmulhuw mm7,mm3 ;mm7: first approx of division
363 :     mov esp,esp
364 :     movq mm2,[intra_matrix + 8*esi+112]
365 :     movq mm6,[intra_matrix + 8*esi+120]
366 :     pmullw mm2,mm5 ;test value <= original
367 :     pmullw mm6,mm7
368 :     psubw mm0,mm2 ;mismatch
369 :     psubw mm3,mm6
370 :     nop4
371 :     movq mm2,[quantd + ecx * 8 - 8]
372 :     movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16
373 :     paddw mm5,mm2 ;first approx with quantd
374 :     paddw mm7,mm2
375 :     mov esp,esp
376 :     pmulhuw mm0,[intra_matrix_fix + 8*esi+112] ;correction
377 :     pmulhuw mm3,[intra_matrix_fix + 8*esi+120]
378 :     paddw mm5,mm0 ;final result with quantd
379 :     paddw mm7,mm3
380 :     movq mm0,[edi]
381 :     movq mm3,[edi]
382 :     mov esp,esp
383 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
384 :     pmulhuw mm7, mm6 ; (level + quantd) / quant (0<quant<32)
385 :     psrlw mm5, 1 ; (level + quantd) / (2*quant)
386 :     psrlw mm7, 1
387 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
388 :     pxor mm7, mm4 ;
389 :     psubw mm5, mm1 ; undisplace
390 :     psubw mm7, mm4 ;
391 :     movq [edx + 8*esi+112], mm5
392 :     movq [edx + 8*esi +120], mm7
393 :     add esi,byte 2
394 :     jng near .lloop
395 :     jmp near .done
396 :    
397 :     ;===========================================================================
398 :     ;
399 :     ; uint32_t quant4_inter_xmm(int16_t * coeff,
400 :     ; const int16_t const * data,
401 :     ; const uint32_t quant);
402 :     ;
403 :     ;===========================================================================
404 :    
405 :     align ALIGN
406 :     cglobal quant4_inter_xmm
407 :     quant4_inter_xmm
408 :    
409 :     mov eax, [esp + 8] ; data
410 :     mov ecx, [esp + 12] ; quant
411 :     mov edx, [esp + 4] ; coeff
412 :     push esi
413 :     push edi
414 :     push ebx
415 :     nop
416 :     mov edi,mmzero
417 :     mov esi,-14
418 :     mov ebx,esp
419 :     sub esp,byte 24
420 :     lea ebx,[esp+8]
421 :     and ebx,byte -8 ;align 8
422 :     pxor mm0,mm0
423 :     pxor mm3,mm3
424 :     movq [byte ebx],mm0
425 :     db 0Fh, 7Fh, 44h, 23h, 8 ;movq [ebx+8],mm0
426 :     cmp ecx,byte 1
427 :     je near .q1loop
428 :     cmp ecx,byte 19
429 :     jg near .lloop
430 :     nop
431 :    
432 :    
433 :     align ALIGN
434 :     .loop
435 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
436 :     psubw mm0,mm1 ;-mm1
437 :     movq mm4, [eax + 8*esi + 120] ;
438 :     psubw mm3,mm4 ;-mm4
439 :     pmaxsw mm0,mm1 ;|src|
440 :     pmaxsw mm3,mm4
441 :     nop2
442 :     psraw mm1,15 ;sign src
443 :     psraw mm4,15
444 :     psllw mm0, 4 ; level << 4
445 :     psllw mm3, 4 ;
446 :     paddw mm0, [inter_matrix1 + 8*esi+112]
447 :     paddw mm3, [inter_matrix1 + 8*esi+120]
448 :     movq mm5,[inter_matrix_fixl + 8*esi+112]
449 :     movq mm7,[inter_matrix_fixl + 8*esi+120]
450 :     pmulhuw mm5,mm0
451 :     pmulhuw mm7,mm3
452 :     mov esp,esp
453 :     movq mm2,[inter_matrix + 8*esi+112]
454 :     movq mm6,[inter_matrix + 8*esi+120]
455 :     pmullw mm2,mm5
456 :     pmullw mm6,mm7
457 :     psubw mm0,mm2
458 :     psubw mm3,mm6
459 :     movq mm2,[byte ebx]
460 :     movq mm6,[mmx_divs + ecx * 8 - 8]
461 :     pmulhuw mm0,[inter_matrix_fix + 8*esi+112]
462 :     pmulhuw mm3,[inter_matrix_fix + 8*esi+120]
463 :     paddw mm2,[ebx+8] ;sum
464 :     paddw mm5,mm0
465 :     paddw mm7,mm3
466 :     movq mm0,[edi]
467 :     movq mm3,[edi]
468 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
469 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
470 :     add esi,byte 2
471 :     paddw mm2,mm5 ;sum += x1
472 :     movq [ebx],mm7 ;store x2
473 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
474 :     pxor mm7, mm4 ;
475 :     psubw mm5, mm1 ; undisplace
476 :     psubw mm7, mm4 ;
477 :     db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
478 :     movq [edx + 8*esi+112-16], mm5
479 :     movq [edx + 8*esi +120-16], mm7
480 :     jng near .loop
481 :     .done
482 :     ; caclulate data[0] // (int32_t)dcscalar)
483 :    
484 :     paddw mm2,[ebx]
485 :     mov ebx,[esp+24]
486 :     mov edi,[esp+4+24]
487 :     mov esi,[esp+8+24]
488 :     add esp,byte 12+24
489 :     pmaddwd mm2, [mmx_one]
490 :     punpckldq mm0,mm2 ;get low dw to mm0:high
491 :     paddd mm0,mm2
492 :     punpckhdq mm0,mm0 ;get result to low
493 :     movd eax, mm0
494 :     ret
495 :    
496 :     align ALIGN
497 :     .q1loop
498 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
499 :     psubw mm0,mm1 ;-mm1
500 :     movq mm4, [eax + 8*esi+120] ;
501 :     psubw mm3,mm4 ;-mm4
502 :     pmaxsw mm0,mm1 ;|src|
503 :     pmaxsw mm3,mm4
504 :     nop2
505 :     psraw mm1,15 ;sign src
506 :     psraw mm4,15
507 :     psllw mm0, 4 ; level << 4
508 :     psllw mm3, 4
509 :     paddw mm0, [inter_matrix1 + 8*esi+112] ;mm0 is to be divided
510 :     paddw mm3, [inter_matrix1 + 8*esi+120] ; inter1 contains fix for division by 1
511 :     movq mm5,[inter_matrix_fixl + 8*esi+112] ;with rounding down
512 :     movq mm7,[inter_matrix_fixl + 8*esi+120]
513 :     pmulhuw mm5,mm0
514 :     pmulhuw mm7,mm3 ;mm7: first approx of division
515 :     mov esp,esp
516 :     movq mm2,[inter_matrix + 8*esi+112]
517 :     movq mm6,[inter_matrix + 8*esi+120] ; divs for q<=16
518 :     pmullw mm2,mm5 ;test value <= original
519 :     pmullw mm6,mm7
520 :     psubw mm0,mm2 ;mismatch
521 :     psubw mm3,mm6
522 :     movq mm2,[byte ebx]
523 :     pmulhuw mm0,[inter_matrix_fix + 8*esi+112] ;correction
524 :     pmulhuw mm3,[inter_matrix_fix + 8*esi+120]
525 :     paddw mm2,[ebx+8] ;sum
526 :     paddw mm5,mm0 ;final result
527 :     paddw mm7,mm3
528 :     movq mm0,[edi]
529 :     movq mm3,[edi]
530 :     psrlw mm5, 1 ; (level ) /2 (quant = 1)
531 :     psrlw mm7, 1
532 :     add esi,byte 2
533 :     paddw mm2,mm5 ;sum += x1
534 :     movq [ebx],mm7 ;store x2
535 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
536 :     pxor mm7, mm4 ;
537 :     psubw mm5, mm1 ; undisplace
538 :     psubw mm7, mm4 ;
539 :     movq [ebx+8],mm2 ;store sum
540 :     movq [edx + 8*esi+112-16], mm5
541 :     movq [edx + 8*esi +120-16], mm7
542 :     jng near .q1loop
543 :     jmp near .done
544 :    
545 :     align 8
546 :     .lloop
547 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
548 :     psubw mm0,mm1 ;-mm1
549 :     movq mm4, [eax + 8*esi+120] ;
550 :     psubw mm3,mm4 ;-mm4
551 :     pmaxsw mm0,mm1 ;|src|
552 :     pmaxsw mm3,mm4
553 :     nop2
554 :     psraw mm1,15 ;sign src
555 :     psraw mm4,15
556 :     psllw mm0, 4 ; level << 4
557 :     psllw mm3, 4 ;
558 :     paddw mm0, [inter_matrix1 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1
559 :     paddw mm3, [inter_matrix1 + 8*esi+120]
560 :     movq mm5,[inter_matrix_fixl + 8*esi+112]
561 :     movq mm7,[inter_matrix_fixl + 8*esi+120]
562 :     pmulhuw mm5,mm0
563 :     pmulhuw mm7,mm3 ;mm7: first approx of division
564 :     mov esp,esp
565 :     movq mm2,[inter_matrix + 8*esi+112]
566 :     movq mm6,[inter_matrix + 8*esi+120]
567 :     pmullw mm2,mm5 ;test value <= original
568 :     pmullw mm6,mm7
569 :     psubw mm0,mm2 ;mismatch
570 :     psubw mm3,mm6
571 :     movq mm2,[byte ebx]
572 :     movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16
573 :     pmulhuw mm0,[inter_matrix_fix + 8*esi+112] ;correction
574 :     pmulhuw mm3,[inter_matrix_fix + 8*esi+120]
575 :     paddw mm5,mm0 ;final result
576 :     paddw mm7,mm3
577 :     movq mm0,[edi]
578 :     movq mm3,[edi]
579 :     mov esp,esp
580 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
581 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
582 :     add esi,byte 2
583 :     paddw mm2,mm5 ;sum += x1
584 :     movq [ebx],mm7 ;store x2
585 :     psrlw mm5, 1 ; (level ) / (2*quant)
586 :     psrlw mm7, 1
587 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
588 :     pxor mm7, mm4 ;
589 :     psubw mm5, mm1 ; undisplace
590 :     psubw mm7, mm4 ;
591 :     db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
592 :     movq [edx + 8*esi+112-16], mm5
593 :     movq [edx + 8*esi +120-16], mm7
594 :     jng near .lloop
595 :     jmp near .done
596 :    
597 :    
598 :     ;===========================================================================
599 :     ;
600 :     ; void dequant4_intra_mmx(int16_t *data,
601 :     ; const int16_t const *coeff,
602 :     ; const uint32_t quant,
603 :     ; const uint32_t dcscalar);
604 :     ;
605 :     ;===========================================================================
606 :    
607 :     ; Note: in order to saturate 'easily', we pre-shift the quantifier
608 :     ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
609 :     ; build a saturating mask. It is non-zero only when an overflow occured.
610 :     ; We thus avoid packing/unpacking toward double-word.
611 :     ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
612 :     ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
613 :     ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
614 :     ; and quant in [1..31].
615 :     ;
616 :     ;********************************************************************
617 :     %macro DEQUANT4INTRAMMX 1
618 :     movq mm1, [byte ecx+ 16 * %1] ; mm0 = c = coeff[i]
619 :     movq mm4, [ecx+ 16 * %1 +8]; mm3 = c' = coeff[i+1]
620 :     psubw mm0,mm1
621 :     psubw mm3,mm4
622 :     pmaxsw mm0,mm1
623 :     pmaxsw mm3,mm4
624 :     psraw mm1,15
625 :     psraw mm4,15
626 :     %if %1
627 :     movq mm2,[eax+8] ;preshifted quant
628 :     movq mm7,[eax+8]
629 :     %endif
630 :     pmullw mm2, [intra_matrix + 16 * %1 ] ; matrix[i]*quant
631 :     pmullw mm7, [intra_matrix + 16 * %1 +8] ; matrix[i+1]*quant
632 :     movq mm5,mm0
633 :     movq mm6,mm3
634 :     pmulhw mm0, mm2 ; high of coeff*(matrix*quant)
635 :     pmulhw mm3, mm7 ; high of coeff*(matrix*quant)
636 :     pmullw mm2, mm5 ; low of coeff*(matrix*quant)
637 :     pmullw mm7, mm6 ; low of coeff*(matrix*quant)
638 :     pcmpgtw mm0, [eax]
639 :     pcmpgtw mm3, [eax]
640 :     paddusw mm2, mm0
641 :     paddusw mm7, mm3
642 :     psrlw mm2, 5
643 :     psrlw mm7, 5
644 :     pxor mm2, mm1 ; start negating back
645 :     pxor mm7, mm4 ; start negating back
646 :     psubusw mm1, mm0
647 :     psubusw mm4, mm3
648 :     movq mm0,[eax] ;zero
649 :     movq mm3,[eax] ;zero
650 :     psubw mm2, mm1 ; finish negating back
651 :     psubw mm7, mm4 ; finish negating back
652 :     movq [byte edx + 16 * %1], mm2 ; data[i]
653 :     movq [edx + 16 * %1 +8], mm7 ; data[i+1]
654 :     %endmacro
655 :    
656 :     align 16
657 :     cglobal dequant4_intra_3dne
658 :     dequant4_intra_3dne:
659 :    
660 :     mov eax, [esp+12] ; quant
661 :     mov ecx, [esp+8] ; coeff
662 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
663 :     psllw mm7, 2 ; << 2. See comment.
664 :     mov edx, [esp+4] ; data
665 :     push ebx
666 :     movsx ebx,word [ecx]
667 :     pxor mm0, mm0
668 :     pxor mm3, mm3
669 :     push esi
670 :     lea eax,[esp-28]
671 :     sub esp,byte 32
672 :     and eax,byte -8 ;points to qword aligned space on stack
673 :     movq [eax],mm0
674 :     movq [eax+8],mm7
675 :     imul ebx,[esp+16+8+32] ; dcscalar
676 :     movq mm2,mm7
677 :    
678 :    
679 :     align 4
680 :     DEQUANT4INTRAMMX 0
681 :     mov esi,-2048
682 :     nop
683 :     cmp ebx,esi
684 :     DEQUANT4INTRAMMX 1
685 :     cmovl ebx,esi
686 :     neg esi
687 :     sub esi,byte 1 ;2047
688 :     DEQUANT4INTRAMMX 2
689 :     cmp ebx,esi
690 :     cmovg ebx,esi
691 :     lea ebp,[byte ebp]
692 :     DEQUANT4INTRAMMX 3
693 :     mov esi,[esp+32]
694 :     mov [byte edx], bx
695 :     mov ebx,[esp+32+4]
696 :     DEQUANT4INTRAMMX 4
697 :     DEQUANT4INTRAMMX 5
698 :     DEQUANT4INTRAMMX 6
699 :     DEQUANT4INTRAMMX 7
700 :     add esp,byte 32+8
701 :    
702 :     ret
703 :    
704 :     ;===========================================================================
705 :     ;
706 :     ; void dequant4_inter_3dne(int16_t * data,
707 :     ; const int16_t * const coeff,
708 :     ; const uint32_t quant);
709 :     ;
710 :     ;===========================================================================
711 :    
712 :     ; Note: We use (2*c + sgn(c) - sgn(-c)) as multiplier
713 :     ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
714 :     ; sgn(x) is the result of 'pcmpgtw 0,x': 0 if x>=0, -1 if x<0.
715 :     ; It's mixed with the extraction of the absolute value.
716 :    
717 :     align 16
718 :     cglobal dequant4_inter_3dne
719 :     dequant4_inter_3dne:
720 :    
721 :     mov edx, [esp+ 4] ; data
722 :     mov ecx, [esp+ 8] ; coeff
723 :     mov eax, [esp+12] ; quant
724 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
725 :     mov eax, -14
726 :     paddw mm7, mm7 ; << 1
727 :     pxor mm6, mm6 ; mismatch sum
728 :     push esi
729 :     mov esi,mmzero
730 :     pxor mm1,mm1
731 :     pxor mm3,mm3
732 :     nop
733 :     nop4
734 :    
735 :     align 16
736 :     .loop
737 :     movq mm0, [ecx+8*eax + 7*16 ] ; mm0 = coeff[i]
738 :     pcmpgtw mm1, mm0 ; mm1 = sgn(c) (preserved)
739 :     movq mm2, [ecx+8*eax + 7*16 +8] ; mm2 = coeff[i+1]
740 :     pcmpgtw mm3, mm2 ; mm3 = sgn(c') (preserved)
741 :     paddsw mm0, mm1 ; c += sgn(c)
742 :     paddsw mm2, mm3 ; c += sgn(c')
743 :     paddw mm0, mm0 ; c *= 2
744 :     paddw mm2, mm2 ; c'*= 2
745 :    
746 :     movq mm4, [esi]
747 :     movq mm5, [esi]
748 :     psubw mm4, mm0 ; -c
749 :     psubw mm5, mm2 ; -c'
750 :    
751 :     psraw mm4, 16 ; mm4 = sgn(-c)
752 :     psraw mm5, 16 ; mm5 = sgn(-c')
753 :     psubsw mm0, mm4 ; c -= sgn(-c)
754 :     psubsw mm2, mm5 ; c' -= sgn(-c')
755 :     pxor mm0, mm1 ; finish changing sign if needed
756 :     pxor mm2, mm3 ; finish changing sign if needed
757 :    
758 :     ; we're short on register, here. Poor pairing...
759 :    
760 :     movq mm4, mm7 ; (matrix*quant)
761 :     nop
762 :     pmullw mm4, [inter_matrix + 8*eax + 7*16]
763 :     movq mm5, mm4
764 :     pmulhw mm5, mm0 ; high of c*(matrix*quant)
765 :     pmullw mm0, mm4 ; low of c*(matrix*quant)
766 :    
767 :     movq mm4, mm7 ; (matrix*quant)
768 :     pmullw mm4, [inter_matrix + 8*eax + 7*16 + 8]
769 :     add eax,byte 2
770 :    
771 :     pcmpgtw mm5, [esi]
772 :     paddusw mm0, mm5
773 :     psrlw mm0, 5
774 :     pxor mm0, mm1 ; start restoring sign
775 :     psubusw mm1, mm5
776 :    
777 :     movq mm5, mm4
778 :     pmulhw mm5, mm2 ; high of c*(matrix*quant)
779 :     pmullw mm2, mm4 ; low of c*(matrix*quant)
780 :     psubw mm0, mm1 ; finish restoring sign
781 :    
782 :     pcmpgtw mm5, [esi]
783 :     paddusw mm2, mm5
784 :     psrlw mm2, 5
785 :     pxor mm2, mm3 ; start restoring sign
786 :     psubusw mm3, mm5
787 :     psubw mm2, mm3 ; finish restoring sign
788 :     movq mm1, [esi]
789 :     movq mm3, [byte esi]
790 :     pxor mm6, mm0 ; mismatch control
791 :     movq [edx + 8*eax + 7*16 -2*8 ], mm0 ; data[i]
792 :     pxor mm6, mm2 ; mismatch control
793 :     movq [edx + 8*eax + 7*16 -2*8 +8], mm2 ; data[i+1]
794 :    
795 :     jng .loop
796 :     nop
797 :    
798 :     ; mismatch control
799 :    
800 :     pshufw mm0,mm6,01010101b
801 :     pshufw mm1,mm6,10101010b
802 :     pshufw mm2,mm6,11111111b
803 :     pxor mm6, mm0
804 :     pxor mm1, mm2
805 :     pxor mm6, mm1
806 :     movd eax, mm6
807 :     and eax,byte 1
808 :     xor eax,byte 1
809 :     mov esi,[esp]
810 :     add esp,byte 4
811 :     xor word [edx + 2*63], ax
812 :    
813 :     ret
814 :    

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