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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1176 - (view) (download)

1 : edgomez 1174 ;/**************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 : edgomez 1176 ; * - 3dne Quantization/Dequantization -
5 : edgomez 1174 ; *
6 : edgomez 1176 ; * Copyright(C) 2002-2003 Jaan Kalda
7 : edgomez 1174 ; *
8 :     ; * This program is free software ; you can redistribute it and/or modify
9 :     ; * 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 : edgomez 1176 ; * $Id: quantize_h263_3dne.asm,v 1.1.2.2 2003-10-09 18:50:22 edgomez Exp $
23 : edgomez 1174 ; *
24 :     ; *************************************************************************/
25 : edgomez 1176 ;
26 : edgomez 1174 ; 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 :     ; data/text alignment
33 :     %define ALIGN 16
34 :    
35 :     bits 32
36 :    
37 :     %macro cglobal 1
38 :     %ifdef PREFIX
39 :     global _%1
40 :     %define %1 _%1
41 :     %else
42 :     global %1
43 :     %endif
44 :     %endmacro
45 : edgomez 1176
46 :     ;***************************************************************************
47 :     ; Local data
48 :     ;***************************************************************************
49 :    
50 :     %ifdef FORMAT_COFF
51 :     section .data data
52 :     %else
53 :     section .data data align=16
54 :     %endif
55 :    
56 : edgomez 1174 align 4
57 : edgomez 1176 int_div:
58 : edgomez 1174 dd 0
59 :     %assign i 1
60 :     %rep 255
61 :     dd (1 << 16) / (i) + 1
62 :     %assign i i+1
63 :     %endrep
64 :    
65 :     align 16
66 : edgomez 1176 plus_one:
67 :     times 8 dw 1
68 : edgomez 1174
69 :     ;===========================================================================
70 :     ;
71 :     ; subtract by Q/2 table
72 :     ;
73 :     ;===========================================================================
74 :    
75 :     align 16
76 : edgomez 1176 mmx_sub:
77 : edgomez 1174 %assign i 1
78 :     %rep 31
79 :     times 4 dw i / 2
80 :     %assign i i+1
81 :     %endrep
82 :    
83 :    
84 :     ;===========================================================================
85 :     ;
86 :     ; divide by 2Q table
87 :     ;
88 :     ; use a shift of 16 to take full advantage of _pmulhw_
89 :     ; for q=1, _pmulhw_ will overflow so it is treated seperately
90 :     ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
91 :     ;
92 :     ;===========================================================================
93 :    
94 :     align 16
95 : edgomez 1176 mmx_div:
96 : edgomez 1174 %assign i 1
97 :     %rep 31
98 :     times 4 dw (1 << 16) / (i * 2) + 1
99 :     %assign i i+1
100 :     %endrep
101 :    
102 :     ;===========================================================================
103 :     ;
104 :     ; add by (odd(Q) ? Q : Q - 1) table
105 :     ;
106 :     ;===========================================================================
107 :    
108 :     align 16
109 : edgomez 1176 mmx_add:
110 : edgomez 1174 %assign i 1
111 :     %rep 31
112 : edgomez 1176 %if i % 2 != 0
113 :     times 4 dw i
114 :     %else
115 :     times 4 dw i - 1
116 :     %endif
117 : edgomez 1174 %assign i i+1
118 :     %endrep
119 :    
120 :     ;===========================================================================
121 :     ;
122 :     ; multiple by 2Q table
123 :     ;
124 :     ;===========================================================================
125 :    
126 :     align 16
127 : edgomez 1176 mmx_mul:
128 : edgomez 1174 %assign i 1
129 :     %rep 31
130 :     times 4 dw i * 2
131 :     %assign i i+1
132 :     %endrep
133 :    
134 :     ;===========================================================================
135 :     ;
136 :     ; saturation limits
137 :     ;
138 :     ;===========================================================================
139 :    
140 :     align 8
141 : edgomez 1176 mmx_32768_minus_2048:
142 :     times 4 dw (32768-2048)
143 :     mmx_32767_minus_2047:
144 :     times 4 dw (32767-2047)
145 : edgomez 1174
146 :     align 16
147 : edgomez 1176 mmx_2047:
148 :     times 4 dw 2047
149 : edgomez 1174
150 :     align 8
151 : edgomez 1176 mmzero:
152 :     dd 0, 0
153 :     int2047:
154 :     dd 2047
155 :     int_2048:
156 :     dd -2048
157 : edgomez 1174
158 : edgomez 1176 ;***************************************************************************
159 :     ; Code
160 :     ;***************************************************************************
161 :    
162 : edgomez 1174 section .text
163 :    
164 :    
165 :     ;===========================================================================
166 :     ;
167 : edgomez 1176 ; uint32_t quant_h263_intra_3dne(int16_t * coeff,
168 :     ; const int16_t const * data,
169 :     ; const uint32_t quant,
170 :     ; const uint32_t dcscalar);
171 : edgomez 1174 ;
172 :     ;===========================================================================
173 :     ;This is Athlon-optimized code (ca 70 clk per call)
174 :    
175 :     %macro quant_intra1 1
176 :    
177 :     psubw mm1, mm0 ;A3
178 :     psubw mm3, mm2 ;B3
179 :     %if (%1)
180 :     psubw mm5, mm4 ;C8
181 :     psubw mm7, mm6 ;D8
182 :     %endif
183 :    
184 :     align 8
185 :     db 0Fh, 6Fh, 64h, 21h, (%1 * 32 +16) ;movq mm4, [ecx + %1 * 32 +16+32] ;C1
186 :     pmaxsw mm1, mm0 ;A4
187 :     db 0Fh, 6Fh, 74h, 21h, (%1 * 32 +24) ;movq mm6, [ecx + %1 * 32 +24+32] ;D1
188 :     pmaxsw mm3, mm2 ;B4
189 :    
190 :    
191 :     psraw mm0, 15 ;A5
192 :     psraw mm2, 15 ;B5
193 :     %if (%1)
194 :     movq [edx + %1 * 32 + 16-32], mm5 ;C9
195 :     movq [edx + %1 * 32 + 24-32], mm7 ;D9
196 :     %endif
197 :    
198 :     psrlw mm1, 1 ;A6
199 :     psrlw mm3, 1 ;B6
200 :     movq mm5, [ebx] ;C2
201 :     movq mm7, [ebx] ;D2
202 :    
203 :     pxor mm1, mm0 ;A7
204 :     pxor mm3, mm2 ;B7
205 :    
206 :     psubw mm5, mm4 ;C3
207 :     psubw mm7, mm6 ;D3
208 :     psubw mm1, mm0 ;A8
209 :     psubw mm3, mm2 ;B8
210 :    
211 :     %if (%1 == 0)
212 :     push ebp
213 :     movq mm0, [ecx + %1 * 32 +32]
214 :     %elif (%1 < 3)
215 :     db 0Fh, 6Fh, 44h, 21h, (%1 * 32 +32) ;movq mm0, [ecx + %1 * 32 +32] ;A1
216 :     %endif
217 :     pmaxsw mm5, mm4 ;C4
218 :     %if (%1 < 3)
219 :     db 0Fh, 6Fh, 54h, 21h, ( %1 * 32 +8+32) ;movq mm2, [ecx + %1 * 32 +8+32] ;B1
220 :     %else
221 :     cmp esp, esp
222 :     %endif
223 :     pmaxsw mm7, mm6 ;D4
224 :    
225 :     psraw mm4, 15 ;C5
226 :     psraw mm6, 15 ;D5
227 :     movq [byte edx + %1 * 32], mm1 ;A9
228 :     movq [edx + %1 * 32+8], mm3 ;B9
229 :    
230 :    
231 :     psrlw mm5, 1 ;C6
232 :     psrlw mm7, 1 ;D6
233 :     %if (%1 < 3)
234 :     movq mm1, [ebx] ;A2
235 :     movq mm3, [ebx] ;B2
236 :     %endif
237 :     %if (%1 == 3)
238 :     imul eax, [int_div+4*edi]
239 :     %endif
240 :     pxor mm5, mm4 ;C7
241 :     pxor mm7, mm6 ;D7
242 :     %endm
243 :    
244 :    
245 :     %macro quant_intra 1
246 :     ; Rules for athlon:
247 :     ; 1) schedule latencies
248 :     ; 2) add/mul and load/store in 2:1 proportion
249 :     ; 3) avoid spliting >3byte instructions over 8byte boundaries
250 :    
251 :     psubw mm1, mm0 ;A3
252 :     psubw mm3, mm2 ;B3
253 :     %if (%1)
254 :     psubw mm5, mm4 ;C8
255 :     psubw mm7, mm6 ;D8
256 :     %endif
257 :    
258 :     align 8
259 :     db 0Fh, 6Fh, 64h, 21h, (%1 * 32 +16) ;movq mm4, [ecx + %1 * 32 +16+32] ;C1
260 :     pmaxsw mm1, mm0 ;A4
261 :     db 0Fh, 6Fh, 74h, 21h, (%1 * 32 +24) ;movq mm6, [ecx + %1 * 32 +24+32] ;D1
262 :     pmaxsw mm3, mm2 ;B4
263 :    
264 :    
265 :     psraw mm0, 15 ;A5
266 :     psraw mm2, 15 ;B5
267 :     %if (%1)
268 :     movq [edx + %1 * 32 + 16-32], mm5 ;C9
269 :     movq [edx + %1 * 32 + 24-32], mm7 ;D9
270 :     %endif
271 :    
272 :     pmulhw mm1, [esi] ;A6
273 :     pmulhw mm3, [esi] ;B6
274 :     movq mm5, [ebx] ;C2
275 :     movq mm7, [ebx] ;D2
276 :    
277 :     nop
278 :     nop
279 :     pxor mm1, mm0 ;A7
280 :     pxor mm3, mm2 ;B7
281 :    
282 :     psubw mm5, mm4 ;C3
283 :     psubw mm7, mm6 ;D3
284 :     psubw mm1, mm0 ;A8
285 :     psubw mm3, mm2 ;B8
286 :    
287 :    
288 :     %if (%1 < 3)
289 :     db 0Fh, 6Fh, 44h, 21h, (%1 * 32 +32) ;movq mm0, [ecx + %1 * 32 +32] ;A1
290 :     %endif
291 :     pmaxsw mm5, mm4 ;C4
292 :     %if (%1 < 3)
293 :     db 0Fh, 6Fh, 54h, 21h, ( %1 * 32 +8+32) ;movq mm2, [ecx + %1 * 32 +8+32] ;B1
294 :     %else
295 :     cmp esp, esp
296 :     %endif
297 :     pmaxsw mm7,mm6 ;D4
298 :    
299 :     psraw mm4, 15 ;C5
300 :     psraw mm6, 15 ;D5
301 :     movq [byte edx + %1 * 32], mm1 ;A9
302 :     movq [edx + %1 * 32+8], mm3 ;B9
303 :    
304 :    
305 :     pmulhw mm5, [esi] ;C6
306 :     pmulhw mm7, [esi] ;D6
307 :     %if (%1 < 3)
308 :     movq mm1, [ebx] ;A2
309 :     movq mm3, [ebx] ;B2
310 :     %endif
311 :     %if (%1 == 0)
312 :     push ebp
313 :     %elif (%1 < 3)
314 :     nop
315 :     %endif
316 :     nop
317 :     %if (%1 == 3)
318 :     imul eax, [int_div+4*edi]
319 :     %endif
320 :     pxor mm5, mm4 ;C7
321 :     pxor mm7, mm6 ;D7
322 :     %endmacro
323 :    
324 :    
325 :     align ALIGN
326 :     cglobal quant_h263_intra_3dne
327 :     quant_h263_intra_3dne:
328 :    
329 : edgomez 1176 mov eax, [esp + 12] ; quant
330 :     mov ecx, [esp + 8] ; data
331 :     mov edx, [esp + 4] ; coeff
332 :     cmp al, 1
333 : edgomez 1174 pxor mm1, mm1
334 :     pxor mm3, mm3
335 :     movq mm0, [ecx] ; mm0 = [1st]
336 :     movq mm2, [ecx + 8]
337 :     push esi
338 : edgomez 1176 lea esi, [mmx_div + eax*8 - 8]
339 : edgomez 1174
340 :     push ebx
341 : edgomez 1176 mov ebx, mmzero
342 : edgomez 1174 push edi
343 : edgomez 1176 jz near .q1loop
344 : edgomez 1174
345 :     quant_intra 0
346 :     mov ebp, [esp + 16 + 16] ; dcscalar
347 :     ; NB -- there are 3 pushes in the function preambule and one more
348 :     ; in "quant_intra 0", thus an added offset of 16 bytes
349 :     movsx eax, word [byte ecx] ; DC
350 :    
351 :     quant_intra 1
352 : edgomez 1176 mov edi, eax
353 :     sar edi, 31 ; sign(DC)
354 : edgomez 1174 shr ebp, byte 1 ; ebp = dcscalar/2
355 :    
356 :     quant_intra 2
357 : edgomez 1176 sub eax, edi ; DC (+1)
358 : edgomez 1174 xor ebp, edi ; sign(DC) dcscalar /2 (-1)
359 : edgomez 1176 mov edi, [esp + 16 + 16] ; dscalar
360 :     lea eax, [byte eax + ebp] ; DC + sign(DC) dcscalar/2
361 :     mov ebp, [byte esp]
362 : edgomez 1174
363 :     quant_intra 3
364 :     psubw mm5, mm4 ;C8
365 : edgomez 1176 mov esi, [esp + 12] ; pop back the register value
366 :     mov edi, [esp + 4] ; pop back the register value
367 :     sar eax, 16
368 :     lea ebx, [byte eax + 1] ; workaround for eax < 0
369 : edgomez 1174 cmovs eax, ebx ; conditionnaly move the corrected value
370 : edgomez 1176 mov [edx], ax ; coeff[0] = ax
371 :     mov ebx, [esp + 8] ; pop back the register value
372 :     add esp, byte 16 ; "quant_intra 0" pushed ebp, but we don't restore that one, just correct the stack offset by 16
373 : edgomez 1174 psubw mm7, mm6 ;D8
374 :     movq [edx + 3 * 32 + 16], mm5 ;C9
375 :     movq [edx + 3 * 32 + 24], mm7 ;D9
376 :    
377 : edgomez 1176 xor eax, eax
378 : edgomez 1174 ret
379 :    
380 :     align 16
381 :    
382 :     .q1loop
383 :     quant_intra1 0
384 : edgomez 1176 mov ebp, [esp + 16 + 16] ; dcscalar
385 : edgomez 1174 movsx eax, word [byte ecx] ; DC
386 :    
387 :     quant_intra1 1
388 : edgomez 1176 mov edi, eax
389 :     sar edi, 31 ; sign(DC)
390 : edgomez 1174 shr ebp, byte 1 ; ebp = dcscalar /2
391 :    
392 :     quant_intra1 2
393 : edgomez 1176 sub eax, edi ; DC (+1)
394 : edgomez 1174 xor ebp, edi ; sign(DC) dcscalar /2 (-1)
395 : edgomez 1176 mov edi, [esp + 16 + 16] ; dcscalar
396 :     lea eax, [byte eax + ebp] ; DC + sign(DC) dcscalar /2
397 :     mov ebp, [byte esp]
398 : edgomez 1174
399 :     quant_intra1 3
400 :     psubw mm5, mm4 ;C8
401 : edgomez 1176 mov esi, [dword esp + 12] ; pop back the register value
402 :     mov edi, [esp + 4] ; pop back the register value
403 :     sar eax, 16
404 :     lea ebx, [byte eax + 1] ; workaround for eax < 0
405 : edgomez 1174 cmovs eax, ebx ; conditionnaly move the corrected value
406 : edgomez 1176 mov [edx], ax ; coeff[0] = ax
407 :     mov ebx, [esp + 8] ; pop back the register value
408 :     add esp, byte 16 ; "quant_intra 0" pushed ebp, but we don't restore that one, just correct the stack offset by 16
409 : edgomez 1174 psubw mm7, mm6 ;D8
410 :     movq [edx + 3 * 32 + 16], mm5 ;C9
411 :     movq [edx + 3 * 32 + 24], mm7 ;D9
412 :    
413 : edgomez 1176 xor eax, eax
414 : edgomez 1174 ret
415 :    
416 :    
417 :    
418 :    
419 :     ;===========================================================================
420 :     ;
421 : edgomez 1176 ; uint32_t quant_h263_inter_3dne(int16_t * coeff,
422 :     ; const int16_t const * data,
423 :     ; const uint32_t quant);
424 : edgomez 1174 ;
425 :     ;===========================================================================
426 :     ;This is Athlon-optimized code (ca 90 clk per call)
427 :     ;Optimized by Jaan, 30 Nov 2002
428 :    
429 :    
430 :     %macro quantinter 1
431 :     movq mm1, [eax] ;A2
432 :     psraw mm3, 15 ;B6
433 :     %if (%1)
434 :     psubw mm2, mm6 ;C10
435 :     %endif
436 :     psubw mm1, mm0 ;A3
437 :     pmulhw mm4, mm7 ;B7
438 :     movq mm6, [ecx + %1*24+16] ;C1
439 :     pmaxsw mm1, mm0 ;A4
440 :     paddw mm5, mm4 ;B8
441 :     %if (%1)
442 :     movq [edx + %1*24+16-24], mm2 ;C11
443 :     %endif
444 :     psubusw mm1, [ebx] ;A5 mm0 -= sub (unsigned, dont go < 0)
445 :     pxor mm4, mm3 ;B9
446 :     movq mm2, [eax] ;C2
447 :     psraw mm0, 15 ;A6
448 :     psubw mm4, mm3 ;B10
449 :     psubw mm2, mm6 ;C3
450 :     pmulhw mm1, mm7 ;A7 mm0 = (mm0 / 2Q) >> 24
451 :     movq mm3, [ecx + %1*24+8] ;B1
452 :     pmaxsw mm2, mm6 ;C4
453 :     paddw mm5, mm1 ;A8 sum += mm0
454 :     %if (%1)
455 :     movq [edx + %1*24+8-24], mm4 ;B11
456 :     %else
457 :     movq [edx + 120], mm4 ;B11
458 :     %endif
459 :     psubusw mm2, [ebx] ;C5
460 :     pxor mm1, mm0 ;A9 mm0 *= sign(mm0)
461 :     movq mm4, [eax] ;B2
462 :     psraw mm6, 15 ;C6
463 :     psubw mm1, mm0 ;A10 undisplace
464 :     psubw mm4, mm3 ;B3
465 :     pmulhw mm2, mm7 ;C7
466 :     movq mm0, [ecx + %1*24+24] ;A1 mm0 = [1st]
467 :     pmaxsw mm4, mm3 ;B4
468 :     paddw mm5, mm2 ;C8
469 :     movq [byte edx + %1*24], mm1 ;A11
470 :     psubusw mm4, [ebx] ;B5
471 :     pxor mm2, mm6 ;C9
472 :     %endmacro
473 :    
474 :     %macro quantinter1 1
475 :     movq mm0, [byte ecx + %1*16] ;mm0 = [1st]
476 :     movq mm3, [ecx + %1*16+8] ;
477 :     movq mm1, [eax]
478 :     movq mm4, [eax]
479 :     psubw mm1, mm0
480 :     psubw mm4, mm3
481 :     pmaxsw mm1, mm0
482 :     pmaxsw mm4, mm3
483 :     psubusw mm1, mm6 ; mm0 -= sub (unsigned, dont go < 0)
484 :     psubusw mm4, mm6 ;
485 :     psraw mm0, 15
486 :     psraw mm3, 15
487 :     psrlw mm1, 1 ; mm0 = (mm0 / 2Q) >> 16
488 :     psrlw mm4, 1 ;
489 :     paddw mm5, mm1 ; sum += mm0
490 :     pxor mm1, mm0 ; mm0 *= sign(mm0)
491 :     paddw mm5, mm4
492 :     pxor mm4, mm3 ;
493 :     psubw mm1, mm0 ; undisplace
494 :     psubw mm4, mm3
495 : edgomez 1176 cmp esp, esp
496 : edgomez 1174 movq [byte edx + %1*16], mm1
497 :     movq [edx + %1*16+8], mm4
498 :     %endmacro
499 :    
500 :     align ALIGN
501 :     cglobal quant_h263_inter_3dne
502 :     quant_h263_inter_3dne:
503 : edgomez 1176 mov edx, [esp + 4] ; coeff
504 :     mov ecx, [esp + 8] ; data
505 :     mov eax, [esp + 12] ; quant
506 : edgomez 1174 push ebx
507 :    
508 :     pxor mm5, mm5 ; sum
509 :     nop
510 : edgomez 1176 lea ebx,[mmx_sub + eax * 8 - 8] ; sub
511 : edgomez 1174 movq mm7, [mmx_div + eax * 8 - 8] ; divider
512 :    
513 : edgomez 1176 cmp al, 1
514 :     lea eax, [mmzero]
515 :     jz near .q1loop
516 :     cmp esp, esp
517 : edgomez 1174 align 8
518 :     movq mm3, [ecx + 120] ;B1
519 :     pxor mm4, mm4 ;B2
520 :     psubw mm4, mm3 ;B3
521 :     movq mm0, [ecx] ;A1 mm0 = [1st]
522 :     pmaxsw mm4, mm3 ;B4
523 :     psubusw mm4, [ebx] ;B5
524 :    
525 :     quantinter 0
526 :     quantinter 1
527 :     quantinter 2
528 :     quantinter 3
529 :     quantinter 4
530 :    
531 :     psraw mm3, 15 ;B6
532 :     psubw mm2, mm6 ;C10
533 :     pmulhw mm4, mm7 ;B7
534 :     paddw mm5, mm4 ;B8
535 :     pxor mm4, mm3 ;B9
536 :     psubw mm4, mm3 ;B10
537 :     movq [edx + 4*24+16], mm2 ;C11
538 : edgomez 1176 pop ebx
539 : edgomez 1174 movq [edx + 4*24+8], mm4 ;B11
540 :     pmaddwd mm5, [plus_one]
541 :     movq mm0, mm5
542 :     punpckhdq mm5, mm5
543 :     paddd mm0, mm5
544 :     movd eax, mm0 ; return sum
545 :    
546 :     ret
547 :    
548 :     align ALIGN
549 :     .q1loop
550 :     movq mm6, [byte ebx]
551 :    
552 :     quantinter1 0
553 :     quantinter1 1
554 :     quantinter1 2
555 :     quantinter1 3
556 :     quantinter1 4
557 :     quantinter1 5
558 :     quantinter1 6
559 :     quantinter1 7
560 :    
561 :     pmaddwd mm5, [plus_one]
562 :     movq mm0, mm5
563 :     psrlq mm5, 32
564 :     paddd mm0, mm5
565 :     movd eax, mm0 ; return sum
566 :    
567 :     pop ebx
568 :    
569 :     ret
570 :    
571 :     ;===========================================================================
572 :     ;
573 : edgomez 1176 ; uint32_t dequant_h263_intra_3dne(int16_t *data,
574 :     ; const int16_t const *coeff,
575 :     ; const uint32_t quant,
576 :     ; const uint32_t dcscalar);
577 : edgomez 1174 ;
578 :     ;===========================================================================
579 :    
580 :     ; this is the same as dequant_inter_3dne, except that we're
581 :     ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
582 :    
583 :     ;This is Athlon-optimized code (ca 106 clk per call)
584 :    
585 :     %macro dequant 1
586 :     movq mm1, [ecx+%1*24] ; c = coeff[i] ;A2
587 :     psubw mm0, mm1 ;-c ;A3 (1st dep)
588 :     %if (%1)
589 :     paddw mm4, mm6 ;C11 mm6 free (4th+)
590 :     %endif
591 :     pmaxsw mm0, mm1 ;|c| ;A4 (2nd)
592 :     %if (%1)
593 : edgomez 1176 mov ebp, ebp
594 : edgomez 1174 pminsw mm4, [ebx] ;C12 saturates to +2047 (5th+) later
595 :     %endif
596 :     movq mm6, [esi] ;0 ;A5 mm6 in use
597 :     pandn mm7, [eax] ;B9 offset = isZero ? 0 : quant_add (2nd)
598 :     %if (%1)
599 :     pxor mm5, mm4 ;C13 (6th+) 1later
600 :     %endif
601 :     movq mm4, [esi] ;C1 ;0
602 : edgomez 1176 mov esp, esp
603 : edgomez 1174 pcmpeqw mm6, [ecx+%1*24] ;A6 (c ==0) ? -1 : 0 (1st)
604 :     align 4
605 :     psraw mm1, 15 ; sign(c) ;A7 (2nd)
606 :     %if (%1)
607 :     movq [edx+%1*24+16-24], mm5 ; C14 (7th) 2later
608 :     %endif
609 :     paddw mm7, mm3 ;B10 offset +negate back (3rd)
610 :     pmullw mm0, [edi] ;*= 2Q ;A8 (3rd+)
611 :     paddw mm2, mm7 ;B11 mm7 free (4th+)
612 : edgomez 1176 lea ebp, [byte ebp]
613 : edgomez 1174 movq mm5, [ecx+%1*24+16] ;C2 ; c = coeff[i]
614 :     psubw mm4, mm5 ;-c ;C3 (1st dep)
615 :     pandn mm6, [eax] ;A9 offset = isZero ? 0 : quant_add (2nd)
616 :     pminsw mm2, [ebx] ;B12 saturates to +2047 (5th+)
617 :     pxor mm3, mm2 ;B13 (6th+)
618 :     movq mm2, [byte esi] ;B1 ;0
619 :     %if (%1)
620 :     movq [edx+%1*24+8-24], mm3 ;B14 (7th)
621 :     %else
622 :     movq [edx+120], mm3
623 :     %endif
624 :     pmaxsw mm4, mm5 ;|c| ;C4 (2nd)
625 :     paddw mm6, mm1 ;A10 offset +negate back (3rd)
626 :     movq mm3, [ecx+%1*24 + 8] ;B2 ; c = coeff[i]
627 :     psubw mm2, mm3 ;-c ;B3 (1st dep)
628 :     paddw mm0, mm6 ;A11 mm6 free (4th+)
629 :     movq mm6, [byte esi] ;0 ;C5 mm6 in use
630 :     pcmpeqw mm6, [ecx+%1*24+16] ;C6 (c ==0) ? -1 : 0 (1st)
631 :     pminsw mm0, [ebx] ;A12 saturates to +2047 (5th+)
632 :     pmaxsw mm2, mm3 ;|c| ;B4 (2nd)
633 :     pxor mm1, mm0 ;A13 (6th+)
634 :     pmullw mm4, [edi] ;*= 2Q ;C8 (3rd+)
635 :     psraw mm5, 15 ; sign(c) ;C7 (2nd)
636 :     movq mm7, [byte esi] ;0 ;B5 mm7 in use
637 :     pcmpeqw mm7, [ecx+%1*24 + 8] ;B6 (c ==0) ? -1 : 0 (1st)
638 :     %if (%1 < 4)
639 :     movq mm0, [byte esi] ;A1 ;0
640 :     %endif
641 :     pandn mm6, [byte eax] ;C9 offset = isZero ? 0 : quant_add (2nd)
642 :     psraw mm3, 15 ;sign(c) ;B7 (2nd)
643 :     movq [byte edx+%1*24], mm1 ;A14 (7th)
644 :     paddw mm6, mm5 ;C10 offset +negate back (3rd)
645 :     pmullw mm2, [edi] ;*= 2Q ;B8 (3rd+)
646 : edgomez 1176 mov esp, esp
647 : edgomez 1174 %endmacro
648 :    
649 :    
650 :     align ALIGN
651 :     cglobal dequant_h263_intra_3dne
652 :     dequant_h263_intra_3dne:
653 : edgomez 1176 mov ecx, [esp+ 8] ; coeff
654 :     mov eax, [esp+12] ; quant
655 : edgomez 1174 pxor mm0, mm0
656 :     pxor mm2, mm2
657 :     push edi
658 :     push ebx
659 : edgomez 1176 lea edi, [mmx_mul + eax*8 - 8] ; 2*quant
660 : edgomez 1174 push ebp
661 : edgomez 1176 mov ebx, mmx_2047
662 : edgomez 1174 movsx ebp, word [ecx]
663 : edgomez 1176 lea eax, [mmx_add + eax*8 - 8] ; quant or quant-1
664 : edgomez 1174 push esi
665 : edgomez 1176 mov esi, mmzero
666 : edgomez 1174 pxor mm7, mm7
667 :     movq mm3, [ecx+120] ;B2 ; c = coeff[i]
668 :     pcmpeqw mm7, [ecx+120] ;B6 (c ==0) ? -1 : 0 (1st)
669 :    
670 :     imul ebp, [esp+16+16] ; dcscalar
671 :     psubw mm2, mm3 ;-c ;B3 (1st dep)
672 :     pmaxsw mm2, mm3 ;|c| ;B4 (2nd)
673 :     pmullw mm2, [edi] ;*= 2Q ;B8 (3rd+)
674 :     psraw mm3, 15 ; sign(c) ;B7 (2nd)
675 : edgomez 1176 mov edx, [esp+ 4+16] ; data
676 : edgomez 1174
677 :     align 8
678 :     dequant 0
679 :    
680 : edgomez 1176 cmp ebp, -2048
681 :     mov esp, esp
682 : edgomez 1174
683 :     dequant 1
684 :    
685 : edgomez 1176 cmovl ebp, [int_2048]
686 : edgomez 1174 nop
687 :    
688 :     dequant 2
689 :    
690 : edgomez 1176 cmp ebp, 2047
691 :     mov esp, esp
692 : edgomez 1174
693 :     dequant 3
694 :    
695 : edgomez 1176 cmovg ebp, [int2047]
696 : edgomez 1174 nop
697 :    
698 :     dequant 4
699 :    
700 :     paddw mm4, mm6 ;C11 mm6 free (4th+)
701 :     pminsw mm4, [ebx] ;C12 saturates to +2047 (5th+)
702 :     pandn mm7, [eax] ;B9 offset = isZero ? 0 : quant_add (2nd)
703 : edgomez 1176 mov eax, ebp
704 :     mov esi, [esp]
705 :     mov ebp, [esp+4]
706 : edgomez 1174 pxor mm5, mm4 ;C13 (6th+)
707 :     paddw mm7, mm3 ;B10 offset +negate back (3rd)
708 :     movq [edx+4*24+16], mm5 ;C14 (7th)
709 :     paddw mm2, mm7 ;B11 mm7 free (4th+)
710 :     pminsw mm2, [ebx] ;B12 saturates to +2047 (5th+)
711 : edgomez 1176 mov ebx, [esp+8]
712 :     mov edi, [esp+12]
713 :     add esp, byte 16
714 : edgomez 1174 pxor mm3, mm2 ;B13 (6th+)
715 :     movq [edx+4*24+8], mm3 ;B14 (7th)
716 : edgomez 1176 mov [edx], ax
717 :    
718 :     xor eax, eax
719 : edgomez 1174 ret
720 :    
721 :     ;===========================================================================
722 :     ;
723 : edgomez 1176 ; uint32_t dequant_h263_inter_3dne(int16_t * data,
724 :     ; const int16_t * const coeff,
725 :     ; const uint32_t quant);
726 : edgomez 1174 ;
727 :     ;===========================================================================
728 :    
729 :     ; this is the same as dequant_inter_3dne,
730 :     ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
731 : edgomez 1176 ; This is Athlon-optimized code (ca 100 clk per call)
732 : edgomez 1174
733 :     align ALIGN
734 :     cglobal dequant_h263_inter_3dne
735 :     dequant_h263_inter_3dne:
736 : edgomez 1176 mov ecx, [esp+ 8] ; coeff
737 :     mov eax, [esp+12] ; quant
738 : edgomez 1174 pxor mm0, mm0
739 :     pxor mm2, mm2
740 :     push edi
741 :     push ebx
742 :     push esi
743 : edgomez 1176 lea edi, [mmx_mul + eax*8 - 8] ; 2*quant
744 :     mov ebx, mmx_2047
745 : edgomez 1174 pxor mm7, mm7
746 :     movq mm3, [ecx+120] ;B2 ; c = coeff[i]
747 :     pcmpeqw mm7, [ecx+120] ;B6 (c ==0) ? -1 : 0 (1st)
748 : edgomez 1176 lea eax, [mmx_add + eax*8 - 8] ; quant or quant-1
749 : edgomez 1174 psubw mm2, mm3 ;-c ;B3 (1st dep)
750 : edgomez 1176 mov esi, mmzero
751 : edgomez 1174 pmaxsw mm2, mm3 ;|c| ;B4 (2nd)
752 :     pmullw mm2, [edi] ;*= 2Q ;B8 (3rd+)
753 :     psraw mm3, 15 ; sign(c) ;B7 (2nd)
754 : edgomez 1176 mov edx, [dword esp+ 4+12] ; data
755 : edgomez 1174
756 :     align 8
757 :    
758 :     dequant 0
759 :     dequant 1
760 :     dequant 2
761 :     dequant 3
762 :     dequant 4
763 :    
764 :     paddw mm4, mm6 ;C11 mm6 free (4th+)
765 :     pminsw mm4, [ebx] ;C12 saturates to +2047 (5th+)
766 :     pandn mm7, [eax] ;B9 offset = isZero ? 0 : quant_add (2nd)
767 : edgomez 1176 mov esi, [esp]
768 : edgomez 1174 pxor mm5, mm4 ;C13 (6th+)
769 :     paddw mm7, mm3 ;B10 offset +negate back (3rd)
770 :     movq [edx+4*24+16], mm5 ;C14 (7th)
771 :     paddw mm2, mm7 ;B11 mm7 free (4th+)
772 :     pminsw mm2, [ebx] ;B12 saturates to +2047 (5th+)
773 : edgomez 1176 mov ebx, [esp+4]
774 :     mov edi, [esp+8]
775 :     add esp, byte 12
776 : edgomez 1174 pxor mm3, mm2 ;B13 (6th+)
777 :     movq [edx+4*24+8], mm3 ;B14 (7th)
778 :    
779 : edgomez 1176 xor eax, eax
780 : edgomez 1174 ret

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