[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 1795 - (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 1795 ; * $Id: quantize_mpeg_xmm.asm,v 1.9 2008-11-26 01:04:34 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 :     %if 0
180 :     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 : Isibaar 1795 %endif
186 : edgomez 1382
187 : Isibaar 1795 ALIGN SECTION_ALIGN
188 : Isibaar 1793 .loop:
189 : Isibaar 1795 movq mm1, [_EAX + 8*_ESI+112] ; mm0 = [1st]
190 : edgomez 1382 psubw mm0, mm1 ;-mm1
191 : Isibaar 1795 movq mm4, [_EAX + 8*_ESI + 120] ;
192 : edgomez 1382 psubw mm3, mm4 ;-mm4
193 :     pmaxsw mm0, mm1 ;|src|
194 :     pmaxsw mm3, mm4
195 :     nop2
196 :     psraw mm1, 15 ;sign src
197 :     psraw mm4, 15
198 :     psllw mm0, 4 ; level << 4
199 :     psllw mm3, 4 ;
200 : Isibaar 1795 paddw mm0, [_EDI + 640 + 8*_ESI+112]
201 :     paddw mm3, [_EDI + 640 + 8*_ESI+120]
202 :     movq mm5, [_EDI + 896 + 8*_ESI+112]
203 :     movq mm7, [_EDI + 896 + 8*_ESI+120]
204 : edgomez 1382 pmulhuw mm5, mm0
205 :     pmulhuw mm7, mm3
206 : Isibaar 1795 mov _ESP, _ESP
207 :     movq mm2, [_EDI + 512 + 8*_ESI+112]
208 :     movq mm6, [_EDI + 512 + 8*_ESI+120]
209 : edgomez 1382 pmullw mm2, mm5
210 :     pmullw mm6, mm7
211 :     psubw mm0, mm2
212 :     psubw mm3, mm6
213 : Isibaar 1795 movq mm2, [byte _EBX]
214 :     %ifdef ARCH_IS_X86_64
215 :     lea r9, [mmx_divs]
216 :     movq mm6, [r9 + TMP0 * 8 - 8]
217 :     %else
218 :     movq mm6, [mmx_divs + TMP0 * 8 - 8]
219 :     %endif
220 :     pmulhuw mm0, [_EDI + 768 + 8*_ESI+112]
221 :     pmulhuw mm3, [_EDI + 768 + 8*_ESI+120]
222 :     paddw mm2, [_EBX+8] ;sum
223 : edgomez 1382 paddw mm5, mm0
224 :     paddw mm7, mm3
225 :     pxor mm0, mm0
226 :     pxor mm3, mm3
227 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
228 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
229 : Isibaar 1795 add _ESI, byte 2
230 : edgomez 1382 paddw mm2, mm5 ;sum += x1
231 : Isibaar 1795 movq [_EBX], mm7 ;store x2
232 : edgomez 1382 pxor mm5, mm1 ; mm0 *= sign(mm0)
233 :     pxor mm7, mm4 ;
234 :     psubw mm5, mm1 ; undisplace
235 :     psubw mm7, mm4 ;
236 : Isibaar 1795 movq [_EBX+8],mm2 ;store sum
237 :     movq [TMP1 + 8*_ESI+112-16], mm5
238 :     movq [TMP1 + 8*_ESI +120-16], mm7
239 : edgomez 1382 jng near .loop
240 :    
241 : Isibaar 1793 .done:
242 : edgomez 1382 ; calculate data[0] // (int32_t)dcscalar)
243 : Isibaar 1795 paddw mm2, [_EBX]
244 :     mov _EBX, [_ESP+24]
245 :     mov _EDI, [_ESP+PTR_SIZE+24]
246 :     mov _ESI, [_ESP+2*PTR_SIZE+24]
247 :     add _ESP, byte 3*PTR_SIZE+24
248 : edgomez 1382 pmaddwd mm2, [mmx_one]
249 :     punpckldq mm0, mm2 ;get low dw to mm0:high
250 :     paddd mm0,mm2
251 :     punpckhdq mm0, mm0 ;get result to low
252 :     movd eax, mm0
253 :    
254 :     ret
255 :    
256 : Isibaar 1795 ALIGN SECTION_ALIGN
257 : Isibaar 1793 .q1loop:
258 : Isibaar 1795 movq mm1, [_EAX + 8*_ESI+112] ; mm0 = [1st]
259 : edgomez 1382 psubw mm0, mm1 ;-mm1
260 : Isibaar 1795 movq mm4, [_EAX + 8*_ESI+120]
261 : edgomez 1382 psubw mm3, mm4 ;-mm4
262 :     pmaxsw mm0, mm1 ;|src|
263 :     pmaxsw mm3, mm4
264 :     nop2
265 :     psraw mm1, 15 ; sign src
266 :     psraw mm4, 15
267 :     psllw mm0, 4 ; level << 4
268 :     psllw mm3, 4
269 : Isibaar 1795 paddw mm0, [_EDI + 640 + 8*_ESI+112] ;mm0 is to be divided
270 :     paddw mm3, [_EDI + 640 + 8*_ESI+120] ; inter1 contains fix for division by 1
271 :     movq mm5, [_EDI + 896 + 8*_ESI+112] ;with rounding down
272 :     movq mm7, [_EDI + 896 + 8*_ESI+120]
273 : edgomez 1382 pmulhuw mm5, mm0
274 :     pmulhuw mm7, mm3 ;mm7: first approx of division
275 : Isibaar 1795 mov _ESP, _ESP
276 :     movq mm2, [_EDI + 512 + 8*_ESI+112]
277 :     movq mm6, [_EDI + 512 + 8*_ESI+120] ; divs for q<=16
278 : edgomez 1382 pmullw mm2, mm5 ;test value <= original
279 :     pmullw mm6, mm7
280 :     psubw mm0, mm2 ;mismatch
281 :     psubw mm3, mm6
282 : Isibaar 1795 movq mm2, [byte _EBX]
283 :     pmulhuw mm0, [_EDI + 768 + 8*_ESI+112] ;correction
284 :     pmulhuw mm3, [_EDI + 768 + 8*_ESI+120]
285 :     paddw mm2, [_EBX+8] ;sum
286 : edgomez 1382 paddw mm5, mm0 ;final result
287 :     paddw mm7, mm3
288 :     pxor mm0, mm0
289 :     pxor mm3, mm3
290 :     psrlw mm5, 1 ; (level ) /2 (quant = 1)
291 :     psrlw mm7, 1
292 : Isibaar 1795 add _ESI, byte 2
293 : edgomez 1382 paddw mm2, mm5 ;sum += x1
294 : Isibaar 1795 movq [_EBX], mm7 ;store x2
295 : edgomez 1382 pxor mm5, mm1 ; mm0 *= sign(mm0)
296 :     pxor mm7, mm4 ;
297 :     psubw mm5, mm1 ; undisplace
298 :     psubw mm7, mm4 ;
299 : Isibaar 1795 movq [_EBX+8], mm2 ;store sum
300 :     movq [TMP1 + 8*_ESI+112-16], mm5
301 :     movq [TMP1 + 8*_ESI +120-16], mm7
302 : edgomez 1382 jng near .q1loop
303 :     jmp near .done
304 :    
305 : Isibaar 1795 ALIGN SECTION_ALIGN
306 : Isibaar 1793 .lloop:
307 : Isibaar 1795 movq mm1, [_EAX + 8*_ESI+112] ; mm0 = [1st]
308 : edgomez 1382 psubw mm0,mm1 ;-mm1
309 : Isibaar 1795 movq mm4, [_EAX + 8*_ESI+120]
310 : edgomez 1382 psubw mm3,mm4 ;-mm4
311 :     pmaxsw mm0,mm1 ;|src|
312 :     pmaxsw mm3,mm4
313 :     nop2
314 :     psraw mm1,15 ;sign src
315 :     psraw mm4,15
316 :     psllw mm0, 4 ; level << 4
317 :     psllw mm3, 4 ;
318 : Isibaar 1795 paddw mm0, [_EDI + 640 + 8*_ESI+112] ;mm0 is to be divided inter1 contains fix for division by 1
319 :     paddw mm3, [_EDI + 640 + 8*_ESI+120]
320 :     movq mm5,[_EDI + 896 + 8*_ESI+112]
321 :     movq mm7,[_EDI + 896 + 8*_ESI+120]
322 : edgomez 1382 pmulhuw mm5,mm0
323 :     pmulhuw mm7,mm3 ;mm7: first approx of division
324 : Isibaar 1795 mov _ESP,_ESP
325 :     movq mm2,[_EDI + 512 + 8*_ESI+112]
326 :     movq mm6,[_EDI + 512 + 8*_ESI+120]
327 : edgomez 1382 pmullw mm2,mm5 ;test value <= original
328 :     pmullw mm6,mm7
329 :     psubw mm0,mm2 ;mismatch
330 :     psubw mm3,mm6
331 : Isibaar 1795 movq mm2,[byte _EBX]
332 :     %ifdef ARCH_IS_X86_64
333 :     lea r9, [mmx_div]
334 :     movq mm6, [r9 + TMP0 * 8 - 8]
335 :     %else
336 :     movq mm6,[mmx_div + TMP0 * 8 - 8] ; divs for q<=16
337 :     %endif
338 :     pmulhuw mm0,[_EDI + 768 + 8*_ESI+112] ;correction
339 :     pmulhuw mm3,[_EDI + 768 + 8*_ESI+120]
340 :     paddw mm2,[_EBX+8] ;sum
341 : edgomez 1382 paddw mm5,mm0 ;final result
342 :     paddw mm7,mm3
343 :     pxor mm0,mm0
344 :     pxor mm3,mm3
345 :     pmulhuw mm5, mm6 ; mm0 = (mm0 / 2Q) >> 16
346 :     pmulhuw mm7, mm6 ; (level ) / quant (0<quant<32)
347 : Isibaar 1795 add _ESI,byte 2
348 : edgomez 1382 psrlw mm5, 1 ; (level ) / (2*quant)
349 :     paddw mm2,mm5 ;sum += x1
350 :     psrlw mm7, 1
351 : Isibaar 1795 movq [_EBX],mm7 ;store x2
352 : edgomez 1382 pxor mm5, mm1 ; mm0 *= sign(mm0)
353 :     pxor mm7, mm4 ;
354 :     psubw mm5, mm1 ; undisplace
355 :     psubw mm7, mm4 ;
356 : Isibaar 1795 movq [_EBX+8], mm2 ;store sum
357 :     movq [TMP1 + 8*_ESI+112-16], mm5
358 :     movq [TMP1 + 8*_ESI +120-16], mm7
359 : edgomez 1382 jng near .lloop
360 :     jmp near .done
361 : Isibaar 1793 ENDFUNC
362 : edgomez 1382
363 :    
364 :     ;-----------------------------------------------------------------------------
365 :     ;
366 :     ; uint32_t dequant_mpeg_intra_3dne(int16_t *data,
367 :     ; const int16_t const *coeff,
368 :     ; const uint32_t quant,
369 :     ; const uint32_t dcscalar,
370 :     ; const uint16_t *mpeg_matrices);
371 :     ;
372 :     ;-----------------------------------------------------------------------------
373 :    
374 :     ; Note: in order to saturate 'easily', we pre-shift the quantifier
375 :     ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
376 :     ; build a saturating mask. It is non-zero only when an overflow occured.
377 :     ; We thus avoid packing/unpacking toward double-word.
378 :     ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
379 :     ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
380 :     ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
381 :     ; and quant in [1..31].
382 :     ;
383 :    
384 :     %macro DEQUANT4INTRAMMX 1
385 : Isibaar 1795 movq mm1, [byte TMP0+ 16 * %1] ; mm0 = c = coeff[i]
386 :     movq mm4, [TMP0+ 16 * %1 +8] ; mm3 = c' = coeff[i+1]
387 : edgomez 1382 psubw mm0, mm1
388 :     psubw mm3, mm4
389 :     pmaxsw mm0, mm1
390 :     pmaxsw mm3, mm4
391 :     psraw mm1, 15
392 :     psraw mm4, 15
393 :     %if %1
394 : Isibaar 1795 movq mm2, [_EAX+8] ;preshifted quant
395 :     movq mm7, [_EAX+8]
396 : edgomez 1382 %endif
397 : Isibaar 1795 pmullw mm2, [TMP1 + 16 * %1 ] ; matrix[i]*quant
398 :     pmullw mm7, [TMP1 + 16 * %1 +8] ; matrix[i+1]*quant
399 : edgomez 1382 movq mm5, mm0
400 :     movq mm6, mm3
401 :     pmulhw mm0, mm2 ; high of coeff*(matrix*quant)
402 :     pmulhw mm3, mm7 ; high of coeff*(matrix*quant)
403 :     pmullw mm2, mm5 ; low of coeff*(matrix*quant)
404 :     pmullw mm7, mm6 ; low of coeff*(matrix*quant)
405 : Isibaar 1795 pcmpgtw mm0, [_EAX]
406 :     pcmpgtw mm3, [_EAX]
407 : edgomez 1382 paddusw mm2, mm0
408 :     paddusw mm7, mm3
409 :     psrlw mm2, 5
410 :     psrlw mm7, 5
411 :     pxor mm2, mm1 ; start negating back
412 :     pxor mm7, mm4 ; start negating back
413 :     psubusw mm1, mm0
414 :     psubusw mm4, mm3
415 : Isibaar 1795 movq mm0, [_EAX] ;zero
416 :     movq mm3, [_EAX] ;zero
417 : edgomez 1382 psubw mm2, mm1 ; finish negating back
418 :     psubw mm7, mm4 ; finish negating back
419 : Isibaar 1795 movq [byte _EDI + 16 * %1], mm2 ; data[i]
420 :     movq [_EDI + 16 * %1 +8], mm7 ; data[i+1]
421 : edgomez 1382 %endmacro
422 :    
423 : Isibaar 1795 ALIGN SECTION_ALIGN
424 : edgomez 1382 dequant_mpeg_intra_3dne:
425 : Isibaar 1795 mov _EAX, prm3 ; quant
426 :     %ifdef ARCH_IS_X86_64
427 :     lea TMP0, [mmx_mul_quant]
428 :     movq mm7, [TMP0 + _EAX*8 - 8]
429 :     %else
430 :     movq mm7, [mmx_mul_quant + _EAX*8 - 8]
431 :     %endif
432 :     mov TMP0, prm2 ; coeff
433 :     psllw mm7, 2 ; << 2. See comment.
434 :     mov TMP1, prm5 ; mpeg_quant_matrices
435 :     push _EBX
436 :     movsx _EBX, word [TMP0]
437 : edgomez 1382 pxor mm0, mm0
438 :     pxor mm3, mm3
439 : Isibaar 1795 push _ESI
440 :     lea _EAX, [_ESP-28]
441 :     sub _ESP, byte 32
442 :     and _EAX, byte -8 ;points to qword ALIGNed space on stack
443 :     movq [_EAX], mm0
444 :     movq [_EAX+8], mm7
445 :     %ifdef ARCH_IS_X86_64
446 :     imul _EBX, prm4 ; dcscalar
447 :     %else
448 :     imul _EBX, [_ESP+16+8+32] ; dcscalar
449 :     %endif
450 : edgomez 1382 movq mm2, mm7
451 : Isibaar 1795 push _EDI
452 : edgomez 1382
453 : Isibaar 1795 %ifdef ARCH_IS_X86_64
454 :     mov _EDI, prm1 ; data
455 :     %else
456 :     mov _EDI, [_ESP+4+12+32]
457 :     %endif
458 :    
459 :     ALIGN SECTION_ALIGN
460 :    
461 : edgomez 1382 DEQUANT4INTRAMMX 0
462 :    
463 : Isibaar 1795 mov _ESI, -2048
464 : edgomez 1382 nop
465 : Isibaar 1795 cmp _EBX, _ESI
466 : edgomez 1382
467 :     DEQUANT4INTRAMMX 1
468 :    
469 : Isibaar 1795 cmovl _EBX, _ESI
470 :     neg _ESI
471 :     sub _ESI, byte 1 ;2047
472 : edgomez 1382
473 :     DEQUANT4INTRAMMX 2
474 :    
475 : Isibaar 1795 cmp _EBX, _ESI
476 :     cmovg _EBX, _ESI
477 :     lea _EBP, [byte _EBP]
478 : edgomez 1382
479 :     DEQUANT4INTRAMMX 3
480 :    
481 : Isibaar 1795 mov _ESI, [_ESP+32+PTR_SIZE]
482 :     mov [byte _EDI], bx
483 :     mov _EBX, [_ESP+32+2*PTR_SIZE]
484 : edgomez 1382
485 :     DEQUANT4INTRAMMX 4
486 :     DEQUANT4INTRAMMX 5
487 :     DEQUANT4INTRAMMX 6
488 :     DEQUANT4INTRAMMX 7
489 :    
490 : Isibaar 1795 pop _EDI
491 : edgomez 1382
492 : Isibaar 1795 add _ESP, byte 32+2*PTR_SIZE
493 : edgomez 1382
494 : Isibaar 1795 xor _EAX, _EAX
495 : edgomez 1382 ret
496 : Isibaar 1793 ENDFUNC
497 : edgomez 1382
498 :     ;-----------------------------------------------------------------------------
499 :     ;
500 :     ; uint32_t dequant_mpeg_inter_3dne(int16_t * data,
501 :     ; const int16_t * const coeff,
502 :     ; const uint32_t quant,
503 :     ; const uint16_t *mpeg_matrices);
504 :     ;
505 :     ;-----------------------------------------------------------------------------
506 :    
507 :     ; Note: We use (2*c + sgn(c) - sgn(-c)) as multiplier
508 :     ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
509 :     ; sgn(x) is the result of 'pcmpgtw 0,x': 0 if x>=0, -1 if x<0.
510 :     ; It's mixed with the extraction of the absolute value.
511 :    
512 : Isibaar 1795 ALIGN SECTION_ALIGN
513 : edgomez 1382 dequant_mpeg_inter_3dne:
514 : Isibaar 1795 mov _EAX, prm3 ; quant
515 :     %ifdef ARCH_IS_X86_64
516 :     lea TMP0, [mmx_mul_quant]
517 :     movq mm7, [TMP0 + _EAX*8 - 8]
518 :     %else
519 :     movq mm7, [mmx_mul_quant + _EAX*8 - 8]
520 :     %endif
521 :     mov TMP1, prm1 ; data
522 :     mov TMP0, prm2 ; coeff
523 :     mov _EAX, -14
524 : edgomez 1382 paddw mm7, mm7 ; << 1
525 :     pxor mm6, mm6 ; mismatch sum
526 : Isibaar 1795 push _ESI
527 :     push _EDI
528 :     mov _ESI, mmzero
529 : edgomez 1382 pxor mm1, mm1
530 :     pxor mm3, mm3
531 : Isibaar 1795 %ifdef ARCH_IS_X86_64
532 :     mov _EDI, prm4
533 :     %else
534 :     mov _EDI, [_ESP + 8 + 16] ; mpeg_quant_matrices
535 :     %endif
536 : edgomez 1382 nop
537 :     nop4
538 :    
539 : Isibaar 1795 ALIGN SECTION_ALIGN
540 : Isibaar 1793 .loop:
541 : Isibaar 1795 movq mm0, [TMP0+8*_EAX + 7*16 ] ; mm0 = coeff[i]
542 : edgomez 1382 pcmpgtw mm1, mm0 ; mm1 = sgn(c) (preserved)
543 : Isibaar 1795 movq mm2, [TMP0+8*_EAX + 7*16 +8] ; mm2 = coeff[i+1]
544 : edgomez 1382 pcmpgtw mm3, mm2 ; mm3 = sgn(c') (preserved)
545 :     paddsw mm0, mm1 ; c += sgn(c)
546 :     paddsw mm2, mm3 ; c += sgn(c')
547 :     paddw mm0, mm0 ; c *= 2
548 :     paddw mm2, mm2 ; c'*= 2
549 :    
550 : Isibaar 1795 movq mm4, [_ESI]
551 :     movq mm5, [_ESI]
552 : edgomez 1382 psubw mm4, mm0 ; -c
553 :     psubw mm5, mm2 ; -c'
554 :    
555 :     psraw mm4, 16 ; mm4 = sgn(-c)
556 :     psraw mm5, 16 ; mm5 = sgn(-c')
557 :     psubsw mm0, mm4 ; c -= sgn(-c)
558 :     psubsw mm2, mm5 ; c' -= sgn(-c')
559 :     pxor mm0, mm1 ; finish changing sign if needed
560 :     pxor mm2, mm3 ; finish changing sign if needed
561 :    
562 :     ; we're short on register, here. Poor pairing...
563 :    
564 :     movq mm4, mm7 ; (matrix*quant)
565 :     nop
566 : Isibaar 1795 pmullw mm4, [_EDI + 512 + 8*_EAX + 7*16]
567 : edgomez 1382 movq mm5, mm4
568 :     pmulhw mm5, mm0 ; high of c*(matrix*quant)
569 :     pmullw mm0, mm4 ; low of c*(matrix*quant)
570 :    
571 :     movq mm4, mm7 ; (matrix*quant)
572 : Isibaar 1795 pmullw mm4, [_EDI + 512 + 8*_EAX + 7*16 + 8]
573 :     add _EAX, byte 2
574 : edgomez 1382
575 : Isibaar 1795 pcmpgtw mm5, [_ESI]
576 : edgomez 1382 paddusw mm0, mm5
577 :     psrlw mm0, 5
578 :     pxor mm0, mm1 ; start restoring sign
579 :     psubusw mm1, mm5
580 :    
581 :     movq mm5, mm4
582 :     pmulhw mm5, mm2 ; high of c*(matrix*quant)
583 :     pmullw mm2, mm4 ; low of c*(matrix*quant)
584 :     psubw mm0, mm1 ; finish restoring sign
585 :    
586 : Isibaar 1795 pcmpgtw mm5, [_ESI]
587 : edgomez 1382 paddusw mm2, mm5
588 :     psrlw mm2, 5
589 :     pxor mm2, mm3 ; start restoring sign
590 :     psubusw mm3, mm5
591 :     psubw mm2, mm3 ; finish restoring sign
592 : Isibaar 1795 movq mm1, [_ESI]
593 :     movq mm3, [byte _ESI]
594 : edgomez 1382 pxor mm6, mm0 ; mismatch control
595 : Isibaar 1795 movq [TMP1 + 8*_EAX + 7*16 -2*8 ], mm0 ; data[i]
596 : edgomez 1382 pxor mm6, mm2 ; mismatch control
597 : Isibaar 1795 movq [TMP1 + 8*_EAX + 7*16 -2*8 +8], mm2 ; data[i+1]
598 : edgomez 1382
599 :     jng .loop
600 :     nop
601 :    
602 :     ; mismatch control
603 :    
604 :     pshufw mm0, mm6, 01010101b
605 :     pshufw mm1, mm6, 10101010b
606 :     pshufw mm2, mm6, 11111111b
607 :     pxor mm6, mm0
608 :     pxor mm1, mm2
609 :     pxor mm6, mm1
610 :     movd eax, mm6
611 : Isibaar 1795 pop _EDI
612 :     and _EAX, byte 1
613 :     xor _EAX, byte 1
614 :     mov _ESI, [_ESP]
615 :     add _ESP, byte PTR_SIZE
616 :     xor word [TMP1 + 2*63], ax
617 : edgomez 1382
618 : Isibaar 1795 xor _EAX, _EAX
619 : edgomez 1382 ret
620 : Isibaar 1793 ENDFUNC
621 : edgomez 1540
622 : Isibaar 1790
623 :     %ifidn __OUTPUT_FORMAT__,elf
624 :     section ".note.GNU-stack" noalloc noexec nowrite progbits
625 :     %endif
626 :    

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