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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1192 - (view) (download)

1 : edgomez 1176 ;/*****************************************************************************
2 : edgomez 1174 ; *
3 : edgomez 1176 ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - MPEG4 Quantization H263 implementation / MMX optimized -
5 : edgomez 1174 ; *
6 : edgomez 1176 ; * Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
7 :     ; * 2002-2003 Pascal Massimino <skal@planet-d.net>
8 : edgomez 1174 ; *
9 : edgomez 1176 ; * This program is free software ; you can redistribute it and/or modify
10 :     ; * it under the terms of the GNU General Public License as published by
11 :     ; * the Free Software Foundation ; either version 2 of the License, or
12 :     ; * (at your option) any later version.
13 : edgomez 1174 ; *
14 : edgomez 1176 ; * This program is distributed in the hope that it will be useful,
15 :     ; * but WITHOUT ANY WARRANTY ; without even the implied warranty of
16 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     ; * GNU General Public License for more details.
18 : edgomez 1174 ; *
19 : edgomez 1176 ; * You should have received a copy of the GNU General Public License
20 :     ; * along with this program ; if not, write to the Free Software
21 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : edgomez 1174 ; *
23 : edgomez 1192 ; * $Id: quantize_h263_mmx.asm,v 1.1.2.3 2003-10-28 22:23:03 edgomez Exp $
24 : edgomez 1174 ; *
25 : edgomez 1176 ; ****************************************************************************/
26 : edgomez 1174
27 :     ; enable dequant saturate [-2048,2047], test purposes only.
28 :     %define SATURATE
29 :    
30 : edgomez 1192 BITS 32
31 : edgomez 1174
32 : edgomez 1192 %macro cglobal 1
33 : edgomez 1176 %ifdef PREFIX
34 : edgomez 1192 global _%1
35 : edgomez 1174 %define %1 _%1
36 :     %else
37 :     global %1
38 :     %endif
39 :     %endmacro
40 :    
41 : edgomez 1192 ;=============================================================================
42 :     ; Read only Local data
43 :     ;=============================================================================
44 : edgomez 1174
45 : edgomez 1192 SECTION .rodata
46 : edgomez 1174
47 : edgomez 1192 ALIGN 16
48 : edgomez 1176 plus_one:
49 :     times 8 dw 1
50 :    
51 : edgomez 1192 ;-----------------------------------------------------------------------------
52 : edgomez 1174 ;
53 :     ; subtract by Q/2 table
54 :     ;
55 : edgomez 1192 ;-----------------------------------------------------------------------------
56 : edgomez 1174
57 : edgomez 1192 ALIGN 16
58 : edgomez 1176 mmx_sub:
59 :     %assign quant 1
60 :     %rep 31
61 : edgomez 1192 times 4 dw quant / 2
62 : edgomez 1176 %assign quant quant+1
63 :     %endrep
64 : edgomez 1174
65 : edgomez 1192 ;-----------------------------------------------------------------------------
66 : edgomez 1174 ;
67 : edgomez 1192 ; divide by 2Q table
68 : edgomez 1174 ;
69 :     ; use a shift of 16 to take full advantage of _pmulhw_
70 :     ; for q=1, _pmulhw_ will overflow so it is treated seperately
71 :     ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
72 :     ;
73 : edgomez 1192 ;-----------------------------------------------------------------------------
74 : edgomez 1174
75 : edgomez 1192 ALIGN 16
76 : edgomez 1176 mmx_div:
77 :     %assign quant 1
78 :     %rep 31
79 :     times 4 dw (1<<16) / (quant*2) + 1
80 :     %assign quant quant+1
81 :     %endrep
82 : edgomez 1174
83 : edgomez 1192 ;-----------------------------------------------------------------------------
84 : edgomez 1174 ;
85 :     ; add by (odd(Q) ? Q : Q - 1) table
86 :     ;
87 : edgomez 1192 ;-----------------------------------------------------------------------------
88 : edgomez 1174
89 : edgomez 1192 ALIGN 16
90 : edgomez 1176 mmx_add:
91 :     %assign quant 1
92 :     %rep 31
93 :     %if quant % 2 != 0
94 :     times 4 dw quant
95 :     %else
96 :     times 4 dw quant - 1
97 :     %endif
98 :     %assign quant quant+1
99 :     %endrep
100 : edgomez 1174
101 : edgomez 1192 ;-----------------------------------------------------------------------------
102 : edgomez 1174 ;
103 :     ; multiple by 2Q table
104 :     ;
105 : edgomez 1192 ;-----------------------------------------------------------------------------
106 : edgomez 1174
107 : edgomez 1192 ALIGN 16
108 : edgomez 1176 mmx_mul:
109 :     %assign quant 1
110 :     %rep 31
111 :     times 4 dw quant*2
112 :     %assign quant quant+1
113 :     %endrep
114 : edgomez 1174
115 : edgomez 1192 ;-----------------------------------------------------------------------------
116 : edgomez 1174 ;
117 : edgomez 1192 ; saturation limits
118 : edgomez 1174 ;
119 : edgomez 1192 ;-----------------------------------------------------------------------------
120 : edgomez 1174
121 : edgomez 1192 ALIGN 16
122 : edgomez 1176 sse2_2047:
123 :     times 8 dw 2047
124 : edgomez 1174
125 : edgomez 1192 ALIGN 16
126 : edgomez 1176 mmx_2047:
127 :     times 4 dw 2047
128 : edgomez 1174
129 : edgomez 1192 ALIGN 8
130 : edgomez 1176 mmx_32768_minus_2048:
131 :     times 4 dw (32768-2048)
132 : edgomez 1174
133 : edgomez 1176 mmx_32767_minus_2047:
134 :     times 4 dw (32767-2047)
135 : edgomez 1174
136 : edgomez 1176
137 : edgomez 1192 ;=============================================================================
138 : edgomez 1176 ; Code
139 : edgomez 1192 ;=============================================================================
140 : edgomez 1176
141 : edgomez 1192 SECTION .text
142 : edgomez 1174
143 : edgomez 1192 cglobal quant_h263_intra_mmx
144 :     cglobal quant_h263_intra_sse2
145 :     cglobal quant_h263_inter_mmx
146 :     cglobal quant_h263_inter_sse2
147 :     cglobal dequant_h263_intra_mmx
148 :     cglobal dequant_h263_intra_xmm
149 :     cglobal dequant_h263_intra_sse2
150 :     cglobal dequant_h263_inter_mmx
151 :     cglobal dequant_h263_inter_xmm
152 :     cglobal dequant_h263_inter_sse2
153 : edgomez 1174
154 : edgomez 1192 ;-----------------------------------------------------------------------------
155 : edgomez 1174 ;
156 : edgomez 1176 ; uint32_t quant_h263_intra_mmx(int16_t * coeff,
157 :     ; const int16_t const * data,
158 :     ; const uint32_t quant,
159 :     ; const uint32_t dcscalar);
160 : edgomez 1174 ;
161 : edgomez 1192 ;-----------------------------------------------------------------------------
162 : edgomez 1174
163 : edgomez 1192 ALIGN 16
164 : edgomez 1174 quant_h263_intra_mmx:
165 :    
166 : edgomez 1192 push ecx
167 :     push esi
168 :     push edi
169 : edgomez 1174
170 : edgomez 1192 mov edi, [esp + 12 + 4] ; coeff
171 :     mov esi, [esp + 12 + 8] ; data
172 :     mov eax, [esp + 12 + 12] ; quant
173 : edgomez 1174
174 : edgomez 1192 xor ecx, ecx
175 :     cmp al, 1
176 :     jz .q1loop
177 : edgomez 1174
178 : edgomez 1192 movq mm7, [mmx_div + eax * 8 - 8]
179 : edgomez 1176
180 : edgomez 1192 ALIGN 16
181 : edgomez 1174 .loop
182 : edgomez 1192 movq mm0, [esi + 8*ecx] ; mm0 = [1st]
183 :     movq mm3, [esi + 8*ecx + 8]
184 :     pxor mm1, mm1 ; mm1 = 0
185 :     pxor mm4, mm4 ;
186 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
187 :     pcmpgtw mm4, mm3 ;
188 :     pxor mm0, mm1 ; mm0 = |mm0|
189 :     pxor mm3, mm4 ;
190 :     psubw mm0, mm1 ; displace
191 :     psubw mm3, mm4 ;
192 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
193 :     pmulhw mm3, mm7 ;
194 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
195 :     pxor mm3, mm4 ;
196 :     psubw mm0, mm1 ; undisplace
197 :     psubw mm3, mm4 ;
198 :     movq [edi + 8*ecx], mm0
199 :     movq [edi + 8*ecx + 8], mm3
200 : edgomez 1174
201 : edgomez 1192 add ecx, 2
202 :     cmp ecx, 16
203 :     jnz .loop
204 : edgomez 1176
205 : edgomez 1192 .done
206 : edgomez 1176
207 : edgomez 1192 ; caclulate data[0] // (int32_t)dcscalar)
208 :     mov ecx, [esp + 12 + 16] ; dcscalar
209 :     mov edx, ecx
210 :     movsx eax, word [esi] ; data[0]
211 :     shr edx, 1 ; edx = dcscalar /2
212 :     cmp eax, 0
213 :     jg .gtzero
214 : edgomez 1174
215 : edgomez 1192 sub eax, edx
216 :     jmp short .mul
217 : edgomez 1174
218 :     .gtzero
219 : edgomez 1192 add eax, edx
220 : edgomez 1174 .mul
221 : edgomez 1192 cdq ; expand eax -> edx:eax
222 :     idiv ecx ; eax = edx:eax / dcscalar
223 :     mov [edi], ax ; coeff[0] = ax
224 : edgomez 1174
225 : edgomez 1192 xor eax, eax ; return(0);
226 :     pop edi
227 :     pop esi
228 :     pop ecx
229 : edgomez 1174
230 : edgomez 1192 ret
231 : edgomez 1174
232 : edgomez 1192 ALIGN 16
233 : edgomez 1174 .q1loop
234 : edgomez 1192 movq mm0, [esi + 8*ecx] ; mm0 = [1st]
235 :     movq mm3, [esi + 8*ecx + 8]
236 :     pxor mm1, mm1 ; mm1 = 0
237 :     pxor mm4, mm4 ;
238 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
239 :     pcmpgtw mm4, mm3 ;
240 :     pxor mm0, mm1 ; mm0 = |mm0|
241 :     pxor mm3, mm4 ;
242 :     psubw mm0, mm1 ; displace
243 :     psubw mm3, mm4 ;
244 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
245 :     psrlw mm3, 1 ;
246 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
247 :     pxor mm3, mm4
248 :     psubw mm0, mm1 ; undisplace
249 :     psubw mm3, mm4 ;
250 :     movq [edi + 8*ecx], mm0
251 :     movq [edi + 8*ecx + 8], mm3
252 : edgomez 1174
253 : edgomez 1192 add ecx, 2
254 :     cmp ecx, 16
255 :     jnz .q1loop
256 :     jmp short .done
257 : edgomez 1174
258 :    
259 :    
260 : edgomez 1192 ;-----------------------------------------------------------------------------
261 : edgomez 1174 ;
262 : edgomez 1192 ; uint32_t quant_h263_intra_sse2(int16_t * coeff,
263 : edgomez 1176 ; const int16_t const * data,
264 :     ; const uint32_t quant,
265 :     ; const uint32_t dcscalar);
266 : edgomez 1174 ;
267 : edgomez 1192 ;-----------------------------------------------------------------------------
268 : edgomez 1174
269 : edgomez 1192 ALIGN 16
270 : edgomez 1174 quant_h263_intra_sse2:
271 :    
272 : edgomez 1192 push esi
273 :     push edi
274 : edgomez 1174
275 : edgomez 1192 mov edi, [esp + 8 + 4] ; coeff
276 :     mov esi, [esp + 8 + 8] ; data
277 :     mov eax, [esp + 8 + 12] ; quant
278 : edgomez 1174
279 : edgomez 1192 xor ecx, ecx
280 :     cmp al, 1
281 :     jz near .qas2_q1loop
282 : edgomez 1174
283 :     .qas2_not1
284 : edgomez 1192 movq mm7, [mmx_div + eax*8 - 8]
285 :     movq2dq xmm7, mm7
286 :     movlhps xmm7, xmm7
287 : edgomez 1174
288 : edgomez 1192 ALIGN 16
289 : edgomez 1174 .qas2_loop
290 : edgomez 1192 movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
291 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
292 :     pxor xmm1, xmm1
293 :     pxor xmm4, xmm4
294 :     pcmpgtw xmm1, xmm0
295 :     pcmpgtw xmm4, xmm3
296 :     pxor xmm0, xmm1
297 :     pxor xmm3, xmm4
298 :     psubw xmm0, xmm1
299 :     psubw xmm3, xmm4
300 :     pmulhw xmm0, xmm7
301 :     pmulhw xmm3, xmm7
302 :     pxor xmm0, xmm1
303 :     pxor xmm3, xmm4
304 :     psubw xmm0, xmm1
305 :     psubw xmm3, xmm4
306 :     movdqa [edi + ecx*8], xmm0
307 :     movdqa [edi + ecx*8 + 16], xmm3
308 : edgomez 1174
309 : edgomez 1192 add ecx, 4
310 :     cmp ecx, 16
311 :     jnz .qas2_loop
312 : edgomez 1174
313 : edgomez 1192 .qas2_done
314 :     mov ecx, [esp + 8 + 16] ; dcscalar
315 :     mov edx, ecx
316 :     movsx eax, word [esi]
317 :     shr edx, 1
318 :     cmp eax, 0
319 :     jg .qas2_gtzero
320 : edgomez 1176
321 : edgomez 1192 sub eax, edx
322 :     jmp short .qas2_mul
323 :    
324 : edgomez 1174 .qas2_gtzero
325 : edgomez 1192 add eax, edx
326 : edgomez 1176
327 : edgomez 1174 .qas2_mul
328 : edgomez 1192 cdq
329 :     idiv ecx
330 : edgomez 1174
331 : edgomez 1192 mov [edi], ax
332 : edgomez 1174
333 : edgomez 1192 xor eax, eax ; return(0);
334 :     pop edi
335 :     pop esi
336 : edgomez 1174
337 : edgomez 1192 ret
338 :    
339 :     ALIGN 16
340 : edgomez 1174 .qas2_q1loop
341 : edgomez 1192 movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
342 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
343 :     pxor xmm1, xmm1
344 :     pxor xmm4, xmm4
345 :     pcmpgtw xmm1, xmm0
346 :     pcmpgtw xmm4, xmm3
347 :     pxor xmm0, xmm1
348 :     pxor xmm3, xmm4
349 :     psubw xmm0, xmm1
350 :     psubw xmm3, xmm4
351 :     psrlw xmm0, 1
352 :     psrlw xmm3, 1
353 :     pxor xmm0, xmm1
354 :     pxor xmm3, xmm4
355 :     psubw xmm0, xmm1
356 :     psubw xmm3, xmm4
357 :     movdqa [edi + ecx*8], xmm0
358 :     movdqa [edi + ecx*8 + 16], xmm3
359 : edgomez 1174
360 : edgomez 1192 add ecx, 4
361 :     cmp ecx, 16
362 :     jnz .qas2_q1loop
363 :     jmp near .qas2_done
364 : edgomez 1174
365 :    
366 :    
367 : edgomez 1192 ;-----------------------------------------------------------------------------
368 : edgomez 1174 ;
369 : edgomez 1176 ; uint32_t quant_h263_inter_mmx(int16_t * coeff,
370 :     ; const int16_t const * data,
371 :     ; const uint32_t quant);
372 : edgomez 1174 ;
373 : edgomez 1192 ;-----------------------------------------------------------------------------
374 : edgomez 1174
375 : edgomez 1192 ALIGN 16
376 : edgomez 1174 quant_h263_inter_mmx:
377 :    
378 : edgomez 1192 push ecx
379 :     push esi
380 :     push edi
381 : edgomez 1174
382 : edgomez 1192 mov edi, [esp + 12 + 4] ; coeff
383 :     mov esi, [esp + 12 + 8] ; data
384 :     mov eax, [esp + 12 + 12] ; quant
385 : edgomez 1174
386 : edgomez 1192 xor ecx, ecx
387 : edgomez 1174
388 : edgomez 1192 pxor mm5, mm5 ; sum
389 :     movq mm6, [mmx_sub + eax * 8 - 8] ; sub
390 : edgomez 1174
391 : edgomez 1192 cmp al, 1
392 :     jz .q1loop
393 : edgomez 1174
394 : edgomez 1192 movq mm7, [mmx_div + eax * 8 - 8] ; divider
395 : edgomez 1174
396 : edgomez 1192 ALIGN 8
397 : edgomez 1174 .loop
398 : edgomez 1192 movq mm0, [esi + 8*ecx] ; mm0 = [1st]
399 :     movq mm3, [esi + 8*ecx + 8]
400 :     pxor mm1, mm1 ; mm1 = 0
401 :     pxor mm4, mm4 ;
402 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
403 :     pcmpgtw mm4, mm3 ;
404 :     pxor mm0, mm1 ; mm0 = |mm0|
405 :     pxor mm3, mm4 ;
406 :     psubw mm0, mm1 ; displace
407 :     psubw mm3, mm4 ;
408 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
409 :     psubusw mm3, mm6 ;
410 :     pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16
411 :     pmulhw mm3, mm7 ;
412 :     paddw mm5, mm0 ; sum += mm0
413 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
414 :     paddw mm5, mm3 ;
415 :     pxor mm3, mm4 ;
416 :     psubw mm0, mm1 ; undisplace
417 :     psubw mm3, mm4
418 :     movq [edi + 8*ecx], mm0
419 :     movq [edi + 8*ecx + 8], mm3
420 : edgomez 1174
421 : edgomez 1192 add ecx, 2
422 :     cmp ecx, 16
423 :     jnz .loop
424 : edgomez 1174
425 :     .done
426 : edgomez 1192 pmaddwd mm5, [plus_one]
427 :     movq mm0, mm5
428 :     psrlq mm5, 32
429 :     paddd mm0, mm5
430 : edgomez 1174
431 : edgomez 1192 movd eax, mm0 ; return sum
432 :     pop edi
433 :     pop esi
434 :     pop ecx
435 : edgomez 1174
436 : edgomez 1192 ret
437 : edgomez 1174
438 : edgomez 1192 ALIGN 8
439 : edgomez 1174 .q1loop
440 : edgomez 1192 movq mm0, [esi + 8*ecx] ; mm0 = [1st]
441 :     movq mm3, [esi + 8*ecx+ 8] ;
442 :     pxor mm1, mm1 ; mm1 = 0
443 :     pxor mm4, mm4 ;
444 :     pcmpgtw mm1, mm0 ; mm1 = (0 > mm0)
445 :     pcmpgtw mm4, mm3 ;
446 :     pxor mm0, mm1 ; mm0 = |mm0|
447 :     pxor mm3, mm4 ;
448 :     psubw mm0, mm1 ; displace
449 :     psubw mm3, mm4 ;
450 :     psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0)
451 :     psubusw mm3, mm6 ;
452 :     psrlw mm0, 1 ; mm0 >>= 1 (/2)
453 :     psrlw mm3, 1 ;
454 :     paddw mm5, mm0 ; sum += mm0
455 :     pxor mm0, mm1 ; mm0 *= sign(mm0)
456 :     paddw mm5, mm3 ;
457 :     pxor mm3, mm4 ;
458 :     psubw mm0, mm1 ; undisplace
459 :     psubw mm3, mm4
460 :     movq [edi + 8*ecx], mm0
461 :     movq [edi + 8*ecx + 8], mm3
462 : edgomez 1174
463 : edgomez 1192 add ecx, 2
464 :     cmp ecx, 16
465 :     jnz .q1loop
466 : edgomez 1174
467 : edgomez 1192 jmp .done
468 : edgomez 1174
469 :    
470 : edgomez 1192
471 :     ;-----------------------------------------------------------------------------
472 : edgomez 1174 ;
473 : edgomez 1176 ; uint32_t quant_h263_inter_sse2(int16_t * coeff,
474 :     ; const int16_t const * data,
475 :     ; const uint32_t quant);
476 : edgomez 1174 ;
477 : edgomez 1192 ;-----------------------------------------------------------------------------
478 : edgomez 1174
479 : edgomez 1192 ALIGN 16
480 : edgomez 1174 quant_h263_inter_sse2:
481 :    
482 : edgomez 1192 push esi
483 :     push edi
484 : edgomez 1174
485 : edgomez 1192 mov edi, [esp + 8 + 4] ; coeff
486 :     mov esi, [esp + 8 + 8] ; data
487 :     mov eax, [esp + 8 + 12] ; quant
488 : edgomez 1174
489 : edgomez 1192 xor ecx, ecx
490 : edgomez 1174
491 : edgomez 1192 pxor xmm5, xmm5 ; sum
492 : edgomez 1174
493 : edgomez 1192 movq mm0, [mmx_sub + eax*8 - 8] ; sub
494 :     movq2dq xmm6, mm0 ; load into low 8 bytes
495 :     movlhps xmm6, xmm6 ; duplicate into high 8 bytes
496 : edgomez 1174
497 : edgomez 1192 cmp al, 1
498 :     jz near .qes2_q1loop
499 : edgomez 1174
500 :     .qes2_not1
501 : edgomez 1192 movq mm0, [mmx_div + eax*8 - 8] ; divider
502 :     movq2dq xmm7, mm0
503 :     movlhps xmm7, xmm7
504 : edgomez 1174
505 : edgomez 1192 ALIGN 16
506 : edgomez 1174 .qes2_loop
507 : edgomez 1192 movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
508 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
509 :     pxor xmm1, xmm1
510 :     pxor xmm4, xmm4
511 :     pcmpgtw xmm1, xmm0
512 :     pcmpgtw xmm4, xmm3
513 :     pxor xmm0, xmm1
514 :     pxor xmm3, xmm4
515 :     psubw xmm0, xmm1
516 :     psubw xmm3, xmm4
517 :     psubusw xmm0, xmm6
518 :     psubusw xmm3, xmm6
519 :     pmulhw xmm0, xmm7
520 :     pmulhw xmm3, xmm7
521 :     paddw xmm5, xmm0
522 :     pxor xmm0, xmm1
523 :     paddw xmm5, xmm3
524 :     pxor xmm3, xmm4
525 :     psubw xmm0, xmm1
526 :     psubw xmm3, xmm4
527 :     movdqa [edi + ecx*8], xmm0
528 :     movdqa [edi + ecx*8 + 16], xmm3
529 : edgomez 1174
530 : edgomez 1192 add ecx, 4
531 :     cmp ecx, 16
532 :     jnz .qes2_loop
533 : edgomez 1174
534 :     .qes2_done
535 : edgomez 1192 movdqu xmm6, [plus_one]
536 :     pmaddwd xmm5, xmm6
537 :     movhlps xmm6, xmm5
538 :     paddd xmm5, xmm6
539 :     movdq2q mm0, xmm5
540 : edgomez 1174
541 : edgomez 1192 movq mm5, mm0
542 :     psrlq mm5, 32
543 :     paddd mm0, mm5
544 : edgomez 1174
545 : edgomez 1192 movd eax, mm0 ; return sum
546 : edgomez 1174
547 : edgomez 1192 pop edi
548 :     pop esi
549 : edgomez 1174
550 : edgomez 1192 ret
551 : edgomez 1176
552 : edgomez 1192 ALIGN 16
553 : edgomez 1174 .qes2_q1loop
554 : edgomez 1192 movdqa xmm0, [esi + ecx*8] ; xmm0 = [1st]
555 :     movdqa xmm3, [esi + ecx*8 + 16] ; xmm3 = [2nd]
556 :     pxor xmm1, xmm1
557 :     pxor xmm4, xmm4
558 :     pcmpgtw xmm1, xmm0
559 :     pcmpgtw xmm4, xmm3
560 :     pxor xmm0, xmm1
561 :     pxor xmm3, xmm4
562 :     psubw xmm0, xmm1
563 :     psubw xmm3, xmm4
564 :     psubusw xmm0, xmm6
565 :     psubusw xmm3, xmm6
566 :     psrlw xmm0, 1
567 :     psrlw xmm3, 1
568 :     paddw xmm5, xmm0
569 :     pxor xmm0, xmm1
570 :     paddw xmm5, xmm3
571 :     pxor xmm3, xmm4
572 :     psubw xmm0, xmm1
573 :     psubw xmm3, xmm4
574 :     movdqa [edi + ecx*8], xmm0
575 :     movdqa [edi + ecx*8 + 16], xmm3
576 :    
577 :     add ecx, 4
578 :     cmp ecx, 16
579 :     jnz .qes2_q1loop
580 :     jmp .qes2_done
581 :    
582 :    
583 :     ;-----------------------------------------------------------------------------
584 : edgomez 1174 ;
585 : edgomez 1176 ; uint32_t dequant_h263_intra_mmx(int16_t *data,
586 :     ; const int16_t const *coeff,
587 :     ; const uint32_t quant,
588 :     ; const uint32_t dcscalar);
589 : edgomez 1174 ;
590 : edgomez 1192 ;-----------------------------------------------------------------------------
591 : edgomez 1174
592 :     ; note: we only saturate to +2047 *before* restoring the sign.
593 :     ; Hence, final clamp really is [-2048,2047]
594 :    
595 : edgomez 1192 ALIGN 16
596 : edgomez 1174 dequant_h263_intra_mmx:
597 :    
598 : edgomez 1192 mov edx, [esp+ 4] ; data
599 :     mov ecx, [esp+ 8] ; coeff
600 :     mov eax, [esp+12] ; quant
601 :     movq mm6, [mmx_add + eax*8 - 8] ; quant or quant-1
602 :     movq mm7, [mmx_mul + eax*8 - 8] ; 2*quant
603 :     mov eax, -16
604 : edgomez 1174
605 : edgomez 1192 ALIGN 16
606 : edgomez 1174 .loop
607 : edgomez 1192 movq mm0, [ecx+8*eax+8*16] ; c = coeff[i]
608 :     movq mm3, [ecx+8*eax+8*16 + 8] ; c' = coeff[i+1]
609 :     pxor mm1, mm1
610 :     pxor mm4, mm4
611 :     pcmpgtw mm1, mm0 ; sign(c)
612 :     pcmpgtw mm4, mm3 ; sign(c')
613 :     pxor mm2, mm2
614 :     pxor mm5, mm5
615 :     pcmpeqw mm2, mm0 ; c is zero
616 :     pcmpeqw mm5, mm3 ; c' is zero
617 :     pandn mm2, mm6 ; offset = isZero ? 0 : quant_add
618 :     pandn mm5, mm6
619 :     pxor mm0, mm1 ; negate if negative
620 :     pxor mm3, mm4 ; negate if negative
621 :     psubw mm0, mm1
622 :     psubw mm3, mm4
623 :     pmullw mm0, mm7 ; *= 2Q
624 :     pmullw mm3, mm7 ; *= 2Q
625 :     paddw mm0, mm2 ; + offset
626 :     paddw mm3, mm5 ; + offset
627 :     paddw mm0, mm1 ; negate back
628 :     paddw mm3, mm4 ; negate back
629 : edgomez 1174
630 : edgomez 1192 ; saturates to +2047
631 :     movq mm2, [mmx_32767_minus_2047]
632 :     add eax, 2
633 :     paddsw mm0, mm2
634 :     paddsw mm3, mm2
635 :     psubsw mm0, mm2
636 :     psubsw mm3, mm2
637 : edgomez 1174
638 : edgomez 1192 pxor mm0, mm1
639 :     pxor mm3, mm4
640 :     movq [edx + 8*eax + 8*16 - 2*8], mm0
641 :     movq [edx + 8*eax + 8*16+8 - 2*8], mm3
642 :     jnz near .loop
643 : edgomez 1174
644 : edgomez 1192 ; deal with DC
645 :     movd mm0, [ecx]
646 :     pmullw mm0, [esp+16] ; dcscalar
647 :     movq mm2, [mmx_32767_minus_2047]
648 :     paddsw mm0, mm2
649 :     psubsw mm0, mm2
650 :     movq mm3, [mmx_32768_minus_2048]
651 :     psubsw mm0, mm3
652 :     paddsw mm0, mm3
653 :     movd eax, mm0
654 :     mov [edx], ax
655 : edgomez 1174
656 : edgomez 1192 xor eax, eax ; return(0);
657 :     ret
658 : edgomez 1174
659 : edgomez 1192 ;-----------------------------------------------------------------------------
660 : edgomez 1174 ;
661 : edgomez 1176 ; uint32_t dequant_h263_intra_xmm(int16_t *data,
662 :     ; const int16_t const *coeff,
663 :     ; const uint32_t quant,
664 :     ; const uint32_t dcscalar);
665 : edgomez 1174 ;
666 : edgomez 1192 ;-----------------------------------------------------------------------------
667 : edgomez 1174
668 :     ; this is the same as dequant_inter_mmx, except that we're
669 :     ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
670 :    
671 : edgomez 1192 ALIGN 16
672 : edgomez 1174 dequant_h263_intra_xmm:
673 :    
674 : edgomez 1192 mov edx, [esp+ 4] ; data
675 :     mov ecx, [esp+ 8] ; coeff
676 :     mov eax, [esp+12] ; quant
677 :     movq mm6, [mmx_add + eax*8 - 8] ; quant or quant-1
678 :     movq mm7, [mmx_mul + eax*8 - 8] ; 2*quant
679 :     mov eax, -16
680 : edgomez 1174
681 : edgomez 1192 ALIGN 16
682 : edgomez 1174 .loop
683 : edgomez 1192 movq mm0, [ecx+8*eax+8*16] ; c = coeff[i]
684 :     movq mm3, [ecx+8*eax+8*16 + 8] ; c' = coeff[i+1]
685 :     pxor mm1, mm1
686 :     pxor mm4, mm4
687 :     pcmpgtw mm1, mm0 ; sign(c)
688 :     pcmpgtw mm4, mm3 ; sign(c')
689 :     pxor mm2, mm2
690 :     pxor mm5, mm5
691 :     pcmpeqw mm2, mm0 ; c is zero
692 :     pcmpeqw mm5, mm3 ; c' is zero
693 :     pandn mm2, mm6 ; offset = isZero ? 0 : quant_add
694 :     pandn mm5, mm6
695 :     pxor mm0, mm1 ; negate if negative
696 :     pxor mm3, mm4 ; negate if negative
697 :     psubw mm0, mm1
698 :     psubw mm3, mm4
699 :     pmullw mm0, mm7 ; *= 2Q
700 :     pmullw mm3, mm7 ; *= 2Q
701 :     paddw mm0, mm2 ; + offset
702 :     paddw mm3, mm5 ; + offset
703 :     paddw mm0, mm1 ; negate back
704 :     paddw mm3, mm4 ; negate back
705 : edgomez 1174
706 : edgomez 1176 ; saturates to +2047
707 : edgomez 1192 movq mm2, [mmx_2047]
708 :     pminsw mm0, mm2
709 :     add eax, 2
710 :     pminsw mm3, mm2
711 : edgomez 1174
712 : edgomez 1192 pxor mm0, mm1
713 :     pxor mm3, mm4
714 :     movq [edx + 8*eax + 8*16 - 2*8], mm0
715 :     movq [edx + 8*eax + 8*16+8 - 2*8], mm3
716 :     jnz near .loop
717 : edgomez 1174
718 :     ; deal with DC
719 : edgomez 1192 movd mm0, [ecx]
720 :     pmullw mm0, [esp+16] ; dcscalar
721 :     movq mm2, [mmx_32767_minus_2047]
722 :     paddsw mm0, mm2
723 :     psubsw mm0, mm2
724 :     movq mm2, [mmx_32768_minus_2048]
725 :     psubsw mm0, mm2
726 :     paddsw mm0, mm2
727 :     movd eax, mm0
728 :     mov [edx], ax
729 : edgomez 1174
730 : edgomez 1192 xor eax, eax
731 :     ret
732 : edgomez 1174
733 :    
734 : edgomez 1192 ;-----------------------------------------------------------------------------
735 : edgomez 1174 ;
736 : edgomez 1176 ; uint32_t dequant_h263_intra_sse2(int16_t *data,
737 :     ; const int16_t const *coeff,
738 :     ; const uint32_t quant,
739 :     ; const uint32_t dcscalar);
740 : edgomez 1174 ;
741 : edgomez 1192 ;-----------------------------------------------------------------------------
742 : edgomez 1176
743 : edgomez 1192 ALIGN 16
744 : edgomez 1174 dequant_h263_intra_sse2:
745 : edgomez 1192 mov edx, [esp+ 4] ; data
746 :     mov ecx, [esp+ 8] ; coeff
747 :     mov eax, [esp+12] ; quant
748 :     movq mm6, [mmx_add + eax * 8 - 8]
749 :     movq mm7, [mmx_mul + eax * 8 - 8]
750 :     movq2dq xmm6, mm6
751 :     movq2dq xmm7, mm7
752 :     movlhps xmm6, xmm6
753 :     movlhps xmm7, xmm7
754 :     mov eax, -16
755 : edgomez 1174
756 : edgomez 1192 ALIGN 16
757 : edgomez 1174 .loop
758 : edgomez 1192 movdqa xmm0, [ecx + 8*16 + 8*eax] ; c = coeff[i]
759 :     movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]
760 :     pxor xmm1, xmm1
761 :     pxor xmm4, xmm4
762 :     pcmpgtw xmm1, xmm0 ; sign(c)
763 :     pcmpgtw xmm4, xmm3
764 :     pxor xmm2, xmm2
765 :     pxor xmm5, xmm5
766 :     pcmpeqw xmm2, xmm0 ; c is zero
767 :     pcmpeqw xmm5, xmm3
768 :     pandn xmm2, xmm6 ; offset = isZero ? 0 : quant_add
769 :     pandn xmm5, xmm6
770 :     pxor xmm0, xmm1 ; negate if negative
771 :     pxor xmm3, xmm4
772 :     psubw xmm0, xmm1
773 :     psubw xmm3, xmm4
774 :     pmullw xmm0, xmm7 ; *= 2Q
775 :     pmullw xmm3, xmm7
776 :     paddw xmm0, xmm2 ; + offset
777 :     paddw xmm3, xmm5
778 :     paddw xmm0, xmm1 ; negate back
779 :     paddw xmm3, xmm4
780 : edgomez 1174
781 : edgomez 1192 ; saturates to +2047
782 :     movdqa xmm2, [sse2_2047]
783 :     pminsw xmm0, xmm2
784 :     add eax, 4
785 :     pminsw xmm3, xmm2
786 : edgomez 1174
787 : edgomez 1192 pxor xmm0, xmm1
788 :     pxor xmm3, xmm4
789 :     movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
790 :     movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
791 :     jnz near .loop
792 : edgomez 1174
793 : edgomez 1192 ; deal with DC
794 :     movd mm0, [ecx]
795 :     pmullw mm0, [esp+16] ; dcscalar
796 :     movq mm2, [mmx_32767_minus_2047]
797 :     paddsw mm0, mm2
798 :     psubsw mm0, mm2
799 :     movq mm2, [mmx_32768_minus_2048]
800 :     psubsw mm0, mm2
801 :     paddsw mm0, mm2
802 :     movd eax, mm0
803 :     mov [edx], ax
804 : edgomez 1174
805 : edgomez 1192 xor eax, eax
806 :     ret
807 : edgomez 1174
808 : edgomez 1192 ;-----------------------------------------------------------------------------
809 : edgomez 1174 ;
810 : edgomez 1176 ; uint32t dequant_h263_inter_mmx(int16_t * data,
811 :     ; const int16_t * const coeff,
812 :     ; const uint32_t quant);
813 : edgomez 1174 ;
814 : edgomez 1192 ;-----------------------------------------------------------------------------
815 : edgomez 1174
816 : edgomez 1192 ALIGN 16
817 : edgomez 1174 dequant_h263_inter_mmx:
818 :    
819 : edgomez 1192 mov edx, [esp+ 4] ; data
820 :     mov ecx, [esp+ 8] ; coeff
821 :     mov eax, [esp+12] ; quant
822 :     movq mm6, [mmx_add + eax*8 - 8] ; quant or quant-1
823 :     movq mm7, [mmx_mul + eax*8 - 8] ; 2*quant
824 :     mov eax, -16
825 : edgomez 1174
826 : edgomez 1192 ALIGN 16
827 : edgomez 1174 .loop
828 : edgomez 1192 movq mm0, [ecx+8*eax+8*16] ; c = coeff[i]
829 :     movq mm3, [ecx+8*eax+8*16 + 8] ; c' = coeff[i+1]
830 :     pxor mm1, mm1
831 :     pxor mm4, mm4
832 :     pcmpgtw mm1, mm0 ; sign(c)
833 :     pcmpgtw mm4, mm3 ; sign(c')
834 :     pxor mm2, mm2
835 :     pxor mm5, mm5
836 :     pcmpeqw mm2, mm0 ; c is zero
837 :     pcmpeqw mm5, mm3 ; c' is zero
838 :     pandn mm2, mm6 ; offset = isZero ? 0 : quant_add
839 :     pandn mm5, mm6
840 :     pxor mm0, mm1 ; negate if negative
841 :     pxor mm3, mm4 ; negate if negative
842 :     psubw mm0, mm1
843 :     psubw mm3, mm4
844 :     pmullw mm0, mm7 ; *= 2Q
845 :     pmullw mm3, mm7 ; *= 2Q
846 :     paddw mm0, mm2 ; + offset
847 :     paddw mm3, mm5 ; + offset
848 :     paddw mm0, mm1 ; negate back
849 :     paddw mm3, mm4 ; negate back
850 :     ; saturates to +2047
851 :     movq mm2, [mmx_32767_minus_2047]
852 :     add eax, 2
853 :     paddsw mm0, mm2
854 :     paddsw mm3, mm2
855 :     psubsw mm0, mm2
856 :     psubsw mm3, mm2
857 : edgomez 1174
858 : edgomez 1192 pxor mm0, mm1
859 :     pxor mm3, mm4
860 :     movq [edx + 8*eax + 8*16 - 2*8], mm0
861 :     movq [edx + 8*eax + 8*16+8 - 2*8], mm3
862 :     jnz near .loop
863 : edgomez 1174
864 : edgomez 1192 xor eax, eax
865 :     ret
866 : edgomez 1174
867 : edgomez 1192 ;-----------------------------------------------------------------------------
868 : edgomez 1174 ;
869 : edgomez 1176 ; uint32_t dequant_h263_inter_xmm(int16_t * data,
870 :     ; const int16_t * const coeff,
871 :     ; const uint32_t quant);
872 : edgomez 1174 ;
873 : edgomez 1192 ;-----------------------------------------------------------------------------
874 : edgomez 1174
875 :     ; this is the same as dequant_inter_mmx,
876 :     ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
877 :    
878 : edgomez 1192 ALIGN 16
879 : edgomez 1174 dequant_h263_inter_xmm:
880 :    
881 : edgomez 1192 mov edx, [esp+ 4] ; data
882 :     mov ecx, [esp+ 8] ; coeff
883 :     mov eax, [esp+12] ; quant
884 :     movq mm6, [mmx_add + eax*8 - 8] ; quant or quant-1
885 :     movq mm7, [mmx_mul + eax*8 - 8] ; 2*quant
886 :     mov eax, -16
887 : edgomez 1174
888 : edgomez 1192 ALIGN 16
889 : edgomez 1174 .loop
890 : edgomez 1192 movq mm0, [ecx+8*eax+8*16] ; c = coeff[i]
891 :     movq mm3, [ecx+8*eax+8*16 + 8] ; c' = coeff[i+1]
892 :     pxor mm1, mm1
893 :     pxor mm4, mm4
894 :     pcmpgtw mm1, mm0 ; sign(c)
895 :     pcmpgtw mm4, mm3 ; sign(c')
896 :     pxor mm2, mm2
897 :     pxor mm5, mm5
898 :     pcmpeqw mm2, mm0 ; c is zero
899 :     pcmpeqw mm5, mm3 ; c' is zero
900 :     pandn mm2, mm6 ; offset = isZero ? 0 : quant_add
901 :     pandn mm5, mm6
902 :     pxor mm0, mm1 ; negate if negative
903 :     pxor mm3, mm4 ; negate if negative
904 :     psubw mm0, mm1
905 :     psubw mm3, mm4
906 :     pmullw mm0, mm7 ; *= 2Q
907 :     pmullw mm3, mm7 ; *= 2Q
908 :     paddw mm0, mm2 ; + offset
909 :     paddw mm3, mm5 ; + offset
910 :     paddw mm0, mm1 ; start restoring sign
911 :     paddw mm3, mm4 ; start restoring sign
912 :     ; saturates to +2047
913 :     movq mm2, [mmx_2047]
914 :     pminsw mm0, mm2
915 :     add eax, 2
916 :     pminsw mm3, mm2
917 : edgomez 1174
918 : edgomez 1192 pxor mm0, mm1 ; finish restoring sign
919 :     pxor mm3, mm4 ; finish restoring sign
920 :     movq [edx + 8*eax + 8*16 - 2*8], mm0
921 :     movq [edx + 8*eax + 8*16+8 - 2*8], mm3
922 :     jnz near .loop
923 : edgomez 1174
924 : edgomez 1192 xor eax, eax
925 :     ret
926 : edgomez 1174
927 : edgomez 1192 ;-----------------------------------------------------------------------------
928 : edgomez 1174 ;
929 : edgomez 1176 ; uint32_t dequant_h263_inter_sse2(int16_t * data,
930 :     ; const int16_t * const coeff,
931 :     ; const uint32_t quant);
932 : edgomez 1174 ;
933 : edgomez 1192 ;-----------------------------------------------------------------------------
934 :    
935 :     ALIGN 16
936 : edgomez 1174 dequant_h263_inter_sse2:
937 : edgomez 1192 mov edx, [esp + 4] ; data
938 :     mov ecx, [esp + 8] ; coeff
939 :     mov eax, [esp + 12] ; quant
940 :     movq mm6, [mmx_add + eax * 8 - 8]
941 :     movq mm7, [mmx_mul + eax * 8 - 8]
942 :     movq2dq xmm6, mm6
943 :     movq2dq xmm7, mm7
944 :     movlhps xmm6, xmm6
945 :     movlhps xmm7, xmm7
946 :     mov eax, -16
947 : edgomez 1174
948 : edgomez 1192 ALIGN 16
949 : edgomez 1174 .loop
950 : edgomez 1192 movdqa xmm0, [ecx + 8*16 + 8*eax] ; c = coeff[i]
951 :     movdqa xmm3, [ecx + 8*16 + 8*eax + 16]
952 : edgomez 1174
953 : edgomez 1192 pxor xmm1, xmm1
954 :     pxor xmm4, xmm4
955 :     pcmpgtw xmm1, xmm0 ; sign(c)
956 :     pcmpgtw xmm4, xmm3
957 :     pxor xmm2, xmm2
958 :     pxor xmm5, xmm5
959 :     pcmpeqw xmm2, xmm0 ; c is zero
960 :     pcmpeqw xmm5, xmm3
961 :     pandn xmm2, xmm6
962 :     pandn xmm5, xmm6
963 :     pxor xmm0, xmm1 ; negate if negative
964 :     pxor xmm3, xmm4
965 :     psubw xmm0, xmm1
966 :     psubw xmm3, xmm4
967 :     pmullw xmm0, xmm7 ; *= 2Q
968 :     pmullw xmm3, xmm7
969 :     paddw xmm0, xmm2 ; + offset
970 :     paddw xmm3, xmm5
971 : edgomez 1174
972 : edgomez 1192 paddw xmm0, xmm1 ; start restoring sign
973 :     paddw xmm3, xmm4
974 : edgomez 1174
975 : edgomez 1192 ; saturates to +2047
976 :     movdqa xmm2, [sse2_2047]
977 :     pminsw xmm0, xmm2
978 :     add eax, 4
979 :     pminsw xmm3, xmm2
980 : edgomez 1174
981 : edgomez 1192 pxor xmm0, xmm1 ; finish restoring sign
982 :     pxor xmm3, xmm4
983 :     movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
984 :     movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
985 :     jnz near .loop
986 : edgomez 1174
987 : edgomez 1192 xor eax, eax
988 :     ret

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