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

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