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

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