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

Annotation of /xvidcore/src/quant/x86_asm/quantize_h263_3dne.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.2.4 - (view) (download)

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

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