[svn] / trunk / xvidcore / src / quant / x86_asm / quantize_h263_3dne.asm Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/quant/x86_asm/quantize_h263_3dne.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 Jaan Kalda
7 :     ; *
8 : Isibaar 1795 ; * This program is free software ; you can r_EDIstribute it and/or modify
9 : edgomez 1382 ; * it under the terms of the GNU General Public License as published by
10 :     ; * the Free Software Foundation ; either version 2 of the License, or
11 :     ; * (at your option) any later version.
12 :     ; *
13 :     ; * This program is distributed in the hope that it will be useful,
14 :     ; * but WITHOUT ANY WARRANTY ; without even the implied warranty of
15 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 :     ; * GNU General Public License for more details.
17 :     ; *
18 :     ; * You should have received a copy of the GNU General Public License
19 :     ; * along with this program ; if not, write to the Free Software
20 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 :     ; *
22 : Isibaar 1795 ; * $Id: quantize_h263_3dne.asm,v 1.9 2008-11-26 01:04:34 Isibaar Exp $
23 : edgomez 1382 ; *
24 :     ; *************************************************************************/
25 :     ;
26 :     ; these 3dne functions are compatible with iSSE, but are optimized specifically for
27 :     ; K7 pipelines
28 :    
29 :     ; enable dequant saturate [-2048,2047], test purposes only.
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 int_div:
42 :     dd 0
43 :     %assign i 1
44 :     %rep 255
45 :     dd (1 << 16) / (i) + 1
46 :     %assign i i+1
47 :     %endrep
48 :    
49 : Isibaar 1795 ALIGN SECTION_ALIGN
50 : edgomez 1382 plus_one:
51 :     times 8 dw 1
52 :    
53 :     ;-----------------------------------------------------------------------------
54 :     ; subtract by Q/2 table
55 :     ;-----------------------------------------------------------------------------
56 :    
57 : Isibaar 1795 ALIGN SECTION_ALIGN
58 : edgomez 1382 mmx_sub:
59 :     %assign i 1
60 :     %rep 31
61 :     times 4 dw i / 2
62 :     %assign i i+1
63 :     %endrep
64 :    
65 :    
66 :     ;-----------------------------------------------------------------------------
67 :     ;
68 :     ; divide by 2Q table
69 :     ;
70 :     ; use a shift of 16 to take full advantage of _pmulhw_
71 :     ; for q=1, _pmulhw_ will overflow so it is treated seperately
72 :     ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
73 :     ;
74 :     ;-----------------------------------------------------------------------------
75 :    
76 : Isibaar 1795 ALIGN SECTION_ALIGN
77 : edgomez 1382 mmx_div:
78 :     %assign i 1
79 :     %rep 31
80 :     times 4 dw (1 << 16) / (i * 2) + 1
81 :     %assign i i+1
82 :     %endrep
83 :    
84 :     ;-----------------------------------------------------------------------------
85 :     ; add by (odd(Q) ? Q : Q - 1) table
86 :     ;-----------------------------------------------------------------------------
87 :    
88 : Isibaar 1795 ALIGN SECTION_ALIGN
89 : edgomez 1382 mmx_add:
90 :     %assign i 1
91 :     %rep 31
92 :     %if i % 2 != 0
93 :     times 4 dw i
94 :     %else
95 :     times 4 dw i - 1
96 :     %endif
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:
106 :     %assign i 1
107 :     %rep 31
108 :     times 4 dw i * 2
109 :     %assign i i+1
110 :     %endrep
111 :    
112 :     ;-----------------------------------------------------------------------------
113 :     ; saturation limits
114 :     ;-----------------------------------------------------------------------------
115 :    
116 : Isibaar 1795 ALIGN SECTION_ALIGN
117 : edgomez 1382 mmx_32768_minus_2048:
118 :     times 4 dw (32768-2048)
119 :     mmx_32767_minus_2047:
120 :     times 4 dw (32767-2047)
121 :    
122 : Isibaar 1795 ALIGN SECTION_ALIGN
123 : edgomez 1382 mmx_2047:
124 :     times 4 dw 2047
125 :    
126 : Isibaar 1795 ALIGN SECTION_ALIGN
127 : edgomez 1382 mmzero:
128 :     dd 0, 0
129 :     int2047:
130 :     dd 2047
131 :     int_2048:
132 :     dd -2048
133 :    
134 :     ;=============================================================================
135 :     ; Code
136 :     ;=============================================================================
137 :    
138 : Isibaar 1795 SECTION .rotext align=SECTION_ALIGN
139 : edgomez 1382
140 :    
141 :     ;-----------------------------------------------------------------------------
142 :     ;
143 :     ; uint32_t quant_h263_intra_3dne(int16_t * coeff,
144 :     ; const int16_t const * data,
145 :     ; const uint32_t quant,
146 :     ; const uint32_t dcscalar,
147 :     ; const uint16_t *mpeg_matrices);
148 :     ;
149 :     ;-----------------------------------------------------------------------------
150 :     ;This is Athlon-optimized code (ca 70 clk per call)
151 :    
152 :     %macro quant_intra1 1
153 :     psubw mm1, mm0 ;A3
154 :     psubw mm3, mm2 ;B3
155 :     %if (%1)
156 :     psubw mm5, mm4 ;C8
157 :     psubw mm7, mm6 ;D8
158 :     %endif
159 :    
160 : Isibaar 1795 ALIGN SECTION_ALIGN
161 :     movq mm4, [_ECX + %1 * 32 +16] ;C1
162 : edgomez 1382 pmaxsw mm1, mm0 ;A4
163 : Isibaar 1795 movq mm6, [_ECX + %1 * 32 +24] ;D1
164 : edgomez 1382 pmaxsw mm3, mm2 ;B4
165 :    
166 :    
167 :     psraw mm0, 15 ;A5
168 :     psraw mm2, 15 ;B5
169 :     %if (%1)
170 : Isibaar 1795 movq [_EDX + %1 * 32 + 16-32], mm5 ;C9
171 :     movq [_EDX + %1 * 32 + 24-32], mm7 ;D9
172 : edgomez 1382 %endif
173 :    
174 :     psrlw mm1, 1 ;A6
175 :     psrlw mm3, 1 ;B6
176 : Isibaar 1795 movq mm5, [_EBX] ;C2
177 :     movq mm7, [_EBX] ;D2
178 : edgomez 1382
179 :     pxor mm1, mm0 ;A7
180 :     pxor mm3, mm2 ;B7
181 :    
182 :     psubw mm5, mm4 ;C3
183 :     psubw mm7, mm6 ;D3
184 :     psubw mm1, mm0 ;A8
185 :     psubw mm3, mm2 ;B8
186 :    
187 :     %if (%1 == 0)
188 : Isibaar 1795 push _EBP
189 :     movq mm0, [_ECX + %1 * 32 +32]
190 : edgomez 1382 %elif (%1 < 3)
191 : Isibaar 1795 movq mm0, [_ECX + %1 * 32 +32] ;A1
192 : edgomez 1382 %endif
193 :     pmaxsw mm5, mm4 ;C4
194 :     %if (%1 < 3)
195 : Isibaar 1795 movq mm2, [_ECX + %1 * 32 +8+32] ;B1
196 : edgomez 1382 %else
197 : Isibaar 1795 cmp _ESP, _ESP
198 : edgomez 1382 %endif
199 :     pmaxsw mm7, mm6 ;D4
200 :    
201 :     psraw mm4, 15 ;C5
202 :     psraw mm6, 15 ;D5
203 : Isibaar 1795 movq [byte _EDX + %1 * 32], mm1 ;A9
204 :     movq [_EDX + %1 * 32+8], mm3 ;B9
205 : edgomez 1382
206 :    
207 :     psrlw mm5, 1 ;C6
208 :     psrlw mm7, 1 ;D6
209 :     %if (%1 < 3)
210 : Isibaar 1795 movq mm1, [_EBX] ;A2
211 :     movq mm3, [_EBX] ;B2
212 : edgomez 1382 %endif
213 :     %if (%1 == 3)
214 : Isibaar 1795 %ifdef ARCH_IS_X86_64
215 :     lea r9, [int_div]
216 :     imul eax, dword [r9+4*_EDI]
217 :     %else
218 :     imul _EAX, [int_div+4*_EDI]
219 : edgomez 1382 %endif
220 : Isibaar 1795 %endif
221 : edgomez 1382 pxor mm5, mm4 ;C7
222 :     pxor mm7, mm6 ;D7
223 :     %endm
224 :    
225 :    
226 :     %macro quant_intra 1
227 :     ; Rules for athlon:
228 :     ; 1) schedule latencies
229 :     ; 2) add/mul and load/store in 2:1 proportion
230 :     ; 3) avoid spliting >3byte instructions over 8byte boundaries
231 :    
232 :     psubw mm1, mm0 ;A3
233 :     psubw mm3, mm2 ;B3
234 :     %if (%1)
235 :     psubw mm5, mm4 ;C8
236 :     psubw mm7, mm6 ;D8
237 :     %endif
238 :    
239 : Isibaar 1795 ALIGN SECTION_ALIGN
240 :     movq mm4, [_ECX + %1 * 32 +16] ;C1
241 : edgomez 1382 pmaxsw mm1, mm0 ;A4
242 : Isibaar 1795 movq mm6, [_ECX + %1 * 32 +24] ;D1
243 : edgomez 1382 pmaxsw mm3, mm2 ;B4
244 :    
245 :    
246 :     psraw mm0, 15 ;A5
247 :     psraw mm2, 15 ;B5
248 :     %if (%1)
249 : Isibaar 1795 movq [_EDX + %1 * 32 + 16-32], mm5 ;C9
250 :     movq [_EDX + %1 * 32 + 24-32], mm7 ;D9
251 : edgomez 1382 %endif
252 :    
253 : Isibaar 1795 pmulhw mm1, [_ESI] ;A6
254 :     pmulhw mm3, [_ESI] ;B6
255 :     movq mm5, [_EBX] ;C2
256 :     movq mm7, [_EBX] ;D2
257 : edgomez 1382
258 :     nop
259 :     nop
260 :     pxor mm1, mm0 ;A7
261 :     pxor mm3, mm2 ;B7
262 :    
263 :     psubw mm5, mm4 ;C3
264 :     psubw mm7, mm6 ;D3
265 :     psubw mm1, mm0 ;A8
266 :     psubw mm3, mm2 ;B8
267 :    
268 :    
269 :     %if (%1 < 3)
270 : Isibaar 1795 movq mm0, [_ECX + %1 * 32 +32] ;A1
271 : edgomez 1382 %endif
272 :     pmaxsw mm5, mm4 ;C4
273 :     %if (%1 < 3)
274 : Isibaar 1795 movq mm2, [_ECX + %1 * 32 +8+32] ;B1
275 : edgomez 1382 %else
276 : Isibaar 1795 cmp _ESP, _ESP
277 : edgomez 1382 %endif
278 :     pmaxsw mm7,mm6 ;D4
279 :    
280 :     psraw mm4, 15 ;C5
281 :     psraw mm6, 15 ;D5
282 : Isibaar 1795 movq [byte _EDX + %1 * 32], mm1 ;A9
283 :     movq [_EDX + %1 * 32+8], mm3 ;B9
284 : edgomez 1382
285 :    
286 : Isibaar 1795 pmulhw mm5, [_ESI] ;C6
287 :     pmulhw mm7, [_ESI] ;D6
288 : edgomez 1382 %if (%1 < 3)
289 : Isibaar 1795 movq mm1, [_EBX] ;A2
290 :     movq mm3, [_EBX] ;B2
291 : edgomez 1382 %endif
292 :     %if (%1 == 0)
293 : Isibaar 1795 push _EBP
294 : edgomez 1382 %elif (%1 < 3)
295 :     nop
296 :     %endif
297 :     nop
298 :     %if (%1 == 3)
299 : Isibaar 1795 %ifdef ARCH_IS_X86_64
300 :     lea r9, [int_div]
301 :     imul eax, dword [r9+4*_EDI]
302 :     %else
303 :     imul _EAX, [int_div+4*_EDI]
304 : edgomez 1382 %endif
305 : Isibaar 1795 %endif
306 : edgomez 1382 pxor mm5, mm4 ;C7
307 :     pxor mm7, mm6 ;D7
308 :     %endmacro
309 :    
310 :    
311 : Isibaar 1795 ALIGN SECTION_ALIGN
312 : edgomez 1382 cglobal quant_h263_intra_3dne
313 :     quant_h263_intra_3dne:
314 :    
315 : Isibaar 1795 %ifdef ARCH_IS_X86_64
316 :     mov TMP0, [_ESP]
317 :     add _ESP, PTR_SIZE
318 :     %ifndef WINDOWS
319 :     push prm6
320 :     push prm5
321 :     %endif
322 :     push prm4
323 :     push prm3
324 :     push prm2
325 :     push prm1
326 :     sub _ESP, PTR_SIZE
327 :     mov [_ESP], TMP0
328 :     %endif
329 :    
330 :     mov _EAX, [_ESP + 3*PTR_SIZE] ; quant
331 :     mov _ECX, [_ESP + 2*PTR_SIZE] ; data
332 :     mov _EDX, [_ESP + 1*PTR_SIZE] ; coeff
333 : edgomez 1382 cmp al, 1
334 :     pxor mm1, mm1
335 :     pxor mm3, mm3
336 : Isibaar 1795 movq mm0, [_ECX] ; mm0 = [1st]
337 :     movq mm2, [_ECX + 8]
338 :     push _ESI
339 :     %ifdef ARCH_IS_X86_64
340 :     lea _ESI, [mmx_div]
341 :     lea _ESI, [_ESI + _EAX*8 - 8]
342 :     %else
343 :     lea _ESI, [mmx_div + _EAX*8 - 8]
344 :     %endif
345 : edgomez 1382
346 : Isibaar 1795 push _EBX
347 :     mov _EBX, mmzero
348 :     push _EDI
349 : edgomez 1382 jz near .q1loop
350 :    
351 :     quant_intra 0
352 : Isibaar 1795 mov _EBP, [_ESP + (4+4)*PTR_SIZE] ; dcscalar
353 :     ; NB -- there are 3 pushes in the function preambule and one more
354 :     ; in "quant_intra 0", thus an added offset of 16 bytes
355 :     movsx _EAX, word [byte _ECX] ; DC
356 : edgomez 1382
357 :     quant_intra 1
358 : Isibaar 1795 mov _EDI, _EAX
359 :     sar _EDI, 31 ; sign(DC)
360 :     shr _EBP, byte 1 ; _EBP = dcscalar/2
361 : edgomez 1382
362 :     quant_intra 2
363 : Isibaar 1795 sub _EAX, _EDI ; DC (+1)
364 :     xor _EBP, _EDI ; sign(DC) dcscalar /2 (-1)
365 :     mov _EDI, [_ESP + (4+4)*PTR_SIZE] ; dscalar
366 :     lea _EAX, [byte _EAX + _EBP] ; DC + sign(DC) dcscalar/2
367 :     mov _EBP, [byte _ESP]
368 : edgomez 1382
369 :     quant_intra 3
370 :     psubw mm5, mm4 ;C8
371 : Isibaar 1795 mov _ESI, [_ESP + 3*PTR_SIZE] ; pop back the register value
372 :     mov _EDI, [_ESP + 1*PTR_SIZE] ; pop back the register value
373 :     sar _EAX, 16
374 :     lea _EBX, [byte _EAX + 1] ; workaround for _EAX < 0
375 :     cmovs _EAX, _EBX ; conditionnaly move the corrected value
376 :     mov [_EDX], ax ; coeff[0] = ax
377 :     mov _EBX, [_ESP + 2*PTR_SIZE] ; pop back the register value
378 :     add _ESP, byte 4*PTR_SIZE ; "quant_intra 0" pushed _EBP, but we don't restore that one, just correct the stack offset by 16
379 : edgomez 1382 psubw mm7, mm6 ;D8
380 : Isibaar 1795 movq [_EDX + 3 * 32 + 16], mm5 ;C9
381 :     movq [_EDX + 3 * 32 + 24], mm7 ;D9
382 : edgomez 1382
383 : Isibaar 1795 xor _EAX, _EAX
384 :    
385 :     %ifdef ARCH_IS_X86_64
386 :     mov TMP0, [_ESP]
387 :     %ifndef WINDOWS
388 :     add _ESP, 6*PTR_SIZE
389 :     %else
390 :     add _ESP, 4*PTR_SIZE
391 :     %endif
392 :     mov [_ESP], TMP0
393 :     %endif
394 :    
395 : edgomez 1382 ret
396 :    
397 : Isibaar 1795 ALIGN SECTION_ALIGN
398 : edgomez 1382
399 : Isibaar 1793 .q1loop:
400 : edgomez 1382 quant_intra1 0
401 : Isibaar 1795 mov _EBP, [_ESP + (4+4)*PTR_SIZE] ; dcscalar
402 :     movsx _EAX, word [byte _ECX] ; DC
403 : edgomez 1382
404 :     quant_intra1 1
405 : Isibaar 1795 mov _EDI, _EAX
406 :     sar _EDI, 31 ; sign(DC)
407 :     shr _EBP, byte 1 ; _EBP = dcscalar /2
408 : edgomez 1382
409 :     quant_intra1 2
410 : Isibaar 1795 sub _EAX, _EDI ; DC (+1)
411 :     xor _EBP, _EDI ; sign(DC) dcscalar /2 (-1)
412 :     mov _EDI, [_ESP + (4+4)*PTR_SIZE] ; dcscalar
413 :     lea _EAX, [byte _EAX + _EBP] ; DC + sign(DC) dcscalar /2
414 :     mov _EBP, [byte _ESP]
415 : edgomez 1382
416 :     quant_intra1 3
417 :     psubw mm5, mm4 ;C8
418 : Isibaar 1795 mov _ESI, [_ESP + 3*PTR_SIZE] ; pop back the register value
419 :     mov _EDI, [_ESP + 1*PTR_SIZE] ; pop back the register value
420 :     sar _EAX, 16
421 :     lea _EBX, [byte _EAX + 1] ; workaround for _EAX < 0
422 :     cmovs _EAX, _EBX ; conditionnaly move the corrected value
423 :     mov [_EDX], ax ; coeff[0] = ax
424 :     mov _EBX, [_ESP + 2*PTR_SIZE] ; pop back the register value
425 :     add _ESP, byte 4*PTR_SIZE ; "quant_intra 0" pushed _EBP, but we don't restore that one, just correct the stack offset by 16
426 : edgomez 1382 psubw mm7, mm6 ;D8
427 : Isibaar 1795 movq [_EDX + 3 * 32 + 16], mm5 ;C9
428 :     movq [_EDX + 3 * 32 + 24], mm7 ;D9
429 : edgomez 1382
430 : Isibaar 1795 xor _EAX, _EAX
431 :    
432 :     %ifdef ARCH_IS_X86_64
433 :     mov TMP0, [_ESP]
434 :     %ifndef WINDOWS
435 :     add _ESP, 6*PTR_SIZE
436 :     %else
437 :     add _ESP, 4*PTR_SIZE
438 :     %endif
439 :     mov [_ESP], TMP0
440 :     %endif
441 :    
442 : edgomez 1382 ret
443 : Isibaar 1793 ENDFUNC
444 : edgomez 1382
445 :    
446 :     ;-----------------------------------------------------------------------------
447 :     ;
448 :     ; uint32_t quant_h263_inter_3dne(int16_t * coeff,
449 :     ; const int16_t const * data,
450 :     ; const uint32_t quant,
451 :     ; const uint16_t *mpeg_matrices);
452 :     ;
453 :     ;-----------------------------------------------------------------------------
454 :     ;This is Athlon-optimized code (ca 90 clk per call)
455 :     ;Optimized by Jaan, 30 Nov 2002
456 :    
457 :    
458 :     %macro quantinter 1
459 : Isibaar 1795 movq mm1, [_EAX] ;A2
460 : edgomez 1382 psraw mm3, 15 ;B6
461 :     %if (%1)
462 :     psubw mm2, mm6 ;C10
463 :     %endif
464 :     psubw mm1, mm0 ;A3
465 :     pmulhw mm4, mm7 ;B7
466 : Isibaar 1795 movq mm6, [_ECX + %1*24+16] ;C1
467 : edgomez 1382 pmaxsw mm1, mm0 ;A4
468 :     paddw mm5, mm4 ;B8
469 :     %if (%1)
470 : Isibaar 1795 movq [_EDX + %1*24+16-24], mm2 ;C11
471 : edgomez 1382 %endif
472 : Isibaar 1795 psubusw mm1, [_EBX] ;A5 mm0 -= sub (unsigned, dont go < 0)
473 : edgomez 1382 pxor mm4, mm3 ;B9
474 : Isibaar 1795 movq mm2, [_EAX] ;C2
475 : edgomez 1382 psraw mm0, 15 ;A6
476 :     psubw mm4, mm3 ;B10
477 :     psubw mm2, mm6 ;C3
478 :     pmulhw mm1, mm7 ;A7 mm0 = (mm0 / 2Q) >> 24
479 : Isibaar 1795 movq mm3, [_ECX + %1*24+8] ;B1
480 : edgomez 1382 pmaxsw mm2, mm6 ;C4
481 :     paddw mm5, mm1 ;A8 sum += mm0
482 :     %if (%1)
483 : Isibaar 1795 movq [_EDX + %1*24+8-24], mm4 ;B11
484 : edgomez 1382 %else
485 : Isibaar 1795 movq [_EDX + 120], mm4 ;B11
486 : edgomez 1382 %endif
487 : Isibaar 1795 psubusw mm2, [_EBX] ;C5
488 : edgomez 1382 pxor mm1, mm0 ;A9 mm0 *= sign(mm0)
489 : Isibaar 1795 movq mm4, [_EAX] ;B2
490 : edgomez 1382 psraw mm6, 15 ;C6
491 :     psubw mm1, mm0 ;A10 undisplace
492 :     psubw mm4, mm3 ;B3
493 :     pmulhw mm2, mm7 ;C7
494 : Isibaar 1795 movq mm0, [_ECX + %1*24+24] ;A1 mm0 = [1st]
495 : edgomez 1382 pmaxsw mm4, mm3 ;B4
496 :     paddw mm5, mm2 ;C8
497 : Isibaar 1795 movq [byte _EDX + %1*24], mm1 ;A11
498 :     psubusw mm4, [_EBX] ;B5
499 : edgomez 1382 pxor mm2, mm6 ;C9
500 :     %endmacro
501 :    
502 :     %macro quantinter1 1
503 : Isibaar 1795 movq mm0, [byte _ECX + %1*16] ;mm0 = [1st]
504 :     movq mm3, [_ECX + %1*16+8] ;
505 :     movq mm1, [_EAX]
506 :     movq mm4, [_EAX]
507 : edgomez 1382 psubw mm1, mm0
508 :     psubw mm4, mm3
509 :     pmaxsw mm1, mm0
510 :     pmaxsw mm4, mm3
511 :     psubusw mm1, mm6 ; mm0 -= sub (unsigned, dont go < 0)
512 :     psubusw mm4, mm6 ;
513 :     psraw mm0, 15
514 :     psraw mm3, 15
515 :     psrlw mm1, 1 ; mm0 = (mm0 / 2Q) >> 16
516 :     psrlw mm4, 1 ;
517 :     paddw mm5, mm1 ; sum += mm0
518 :     pxor mm1, mm0 ; mm0 *= sign(mm0)
519 :     paddw mm5, mm4
520 :     pxor mm4, mm3 ;
521 :     psubw mm1, mm0 ; undisplace
522 :     psubw mm4, mm3
523 : Isibaar 1795 cmp _ESP, _ESP
524 :     movq [byte _EDX + %1*16], mm1
525 :     movq [_EDX + %1*16+8], mm4
526 : edgomez 1382 %endmacro
527 :    
528 : Isibaar 1795 ALIGN SECTION_ALIGN
529 : edgomez 1382 cglobal quant_h263_inter_3dne
530 :     quant_h263_inter_3dne:
531 :    
532 : Isibaar 1795 %ifdef ARCH_IS_X86_64
533 :     mov TMP0, [_ESP]
534 :     add _ESP, PTR_SIZE
535 :     %ifndef WINDOWS
536 :     push prm6
537 :     push prm5
538 :     %endif
539 :     push prm4
540 :     push prm3
541 :     push prm2
542 :     push prm1
543 :     sub _ESP, PTR_SIZE
544 :     mov [_ESP], TMP0
545 :     %endif
546 :    
547 :     mov _EDX, [_ESP + 1*PTR_SIZE] ; coeff
548 :     mov _ECX, [_ESP + 2*PTR_SIZE] ; data
549 :     mov _EAX, [_ESP + 3*PTR_SIZE] ; quant
550 :     push _EBX
551 :    
552 : edgomez 1382 pxor mm5, mm5 ; sum
553 :     nop
554 : Isibaar 1795 %ifdef ARCH_IS_X86_64
555 :     lea _EBX, [mmx_div]
556 :     movq mm7, [_EBX + _EAX * 8 - 8]
557 :     lea _EBX, [mmx_sub]
558 :     lea _EBX, [_EBX + _EAX * 8 - 8]
559 :     %else
560 :     lea _EBX,[mmx_sub + _EAX * 8 - 8] ; sub
561 :     movq mm7, [mmx_div + _EAX * 8 - 8] ; divider
562 :     %endif
563 : edgomez 1382
564 :     cmp al, 1
565 : Isibaar 1795 lea _EAX, [mmzero]
566 : edgomez 1382 jz near .q1loop
567 : Isibaar 1795 cmp _ESP, _ESP
568 :     ALIGN SECTION_ALIGN
569 :     movq mm3, [_ECX + 120] ;B1
570 : edgomez 1382 pxor mm4, mm4 ;B2
571 :     psubw mm4, mm3 ;B3
572 : Isibaar 1795 movq mm0, [_ECX] ;A1 mm0 = [1st]
573 : edgomez 1382 pmaxsw mm4, mm3 ;B4
574 : Isibaar 1795 psubusw mm4, [_EBX] ;B5
575 : edgomez 1382
576 :     quantinter 0
577 :     quantinter 1
578 :     quantinter 2
579 :     quantinter 3
580 :     quantinter 4
581 :    
582 :     psraw mm3, 15 ;B6
583 :     psubw mm2, mm6 ;C10
584 :     pmulhw mm4, mm7 ;B7
585 :     paddw mm5, mm4 ;B8
586 :     pxor mm4, mm3 ;B9
587 :     psubw mm4, mm3 ;B10
588 : Isibaar 1795 movq [_EDX + 4*24+16], mm2 ;C11
589 :     pop _EBX
590 :     movq [_EDX + 4*24+8], mm4 ;B11
591 : edgomez 1382 pmaddwd mm5, [plus_one]
592 :     movq mm0, mm5
593 :     punpckhdq mm5, mm5
594 :     paddd mm0, mm5
595 :     movd eax, mm0 ; return sum
596 :    
597 : Isibaar 1795 %ifdef ARCH_IS_X86_64
598 :     mov TMP0, [_ESP]
599 :     %ifndef WINDOWS
600 :     add _ESP, 6*PTR_SIZE
601 :     %else
602 :     add _ESP, 4*PTR_SIZE
603 :     %endif
604 :     mov [_ESP], TMP0
605 :     %endif
606 :    
607 : edgomez 1382 ret
608 :    
609 : Isibaar 1795 ALIGN SECTION_ALIGN
610 : Isibaar 1793 .q1loop:
611 : Isibaar 1795 movq mm6, [byte _EBX]
612 : edgomez 1382
613 :     quantinter1 0
614 :     quantinter1 1
615 :     quantinter1 2
616 :     quantinter1 3
617 :     quantinter1 4
618 :     quantinter1 5
619 :     quantinter1 6
620 :     quantinter1 7
621 :    
622 :     pmaddwd mm5, [plus_one]
623 :     movq mm0, mm5
624 :     psrlq mm5, 32
625 :     paddd mm0, mm5
626 :     movd eax, mm0 ; return sum
627 :    
628 : Isibaar 1795 pop _EBX
629 : edgomez 1382
630 : Isibaar 1795 %ifdef ARCH_IS_X86_64
631 :     mov TMP0, [_ESP]
632 :     %ifndef WINDOWS
633 :     add _ESP, 6*PTR_SIZE
634 :     %else
635 :     add _ESP, 4*PTR_SIZE
636 :     %endif
637 :     mov [_ESP], TMP0
638 :     %endif
639 :    
640 : edgomez 1382 ret
641 : Isibaar 1793 ENDFUNC
642 : edgomez 1382
643 : Isibaar 1795
644 : edgomez 1382 ;-----------------------------------------------------------------------------
645 :     ;
646 :     ; uint32_t dequant_h263_intra_3dne(int16_t *data,
647 :     ; const int16_t const *coeff,
648 :     ; const uint32_t quant,
649 :     ; const uint32_t dcscalar,
650 :     ; const uint16_t *mpeg_matrices);
651 :     ;
652 :     ;-----------------------------------------------------------------------------
653 :    
654 :     ; this is the same as dequant_inter_3dne, except that we're
655 :     ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
656 :    
657 :     ;This is Athlon-optimized code (ca 106 clk per call)
658 :    
659 :     %macro dequant 1
660 : Isibaar 1795 movq mm1, [_ECX+%1*24] ; c = coeff[i] ;A2
661 : edgomez 1382 psubw mm0, mm1 ;-c ;A3 (1st dep)
662 :     %if (%1)
663 :     paddw mm4, mm6 ;C11 mm6 free (4th+)
664 :     %endif
665 :     pmaxsw mm0, mm1 ;|c| ;A4 (2nd)
666 :     %if (%1)
667 : Isibaar 1795 mov _EBP, _EBP
668 :     pminsw mm4, [_EBX] ;C12 saturates to +2047 (5th+) later
669 : edgomez 1382 %endif
670 : Isibaar 1795 movq mm6, [_ESI] ;0 ;A5 mm6 in use
671 :     pandn mm7, [_EAX] ;B9 offset = isZero ? 0 : quant_add (2nd)
672 : edgomez 1382 %if (%1)
673 :     pxor mm5, mm4 ;C13 (6th+) 1later
674 :     %endif
675 : Isibaar 1795 movq mm4, [_ESI] ;C1 ;0
676 :     mov _ESP, _ESP
677 :     pcmpeqw mm6, [_ECX+%1*24] ;A6 (c ==0) ? -1 : 0 (1st)
678 :     ALIGN SECTION_ALIGN
679 : edgomez 1382 psraw mm1, 15 ; sign(c) ;A7 (2nd)
680 :     %if (%1)
681 : Isibaar 1795 movq [_EDX+%1*24+16-24], mm5 ; C14 (7th) 2later
682 : edgomez 1382 %endif
683 :     paddw mm7, mm3 ;B10 offset +negate back (3rd)
684 : Isibaar 1795 pmullw mm0, [_EDI] ;*= 2Q ;A8 (3rd+)
685 : edgomez 1382 paddw mm2, mm7 ;B11 mm7 free (4th+)
686 : Isibaar 1795 lea _EBP, [byte _EBP]
687 :     movq mm5, [_ECX+%1*24+16] ;C2 ; c = coeff[i]
688 : edgomez 1382 psubw mm4, mm5 ;-c ;C3 (1st dep)
689 : Isibaar 1795 pandn mm6, [_EAX] ;A9 offset = isZero ? 0 : quant_add (2nd)
690 :     pminsw mm2, [_EBX] ;B12 saturates to +2047 (5th+)
691 : edgomez 1382 pxor mm3, mm2 ;B13 (6th+)
692 : Isibaar 1795 movq mm2, [byte _ESI] ;B1 ;0
693 : edgomez 1382 %if (%1)
694 : Isibaar 1795 movq [_EDX+%1*24+8-24], mm3 ;B14 (7th)
695 : edgomez 1382 %else
696 : Isibaar 1795 movq [_EDX+120], mm3
697 : edgomez 1382 %endif
698 :     pmaxsw mm4, mm5 ;|c| ;C4 (2nd)
699 :     paddw mm6, mm1 ;A10 offset +negate back (3rd)
700 : Isibaar 1795 movq mm3, [_ECX+%1*24 + 8] ;B2 ; c = coeff[i]
701 : edgomez 1382 psubw mm2, mm3 ;-c ;B3 (1st dep)
702 :     paddw mm0, mm6 ;A11 mm6 free (4th+)
703 : Isibaar 1795 movq mm6, [byte _ESI] ;0 ;C5 mm6 in use
704 :     pcmpeqw mm6, [_ECX+%1*24+16] ;C6 (c ==0) ? -1 : 0 (1st)
705 :     pminsw mm0, [_EBX] ;A12 saturates to +2047 (5th+)
706 : edgomez 1382 pmaxsw mm2, mm3 ;|c| ;B4 (2nd)
707 :     pxor mm1, mm0 ;A13 (6th+)
708 : Isibaar 1795 pmullw mm4, [_EDI] ;*= 2Q ;C8 (3rd+)
709 : edgomez 1382 psraw mm5, 15 ; sign(c) ;C7 (2nd)
710 : Isibaar 1795 movq mm7, [byte _ESI] ;0 ;B5 mm7 in use
711 :     pcmpeqw mm7, [_ECX+%1*24 + 8] ;B6 (c ==0) ? -1 : 0 (1st)
712 : edgomez 1382 %if (%1 < 4)
713 : Isibaar 1795 movq mm0, [byte _ESI] ;A1 ;0
714 : edgomez 1382 %endif
715 : Isibaar 1795 pandn mm6, [byte _EAX] ;C9 offset = isZero ? 0 : quant_add (2nd)
716 : edgomez 1382 psraw mm3, 15 ;sign(c) ;B7 (2nd)
717 : Isibaar 1795 movq [byte _EDX+%1*24], mm1 ;A14 (7th)
718 : edgomez 1382 paddw mm6, mm5 ;C10 offset +negate back (3rd)
719 : Isibaar 1795 pmullw mm2, [_EDI] ;*= 2Q ;B8 (3rd+)
720 :     mov _ESP, _ESP
721 : edgomez 1382 %endmacro
722 :    
723 :    
724 : Isibaar 1795 ALIGN SECTION_ALIGN
725 : edgomez 1382 cglobal dequant_h263_intra_3dne
726 :     dequant_h263_intra_3dne:
727 : Isibaar 1795
728 :     %ifdef ARCH_IS_X86_64
729 :     mov TMP0, [_ESP]
730 :     add _ESP, PTR_SIZE
731 :     %ifndef WINDOWS
732 :     push prm6
733 :     push prm5
734 :     %endif
735 :     push prm4
736 :     push prm3
737 :     push prm2
738 :     push prm1
739 :     sub _ESP, PTR_SIZE
740 :     mov [_ESP], TMP0
741 :     %endif
742 :    
743 :     mov _ECX, [_ESP+ 2*PTR_SIZE] ; coeff
744 :     mov _EAX, [_ESP+ 3*PTR_SIZE] ; quant
745 : edgomez 1382 pxor mm0, mm0
746 :     pxor mm2, mm2
747 : Isibaar 1795 push _EDI
748 :     push _EBX
749 :     %ifdef ARCH_IS_X86_64
750 :     lea _EDI, [mmx_mul]
751 :     lea _EDI, [_EDI + _EAX*8 - 8] ; 2*quant
752 :     %else
753 :     lea _EDI, [mmx_mul + _EAX*8 - 8] ; 2*quant
754 :     %endif
755 :     push _EBP
756 :     mov _EBX, mmx_2047
757 :     movsx _EBP, word [_ECX]
758 :     %ifdef ARCH_IS_X86_64
759 :     lea r9, [mmx_add]
760 :     lea _EAX, [r9 + _EAX*8 - 8] ; quant or quant-1
761 :     %else
762 :     lea _EAX, [mmx_add + _EAX*8 - 8] ; quant or quant-1
763 :     %endif
764 :     push _ESI
765 :     mov _ESI, mmzero
766 : edgomez 1382 pxor mm7, mm7
767 : Isibaar 1795 movq mm3, [_ECX+120] ;B2 ; c = coeff[i]
768 :     pcmpeqw mm7, [_ECX+120] ;B6 (c ==0) ? -1 : 0 (1st)
769 : edgomez 1382
770 : Isibaar 1795 imul _EBP, [_ESP+(4+4)*PTR_SIZE] ; dcscalar
771 : edgomez 1382 psubw mm2, mm3 ;-c ;B3 (1st dep)
772 :     pmaxsw mm2, mm3 ;|c| ;B4 (2nd)
773 : Isibaar 1795 pmullw mm2, [_EDI] ;*= 2Q ;B8 (3rd+)
774 : edgomez 1382 psraw mm3, 15 ; sign(c) ;B7 (2nd)
775 : Isibaar 1795 mov _EDX, [_ESP+ (1+4)*PTR_SIZE] ; data
776 : edgomez 1382
777 : Isibaar 1795 ALIGN SECTION_ALIGN
778 : edgomez 1382 dequant 0
779 :    
780 : Isibaar 1795 cmp _EBP, -2048
781 :     mov _ESP, _ESP
782 : edgomez 1382
783 :     dequant 1
784 :    
785 : Isibaar 1795 cmovl _EBP, [int_2048]
786 : edgomez 1382 nop
787 :    
788 :     dequant 2
789 :    
790 : Isibaar 1795 cmp _EBP, 2047
791 :     mov _ESP, _ESP
792 : edgomez 1382
793 :     dequant 3
794 :    
795 : Isibaar 1795 cmovg _EBP, [int2047]
796 : edgomez 1382 nop
797 :    
798 :     dequant 4
799 :    
800 :     paddw mm4, mm6 ;C11 mm6 free (4th+)
801 : Isibaar 1795 pminsw mm4, [_EBX] ;C12 saturates to +2047 (5th+)
802 :     pandn mm7, [_EAX] ;B9 offset = isZero ? 0 : quant_add (2nd)
803 :     mov _EAX, _EBP
804 :     mov _ESI, [_ESP]
805 :     mov _EBP, [_ESP+PTR_SIZE]
806 : edgomez 1382 pxor mm5, mm4 ;C13 (6th+)
807 :     paddw mm7, mm3 ;B10 offset +negate back (3rd)
808 : Isibaar 1795 movq [_EDX+4*24+16], mm5 ;C14 (7th)
809 : edgomez 1382 paddw mm2, mm7 ;B11 mm7 free (4th+)
810 : Isibaar 1795 pminsw mm2, [_EBX] ;B12 saturates to +2047 (5th+)
811 :     mov _EBX, [_ESP+2*PTR_SIZE]
812 :     mov _EDI, [_ESP+3*PTR_SIZE]
813 :     add _ESP, byte 4*PTR_SIZE
814 : edgomez 1382 pxor mm3, mm2 ;B13 (6th+)
815 : Isibaar 1795 movq [_EDX+4*24+8], mm3 ;B14 (7th)
816 :     mov [_EDX], ax
817 : edgomez 1382
818 : Isibaar 1795 xor _EAX, _EAX
819 :    
820 :     %ifdef ARCH_IS_X86_64
821 :     mov TMP0, [_ESP]
822 :     %ifndef WINDOWS
823 :     add _ESP, 6*PTR_SIZE
824 :     %else
825 :     add _ESP, 4*PTR_SIZE
826 :     %endif
827 :     mov [_ESP], TMP0
828 :     %endif
829 :    
830 : edgomez 1382 ret
831 : Isibaar 1793 ENDFUNC
832 : edgomez 1382
833 : Isibaar 1795
834 : edgomez 1382 ;-----------------------------------------------------------------------------
835 :     ;
836 :     ; uint32_t dequant_h263_inter_3dne(int16_t * data,
837 :     ; const int16_t * const coeff,
838 :     ; const uint32_t quant,
839 :     ; const uint16_t *mpeg_matrices);
840 :     ;
841 :     ;-----------------------------------------------------------------------------
842 :    
843 :     ; this is the same as dequant_inter_3dne,
844 :     ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
845 :     ; This is Athlon-optimized code (ca 100 clk per call)
846 :    
847 : Isibaar 1795 ALIGN SECTION_ALIGN
848 : edgomez 1382 cglobal dequant_h263_inter_3dne
849 :     dequant_h263_inter_3dne:
850 : Isibaar 1795
851 :     %ifdef ARCH_IS_X86_64
852 :     mov TMP0, [_ESP]
853 :     add _ESP, PTR_SIZE
854 :     %ifndef WINDOWS
855 :     push prm6
856 :     push prm5
857 :     %endif
858 :     push prm4
859 :     push prm3
860 :     push prm2
861 :     push prm1
862 :     sub _ESP, PTR_SIZE
863 :     mov [_ESP], TMP0
864 :     %endif
865 :    
866 :     mov _ECX, [_ESP+ 2*PTR_SIZE] ; coeff
867 :     mov _EAX, [_ESP+ 3*PTR_SIZE] ; quant
868 : edgomez 1382 pxor mm0, mm0
869 :     pxor mm2, mm2
870 : Isibaar 1795 push _EDI
871 :     push _EBX
872 :     push _ESI
873 :     %ifdef ARCH_IS_X86_64
874 :     lea _EDI, [mmx_mul]
875 :     lea _EDI, [_EDI + _EAX*8 - 8] ; 2*quant
876 :     %else
877 :     lea _EDI, [mmx_mul + _EAX*8 - 8] ; 2*quant
878 :     %endif
879 :     mov _EBX, mmx_2047
880 : edgomez 1382 pxor mm7, mm7
881 : Isibaar 1795 movq mm3, [_ECX+120] ;B2 ; c = coeff[i]
882 :     pcmpeqw mm7, [_ECX+120] ;B6 (c ==0) ? -1 : 0 (1st)
883 :     %ifdef ARCH_IS_X86_64
884 :     lea r9, [mmx_add]
885 :     lea _EAX, [r9 + _EAX*8 - 8] ; quant or quant-1
886 :     %else
887 :     lea _EAX, [mmx_add + _EAX*8 - 8] ; quant or quant-1
888 :     %endif
889 : edgomez 1382 psubw mm2, mm3 ;-c ;B3 (1st dep)
890 : Isibaar 1795 mov _ESI, mmzero
891 : edgomez 1382 pmaxsw mm2, mm3 ;|c| ;B4 (2nd)
892 : Isibaar 1795 pmullw mm2, [_EDI] ;*= 2Q ;B8 (3rd+)
893 : edgomez 1382 psraw mm3, 15 ; sign(c) ;B7 (2nd)
894 : Isibaar 1795 mov _EDX, [_ESP+ (1+3)*PTR_SIZE] ; data
895 : edgomez 1382
896 : Isibaar 1795 ALIGN SECTION_ALIGN
897 : edgomez 1382
898 :     dequant 0
899 :     dequant 1
900 :     dequant 2
901 :     dequant 3
902 :     dequant 4
903 :    
904 :     paddw mm4, mm6 ;C11 mm6 free (4th+)
905 : Isibaar 1795 pminsw mm4, [_EBX] ;C12 saturates to +2047 (5th+)
906 :     pandn mm7, [_EAX] ;B9 offset = isZero ? 0 : quant_add (2nd)
907 :     mov _ESI, [_ESP]
908 : edgomez 1382 pxor mm5, mm4 ;C13 (6th+)
909 :     paddw mm7, mm3 ;B10 offset +negate back (3rd)
910 : Isibaar 1795 movq [_EDX+4*24+16], mm5 ;C14 (7th)
911 : edgomez 1382 paddw mm2, mm7 ;B11 mm7 free (4th+)
912 : Isibaar 1795 pminsw mm2, [_EBX] ;B12 saturates to +2047 (5th+)
913 :     mov _EBX, [_ESP+PTR_SIZE]
914 :     mov _EDI, [_ESP+2*PTR_SIZE]
915 :     add _ESP, byte 3*PTR_SIZE
916 : edgomez 1382 pxor mm3, mm2 ;B13 (6th+)
917 : Isibaar 1795 movq [_EDX+4*24+8], mm3 ;B14 (7th)
918 : edgomez 1382
919 : Isibaar 1795 xor _EAX, _EAX
920 :    
921 :     %ifdef ARCH_IS_X86_64
922 :     mov TMP0, [_ESP]
923 :     %ifndef WINDOWS
924 :     add _ESP, 6*PTR_SIZE
925 :     %else
926 :     add _ESP, 4*PTR_SIZE
927 :     %endif
928 :     mov [_ESP], TMP0
929 :     %endif
930 :    
931 : edgomez 1382 ret
932 : Isibaar 1793 ENDFUNC
933 : edgomez 1540
934 : Isibaar 1790 %ifidn __OUTPUT_FORMAT__,elf
935 :     section ".note.GNU-stack" noalloc noexec nowrite progbits
936 :     %endif
937 :    

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