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

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