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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1089 - (view) (download)

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

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