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

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