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

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