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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1176 - (view) (download)

1 : edgomez 1174 ;/**************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 : edgomez 1176 ; * - 3dne Quantization/Dequantization -
5 : edgomez 1174 ; *
6 : edgomez 1176 ; * Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>
7 :     ; * 2002 Jaan Kalda
8 : edgomez 1174 ; *
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 : edgomez 1176 ; * $Id: quantize_mpeg_xmm.asm,v 1.1.2.2 2003-10-09 18:50:22 edgomez Exp $
24 : edgomez 1174 ; *
25 :     ; *************************************************************************/
26 : edgomez 1176
27 : edgomez 1174 ; _3dne functions are compatible with iSSE, but are optimized specifically
28 :     ; for K7 pipelines
29 :    
30 :     ; data/text alignment
31 :     %define ALIGN 8
32 :     %define SATURATE
33 :    
34 :     bits 32
35 :    
36 :     %macro cglobal 1
37 :     %ifdef PREFIX
38 :     global _%1
39 :     %define %1 _%1
40 :     %else
41 :     global %1
42 :     %endif
43 :     %endmacro
44 :    
45 :     %macro cextern 1
46 :     %ifdef PREFIX
47 :     extern _%1
48 :     %define %1 _%1
49 :     %else
50 :     extern %1
51 :     %endif
52 :     %endmacro
53 : edgomez 1176
54 :     ;***************************************************************************
55 :     ; Local data
56 :     ;***************************************************************************
57 :    
58 :     %ifdef FORMAT_COFF
59 :     SECTION .data data
60 :     %else
61 :     SECTION .data data align=8
62 :     %endif
63 :    
64 : edgomez 1174 align 8
65 : edgomez 1176 mmzero:
66 :     dd 0,0
67 :     mmx_one:
68 :     times 4 dw 1
69 : edgomez 1174
70 :     ;===========================================================================
71 :     ;
72 :     ; divide by 2Q table
73 :     ;
74 :     ;===========================================================================
75 :    
76 :     align ALIGN
77 : edgomez 1176 mmx_divs: ;i>2
78 : edgomez 1174 %assign i 1
79 :     %rep 31
80 :     times 4 dw ((1 << 15) / i + 1)
81 :     %assign i i+1
82 :     %endrep
83 :    
84 :     align ALIGN
85 : edgomez 1176 mmx_div: ;i>2
86 : edgomez 1174 %assign i 1
87 :     %rep 31
88 :     times 4 dw ((1 << 16) / i + 1)
89 :     %assign i i+1
90 :     %endrep
91 :    
92 :    
93 :     ;===========================================================================
94 :     ;
95 :     ; intra matrix
96 :     ;
97 :     ;===========================================================================
98 :    
99 :     %macro FIXX 1
100 :     dw (1 << 16) / (%1) + 1
101 :     %endmacro
102 :    
103 :     cextern intra_matrix_fixl
104 :     cextern intra_matrix_fix
105 :     cextern intra_matrix1
106 :     cextern intra_matrix
107 :    
108 :     ;===========================================================================
109 :     ;
110 :     ; inter matrix
111 :     ;
112 :     ;===========================================================================
113 :    
114 :     cextern inter_matrix1
115 :     cextern inter_matrix
116 :     cextern inter_matrix_fix
117 :     cextern inter_matrix_fixl
118 :    
119 :    
120 : edgomez 1176 %define nop4 db 08Dh, 074h, 026h,0
121 :     %define nop3 add esp, byte 0
122 :     %define nop2 mov esp, esp
123 :     %define nop7 db 08dh, 02ch, 02dh,0,0,0,0
124 :     %define nop6 add ebp, dword 0
125 : edgomez 1174
126 :     ;===========================================================================
127 :     ;
128 :     ; quantd table
129 :     ;
130 :     ;===========================================================================
131 :    
132 : edgomez 1176 %define VM18P 3
133 :     %define VM18Q 4
134 : edgomez 1174
135 : edgomez 1176 align 16
136 :     quantd:
137 : edgomez 1174 %assign i 1
138 :     %rep 31
139 :     times 4 dw (((VM18P*i) + (VM18Q/2)) / VM18Q)
140 :     %assign i i+1
141 :     %endrep
142 :    
143 :     ;===========================================================================
144 :     ;
145 :     ; multiple by 2Q table
146 :     ;
147 :     ;===========================================================================
148 :    
149 : edgomez 1176 align 16
150 :     mmx_mul_quant:
151 : edgomez 1174 %assign i 1
152 :     %rep 31
153 :     times 4 dw i
154 :     %assign i i+1
155 :     %endrep
156 :    
157 :     ;===========================================================================
158 :     ;
159 :     ; saturation limits
160 :     ;
161 :     ;===========================================================================
162 :    
163 :     align 16
164 : edgomez 1176 mmx_32767_minus_2047:
165 :     times 4 dw (32767-2047)
166 :     mmx_32768_minus_2048:
167 :     times 4 dw (32768-2048)
168 :     mmx_2047:
169 :     times 4 dw 2047
170 :     mmx_minus_2048:
171 :     times 4 dw (-2048)
172 :     zero:
173 :     times 4 dw 0
174 : edgomez 1174
175 : edgomez 1176 int_div:
176 : edgomez 1174 dd 0
177 :     %assign i 1
178 :     %rep 255
179 :     dd (1 << 17) / ( i) + 1
180 :     %assign i i+1
181 :     %endrep
182 :    
183 : edgomez 1176 ;***************************************************************************
184 :     ; Code
185 :     ;***************************************************************************
186 :    
187 : edgomez 1174 section .text
188 :    
189 :     ;===========================================================================
190 :     ;
191 : edgomez 1176 ; uint32_t quant_mpeg_intra_xmm(int16_t * coeff,
192 :     ; const int16_t const * data,
193 :     ; const uint32_t quant,
194 :     ; const uint32_t dcscalar);
195 : edgomez 1174 ;
196 :     ;===========================================================================
197 :    
198 :     align ALIGN
199 :     cglobal quant_mpeg_intra_xmm
200 :     quant_mpeg_intra_xmm:
201 : edgomez 1176 mov eax, [esp + 8] ; data
202 :     mov ecx, [esp + 12] ; quant
203 :     mov edx, [esp + 4] ; coeff
204 : edgomez 1174 push esi
205 :     push edi
206 :     push ebx
207 :     nop
208 : edgomez 1176 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 : edgomez 1174 nop6
217 :    
218 :     align ALIGN
219 :     .loop
220 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
221 :     psubw mm0, mm1 ;-mm1
222 :     movq mm4, [eax + 8*esi + 120] ;
223 :     psubw mm3, mm4 ;-mm4
224 :     pmaxsw mm0, mm1 ;|src|
225 :     pmaxsw mm3,mm4
226 :     nop2
227 :     psraw mm1, 15 ;sign src
228 :     psraw mm4, 15
229 :     psllw mm0, 4 ;level << 4 ;
230 :     psllw mm3, 4
231 :     paddw mm0, [intra_matrix1 + 8*esi+112]
232 :     paddw mm3, [intra_matrix1 + 8*esi+120]
233 :     movq mm5, [intra_matrix_fixl + 8*esi+112]
234 :     movq mm7, [intra_matrix_fixl + 8*esi+120]
235 :     pmulhuw mm5, mm0
236 :     pmulhuw mm7, mm3
237 : edgomez 1176 mov esp, esp
238 : edgomez 1174 movq mm2, [intra_matrix + 8*esi+112]
239 :     movq mm6, [intra_matrix + 8*esi+120]
240 :     pmullw mm2, mm5
241 :     pmullw mm6, mm7
242 :     psubw mm0, mm2
243 :     psubw mm3, mm6
244 :     nop4
245 :     movq mm2, [quantd + ecx * 8 - 8]
246 :     movq mm6, [mmx_divs + ecx * 8 - 8]
247 :     paddw mm5, mm2
248 :     paddw mm7, mm2
249 : edgomez 1176 mov esp, esp
250 : edgomez 1174 pmulhuw mm0, [intra_matrix_fix + 8*esi+112]
251 :     pmulhuw mm3, [intra_matrix_fix + 8*esi+120]
252 :     paddw mm5, mm0
253 :     paddw mm7, mm3
254 :     movq mm0, [edi]
255 :     movq mm3, [edi]
256 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
257 :     pmulhuw mm7, mm6 ; (level + quantd) / quant (0<quant<32)
258 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
259 :     pxor mm7, mm4 ;
260 :     psubw mm5, mm1 ; undisplace
261 :     psubw mm7, mm4 ;
262 :     movq [edx + 8*esi+112], mm5
263 :     movq [edx + 8*esi +120], mm7
264 : edgomez 1176 add esi, byte 2
265 :     jng near .loop
266 : edgomez 1174
267 :     .done
268 :     ; calculate data[0] // (int32_t)dcscalar)
269 : edgomez 1176 mov esi, [esp + 12 + 16] ; dcscalar
270 : edgomez 1174 movsx ecx, word [eax]
271 : edgomez 1176 mov edi, ecx
272 :     mov edx, [esp + 12 + 16]
273 :     shr edx, 1 ; ebx = dcscalar /2
274 :     sar edi, 31 ; cdq is vectorpath
275 :     xor edx, edi ; ebx = eax V -eax -1
276 :     sub ecx, edi
277 :     add ecx, edx
278 :     mov edx, [dword esp + 12 + 4]
279 :     mov esi, [int_div+4*esi]
280 : edgomez 1174 imul ecx, esi
281 : edgomez 1176 sar ecx, 17
282 :     lea ebx, [byte ecx + 1]
283 : edgomez 1174 cmovs ecx, ebx
284 :     ; idiv cx ; ecx = edi:ecx / dcscalar
285 :    
286 : edgomez 1176 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 : edgomez 1174
292 : edgomez 1176 xor eax, eax
293 : edgomez 1174 ret
294 :    
295 :     align ALIGN
296 :     .q1loop
297 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
298 :     psubw mm0, mm1 ;-mm1
299 :     movq mm4, [eax + 8*esi+120] ;
300 :     psubw mm3, mm4 ;-mm4
301 :     pmaxsw mm0, mm1 ;|src|
302 :     pmaxsw mm3, mm4
303 :     nop2
304 :     psraw mm1, 15 ;sign src
305 :     psraw mm4, 15
306 :     psllw mm0, 4 ; level << 4
307 :     psllw mm3, 4
308 :     paddw mm0, [intra_matrix1 + 8*esi+112] ;mm0 is to be divided
309 :     paddw mm3, [intra_matrix1 + 8*esi+120] ;intra1 contains fix for division by 1
310 :     movq mm5, [intra_matrix_fixl + 8*esi+112] ;with rounding down
311 :     movq mm7, [intra_matrix_fixl + 8*esi+120]
312 :     pmulhuw mm5, mm0
313 :     pmulhuw mm7, mm3 ;mm7: first approx of division
314 : edgomez 1176 mov esp, esp
315 : edgomez 1174 movq mm2, [intra_matrix + 8*esi+112]
316 :     movq mm6, [intra_matrix + 8*esi+120] ; divs for q<=16
317 :     pmullw mm2, mm5 ;test value <= original
318 :     pmullw mm6, mm7
319 :     psubw mm0, mm2 ;mismatch
320 :     psubw mm3, mm6
321 :     nop4
322 :     movq mm2, [quantd + ecx * 8 - 8]
323 :     paddw mm5, mm2 ;first approx with quantd
324 :     paddw mm7, mm2
325 : edgomez 1176 mov esp, esp
326 : edgomez 1174 pmulhuw mm0, [intra_matrix_fix + 8*esi+112] ;correction
327 :     pmulhuw mm3, [intra_matrix_fix + 8*esi+120]
328 :     paddw mm5, mm0 ;final result with quantd
329 :     paddw mm7, mm3
330 :     movq mm0, [edi]
331 :     movq mm3, [edi]
332 : edgomez 1176 mov esp, esp
333 : edgomez 1174 psrlw mm5, 1 ; (level + quantd) /2 (quant = 1)
334 :     psrlw mm7, 1
335 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
336 :     pxor mm7, mm4 ;
337 :     psubw mm5, mm1 ; undisplace
338 :     psubw mm7, mm4 ;
339 :     movq [edx + 8*esi+112], mm5
340 :     movq [edx + 8*esi +120], mm7
341 : edgomez 1176 add esi, byte 2
342 :     jng near .q1loop
343 :     jmp near .done
344 : edgomez 1174
345 :     align 8
346 :     .lloop
347 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
348 :     psubw mm0, mm1 ;-mm1
349 :     movq mm4, [eax + 8*esi+120] ;
350 :     psubw mm3, mm4 ;-mm4
351 :     pmaxsw mm0, mm1 ;|src|
352 :     pmaxsw mm3, mm4
353 :     nop2
354 :     psraw mm1, 15 ;sign src
355 :     psraw mm4, 15
356 :     psllw mm0, 4 ; level << 4
357 :     psllw mm3, 4 ;
358 :     paddw mm0, [intra_matrix1 + 8*esi+112] ;mm0 is to be divided intra1 contains fix for division by 1
359 :     paddw mm3, [intra_matrix1 + 8*esi+120]
360 :     movq mm5, [intra_matrix_fixl + 8*esi+112]
361 :     movq mm7, [intra_matrix_fixl + 8*esi+120]
362 :     pmulhuw mm5, mm0
363 :     pmulhuw mm7, mm3 ;mm7: first approx of division
364 : edgomez 1176 mov esp, esp
365 : edgomez 1174 movq mm2, [intra_matrix + 8*esi+112]
366 :     movq mm6, [intra_matrix + 8*esi+120]
367 :     pmullw mm2, mm5 ;test value <= original
368 :     pmullw mm6, mm7
369 :     psubw mm0, mm2 ;mismatch
370 :     psubw mm3, mm6
371 :     nop4
372 :     movq mm2, [quantd + ecx * 8 - 8]
373 :     movq mm6, [mmx_div + ecx * 8 - 8] ; divs for q<=16
374 :     paddw mm5, mm2 ;first approx with quantd
375 :     paddw mm7, mm2
376 : edgomez 1176 mov esp, esp
377 : edgomez 1174 pmulhuw mm0, [intra_matrix_fix + 8*esi+112] ;correction
378 :     pmulhuw mm3, [intra_matrix_fix + 8*esi+120]
379 :     paddw mm5, mm0 ;final result with quantd
380 :     paddw mm7, mm3
381 :     movq mm0, [edi]
382 :     movq mm3, [edi]
383 : edgomez 1176 mov esp, esp
384 : edgomez 1174 pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
385 :     pmulhuw mm7, mm6 ; (level + quantd) / quant (0<quant<32)
386 :     psrlw mm5, 1 ; (level + quantd) / (2*quant)
387 :     psrlw mm7, 1
388 :     pxor mm5, mm1 ; mm0 *= sign(mm0)
389 :     pxor mm7, mm4 ;
390 :     psubw mm5, mm1 ; undisplace
391 :     psubw mm7, mm4 ;
392 :     movq [edx + 8*esi+112], mm5
393 :     movq [edx + 8*esi +120], mm7
394 : edgomez 1176 add esi,byte 2
395 :     jng near .lloop
396 :     jmp near .done
397 : edgomez 1174
398 :     ;===========================================================================
399 :     ;
400 : edgomez 1176 ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,
401 :     ; const int16_t const * data,
402 :     ; const uint32_t quant);
403 : edgomez 1174 ;
404 :     ;===========================================================================
405 :    
406 :     align ALIGN
407 :     cglobal quant_mpeg_inter_xmm
408 :     quant_mpeg_inter_xmm:
409 : edgomez 1176 mov eax, [esp + 8] ; data
410 :     mov ecx, [esp + 12] ; quant
411 :     mov edx, [esp + 4] ; coeff
412 : edgomez 1174 push esi
413 :     push edi
414 :     push ebx
415 :     nop
416 : edgomez 1176 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 : edgomez 1174 nop
431 :    
432 :     align ALIGN
433 :     .loop
434 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
435 : edgomez 1176 psubw mm0, mm1 ;-mm1
436 : edgomez 1174 movq mm4, [eax + 8*esi + 120] ;
437 : edgomez 1176 psubw mm3, mm4 ;-mm4
438 :     pmaxsw mm0, mm1 ;|src|
439 :     pmaxsw mm3, mm4
440 : edgomez 1174 nop2
441 : edgomez 1176 psraw mm1, 15 ;sign src
442 :     psraw mm4, 15
443 :     psllw mm0, 4 ; level << 4
444 :     psllw mm3, 4 ;
445 :     paddw mm0, [inter_matrix1 + 8*esi+112]
446 :     paddw mm3, [inter_matrix1 + 8*esi+120]
447 :     movq mm5, [inter_matrix_fixl + 8*esi+112]
448 :     movq mm7, [inter_matrix_fixl + 8*esi+120]
449 :     pmulhuw mm5, mm0
450 :     pmulhuw mm7, mm3
451 :     mov esp, esp
452 :     movq mm2, [inter_matrix + 8*esi+112]
453 :     movq mm6, [inter_matrix + 8*esi+120]
454 :     pmullw mm2, mm5
455 :     pmullw mm6, mm7
456 :     psubw mm0, mm2
457 :     psubw mm3, mm6
458 :     movq mm2, [byte ebx]
459 :     movq mm6, [mmx_divs + ecx * 8 - 8]
460 :     pmulhuw mm0, [inter_matrix_fix + 8*esi+112]
461 :     pmulhuw mm3, [inter_matrix_fix + 8*esi+120]
462 :     paddw mm2, [ebx+8] ;sum
463 :     paddw mm5, mm0
464 :     paddw mm7, mm3
465 :     movq mm0, [edi]
466 :     movq mm3, [edi]
467 : edgomez 1174 pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
468 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
469 : edgomez 1176 add esi, byte 2
470 :     paddw mm2, mm5 ;sum += x1
471 :     movq [ebx], mm7 ;store x2
472 : edgomez 1174 pxor mm5, mm1 ; mm0 *= sign(mm0)
473 :     pxor mm7, mm4 ;
474 :     psubw mm5, mm1 ; undisplace
475 :     psubw mm7, mm4 ;
476 : edgomez 1176 db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
477 : edgomez 1174 movq [edx + 8*esi+112-16], mm5
478 :     movq [edx + 8*esi +120-16], mm7
479 :     jng near .loop
480 :    
481 :     .done
482 :     ; calculate data[0] // (int32_t)dcscalar)
483 : edgomez 1176 paddw mm2, [ebx]
484 :     mov ebx, [esp+24]
485 :     mov edi, [esp+4+24]
486 :     mov esi, [esp+8+24]
487 :     add esp, byte 12+24
488 :     pmaddwd mm2, [mmx_one]
489 :     punpckldq mm0, mm2 ;get low dw to mm0:high
490 :     paddd mm0,mm2
491 :     punpckhdq mm0, mm0 ;get result to low
492 : edgomez 1174 movd eax, mm0
493 :    
494 :     ret
495 :    
496 :     align ALIGN
497 :     .q1loop
498 :     movq mm1, [eax + 8*esi+112] ; mm0 = [1st]
499 : edgomez 1176 psubw mm0, mm1 ;-mm1
500 : edgomez 1174 movq mm4, [eax + 8*esi+120] ;
501 : edgomez 1176 psubw mm3, mm4 ;-mm4
502 :     pmaxsw mm0, mm1 ;|src|
503 :     pmaxsw mm3, mm4
504 : edgomez 1174 nop2
505 : edgomez 1176 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 : edgomez 1174 pxor mm5, mm1 ; mm0 *= sign(mm0)
536 :     pxor mm7, mm4 ;
537 :     psubw mm5, mm1 ; undisplace
538 :     psubw mm7, mm4 ;
539 : edgomez 1176 movq [ebx+8], mm2 ;store sum
540 : edgomez 1174 movq [edx + 8*esi+112-16], mm5
541 :     movq [edx + 8*esi +120-16], mm7
542 : edgomez 1176 jng near .q1loop
543 :     jmp near .done
544 : edgomez 1174
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 : edgomez 1176 pmaxsw mm0,mm1 ;|src|
552 :     pmaxsw mm3,mm4
553 : edgomez 1174 nop2
554 : edgomez 1176 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 mm2,[ebx+8] ;sum
576 :     paddw mm5,mm0 ;final result
577 :     paddw mm7,mm3
578 :     movq mm0,[edi]
579 :     movq mm3,[edi]
580 : edgomez 1174 pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
581 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
582 : edgomez 1176 add esi,byte 2
583 :     psrlw mm5, 1 ; (level ) / (2*quant)
584 :     paddw mm2,mm5 ;sum += x1
585 :     psrlw mm7, 1
586 :     movq [ebx],mm7 ;store x2
587 : edgomez 1174 pxor mm5, mm1 ; mm0 *= sign(mm0)
588 :     pxor mm7, mm4 ;
589 :     psubw mm5, mm1 ; undisplace
590 :     psubw mm7, mm4 ;
591 : edgomez 1176 db 0Fh, 7Fh, 54h, 23h, 08 ;movq [ebx+8],mm2 ;store sum
592 : edgomez 1174 movq [edx + 8*esi+112-16], mm5
593 :     movq [edx + 8*esi +120-16], mm7
594 :     jng near .lloop
595 : edgomez 1176 jmp near .done
596 : edgomez 1174
597 :    
598 :     ;===========================================================================
599 :     ;
600 : edgomez 1176 ; uint32_t dequant_mpeg_intra_3dne(int16_t *data,
601 :     ; const int16_t const *coeff,
602 :     ; const uint32_t quant,
603 :     ; const uint32_t dcscalar);
604 : edgomez 1174 ;
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 : edgomez 1176
618 : edgomez 1174 %macro DEQUANT4INTRAMMX 1
619 : edgomez 1176 movq mm1, [byte ecx+ 16 * %1] ; mm0 = c = coeff[i]
620 :     movq mm4, [ecx+ 16 * %1 +8]; mm3 = c' = coeff[i+1]
621 :     psubw mm0, mm1
622 :     psubw mm3, mm4
623 :     pmaxsw mm0, mm1
624 :     pmaxsw mm3, mm4
625 :     psraw mm1, 15
626 :     psraw mm4, 15
627 : edgomez 1174 %if %1
628 : edgomez 1176 movq mm2, [eax+8] ;preshifted quant
629 :     movq mm7, [eax+8]
630 : edgomez 1174 %endif
631 : edgomez 1176 pmullw mm2, [intra_matrix + 16 * %1 ] ; matrix[i]*quant
632 :     pmullw mm7, [intra_matrix + 16 * %1 +8] ; matrix[i+1]*quant
633 :     movq mm5, mm0
634 :     movq mm6, mm3
635 :     pmulhw mm0, mm2 ; high of coeff*(matrix*quant)
636 :     pmulhw mm3, mm7 ; high of coeff*(matrix*quant)
637 :     pmullw mm2, mm5 ; low of coeff*(matrix*quant)
638 :     pmullw mm7, mm6 ; low of coeff*(matrix*quant)
639 :     pcmpgtw mm0, [eax]
640 :     pcmpgtw mm3, [eax]
641 :     paddusw mm2, mm0
642 :     paddusw mm7, mm3
643 :     psrlw mm2, 5
644 :     psrlw mm7, 5
645 :     pxor mm2, mm1 ; start negating back
646 :     pxor mm7, mm4 ; start negating back
647 :     psubusw mm1, mm0
648 :     psubusw mm4, mm3
649 :     movq mm0, [eax] ;zero
650 :     movq mm3, [eax] ;zero
651 :     psubw mm2, mm1 ; finish negating back
652 :     psubw mm7, mm4 ; finish negating back
653 :     movq [byte edx + 16 * %1], mm2 ; data[i]
654 :     movq [edx + 16 * %1 +8], mm7 ; data[i+1]
655 : edgomez 1174 %endmacro
656 :    
657 :     align 16
658 :     cglobal dequant_mpeg_intra_3dne
659 :     dequant_mpeg_intra_3dne:
660 : edgomez 1176 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 : edgomez 1174
678 :     align 4
679 :    
680 :     DEQUANT4INTRAMMX 0
681 :    
682 : edgomez 1176 mov esi, -2048
683 : edgomez 1174 nop
684 : edgomez 1176 cmp ebx, esi
685 : edgomez 1174
686 :     DEQUANT4INTRAMMX 1
687 :    
688 : edgomez 1176 cmovl ebx, esi
689 :     neg esi
690 :     sub esi, byte 1 ;2047
691 : edgomez 1174
692 :     DEQUANT4INTRAMMX 2
693 :    
694 : edgomez 1176 cmp ebx, esi
695 :     cmovg ebx, esi
696 :     lea ebp, [byte ebp]
697 : edgomez 1174
698 :     DEQUANT4INTRAMMX 3
699 :    
700 : edgomez 1176 mov esi, [esp+32]
701 :     mov [byte edx], bx
702 :     mov ebx, [esp+32+4]
703 : edgomez 1174
704 :     DEQUANT4INTRAMMX 4
705 :     DEQUANT4INTRAMMX 5
706 :     DEQUANT4INTRAMMX 6
707 :     DEQUANT4INTRAMMX 7
708 :    
709 : edgomez 1176 add esp, byte 32+8
710 : edgomez 1174
711 : edgomez 1176 xor eax, eax
712 :     ret
713 : edgomez 1174
714 :     ;===========================================================================
715 :     ;
716 : edgomez 1176 ; uint32_t dequant_mpeg_inter_3dne(int16_t * data,
717 :     ; const int16_t * const coeff,
718 :     ; const uint32_t quant);
719 : edgomez 1174 ;
720 :     ;===========================================================================
721 :    
722 :     ; Note: We use (2*c + sgn(c) - sgn(-c)) as multiplier
723 :     ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
724 :     ; sgn(x) is the result of 'pcmpgtw 0,x': 0 if x>=0, -1 if x<0.
725 :     ; It's mixed with the extraction of the absolute value.
726 :    
727 :     align 16
728 :     cglobal dequant_mpeg_inter_3dne
729 :     dequant_mpeg_inter_3dne:
730 : edgomez 1176 mov edx, [esp+ 4] ; data
731 :     mov ecx, [esp+ 8] ; coeff
732 :     mov eax, [esp+12] ; quant
733 :     movq mm7, [mmx_mul_quant + eax*8 - 8]
734 :     mov eax, -14
735 :     paddw mm7, mm7 ; << 1
736 :     pxor mm6, mm6 ; mismatch sum
737 :     push esi
738 :     mov esi, mmzero
739 :     pxor mm1, mm1
740 :     pxor mm3, mm3
741 : edgomez 1174 nop
742 :     nop4
743 :    
744 :     align 16
745 :     .loop
746 : edgomez 1176 movq mm0, [ecx+8*eax + 7*16 ] ; mm0 = coeff[i]
747 :     pcmpgtw mm1, mm0 ; mm1 = sgn(c) (preserved)
748 :     movq mm2, [ecx+8*eax + 7*16 +8] ; mm2 = coeff[i+1]
749 :     pcmpgtw mm3, mm2 ; mm3 = sgn(c') (preserved)
750 :     paddsw mm0, mm1 ; c += sgn(c)
751 :     paddsw mm2, mm3 ; c += sgn(c')
752 :     paddw mm0, mm0 ; c *= 2
753 :     paddw mm2, mm2 ; c'*= 2
754 : edgomez 1174
755 : edgomez 1176 movq mm4, [esi]
756 :     movq mm5, [esi]
757 :     psubw mm4, mm0 ; -c
758 :     psubw mm5, mm2 ; -c'
759 : edgomez 1174
760 : edgomez 1176 psraw mm4, 16 ; mm4 = sgn(-c)
761 :     psraw mm5, 16 ; mm5 = sgn(-c')
762 :     psubsw mm0, mm4 ; c -= sgn(-c)
763 :     psubsw mm2, mm5 ; c' -= sgn(-c')
764 :     pxor mm0, mm1 ; finish changing sign if needed
765 :     pxor mm2, mm3 ; finish changing sign if needed
766 : edgomez 1174
767 :     ; we're short on register, here. Poor pairing...
768 :    
769 : edgomez 1176 movq mm4, mm7 ; (matrix*quant)
770 : edgomez 1174 nop
771 : edgomez 1176 pmullw mm4, [inter_matrix + 8*eax + 7*16]
772 :     movq mm5, mm4
773 :     pmulhw mm5, mm0 ; high of c*(matrix*quant)
774 :     pmullw mm0, mm4 ; low of c*(matrix*quant)
775 : edgomez 1174
776 : edgomez 1176 movq mm4, mm7 ; (matrix*quant)
777 :     pmullw mm4, [inter_matrix + 8*eax + 7*16 + 8]
778 :     add eax, byte 2
779 : edgomez 1174
780 : edgomez 1176 pcmpgtw mm5, [esi]
781 :     paddusw mm0, mm5
782 :     psrlw mm0, 5
783 :     pxor mm0, mm1 ; start restoring sign
784 :     psubusw mm1, mm5
785 : edgomez 1174
786 : edgomez 1176 movq mm5, mm4
787 :     pmulhw mm5, mm2 ; high of c*(matrix*quant)
788 :     pmullw mm2, mm4 ; low of c*(matrix*quant)
789 :     psubw mm0, mm1 ; finish restoring sign
790 : edgomez 1174
791 : edgomez 1176 pcmpgtw mm5, [esi]
792 :     paddusw mm2, mm5
793 :     psrlw mm2, 5
794 :     pxor mm2, mm3 ; start restoring sign
795 :     psubusw mm3, mm5
796 :     psubw mm2, mm3 ; finish restoring sign
797 :     movq mm1, [esi]
798 :     movq mm3, [byte esi]
799 :     pxor mm6, mm0 ; mismatch control
800 :     movq [edx + 8*eax + 7*16 -2*8 ], mm0 ; data[i]
801 :     pxor mm6, mm2 ; mismatch control
802 :     movq [edx + 8*eax + 7*16 -2*8 +8], mm2 ; data[i+1]
803 : edgomez 1174
804 : edgomez 1176 jng .loop
805 : edgomez 1174 nop
806 :    
807 :     ; mismatch control
808 :    
809 : edgomez 1176 pshufw mm0, mm6, 01010101b
810 :     pshufw mm1, mm6, 10101010b
811 :     pshufw mm2, mm6, 11111111b
812 :     pxor mm6, mm0
813 :     pxor mm1, mm2
814 :     pxor mm6, mm1
815 :     movd eax, mm6
816 :     and eax, byte 1
817 :     xor eax, byte 1
818 :     mov esi, [esp]
819 :     add esp, byte 4
820 :     xor word [edx + 2*63], ax
821 : edgomez 1174
822 : edgomez 1176 xor eax, eax
823 : edgomez 1174 ret

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