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

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