00001 /* 00002 00003 SDL_imageFilter - bytes-image "filter" routines. 00004 (Uses inline x86 MMX or ASM optimizations if available and enabled.) 00005 00006 LGPL (c) A. Schiffler 00007 00008 Note: Most of the MMX code is based on published routines 00009 by Vladimir Kravtchenko at vk@cs.ubc.ca - credits go to 00010 him for his work. 00011 00012 */ 00013 00014 #include <stdio.h> 00015 #include <stdlib.h> 00016 #include <string.h> 00017 00018 #include "SDL_imageFilter.h" 00019 00023 #define SWAP_32(x) (((x) >> 24) | (((x) & 0x00ff0000) >> 8) | (((x) & 0x0000ff00) << 8) | ((x) << 24)) 00024 00025 /* ------ Static variables ----- */ 00026 00030 static int SDL_imageFilterUseMMX = 1; 00031 00032 /* Detect GCC */ 00033 #if defined(__GNUC__) 00034 #define GCC__ 00035 #endif 00036 00042 unsigned int _cpuFlags() 00043 { 00044 unsigned int flags = 0; 00045 00046 #ifdef USE_MMX 00047 #if !defined(GCC__) 00048 __asm 00049 { 00050 pusha 00051 mov eax, 1 00052 cpuid /* get CPU ID flag */ 00053 mov flags,edx /* move result to mmx_bit */ 00054 popa 00055 } 00056 #else 00057 asm volatile ("pusha \n\t" "mov %1, %%eax \n\t" /* request feature flag */ 00058 "cpuid \n\t" /* get CPU ID flag */ 00059 "mov %%edx, %0 \n\t" /* move result to mmx_bit */ 00060 "popa \n\t":"=m" (flags) /* %0 */ 00061 :"i"(0x00000001) /* %1 */ 00062 ); 00063 #endif 00064 #endif 00065 00066 return (flags); 00067 } 00068 00074 int SDL_imageFilterMMXdetect(void) 00075 { 00076 unsigned int mmx_bit; 00077 00078 /* Check override flag */ 00079 if (SDL_imageFilterUseMMX == 0) { 00080 return (0); 00081 } 00082 00083 mmx_bit = _cpuFlags(); 00084 mmx_bit &= 0x00800000; 00085 mmx_bit = (mmx_bit && 0x00800000); 00086 00087 return (int)(mmx_bit); 00088 } 00089 00093 void SDL_imageFilterMMXoff() 00094 { 00095 SDL_imageFilterUseMMX = 0; 00096 } 00097 00101 void SDL_imageFilterMMXon() 00102 { 00103 SDL_imageFilterUseMMX = 1; 00104 } 00105 00106 /* ------------------------------------------------------------------------------------ */ 00107 00118 int SDL_imageFilterAddMMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 00119 { 00120 #ifdef USE_MMX 00121 #if !defined(GCC__) 00122 __asm 00123 { 00124 pusha 00125 mov eax, Src1 /* load Src1 address into eax */ 00126 mov ebx, Src2 /* load Src2 address into ebx */ 00127 mov edi, Dest /* load Dest address into edi */ 00128 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 00129 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 00130 align 16 /* 16 byte alignment of the loop entry */ 00131 L1010: 00132 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 00133 paddusb mm1, [ebx] /* mm1=Src1+Src2 (add 8 bytes with saturation) */ 00134 movq [edi], mm1 /* store result in Dest */ 00135 add eax, 8 /* increase Src1, Src2 and Dest */ 00136 add ebx, 8 /* register pointers by 8 */ 00137 add edi, 8 00138 dec ecx /* decrease loop counter */ 00139 jnz L1010 /* check loop termination, proceed if required */ 00140 emms /* exit MMX state */ 00141 popa 00142 } 00143 #else 00144 asm volatile 00145 ("pusha \n\t" "mov %2, %%eax \n\t" /* load Src1 address into eax */ 00146 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 00147 "mov %0, %%edi \n\t" /* load Dest address into edi */ 00148 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 00149 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 00150 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 00151 "1: movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 00152 "paddusb (%%ebx), %%mm1 \n\t" /* mm1=Src1+Src2 (add 8 bytes with saturation) */ 00153 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 00154 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 00155 "add $8, %%ebx \n\t" /* register pointers by 8 */ 00156 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 00157 "jnz 1b \n\t" /* check loop termination, proceed if required */ 00158 "emms \n\t" /* exit MMX state */ 00159 "popa \n\t":"=m" (Dest) /* %0 */ 00160 :"m"(Src2), /* %1 */ 00161 "m"(Src1), /* %2 */ 00162 "m"(SrcLength) /* %3 */ 00163 ); 00164 #endif 00165 return (0); 00166 #else 00167 return (-1); 00168 #endif 00169 } 00170 00181 int SDL_imageFilterAdd(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 00182 { 00183 unsigned int i, istart; 00184 unsigned char *cursrc1, *cursrc2, *curdst; 00185 int result; 00186 00187 /* Validate input parameters */ 00188 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 00189 return(-1); 00190 if (length == 0) 00191 return(0); 00192 00193 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 00194 00195 /* Use MMX assembly routine */ 00196 SDL_imageFilterAddMMX(Src1, Src2, Dest, length); 00197 00198 /* Check for unaligned bytes */ 00199 if ((length & 7) > 0) { 00200 /* Setup to process unaligned bytes */ 00201 istart = length & 0xfffffff8; 00202 cursrc1 = &Src1[istart]; 00203 cursrc2 = &Src2[istart]; 00204 curdst = &Dest[istart]; 00205 } else { 00206 /* No unaligned bytes - we are done */ 00207 return (0); 00208 } 00209 } else { 00210 /* Setup to process whole image */ 00211 istart = 0; 00212 cursrc1 = Src1; 00213 cursrc2 = Src2; 00214 curdst = Dest; 00215 } 00216 00217 /* C routine to process image */ 00218 for (i = istart; i < length; i++) { 00219 result = (int) *cursrc1 + (int) *cursrc2; 00220 if (result > 255) 00221 result = 255; 00222 *curdst = (unsigned char) result; 00223 /* Advance pointers */ 00224 cursrc1++; 00225 cursrc2++; 00226 curdst++; 00227 } 00228 00229 return (0); 00230 } 00231 00243 int SDL_imageFilterMeanMMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength, 00244 unsigned char *Mask) 00245 { 00246 #ifdef USE_MMX 00247 #if !defined(GCC__) 00248 __asm 00249 { 00250 pusha 00251 mov edx, Mask /* load Mask address into edx */ 00252 movq mm0, [edx] /* load Mask into mm0 */ 00253 mov eax, Src1 /* load Src1 address into eax */ 00254 mov ebx, Src2 /* load Src2 address into ebx */ 00255 mov edi, Dest /* load Dest address into edi */ 00256 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 00257 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 00258 align 16 /* 16 byte alignment of the loop entry */ 00259 L21011: 00260 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 00261 movq mm2, [ebx] /* load 8 bytes from Src2 into mm2 */ 00262 /* --- Byte shift via Word shift --- */ 00263 psrlw mm1, 1 /* shift 4 WORDS of mm1 1 bit to the right */ 00264 psrlw mm2, 1 /* shift 4 WORDS of mm2 1 bit to the right */ 00265 pand mm1, mm0 // apply Mask to 8 BYTES of mm1 */ 00266 /* byte 0x0f, 0xdb, 0xc8 */ 00267 pand mm2, mm0 // apply Mask to 8 BYTES of mm2 */ 00268 /* byte 0x0f, 0xdb, 0xd0 */ 00269 paddusb mm1, mm2 /* mm1=mm1+mm2 (add 8 bytes with saturation) */ 00270 movq [edi], mm1 /* store result in Dest */ 00271 add eax, 8 /* increase Src1, Src2 and Dest */ 00272 add ebx, 8 /* register pointers by 8 */ 00273 add edi, 8 00274 dec ecx /* decrease loop counter */ 00275 jnz L21011 /* check loop termination, proceed if required */ 00276 emms /* exit MMX state */ 00277 popa 00278 } 00279 #else 00280 asm volatile 00281 ("pusha \n\t" "movl %4, %%edx \n\t" /* load Mask address into edx */ 00282 "movq (%%edx), %%mm0 \n\t" /* load Mask into mm0 */ 00283 "mov %2, %%eax \n\t" /* load Src1 address into eax */ 00284 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 00285 "mov %0, %%edi \n\t" /* load Dest address into edi */ 00286 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 00287 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 00288 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 00289 "1: \n\t" 00290 "movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 00291 "movq (%%ebx), %%mm2 \n\t" /* load 8 bytes from Src2 into mm2 */ 00292 /* --- Byte shift via Word shift --- */ 00293 "psrlw $1, %%mm1 \n\t" /* shift 4 WORDS of mm1 1 bit to the right */ 00294 "psrlw $1, %%mm2 \n\t" /* shift 4 WORDS of mm2 1 bit to the right */ 00295 /* "pand %%mm0, %%mm1 \n\t" // apply Mask to 8 BYTES of mm1 */ 00296 ".byte 0x0f, 0xdb, 0xc8 \n\t" 00297 /* "pand %%mm0, %%mm2 \n\t" // apply Mask to 8 BYTES of mm2 */ 00298 ".byte 0x0f, 0xdb, 0xd0 \n\t" 00299 "paddusb %%mm2, %%mm1 \n\t" /* mm1=mm1+mm2 (add 8 bytes with saturation) */ 00300 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 00301 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 00302 "add $8, %%ebx \n\t" /* register pointers by 8 */ 00303 "add $8, %%edi \n\t" 00304 "dec %%ecx \n\t" /* decrease loop counter */ 00305 "jnz 1b \n\t" /* check loop termination, proceed if required */ 00306 "emms \n\t" /* exit MMX state */ 00307 "popa \n\t":"=m" (Dest) /* %0 */ 00308 :"m"(Src2), /* %1 */ 00309 "m"(Src1), /* %2 */ 00310 "m"(SrcLength), /* %3 */ 00311 "m"(Mask) /* %4 */ 00312 ); 00313 #endif 00314 return (0); 00315 #else 00316 return (-1); 00317 #endif 00318 } 00319 00330 int SDL_imageFilterMean(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 00331 { 00332 static unsigned char Mask[8] = { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F }; 00333 unsigned int i, istart; 00334 unsigned char *cursrc1, *cursrc2, *curdst; 00335 int result; 00336 00337 /* Validate input parameters */ 00338 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 00339 return(-1); 00340 if (length == 0) 00341 return(0); 00342 00343 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 00344 /* MMX routine */ 00345 SDL_imageFilterMeanMMX(Src1, Src2, Dest, length, Mask); 00346 00347 /* Check for unaligned bytes */ 00348 if ((length & 7) > 0) { 00349 /* Setup to process unaligned bytes */ 00350 istart = length & 0xfffffff8; 00351 cursrc1 = &Src1[istart]; 00352 cursrc2 = &Src2[istart]; 00353 curdst = &Dest[istart]; 00354 } else { 00355 /* No unaligned bytes - we are done */ 00356 return (0); 00357 } 00358 } else { 00359 /* Setup to process whole image */ 00360 istart = 0; 00361 cursrc1 = Src1; 00362 cursrc2 = Src2; 00363 curdst = Dest; 00364 } 00365 00366 /* C routine to process image */ 00367 for (i = istart; i < length; i++) { 00368 result = (int) *cursrc1 / 2 + (int) *cursrc2 / 2; 00369 *curdst = (unsigned char) result; 00370 /* Advance pointers */ 00371 cursrc1++; 00372 cursrc2++; 00373 curdst++; 00374 } 00375 00376 return (0); 00377 } 00378 00389 int SDL_imageFilterSubMMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 00390 { 00391 #ifdef USE_MMX 00392 #if !defined(GCC__) 00393 __asm 00394 { 00395 pusha 00396 mov eax, Src1 /* load Src1 address into eax */ 00397 mov ebx, Src2 /* load Src2 address into ebx */ 00398 mov edi, Dest /* load Dest address into edi */ 00399 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 00400 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 00401 align 16 /* 16 byte alignment of the loop entry */ 00402 L1012: 00403 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 00404 psubusb mm1, [ebx] /* mm1=Src1-Src2 (sub 8 bytes with saturation) */ 00405 movq [edi], mm1 /* store result in Dest */ 00406 add eax, 8 /* increase Src1, Src2 and Dest */ 00407 add ebx, 8 /* register pointers by 8 */ 00408 add edi, 8 00409 dec ecx /* decrease loop counter */ 00410 jnz L1012 /* check loop termination, proceed if required */ 00411 emms /* exit MMX state */ 00412 popa 00413 } 00414 #else 00415 asm volatile 00416 ("pusha \n\t" "mov %2, %%eax \n\t" /* load Src1 address into eax */ 00417 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 00418 "mov %0, %%edi \n\t" /* load Dest address into edi */ 00419 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 00420 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 00421 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 00422 "1: movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 00423 "psubusb (%%ebx), %%mm1 \n\t" /* mm1=Src1-Src2 (sub 8 bytes with saturation) */ 00424 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 00425 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 00426 "add $8, %%ebx \n\t" /* register pointers by 8 */ 00427 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 00428 "jnz 1b \n\t" /* check loop termination, proceed if required */ 00429 "emms \n\t" /* exit MMX state */ 00430 "popa \n\t":"=m" (Dest) /* %0 */ 00431 :"m"(Src2), /* %1 */ 00432 "m"(Src1), /* %2 */ 00433 "m"(SrcLength) /* %3 */ 00434 ); 00435 #endif 00436 return (0); 00437 #else 00438 return (-1); 00439 #endif 00440 } 00441 00452 int SDL_imageFilterSub(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 00453 { 00454 unsigned int i, istart; 00455 unsigned char *cursrc1, *cursrc2, *curdst; 00456 int result; 00457 00458 /* Validate input parameters */ 00459 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 00460 return(-1); 00461 if (length == 0) 00462 return(0); 00463 00464 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 00465 /* MMX routine */ 00466 SDL_imageFilterSubMMX(Src1, Src2, Dest, length); 00467 00468 /* Check for unaligned bytes */ 00469 if ((length & 7) > 0) { 00470 /* Setup to process unaligned bytes */ 00471 istart = length & 0xfffffff8; 00472 cursrc1 = &Src1[istart]; 00473 cursrc2 = &Src2[istart]; 00474 curdst = &Dest[istart]; 00475 } else { 00476 /* No unaligned bytes - we are done */ 00477 return (0); 00478 } 00479 } else { 00480 /* Setup to process whole image */ 00481 istart = 0; 00482 cursrc1 = Src1; 00483 cursrc2 = Src2; 00484 curdst = Dest; 00485 } 00486 00487 /* C routine to process image */ 00488 for (i = istart; i < length; i++) { 00489 result = (int) *cursrc1 - (int) *cursrc2; 00490 if (result < 0) 00491 result = 0; 00492 *curdst = (unsigned char) result; 00493 /* Advance pointers */ 00494 cursrc1++; 00495 cursrc2++; 00496 curdst++; 00497 } 00498 00499 return (0); 00500 } 00501 00512 int SDL_imageFilterAbsDiffMMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 00513 { 00514 #ifdef USE_MMX 00515 #if !defined(GCC__) 00516 __asm 00517 { 00518 pusha 00519 mov eax, Src1 /* load Src1 address into eax */ 00520 mov ebx, Src2 /* load Src2 address into ebx */ 00521 mov edi, Dest /* load Dest address into edi */ 00522 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 00523 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 00524 align 16 /* 16 byte alignment of the loop entry */ 00525 L1013: 00526 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 00527 movq mm2, [ebx] /* load 8 bytes from Src2 into mm2 */ 00528 psubusb mm1, [ebx] /* mm1=Src1-Src2 (sub 8 bytes with saturation) */ 00529 psubusb mm2, [eax] /* mm2=Src2-Src1 (sub 8 bytes with saturation) */ 00530 por mm1, mm2 /* combine both mm2 and mm1 results */ 00531 movq [edi], mm1 /* store result in Dest */ 00532 add eax, 8 /* increase Src1, Src2 and Dest */ 00533 add ebx, 8 /* register pointers by 8 */ 00534 add edi, 8 00535 dec ecx /* decrease loop counter */ 00536 jnz L1013 /* check loop termination, proceed if required */ 00537 emms /* exit MMX state */ 00538 popa 00539 } 00540 #else 00541 asm volatile 00542 ("pusha \n\t" "mov %2, %%eax \n\t" /* load Src1 address into eax */ 00543 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 00544 "mov %0, %%edi \n\t" /* load Dest address into edi */ 00545 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 00546 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 00547 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 00548 "1: movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 00549 "movq (%%ebx), %%mm2 \n\t" /* load 8 bytes from Src2 into mm2 */ 00550 "psubusb (%%ebx), %%mm1 \n\t" /* mm1=Src1-Src2 (sub 8 bytes with saturation) */ 00551 "psubusb (%%eax), %%mm2 \n\t" /* mm2=Src2-Src1 (sub 8 bytes with saturation) */ 00552 "por %%mm2, %%mm1 \n\t" /* combine both mm2 and mm1 results */ 00553 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 00554 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 00555 "add $8, %%ebx \n\t" /* register pointers by 8 */ 00556 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 00557 "jnz 1b \n\t" /* check loop termination, proceed if required */ 00558 "emms \n\t" /* exit MMX state */ 00559 "popa \n\t":"=m" (Dest) /* %0 */ 00560 :"m"(Src2), /* %1 */ 00561 "m"(Src1), /* %2 */ 00562 "m"(SrcLength) /* %3 */ 00563 ); 00564 #endif 00565 return (0); 00566 #else 00567 return (-1); 00568 #endif 00569 } 00570 00581 int SDL_imageFilterAbsDiff(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 00582 { 00583 unsigned int i, istart; 00584 unsigned char *cursrc1, *cursrc2, *curdst; 00585 int result; 00586 00587 /* Validate input parameters */ 00588 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 00589 return(-1); 00590 if (length == 0) 00591 return(0); 00592 00593 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 00594 /* MMX routine */ 00595 SDL_imageFilterAbsDiffMMX(Src1, Src2, Dest, length); 00596 00597 /* Check for unaligned bytes */ 00598 if ((length & 7) > 0) { 00599 /* Setup to process unaligned bytes */ 00600 istart = length & 0xfffffff8; 00601 cursrc1 = &Src1[istart]; 00602 cursrc2 = &Src2[istart]; 00603 curdst = &Dest[istart]; 00604 } else { 00605 /* No unaligned bytes - we are done */ 00606 return (0); 00607 } 00608 } else { 00609 /* Setup to process whole image */ 00610 istart = 0; 00611 cursrc1 = Src1; 00612 cursrc2 = Src2; 00613 curdst = Dest; 00614 } 00615 00616 /* C routine to process image */ 00617 for (i = istart; i < length; i++) { 00618 result = abs((int) *cursrc1 - (int) *cursrc2); 00619 *curdst = (unsigned char) result; 00620 /* Advance pointers */ 00621 cursrc1++; 00622 cursrc2++; 00623 curdst++; 00624 } 00625 00626 return (0); 00627 } 00628 00639 int SDL_imageFilterMultMMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 00640 { 00641 #ifdef USE_MMX 00642 #if !defined(GCC__) 00643 __asm 00644 { 00645 pusha 00646 mov eax, Src1 /* load Src1 address into eax */ 00647 mov ebx, Src2 /* load Src2 address into ebx */ 00648 mov edi, Dest /* load Dest address into edi */ 00649 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 00650 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 00651 pxor mm0, mm0 /* zero mm0 register */ 00652 align 16 /* 16 byte alignment of the loop entry */ 00653 L1014: 00654 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 00655 movq mm3, [ebx] /* load 8 bytes from Src2 into mm3 */ 00656 movq mm2, mm1 /* copy mm1 into mm2 */ 00657 movq mm4, mm3 /* copy mm3 into mm4 */ 00658 punpcklbw mm1, mm0 /* unpack low bytes of Src1 into words */ 00659 punpckhbw mm2, mm0 /* unpack high bytes of Src1 into words */ 00660 punpcklbw mm3, mm0 /* unpack low bytes of Src2 into words */ 00661 punpckhbw mm4, mm0 /* unpack high bytes of Src2 into words */ 00662 pmullw mm1, mm3 /* mul low bytes of Src1 and Src2 */ 00663 pmullw mm2, mm4 /* mul high bytes of Src1 and Src2 */ 00664 /* Take abs value of the results (signed words) */ 00665 movq mm5, mm1 /* copy mm1 into mm5 */ 00666 movq mm6, mm2 /* copy mm2 into mm6 */ 00667 psraw mm5, 15 /* fill mm5 words with word sign bit */ 00668 psraw mm6, 15 /* fill mm6 words with word sign bit */ 00669 pxor mm1, mm5 /* take 1's compliment of only neg. words */ 00670 pxor mm2, mm6 /* take 1's compliment of only neg. words */ 00671 psubsw mm1, mm5 /* add 1 to only neg. words, W-(-1) or W-0 */ 00672 psubsw mm2, mm6 /* add 1 to only neg. words, W-(-1) or W-0 */ 00673 packuswb mm1, mm2 /* pack words back into bytes with saturation */ 00674 movq [edi], mm1 /* store result in Dest */ 00675 add eax, 8 /* increase Src1, Src2 and Dest */ 00676 add ebx, 8 /* register pointers by 8 */ 00677 add edi, 8 00678 dec ecx /* decrease loop counter */ 00679 jnz L1014 /* check loop termination, proceed if required */ 00680 emms /* exit MMX state */ 00681 popa 00682 } 00683 #else 00684 asm volatile 00685 ("pusha \n\t" "mov %2, %%eax \n\t" /* load Src1 address into eax */ 00686 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 00687 "mov %0, %%edi \n\t" /* load Dest address into edi */ 00688 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 00689 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 00690 "pxor %%mm0, %%mm0 \n\t" /* zero mm0 register */ 00691 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 00692 "1: movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 00693 "movq (%%ebx), %%mm3 \n\t" /* load 8 bytes from Src2 into mm3 */ 00694 "movq %%mm1, %%mm2 \n\t" /* copy mm1 into mm2 */ 00695 "movq %%mm3, %%mm4 \n\t" /* copy mm3 into mm4 */ 00696 "punpcklbw %%mm0, %%mm1 \n\t" /* unpack low bytes of Src1 into words */ 00697 "punpckhbw %%mm0, %%mm2 \n\t" /* unpack high bytes of Src1 into words */ 00698 "punpcklbw %%mm0, %%mm3 \n\t" /* unpack low bytes of Src2 into words */ 00699 "punpckhbw %%mm0, %%mm4 \n\t" /* unpack high bytes of Src2 into words */ 00700 "pmullw %%mm3, %%mm1 \n\t" /* mul low bytes of Src1 and Src2 */ 00701 "pmullw %%mm4, %%mm2 \n\t" /* mul high bytes of Src1 and Src2 */ 00702 /* Take abs value of the results (signed words) */ 00703 "movq %%mm1, %%mm5 \n\t" /* copy mm1 into mm5 */ 00704 "movq %%mm2, %%mm6 \n\t" /* copy mm2 into mm6 */ 00705 "psraw $15, %%mm5 \n\t" /* fill mm5 words with word sign bit */ 00706 "psraw $15, %%mm6 \n\t" /* fill mm6 words with word sign bit */ 00707 "pxor %%mm5, %%mm1 \n\t" /* take 1's compliment of only neg. words */ 00708 "pxor %%mm6, %%mm2 \n\t" /* take 1's compliment of only neg. words */ 00709 "psubsw %%mm5, %%mm1 \n\t" /* add 1 to only neg. words, W-(-1) or W-0 */ 00710 "psubsw %%mm6, %%mm2 \n\t" /* add 1 to only neg. words, W-(-1) or W-0 */ 00711 "packuswb %%mm2, %%mm1 \n\t" /* pack words back into bytes with saturation */ 00712 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 00713 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 00714 "add $8, %%ebx \n\t" /* register pointers by 8 */ 00715 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 00716 "jnz 1b \n\t" /* check loop termination, proceed if required */ 00717 "emms \n\t" /* exit MMX state */ 00718 "popa \n\t":"=m" (Dest) /* %0 */ 00719 :"m"(Src2), /* %1 */ 00720 "m"(Src1), /* %2 */ 00721 "m"(SrcLength) /* %3 */ 00722 ); 00723 #endif 00724 return (0); 00725 #else 00726 return (-1); 00727 #endif 00728 } 00729 00740 int SDL_imageFilterMult(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 00741 { 00742 unsigned int i, istart; 00743 unsigned char *cursrc1, *cursrc2, *curdst; 00744 int result; 00745 00746 /* Validate input parameters */ 00747 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 00748 return(-1); 00749 if (length == 0) 00750 return(0); 00751 00752 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 00753 /* MMX routine */ 00754 SDL_imageFilterMultMMX(Src1, Src2, Dest, length); 00755 00756 /* Check for unaligned bytes */ 00757 if ((length & 7) > 0) { 00758 /* Setup to process unaligned bytes */ 00759 istart = length & 0xfffffff8; 00760 cursrc1 = &Src1[istart]; 00761 cursrc2 = &Src2[istart]; 00762 curdst = &Dest[istart]; 00763 } else { 00764 /* No unaligned bytes - we are done */ 00765 return (0); 00766 } 00767 } else { 00768 /* Setup to process whole image */ 00769 istart = 0; 00770 cursrc1 = Src1; 00771 cursrc2 = Src2; 00772 curdst = Dest; 00773 } 00774 00775 /* C routine to process image */ 00776 for (i = istart; i < length; i++) { 00777 00778 /* NOTE: this is probably wrong - dunno what the MMX code does */ 00779 00780 result = (int) *cursrc1 * (int) *cursrc2; 00781 if (result > 255) 00782 result = 255; 00783 *curdst = (unsigned char) result; 00784 /* Advance pointers */ 00785 cursrc1++; 00786 cursrc2++; 00787 curdst++; 00788 } 00789 00790 return (0); 00791 } 00792 00803 int SDL_imageFilterMultNorASM(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 00804 { 00805 #ifdef USE_MMX 00806 #if !defined(GCC__) 00807 __asm 00808 { 00809 pusha 00810 mov edx, Src1 /* load Src1 address into edx */ 00811 mov esi, Src2 /* load Src2 address into esi */ 00812 mov edi, Dest /* load Dest address into edi */ 00813 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 00814 align 16 /* 16 byte alignment of the loop entry */ 00815 L10141: 00816 mov al, [edx] /* load a byte from Src1 */ 00817 mul [esi] /* mul with a byte from Src2 */ 00818 mov [edi], al /* move a byte result to Dest */ 00819 inc edx /* increment Src1, Src2, Dest */ 00820 inc esi /* pointer registers by one */ 00821 inc edi 00822 dec ecx /* decrease loop counter */ 00823 jnz L10141 /* check loop termination, proceed if required */ 00824 popa 00825 } 00826 #else 00827 asm volatile 00828 ("pusha \n\t" "mov %2, %%edx \n\t" /* load Src1 address into edx */ 00829 "mov %1, %%esi \n\t" /* load Src2 address into esi */ 00830 "mov %0, %%edi \n\t" /* load Dest address into edi */ 00831 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 00832 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 00833 "1:mov (%%edx), %%al \n\t" /* load a byte from Src1 */ 00834 "mulb (%%esi) \n\t" /* mul with a byte from Src2 */ 00835 "mov %%al, (%%edi) \n\t" /* move a byte result to Dest */ 00836 "inc %%edx \n\t" /* increment Src1, Src2, Dest */ 00837 "inc %%esi \n\t" /* pointer registers by one */ 00838 "inc %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 00839 "jnz 1b \n\t" /* check loop termination, proceed if required */ 00840 "popa \n\t":"=m" (Dest) /* %0 */ 00841 :"m"(Src2), /* %1 */ 00842 "m"(Src1), /* %2 */ 00843 "m"(SrcLength) /* %3 */ 00844 ); 00845 #endif 00846 return (0); 00847 #else 00848 return (-1); 00849 #endif 00850 } 00851 00862 int SDL_imageFilterMultNor(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 00863 { 00864 unsigned int i, istart; 00865 unsigned char *cursrc1, *cursrc2, *curdst; 00866 int result; 00867 00868 /* Validate input parameters */ 00869 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 00870 return(-1); 00871 if (length == 0) 00872 return(0); 00873 00874 if (SDL_imageFilterMMXdetect()) { 00875 if (length > 0) { 00876 /* ASM routine */ 00877 SDL_imageFilterMultNorASM(Src1, Src2, Dest, length); 00878 00879 /* Check for unaligned bytes */ 00880 if ((length & 7) > 0) { 00881 /* Setup to process unaligned bytes */ 00882 istart = length & 0xfffffff8; 00883 cursrc1 = &Src1[istart]; 00884 cursrc2 = &Src2[istart]; 00885 curdst = &Dest[istart]; 00886 } else { 00887 /* No unaligned bytes - we are done */ 00888 return (0); 00889 } 00890 } else { 00891 /* No bytes - we are done */ 00892 return (0); 00893 } 00894 } else { 00895 /* Setup to process whole image */ 00896 istart = 0; 00897 cursrc1 = Src1; 00898 cursrc2 = Src2; 00899 curdst = Dest; 00900 } 00901 00902 /* C routine to process image */ 00903 for (i = istart; i < length; i++) { 00904 result = (int) *cursrc1 * (int) *cursrc2; 00905 *curdst = (unsigned char) result; 00906 /* Advance pointers */ 00907 cursrc1++; 00908 cursrc2++; 00909 curdst++; 00910 } 00911 00912 return (0); 00913 } 00914 00925 int SDL_imageFilterMultDivby2MMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 00926 { 00927 #ifdef USE_MMX 00928 #if !defined(GCC__) 00929 __asm 00930 { 00931 pusha 00932 mov eax, Src1 /* load Src1 address into eax */ 00933 mov ebx, Src2 /* load Src2 address into ebx */ 00934 mov edi, Dest /* load Dest address into edi */ 00935 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 00936 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 00937 pxor mm0, mm0 /* zero mm0 register */ 00938 align 16 /* 16 byte alignment of the loop entry */ 00939 L1015: 00940 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 00941 movq mm3, [ebx] /* load 8 bytes from Src2 into mm3 */ 00942 movq mm2, mm1 /* copy mm1 into mm2 */ 00943 movq mm4, mm3 /* copy mm3 into mm4 */ 00944 punpcklbw mm1, mm0 /* unpack low bytes of Src1 into words */ 00945 punpckhbw mm2, mm0 /* unpack high bytes of Src1 into words */ 00946 punpcklbw mm3, mm0 /* unpack low bytes of Src2 into words */ 00947 punpckhbw mm4, mm0 /* unpack high bytes of Src2 into words */ 00948 psrlw mm1, 1 /* divide mm1 words by 2, Src1 low bytes */ 00949 psrlw mm2, 1 /* divide mm2 words by 2, Src1 high bytes */ 00950 pmullw mm1, mm3 /* mul low bytes of Src1 and Src2 */ 00951 pmullw mm2, mm4 /* mul high bytes of Src1 and Src2 */ 00952 packuswb mm1, mm2 /* pack words back into bytes with saturation */ 00953 movq [edi], mm1 /* store result in Dest */ 00954 add eax, 8 /* increase Src1, Src2 and Dest */ 00955 add ebx, 8 /* register pointers by 8 */ 00956 add edi, 8 00957 dec ecx /* decrease loop counter */ 00958 jnz L1015 /* check loop termination, proceed if required */ 00959 emms /* exit MMX state */ 00960 popa 00961 } 00962 #else 00963 asm volatile 00964 ("pusha \n\t" "mov %2, %%eax \n\t" /* load Src1 address into eax */ 00965 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 00966 "mov %0, %%edi \n\t" /* load Dest address into edi */ 00967 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 00968 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 00969 "pxor %%mm0, %%mm0 \n\t" /* zero mm0 register */ 00970 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 00971 "1: movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 00972 "movq (%%ebx), %%mm3 \n\t" /* load 8 bytes from Src2 into mm3 */ 00973 "movq %%mm1, %%mm2 \n\t" /* copy mm1 into mm2 */ 00974 "movq %%mm3, %%mm4 \n\t" /* copy mm3 into mm4 */ 00975 "punpcklbw %%mm0, %%mm1 \n\t" /* unpack low bytes of Src1 into words */ 00976 "punpckhbw %%mm0, %%mm2 \n\t" /* unpack high bytes of Src1 into words */ 00977 "punpcklbw %%mm0, %%mm3 \n\t" /* unpack low bytes of Src2 into words */ 00978 "punpckhbw %%mm0, %%mm4 \n\t" /* unpack high bytes of Src2 into words */ 00979 "psrlw $1, %%mm1 \n\t" /* divide mm1 words by 2, Src1 low bytes */ 00980 "psrlw $1, %%mm2 \n\t" /* divide mm2 words by 2, Src1 high bytes */ 00981 "pmullw %%mm3, %%mm1 \n\t" /* mul low bytes of Src1 and Src2 */ 00982 "pmullw %%mm4, %%mm2 \n\t" /* mul high bytes of Src1 and Src2 */ 00983 "packuswb %%mm2, %%mm1 \n\t" /* pack words back into bytes with saturation */ 00984 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 00985 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 00986 "add $8, %%ebx \n\t" /* register pointers by 8 */ 00987 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 00988 "jnz 1b \n\t" /* check loop termination, proceed if required */ 00989 "emms \n\t" /* exit MMX state */ 00990 "popa \n\t":"=m" (Dest) /* %0 */ 00991 :"m"(Src2), /* %1 */ 00992 "m"(Src1), /* %2 */ 00993 "m"(SrcLength) /* %3 */ 00994 ); 00995 #endif 00996 return (0); 00997 #else 00998 return (-1); 00999 #endif 01000 } 01001 01012 int SDL_imageFilterMultDivby2(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 01013 { 01014 unsigned int i, istart; 01015 unsigned char *cursrc1, *cursrc2, *curdst; 01016 int result; 01017 01018 /* Validate input parameters */ 01019 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 01020 return(-1); 01021 if (length == 0) 01022 return(0); 01023 01024 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 01025 /* MMX routine */ 01026 SDL_imageFilterMultDivby2MMX(Src1, Src2, Dest, length); 01027 01028 /* Check for unaligned bytes */ 01029 if ((length & 7) > 0) { 01030 /* Setup to process unaligned bytes */ 01031 istart = length & 0xfffffff8; 01032 cursrc1 = &Src1[istart]; 01033 cursrc2 = &Src2[istart]; 01034 curdst = &Dest[istart]; 01035 } else { 01036 /* No unaligned bytes - we are done */ 01037 return (0); 01038 } 01039 } else { 01040 /* Setup to process whole image */ 01041 istart = 0; 01042 cursrc1 = Src1; 01043 cursrc2 = Src2; 01044 curdst = Dest; 01045 } 01046 01047 /* C routine to process image */ 01048 for (i = istart; i < length; i++) { 01049 result = ((int) *cursrc1 / 2) * (int) *cursrc2; 01050 if (result > 255) 01051 result = 255; 01052 *curdst = (unsigned char) result; 01053 /* Advance pointers */ 01054 cursrc1++; 01055 cursrc2++; 01056 curdst++; 01057 } 01058 01059 return (0); 01060 } 01061 01072 int SDL_imageFilterMultDivby4MMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 01073 { 01074 #ifdef USE_MMX 01075 #if !defined(GCC__) 01076 __asm 01077 { 01078 pusha 01079 mov eax, Src1 /* load Src1 address into eax */ 01080 mov ebx, Src2 /* load Src2 address into ebx */ 01081 mov edi, Dest /* load Dest address into edi */ 01082 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 01083 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 01084 pxor mm0, mm0 /* zero mm0 register */ 01085 align 16 /* 16 byte alignment of the loop entry */ 01086 L1016: 01087 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 01088 movq mm3, [ebx] /* load 8 bytes from Src2 into mm3 */ 01089 movq mm2, mm1 /* copy mm1 into mm2 */ 01090 movq mm4, mm3 /* copy mm3 into mm4 */ 01091 punpcklbw mm1, mm0 /* unpack low bytes of Src1 into words */ 01092 punpckhbw mm2, mm0 /* unpack high bytes of Src1 into words */ 01093 punpcklbw mm3, mm0 /* unpack low bytes of Src2 into words */ 01094 punpckhbw mm4, mm0 /* unpack high bytes of Src2 into words */ 01095 psrlw mm1, 1 /* divide mm1 words by 2, Src1 low bytes */ 01096 psrlw mm2, 1 /* divide mm2 words by 2, Src1 high bytes */ 01097 psrlw mm3, 1 /* divide mm3 words by 2, Src2 low bytes */ 01098 psrlw mm4, 1 /* divide mm4 words by 2, Src2 high bytes */ 01099 pmullw mm1, mm3 /* mul low bytes of Src1 and Src2 */ 01100 pmullw mm2, mm4 /* mul high bytes of Src1 and Src2 */ 01101 packuswb mm1, mm2 /* pack words back into bytes with saturation */ 01102 movq [edi], mm1 /* store result in Dest */ 01103 add eax, 8 /* increase Src1, Src2 and Dest */ 01104 add ebx, 8 /* register pointers by 8 */ 01105 add edi, 8 01106 dec ecx /* decrease loop counter */ 01107 jnz L1016 /* check loop termination, proceed if required */ 01108 emms /* exit MMX state */ 01109 popa 01110 } 01111 #else 01112 asm volatile 01113 ("pusha \n\t" "mov %2, %%eax \n\t" /* load Src1 address into eax */ 01114 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 01115 "mov %0, %%edi \n\t" /* load Dest address into edi */ 01116 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 01117 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 01118 "pxor %%mm0, %%mm0 \n\t" /* zero mm0 register */ 01119 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 01120 "1: movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 01121 "movq (%%ebx), %%mm3 \n\t" /* load 8 bytes from Src2 into mm3 */ 01122 "movq %%mm1, %%mm2 \n\t" /* copy mm1 into mm2 */ 01123 "movq %%mm3, %%mm4 \n\t" /* copy mm3 into mm4 */ 01124 "punpcklbw %%mm0, %%mm1 \n\t" /* unpack low bytes of Src1 into words */ 01125 "punpckhbw %%mm0, %%mm2 \n\t" /* unpack high bytes of Src1 into words */ 01126 "punpcklbw %%mm0, %%mm3 \n\t" /* unpack low bytes of Src2 into words */ 01127 "punpckhbw %%mm0, %%mm4 \n\t" /* unpack high bytes of Src2 into words */ 01128 "psrlw $1, %%mm1 \n\t" /* divide mm1 words by 2, Src1 low bytes */ 01129 "psrlw $1, %%mm2 \n\t" /* divide mm2 words by 2, Src1 high bytes */ 01130 "psrlw $1, %%mm3 \n\t" /* divide mm3 words by 2, Src2 low bytes */ 01131 "psrlw $1, %%mm4 \n\t" /* divide mm4 words by 2, Src2 high bytes */ 01132 "pmullw %%mm3, %%mm1 \n\t" /* mul low bytes of Src1 and Src2 */ 01133 "pmullw %%mm4, %%mm2 \n\t" /* mul high bytes of Src1 and Src2 */ 01134 "packuswb %%mm2, %%mm1 \n\t" /* pack words back into bytes with saturation */ 01135 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 01136 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 01137 "add $8, %%ebx \n\t" /* register pointers by 8 */ 01138 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 01139 "jnz 1b \n\t" /* check loop termination, proceed if required */ 01140 "emms \n\t" /* exit MMX state */ 01141 "popa \n\t":"=m" (Dest) /* %0 */ 01142 :"m"(Src2), /* %1 */ 01143 "m"(Src1), /* %2 */ 01144 "m"(SrcLength) /* %3 */ 01145 ); 01146 #endif 01147 return (0); 01148 #else 01149 return (-1); 01150 #endif 01151 } 01152 01163 int SDL_imageFilterMultDivby4(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 01164 { 01165 unsigned int i, istart; 01166 unsigned char *cursrc1, *cursrc2, *curdst; 01167 int result; 01168 01169 /* Validate input parameters */ 01170 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 01171 return(-1); 01172 if (length == 0) 01173 return(0); 01174 01175 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 01176 /* MMX routine */ 01177 SDL_imageFilterMultDivby4MMX(Src1, Src2, Dest, length); 01178 01179 /* Check for unaligned bytes */ 01180 if ((length & 7) > 0) { 01181 /* Setup to process unaligned bytes */ 01182 istart = length & 0xfffffff8; 01183 cursrc1 = &Src1[istart]; 01184 cursrc2 = &Src2[istart]; 01185 curdst = &Dest[istart]; 01186 } else { 01187 /* No unaligned bytes - we are done */ 01188 return (0); 01189 } 01190 } else { 01191 /* Setup to process whole image */ 01192 istart = 0; 01193 cursrc1 = Src1; 01194 cursrc2 = Src2; 01195 curdst = Dest; 01196 } 01197 01198 /* C routine to process image */ 01199 for (i = istart; i < length; i++) { 01200 result = ((int) *cursrc1 / 2) * ((int) *cursrc2 / 2); 01201 if (result > 255) 01202 result = 255; 01203 *curdst = (unsigned char) result; 01204 /* Advance pointers */ 01205 cursrc1++; 01206 cursrc2++; 01207 curdst++; 01208 } 01209 01210 return (0); 01211 } 01212 01223 int SDL_imageFilterBitAndMMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 01224 { 01225 #ifdef USE_MMX 01226 #if !defined(GCC__) 01227 __asm 01228 { 01229 pusha 01230 mov eax, Src1 /* load Src1 address into eax */ 01231 mov ebx, Src2 /* load Src2 address into ebx */ 01232 mov edi, Dest /* load Dest address into edi */ 01233 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 01234 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 01235 align 16 /* 16 byte alignment of the loop entry */ 01236 L1017: 01237 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 01238 pand mm1, [ebx] /* mm1=Src1&Src2 */ 01239 movq [edi], mm1 /* store result in Dest */ 01240 add eax, 8 /* increase Src1, Src2 and Dest */ 01241 add ebx, 8 /* register pointers by 8 */ 01242 add edi, 8 01243 dec ecx /* decrease loop counter */ 01244 jnz L1017 /* check loop termination, proceed if required */ 01245 emms /* exit MMX state */ 01246 popa 01247 } 01248 #else 01249 asm volatile 01250 ("pusha \n\t" "mov %2, %%eax \n\t" /* load Src1 address into eax */ 01251 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 01252 "mov %0, %%edi \n\t" /* load Dest address into edi */ 01253 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 01254 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 01255 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 01256 "1: movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 01257 "pand (%%ebx), %%mm1 \n\t" /* mm1=Src1&Src2 */ 01258 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 01259 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 01260 "add $8, %%ebx \n\t" /* register pointers by 8 */ 01261 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 01262 "jnz 1b \n\t" /* check loop termination, proceed if required */ 01263 "emms \n\t" /* exit MMX state */ 01264 "popa \n\t":"=m" (Dest) /* %0 */ 01265 :"m"(Src2), /* %1 */ 01266 "m"(Src1), /* %2 */ 01267 "m"(SrcLength) /* %3 */ 01268 ); 01269 #endif 01270 return (0); 01271 #else 01272 return (-1); 01273 #endif 01274 } 01275 01286 int SDL_imageFilterBitAnd(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 01287 { 01288 unsigned int i, istart; 01289 unsigned char *cursrc1, *cursrc2, *curdst; 01290 01291 /* Validate input parameters */ 01292 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 01293 return(-1); 01294 if (length == 0) 01295 return(0); 01296 01297 if ((SDL_imageFilterMMXdetect()>0) && (length>7)) { 01298 /* if (length > 7) { */ 01299 /* Call MMX routine */ 01300 01301 SDL_imageFilterBitAndMMX(Src1, Src2, Dest, length); 01302 01303 /* Check for unaligned bytes */ 01304 if ((length & 7) > 0) { 01305 01306 /* Setup to process unaligned bytes */ 01307 istart = length & 0xfffffff8; 01308 cursrc1 = &Src1[istart]; 01309 cursrc2 = &Src2[istart]; 01310 curdst = &Dest[istart]; 01311 } else { 01312 /* No unaligned bytes - we are done */ 01313 return (0); 01314 } 01315 } else { 01316 /* Setup to process whole image */ 01317 istart = 0; 01318 cursrc1 = Src1; 01319 cursrc2 = Src2; 01320 curdst = Dest; 01321 } 01322 01323 /* C routine to process image */ 01324 for (i = istart; i < length; i++) { 01325 *curdst = (*cursrc1) & (*cursrc2); 01326 /* Advance pointers */ 01327 cursrc1++; 01328 cursrc2++; 01329 curdst++; 01330 } 01331 01332 return (0); 01333 } 01334 01345 int SDL_imageFilterBitOrMMX(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 01346 { 01347 #ifdef USE_MMX 01348 #if !defined(GCC__) 01349 __asm 01350 { 01351 pusha 01352 mov eax, Src1 /* load Src1 address into eax */ 01353 mov ebx, Src2 /* load Src2 address into ebx */ 01354 mov edi, Dest /* load Dest address into edi */ 01355 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 01356 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 01357 align 16 /* 16 byte alignment of the loop entry */ 01358 L91017: 01359 movq mm1, [eax] /* load 8 bytes from Src1 into mm1 */ 01360 por mm1, [ebx] /* mm1=Src1|Src2 */ 01361 movq [edi], mm1 /* store result in Dest */ 01362 add eax, 8 /* increase Src1, Src2 and Dest */ 01363 add ebx, 8 /* register pointers by 8 */ 01364 add edi, 8 01365 dec ecx /* decrease loop counter */ 01366 jnz L91017 /* check loop termination, proceed if required */ 01367 emms /* exit MMX state */ 01368 popa 01369 } 01370 #else 01371 asm volatile 01372 ("pusha \n\t" "mov %2, %%eax \n\t" /* load Src1 address into eax */ 01373 "mov %1, %%ebx \n\t" /* load Src2 address into ebx */ 01374 "mov %0, %%edi \n\t" /* load Dest address into edi */ 01375 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 01376 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 01377 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 01378 "1: movq (%%eax), %%mm1 \n\t" /* load 8 bytes from Src1 into mm1 */ 01379 "por (%%ebx), %%mm1 \n\t" /* mm1=Src1|Src2 */ 01380 "movq %%mm1, (%%edi) \n\t" /* store result in Dest */ 01381 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 01382 "add $8, %%ebx \n\t" /* register pointers by 8 */ 01383 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 01384 "jnz 1b \n\t" /* check loop termination, proceed if required */ 01385 "emms \n\t" /* exit MMX state */ 01386 "popa \n\t":"=m" (Dest) /* %0 */ 01387 :"m"(Src2), /* %1 */ 01388 "m"(Src1), /* %2 */ 01389 "m"(SrcLength) /* %3 */ 01390 ); 01391 #endif 01392 return (0); 01393 #else 01394 return (-1); 01395 #endif 01396 } 01397 01408 int SDL_imageFilterBitOr(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 01409 { 01410 unsigned int i, istart; 01411 unsigned char *cursrc1, *cursrc2, *curdst; 01412 01413 /* Validate input parameters */ 01414 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 01415 return(-1); 01416 if (length == 0) 01417 return(0); 01418 01419 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 01420 01421 /* MMX routine */ 01422 SDL_imageFilterBitOrMMX(Src1, Src2, Dest, length); 01423 01424 /* Check for unaligned bytes */ 01425 if ((length & 7) > 0) { 01426 /* Setup to process unaligned bytes */ 01427 istart = length & 0xfffffff8; 01428 cursrc1 = &Src1[istart]; 01429 cursrc2 = &Src2[istart]; 01430 curdst = &Dest[istart]; 01431 } else { 01432 /* No unaligned bytes - we are done */ 01433 return (0); 01434 } 01435 } else { 01436 /* Setup to process whole image */ 01437 istart = 0; 01438 cursrc1 = Src1; 01439 cursrc2 = Src2; 01440 curdst = Dest; 01441 } 01442 01443 /* C routine to process image */ 01444 for (i = istart; i < length; i++) { 01445 *curdst = *cursrc1 | *cursrc2; 01446 /* Advance pointers */ 01447 cursrc1++; 01448 cursrc2++; 01449 curdst++; 01450 } 01451 return (0); 01452 } 01453 01464 int SDL_imageFilterDivASM(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int SrcLength) 01465 { 01466 #ifdef USE_MMX 01467 #if !defined(GCC__) 01468 __asm 01469 { 01470 pusha 01471 mov edx, Src1 /* load Src1 address into edx */ 01472 mov esi, Src2 /* load Src2 address into esi */ 01473 mov edi, Dest /* load Dest address into edi */ 01474 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 01475 align 16 /* 16 byte alignment of the loop entry */ 01476 L10191: 01477 mov bl, [esi] /* load a byte from Src2 */ 01478 cmp bl, 0 /* check if it zero */ 01479 jnz L10192 01480 mov [edi], 255 /* division by zero = 255 !!! */ 01481 jmp L10193 01482 L10192: 01483 xor ah, ah /* prepare AX, zero AH register */ 01484 mov al, [edx] /* load a byte from Src1 into AL */ 01485 div bl /* divide AL by BL */ 01486 mov [edi], al /* move a byte result to Dest */ 01487 L10193: 01488 inc edx /* increment Src1, Src2, Dest */ 01489 inc esi /* pointer registers by one */ 01490 inc edi 01491 dec ecx /* decrease loop counter */ 01492 jnz L10191 /* check loop termination, proceed if required */ 01493 popa 01494 } 01495 #else 01496 asm volatile 01497 ("pusha \n\t" "mov %2, %%edx \n\t" /* load Src1 address into edx */ 01498 "mov %1, %%esi \n\t" /* load Src2 address into esi */ 01499 "mov %0, %%edi \n\t" /* load Dest address into edi */ 01500 "mov %3, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 01501 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 01502 "1: mov (%%esi), %%bl \n\t" /* load a byte from Src2 */ 01503 "cmp $0, %%bl \n\t" /* check if it zero */ 01504 "jnz 2f \n\t" "movb $255, (%%edi) \n\t" /* division by zero = 255 !!! */ 01505 "jmp 3f \n\t" "2: \n\t" "xor %%ah, %%ah \n\t" /* prepare AX, zero AH register */ 01506 "mov (%%edx), %%al \n\t" /* load a byte from Src1 into AL */ 01507 "div %%bl \n\t" /* divide AL by BL */ 01508 "mov %%al, (%%edi) \n\t" /* move a byte result to Dest */ 01509 "3: inc %%edx \n\t" /* increment Src1, Src2, Dest */ 01510 "inc %%esi \n\t" /* pointer registers by one */ 01511 "inc %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 01512 "jnz 1b \n\t" /* check loop termination, proceed if required */ 01513 "popa \n\t":"=m" (Dest) /* %0 */ 01514 :"m"(Src2), /* %1 */ 01515 "m"(Src1), /* %2 */ 01516 "m"(SrcLength) /* %3 */ 01517 ); 01518 #endif 01519 return (0); 01520 #else 01521 return (-1); 01522 #endif 01523 } 01524 01535 int SDL_imageFilterDiv(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) 01536 { 01537 unsigned int i, istart; 01538 unsigned char *cursrc1, *cursrc2, *curdst; 01539 int result; 01540 01541 /* Validate input parameters */ 01542 if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) 01543 return(-1); 01544 if (length == 0) 01545 return(0); 01546 01547 if (SDL_imageFilterMMXdetect()) { 01548 if (length > 0) { 01549 /* Call ASM routine */ 01550 SDL_imageFilterDivASM(Src1, Src2, Dest, length); 01551 01552 /* Never unaligned bytes - we are done */ 01553 return (0); 01554 } else { 01555 return (-1); 01556 } 01557 } 01558 01559 /* Setup to process whole image */ 01560 istart = 0; 01561 cursrc1 = Src1; 01562 cursrc2 = Src2; 01563 curdst = Dest; 01564 01565 /* C routine to process image */ 01566 for (i = istart; i < length; i++) { 01567 result = (int) *cursrc1 / (int) *cursrc2; 01568 *curdst = (unsigned char) result; 01569 /* Advance pointers */ 01570 cursrc1++; 01571 cursrc2++; 01572 curdst++; 01573 } 01574 01575 return (0); 01576 } 01577 01578 /* ------------------------------------------------------------------------------------ */ 01579 01589 int SDL_imageFilterBitNegationMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength) 01590 { 01591 #ifdef USE_MMX 01592 #if !defined(GCC__) 01593 __asm 01594 { 01595 pusha 01596 pcmpeqb mm1, mm1 /* generate all 1's in mm1 */ 01597 mov eax, Src1 /* load Src1 address into eax */ 01598 mov edi, Dest /* load Dest address into edi */ 01599 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 01600 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 01601 align 16 /* 16 byte alignment of the loop entry */ 01602 L91117: 01603 movq mm0, [eax] /* load 8 bytes from Src1 into mm1 */ 01604 pxor mm0, mm1 /* negate mm0 by xoring with mm1 */ 01605 movq [edi], mm0 /* store result in Dest */ 01606 add eax, 8 /* increase Src1, Src2 and Dest */ 01607 add edi, 8 01608 dec ecx /* decrease loop counter */ 01609 jnz L91117 /* check loop termination, proceed if required */ 01610 emms /* exit MMX state */ 01611 popa 01612 } 01613 #else 01614 asm volatile 01615 ("pusha \n\t" "pcmpeqb %%mm1, %%mm1 \n\t" /* generate all 1's in mm1 */ 01616 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 01617 "mov %0, %%edi \n\t" /* load Dest address into edi */ 01618 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 01619 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 01620 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 01621 "1: movq (%%eax), %%mm0 \n\t" /* load 8 bytes from Src1 into mm1 */ 01622 "pxor %%mm1, %%mm0 \n\t" /* negate mm0 by xoring with mm1 */ 01623 "movq %%mm0, (%%edi) \n\t" /* store result in Dest */ 01624 "add $8, %%eax \n\t" /* increase Src1, Src2 and Dest */ 01625 "add $8, %%edi \n\t" "dec %%ecx \n\t" /* decrease loop counter */ 01626 "jnz 1b \n\t" /* check loop termination, proceed if required */ 01627 "emms \n\t" /* exit MMX state */ 01628 "popa \n\t":"=m" (Dest) /* %0 */ 01629 :"m"(Src1), /* %1 */ 01630 "m"(SrcLength) /* %2 */ 01631 ); 01632 #endif 01633 return (0); 01634 #else 01635 return (-1); 01636 #endif 01637 } 01638 01648 int SDL_imageFilterBitNegation(unsigned char *Src1, unsigned char *Dest, unsigned int length) 01649 { 01650 unsigned int i, istart; 01651 unsigned char *cursrc1, *curdst; 01652 01653 /* Validate input parameters */ 01654 if ((Src1 == NULL) || (Dest == NULL)) 01655 return(-1); 01656 if (length == 0) 01657 return(0); 01658 01659 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 01660 /* MMX routine */ 01661 SDL_imageFilterBitNegationMMX(Src1, Dest, length); 01662 01663 /* Check for unaligned bytes */ 01664 if ((length & 7) > 0) { 01665 /* Setup to process unaligned bytes */ 01666 istart = length & 0xfffffff8; 01667 cursrc1 = &Src1[istart]; 01668 curdst = &Dest[istart]; 01669 } else { 01670 /* No unaligned bytes - we are done */ 01671 return (0); 01672 } 01673 } else { 01674 /* Setup to process whole image */ 01675 istart = 0; 01676 cursrc1 = Src1; 01677 curdst = Dest; 01678 } 01679 01680 /* C routine to process image */ 01681 for (i = istart; i < length; i++) { 01682 *curdst = ~(*cursrc1); 01683 /* Advance pointers */ 01684 cursrc1++; 01685 curdst++; 01686 } 01687 01688 return (0); 01689 } 01690 01701 int SDL_imageFilterAddByteMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char C) 01702 { 01703 #ifdef USE_MMX 01704 #if !defined(GCC__) 01705 __asm 01706 { 01707 pusha 01708 /* ** Duplicate C in 8 bytes of MM1 ** */ 01709 mov al, C /* load C into AL */ 01710 mov ah, al /* copy AL into AH */ 01711 mov bx, ax /* copy AX into BX */ 01712 shl eax, 16 /* shift 2 bytes of EAX left */ 01713 mov ax, bx /* copy BX into AX */ 01714 movd mm1, eax /* copy EAX into MM1 */ 01715 movd mm2, eax /* copy EAX into MM2 */ 01716 punpckldq mm1, mm2 /* fill higher bytes of MM1 with C */ 01717 mov eax, Src1 /* load Src1 address into eax */ 01718 mov edi, Dest /* load Dest address into edi */ 01719 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 01720 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 01721 align 16 /* 16 byte alignment of the loop entry */ 01722 L1021: 01723 movq mm0, [eax] /* load 8 bytes from Src1 into MM0 */ 01724 paddusb mm0, mm1 /* MM0=SrcDest+C (add 8 bytes with saturation) */ 01725 movq [edi], mm0 /* store result in Dest */ 01726 add eax, 8 /* increase Dest register pointer by 8 */ 01727 add edi, 8 /* increase Dest register pointer by 8 */ 01728 dec ecx /* decrease loop counter */ 01729 jnz L1021 /* check loop termination, proceed if required */ 01730 emms /* exit MMX state */ 01731 popa 01732 } 01733 #else 01734 asm volatile 01735 ("pusha \n\t" 01736 /* ** Duplicate C in 8 bytes of MM1 ** */ 01737 "mov %3, %%al \n\t" /* load C into AL */ 01738 "mov %%al, %%ah \n\t" /* copy AL into AH */ 01739 "mov %%ax, %%bx \n\t" /* copy AX into BX */ 01740 "shl $16, %%eax \n\t" /* shift 2 bytes of EAX left */ 01741 "mov %%bx, %%ax \n\t" /* copy BX into AX */ 01742 "movd %%eax, %%mm1 \n\t" /* copy EAX into MM1 */ 01743 "movd %%eax, %%mm2 \n\t" /* copy EAX into MM2 */ 01744 "punpckldq %%mm2, %%mm1 \n\t" /* fill higher bytes of MM1 with C */ 01745 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 01746 "mov %0, %%edi \n\t" /* load Dest address into edi */ 01747 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 01748 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 01749 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 01750 "1: \n\t" 01751 "movq (%%eax), %%mm0 \n\t" /* load 8 bytes from Src1 into MM0 */ 01752 "paddusb %%mm1, %%mm0 \n\t" /* MM0=SrcDest+C (add 8 bytes with saturation) */ 01753 "movq %%mm0, (%%edi) \n\t" /* store result in Dest */ 01754 "add $8, %%eax \n\t" /* increase Dest register pointer by 8 */ 01755 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 01756 "dec %%ecx \n\t" /* decrease loop counter */ 01757 "jnz 1b \n\t" /* check loop termination, proceed if required */ 01758 "emms \n\t" /* exit MMX state */ 01759 "popa \n\t":"=m" (Dest) /* %0 */ 01760 :"m"(Src1), /* %1 */ 01761 "m"(SrcLength), /* %2 */ 01762 "m"(C) /* %3 */ 01763 ); 01764 #endif 01765 return (0); 01766 #else 01767 return (-1); 01768 #endif 01769 } 01770 01782 int SDL_imageFilterAddByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C) 01783 { 01784 unsigned int i, istart; 01785 int iC; 01786 unsigned char *cursrc1, *curdest; 01787 int result; 01788 01789 /* Validate input parameters */ 01790 if ((Src1 == NULL) || (Dest == NULL)) 01791 return(-1); 01792 if (length == 0) 01793 return(0); 01794 01795 /* Special case: C==0 */ 01796 if (C == 0) { 01797 memcpy(Src1, Dest, length); 01798 return (0); 01799 } 01800 01801 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 01802 01803 /* MMX routine */ 01804 SDL_imageFilterAddByteMMX(Src1, Dest, length, C); 01805 01806 /* Check for unaligned bytes */ 01807 if ((length & 7) > 0) { 01808 /* Setup to process unaligned bytes */ 01809 istart = length & 0xfffffff8; 01810 cursrc1 = &Src1[istart]; 01811 curdest = &Dest[istart]; 01812 } else { 01813 /* No unaligned bytes - we are done */ 01814 return (0); 01815 } 01816 } else { 01817 /* Setup to process whole image */ 01818 istart = 0; 01819 cursrc1 = Src1; 01820 curdest = Dest; 01821 } 01822 01823 /* C routine to process image */ 01824 iC = (int) C; 01825 for (i = istart; i < length; i++) { 01826 result = (int) *cursrc1 + iC; 01827 if (result > 255) 01828 result = 255; 01829 *curdest = (unsigned char) result; 01830 /* Advance pointers */ 01831 cursrc1++; 01832 curdest++; 01833 } 01834 return (0); 01835 } 01836 01848 int SDL_imageFilterAddUintMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned int C, unsigned int D) 01849 { 01850 #ifdef USE_MMX 01851 #if !defined(GCC__) 01852 __asm 01853 { 01854 pusha 01855 /* ** Duplicate (int)C in 8 bytes of MM1 ** */ 01856 mov eax, C /* load C into EAX */ 01857 movd mm1, eax /* copy EAX into MM1 */ 01858 mov eax, D /* load D into EAX */ 01859 movd mm2, eax /* copy EAX into MM2 */ 01860 punpckldq mm1, mm2 /* fill higher bytes of MM1 with C */ 01861 mov eax, Src1 /* load Src1 address into eax */ 01862 mov edi, Dest /* load Dest address into edi */ 01863 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 01864 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 01865 align 16 /* 16 byte alignment of the loop entry */ 01866 L11023: 01867 movq mm0, [eax] /* load 8 bytes from SrcDest into MM0 */ 01868 paddusb mm0, mm1 /* MM0=SrcDest+C (add 8 bytes with saturation) */ 01869 movq [edi], mm0 /* store result in SrcDest */ 01870 add eax, 8 /* increase Src1 register pointer by 8 */ 01871 add edi, 8 /* increase Dest register pointer by 8 */ 01872 dec ecx /* decrease loop counter */ 01873 jnz L11023 /* check loop termination, proceed if required */ 01874 emms /* exit MMX state */ 01875 popa 01876 } 01877 #else 01878 asm volatile 01879 ("pusha \n\t" 01880 /* ** Duplicate (int)C in 8 bytes of MM1 ** */ 01881 "mov %3, %%eax \n\t" /* load C into EAX */ 01882 "movd %%eax, %%mm1 \n\t" /* copy EAX into MM1 */ 01883 "mov %4, %%eax \n\t" /* load D into EAX */ 01884 "movd %%eax, %%mm2 \n\t" /* copy EAX into MM2 */ 01885 "punpckldq %%mm2, %%mm1 \n\t" /* fill higher bytes of MM1 with C */ 01886 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 01887 "mov %0, %%edi \n\t" /* load Dest address into edi */ 01888 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 01889 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 01890 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 01891 "1: \n\t" 01892 "movq (%%eax), %%mm0 \n\t" /* load 8 bytes from SrcDest into MM0 */ 01893 "paddusb %%mm1, %%mm0 \n\t" /* MM0=SrcDest+C (add 8 bytes with saturation) */ 01894 "movq %%mm0, (%%edi) \n\t" /* store result in SrcDest */ 01895 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 01896 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 01897 "dec %%ecx \n\t" /* decrease loop counter */ 01898 "jnz 1b \n\t" /* check loop termination, proceed if required */ 01899 "emms \n\t" /* exit MMX state */ 01900 "popa \n\t":"=m" (Dest) /* %0 */ 01901 :"m"(Src1), /* %1 */ 01902 "m"(SrcLength), /* %2 */ 01903 "m"(C), /* %3 */ 01904 "m"(D) /* %4 */ 01905 ); 01906 #endif 01907 return (0); 01908 #else 01909 return (-1); 01910 #endif 01911 } 01912 01923 int SDL_imageFilterAddUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int C) 01924 { 01925 unsigned int i, j, istart, D; 01926 int iC[4]; 01927 unsigned char *cursrc1; 01928 unsigned char *curdest; 01929 int result; 01930 01931 /* Validate input parameters */ 01932 if ((Src1 == NULL) || (Dest == NULL)) 01933 return(-1); 01934 if (length == 0) 01935 return(0); 01936 01937 /* Special case: C==0 */ 01938 if (C == 0) { 01939 memcpy(Src1, Dest, length); 01940 return (0); 01941 } 01942 01943 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 01944 01945 /* MMX routine */ 01946 D=SWAP_32(C); 01947 SDL_imageFilterAddUintMMX(Src1, Dest, length, C, D); 01948 01949 /* Check for unaligned bytes */ 01950 if ((length & 7) > 0) { 01951 /* Setup to process unaligned bytes */ 01952 istart = length & 0xfffffff8; 01953 cursrc1 = &Src1[istart]; 01954 curdest = &Dest[istart]; 01955 } else { 01956 /* No unaligned bytes - we are done */ 01957 return (0); 01958 } 01959 } else { 01960 /* Setup to process whole image */ 01961 istart = 0; 01962 cursrc1 = Src1; 01963 curdest = Dest; 01964 } 01965 01966 /* C routine to process bytes */ 01967 iC[3] = (int) ((C >> 24) & 0xff); 01968 iC[2] = (int) ((C >> 16) & 0xff); 01969 iC[1] = (int) ((C >> 8) & 0xff); 01970 iC[0] = (int) ((C >> 0) & 0xff); 01971 for (i = istart; i < length; i += 4) { 01972 for (j = 0; j < 4; j++) { 01973 if ((i+j)<length) { 01974 result = (int) *cursrc1 + iC[j]; 01975 if (result > 255) result = 255; 01976 *curdest = (unsigned char) result; 01977 /* Advance pointers */ 01978 cursrc1++; 01979 curdest++; 01980 } 01981 } 01982 } 01983 return (0); 01984 } 01985 01997 int SDL_imageFilterAddByteToHalfMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char C, 01998 unsigned char *Mask) 01999 { 02000 #ifdef USE_MMX 02001 #if !defined(GCC__) 02002 __asm 02003 { 02004 pusha 02005 /* ** Duplicate C in 8 bytes of MM1 ** */ 02006 mov al, C /* load C into AL */ 02007 mov ah, al /* copy AL into AH */ 02008 mov bx, ax /* copy AX into BX */ 02009 shl eax, 16 /* shift 2 bytes of EAX left */ 02010 mov ax, bx /* copy BX into AX */ 02011 movd mm1, eax /* copy EAX into MM1 */ 02012 movd mm2, eax /* copy EAX into MM2 */ 02013 punpckldq mm1, mm2 /* fill higher bytes of MM1 with C */ 02014 mov edx, Mask /* load Mask address into edx */ 02015 movq mm0, [edx] /* load Mask into mm0 */ 02016 mov eax, Src1 /* load Src1 address into eax */ 02017 mov edi, Dest /* load Dest address into edi */ 02018 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 02019 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 02020 align 16 /* 16 byte alignment of the loop entry */ 02021 L1022: 02022 movq mm2, [eax] /* load 8 bytes from Src1 into MM2 */ 02023 psrlw mm2, 1 /* shift 4 WORDS of MM2 1 bit to the right */ 02024 pand mm2, mm0 // apply Mask to 8 BYTES of MM2 */ 02025 /* byte 0x0f, 0xdb, 0xd0 */ 02026 paddusb mm2, mm1 /* MM2=SrcDest+C (add 8 bytes with saturation) */ 02027 movq [edi], mm2 /* store result in Dest */ 02028 add eax, 8 /* increase Src1 register pointer by 8 */ 02029 add edi, 8 /* increase Dest register pointer by 8 */ 02030 dec ecx /* decrease loop counter */ 02031 jnz L1022 /* check loop termination, proceed if required */ 02032 emms /* exit MMX state */ 02033 popa 02034 } 02035 #else 02036 asm volatile 02037 ("pusha \n\t" 02038 /* ** Duplicate C in 8 bytes of MM1 ** */ 02039 "mov %3, %%al \n\t" /* load C into AL */ 02040 "mov %%al, %%ah \n\t" /* copy AL into AH */ 02041 "mov %%ax, %%bx \n\t" /* copy AX into BX */ 02042 "shl $16, %%eax \n\t" /* shift 2 bytes of EAX left */ 02043 "mov %%bx, %%ax \n\t" /* copy BX into AX */ 02044 "movd %%eax, %%mm1 \n\t" /* copy EAX into MM1 */ 02045 "movd %%eax, %%mm2 \n\t" /* copy EAX into MM2 */ 02046 "punpckldq %%mm2, %%mm1 \n\t" /* fill higher bytes of MM1 with C */ 02047 "movl %4, %%edx \n\t" /* load Mask address into edx */ 02048 "movq (%%edx), %%mm0 \n\t" /* load Mask into mm0 */ 02049 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 02050 "mov %0, %%edi \n\t" /* load Dest address into edi */ 02051 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 02052 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 02053 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 02054 "1: \n\t" 02055 "movq (%%eax), %%mm2 \n\t" /* load 8 bytes from Src1 into MM2 */ 02056 "psrlw $1, %%mm2 \n\t" /* shift 4 WORDS of MM2 1 bit to the right */ 02057 /* "pand %%mm0, %%mm2 \n\t" // apply Mask to 8 BYTES of MM2 */ 02058 ".byte 0x0f, 0xdb, 0xd0 \n\t" 02059 "paddusb %%mm1, %%mm2 \n\t" /* MM2=SrcDest+C (add 8 bytes with saturation) */ 02060 "movq %%mm2, (%%edi) \n\t" /* store result in Dest */ 02061 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 02062 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 02063 "dec %%ecx \n\t" /* decrease loop counter */ 02064 "jnz 1b \n\t" /* check loop termination, proceed if required */ 02065 "emms \n\t" /* exit MMX state */ 02066 "popa \n\t":"=m" (Dest) /* %0 */ 02067 :"m"(Src1), /* %1 */ 02068 "m"(SrcLength), /* %2 */ 02069 "m"(C), /* %3 */ 02070 "m"(Mask) /* %4 */ 02071 ); 02072 #endif 02073 return (0); 02074 #else 02075 return (-1); 02076 #endif 02077 } 02078 02089 int SDL_imageFilterAddByteToHalf(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C) 02090 { 02091 static unsigned char Mask[8] = { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F }; 02092 unsigned int i, istart; 02093 int iC; 02094 unsigned char *cursrc1; 02095 unsigned char *curdest; 02096 int result; 02097 02098 /* Validate input parameters */ 02099 if ((Src1 == NULL) || (Dest == NULL)) 02100 return(-1); 02101 if (length == 0) 02102 return(0); 02103 02104 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 02105 02106 /* MMX routine */ 02107 SDL_imageFilterAddByteToHalfMMX(Src1, Dest, length, C, Mask); 02108 02109 /* Check for unaligned bytes */ 02110 if ((length & 7) > 0) { 02111 /* Setup to process unaligned bytes */ 02112 istart = length & 0xfffffff8; 02113 cursrc1 = &Src1[istart]; 02114 curdest = &Dest[istart]; 02115 } else { 02116 /* No unaligned bytes - we are done */ 02117 return (0); 02118 } 02119 } else { 02120 /* Setup to process whole image */ 02121 istart = 0; 02122 cursrc1 = Src1; 02123 curdest = Dest; 02124 } 02125 02126 /* C routine to process image */ 02127 iC = (int) C; 02128 for (i = istart; i < length; i++) { 02129 result = (int) (*cursrc1 / 2) + iC; 02130 if (result > 255) 02131 result = 255; 02132 *curdest = (unsigned char) result; 02133 /* Advance pointers */ 02134 cursrc1++; 02135 curdest++; 02136 } 02137 02138 return (0); 02139 } 02140 02151 int SDL_imageFilterSubByteMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char C) 02152 { 02153 #ifdef USE_MMX 02154 #if !defined(GCC__) 02155 __asm 02156 { 02157 pusha 02158 /* ** Duplicate C in 8 bytes of MM1 ** */ 02159 mov al, C /* load C into AL */ 02160 mov ah, al /* copy AL into AH */ 02161 mov bx, ax /* copy AX into BX */ 02162 shl eax, 16 /* shift 2 bytes of EAX left */ 02163 mov ax, bx /* copy BX into AX */ 02164 movd mm1, eax /* copy EAX into MM1 */ 02165 movd mm2, eax /* copy EAX into MM2 */ 02166 punpckldq mm1, mm2 /* fill higher bytes of MM1 with C */ 02167 mov eax, Src1 /* load Src1 address into eax */ 02168 mov edi, Dest /* load Dest address into edi */ 02169 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 02170 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 02171 align 16 /* 16 byte alignment of the loop entry */ 02172 L1023: 02173 movq mm0, [eax] /* load 8 bytes from SrcDest into MM0 */ 02174 psubusb mm0, mm1 /* MM0=SrcDest-C (sub 8 bytes with saturation) */ 02175 movq [edi], mm0 /* store result in SrcDest */ 02176 add eax, 8 /* increase Src1 register pointer by 8 */ 02177 add edi, 8 /* increase Dest register pointer by 8 */ 02178 dec ecx /* decrease loop counter */ 02179 jnz L1023 /* check loop termination, proceed if required */ 02180 emms /* exit MMX state */ 02181 popa 02182 } 02183 #else 02184 asm volatile 02185 ("pusha \n\t" 02186 /* ** Duplicate C in 8 bytes of MM1 ** */ 02187 "mov %3, %%al \n\t" /* load C into AL */ 02188 "mov %%al, %%ah \n\t" /* copy AL into AH */ 02189 "mov %%ax, %%bx \n\t" /* copy AX into BX */ 02190 "shl $16, %%eax \n\t" /* shift 2 bytes of EAX left */ 02191 "mov %%bx, %%ax \n\t" /* copy BX into AX */ 02192 "movd %%eax, %%mm1 \n\t" /* copy EAX into MM1 */ 02193 "movd %%eax, %%mm2 \n\t" /* copy EAX into MM2 */ 02194 "punpckldq %%mm2, %%mm1 \n\t" /* fill higher bytes of MM1 with C */ 02195 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 02196 "mov %0, %%edi \n\t" /* load Dest address into edi */ 02197 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 02198 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 02199 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 02200 "1: movq (%%eax), %%mm0 \n\t" /* load 8 bytes from SrcDest into MM0 */ 02201 "psubusb %%mm1, %%mm0 \n\t" /* MM0=SrcDest-C (sub 8 bytes with saturation) */ 02202 "movq %%mm0, (%%edi) \n\t" /* store result in SrcDest */ 02203 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 02204 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 02205 "dec %%ecx \n\t" /* decrease loop counter */ 02206 "jnz 1b \n\t" /* check loop termination, proceed if required */ 02207 "emms \n\t" /* exit MMX state */ 02208 "popa \n\t":"=m" (Dest) /* %0 */ 02209 :"m"(Src1), /* %1 */ 02210 "m"(SrcLength), /* %2 */ 02211 "m"(C) /* %3 */ 02212 ); 02213 #endif 02214 return (0); 02215 #else 02216 return (-1); 02217 #endif 02218 } 02219 02230 int SDL_imageFilterSubByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C) 02231 { 02232 unsigned int i, istart; 02233 int iC; 02234 unsigned char *cursrc1; 02235 unsigned char *curdest; 02236 int result; 02237 02238 /* Validate input parameters */ 02239 if ((Src1 == NULL) || (Dest == NULL)) 02240 return(-1); 02241 if (length == 0) 02242 return(0); 02243 02244 /* Special case: C==0 */ 02245 if (C == 0) { 02246 memcpy(Src1, Dest, length); 02247 return (0); 02248 } 02249 02250 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 02251 02252 /* MMX routine */ 02253 SDL_imageFilterSubByteMMX(Src1, Dest, length, C); 02254 02255 /* Check for unaligned bytes */ 02256 if ((length & 7) > 0) { 02257 /* Setup to process unaligned bytes */ 02258 istart = length & 0xfffffff8; 02259 cursrc1 = &Src1[istart]; 02260 curdest = &Dest[istart]; 02261 } else { 02262 /* No unaligned bytes - we are done */ 02263 return (0); 02264 } 02265 } else { 02266 /* Setup to process whole image */ 02267 istart = 0; 02268 cursrc1 = Src1; 02269 curdest = Dest; 02270 } 02271 02272 /* C routine to process image */ 02273 iC = (int) C; 02274 for (i = istart; i < length; i++) { 02275 result = (int) *cursrc1 - iC; 02276 if (result < 0) 02277 result = 0; 02278 *curdest = (unsigned char) result; 02279 /* Advance pointers */ 02280 cursrc1++; 02281 curdest++; 02282 } 02283 return (0); 02284 } 02285 02297 int SDL_imageFilterSubUintMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned int C, unsigned int D) 02298 { 02299 #ifdef USE_MMX 02300 #if !defined(GCC__) 02301 __asm 02302 { 02303 pusha 02304 /* ** Duplicate (int)C in 8 bytes of MM1 ** */ 02305 mov eax, C /* load C into EAX */ 02306 movd mm1, eax /* copy EAX into MM1 */ 02307 mov eax, D /* load D into EAX */ 02308 movd mm2, eax /* copy EAX into MM2 */ 02309 punpckldq mm1, mm2 /* fill higher bytes of MM1 with C */ 02310 mov eax, Src1 /* load Src1 address into eax */ 02311 mov edi, Dest /* load Dest address into edi */ 02312 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 02313 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 02314 align 16 /* 16 byte alignment of the loop entry */ 02315 L11024: 02316 movq mm0, [eax] /* load 8 bytes from SrcDest into MM0 */ 02317 psubusb mm0, mm1 /* MM0=SrcDest-C (sub 8 bytes with saturation) */ 02318 movq [edi], mm0 /* store result in SrcDest */ 02319 add eax, 8 /* increase Src1 register pointer by 8 */ 02320 add edi, 8 /* increase Dest register pointer by 8 */ 02321 dec ecx /* decrease loop counter */ 02322 jnz L11024 /* check loop termination, proceed if required */ 02323 emms /* exit MMX state */ 02324 popa 02325 } 02326 #else 02327 asm volatile 02328 ("pusha \n\t" 02329 /* ** Duplicate (int)C in 8 bytes of MM1 ** */ 02330 "mov %3, %%eax \n\t" /* load C into EAX */ 02331 "movd %%eax, %%mm1 \n\t" /* copy EAX into MM1 */ 02332 "mov %4, %%eax \n\t" /* load D into EAX */ 02333 "movd %%eax, %%mm2 \n\t" /* copy EAX into MM2 */ 02334 "punpckldq %%mm2, %%mm1 \n\t" /* fill higher bytes of MM1 with C */ 02335 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 02336 "mov %0, %%edi \n\t" /* load Dest address into edi */ 02337 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 02338 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 02339 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 02340 "1: movq (%%eax), %%mm0 \n\t" /* load 8 bytes from SrcDest into MM0 */ 02341 "psubusb %%mm1, %%mm0 \n\t" /* MM0=SrcDest-C (sub 8 bytes with saturation) */ 02342 "movq %%mm0, (%%edi) \n\t" /* store result in SrcDest */ 02343 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 02344 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 02345 "dec %%ecx \n\t" /* decrease loop counter */ 02346 "jnz 1b \n\t" /* check loop termination, proceed if required */ 02347 "emms \n\t" /* exit MMX state */ 02348 "popa \n\t":"=m" (Dest) /* %0 */ 02349 :"m"(Src1), /* %1 */ 02350 "m"(SrcLength), /* %2 */ 02351 "m"(C), /* %3 */ 02352 "m"(D) /* %4 */ 02353 ); 02354 #endif 02355 return (0); 02356 #else 02357 return (-1); 02358 #endif 02359 } 02360 02371 int SDL_imageFilterSubUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int C) 02372 { 02373 unsigned int i, j, istart, D; 02374 int iC[4]; 02375 unsigned char *cursrc1; 02376 unsigned char *curdest; 02377 int result; 02378 02379 /* Validate input parameters */ 02380 if ((Src1 == NULL) || (Dest == NULL)) 02381 return(-1); 02382 if (length == 0) 02383 return(0); 02384 02385 /* Special case: C==0 */ 02386 if (C == 0) { 02387 memcpy(Src1, Dest, length); 02388 return (0); 02389 } 02390 02391 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 02392 02393 /* MMX routine */ 02394 D=SWAP_32(C); 02395 SDL_imageFilterSubUintMMX(Src1, Dest, length, C, D); 02396 02397 /* Check for unaligned bytes */ 02398 if ((length & 7) > 0) { 02399 /* Setup to process unaligned bytes */ 02400 istart = length & 0xfffffff8; 02401 cursrc1 = &Src1[istart]; 02402 curdest = &Dest[istart]; 02403 } else { 02404 /* No unaligned bytes - we are done */ 02405 return (0); 02406 } 02407 } else { 02408 /* Setup to process whole image */ 02409 istart = 0; 02410 cursrc1 = Src1; 02411 curdest = Dest; 02412 } 02413 02414 /* C routine to process image */ 02415 iC[3] = (int) ((C >> 24) & 0xff); 02416 iC[2] = (int) ((C >> 16) & 0xff); 02417 iC[1] = (int) ((C >> 8) & 0xff); 02418 iC[0] = (int) ((C >> 0) & 0xff); 02419 for (i = istart; i < length; i += 4) { 02420 for (j = 0; j < 4; j++) { 02421 if ((i+j)<length) { 02422 result = (int) *cursrc1 - iC[j]; 02423 if (result < 0) result = 0; 02424 *curdest = (unsigned char) result; 02425 /* Advance pointers */ 02426 cursrc1++; 02427 curdest++; 02428 } 02429 } 02430 } 02431 return (0); 02432 } 02433 02445 int SDL_imageFilterShiftRightMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char N, 02446 unsigned char *Mask) 02447 { 02448 #ifdef USE_MMX 02449 #if !defined(GCC__) 02450 __asm 02451 { 02452 pusha 02453 mov edx, Mask /* load Mask address into edx */ 02454 movq mm0, [edx] /* load Mask into mm0 */ 02455 xor ecx, ecx /* zero ECX */ 02456 mov cl, N /* load loop counter (N) into CL */ 02457 movd mm3, ecx /* copy (N) into MM3 */ 02458 pcmpeqb mm1, mm1 /* generate all 1's in mm1 */ 02459 L10240: /* ** Prepare proper bit-Mask in MM1 ** */ 02460 psrlw mm1, 1 /* shift 4 WORDS of MM1 1 bit to the right */ 02461 pand mm1, mm0 // apply Mask to 8 BYTES of MM1 */ 02462 /* byte 0x0f, 0xdb, 0xc8 */ 02463 dec cl /* decrease loop counter */ 02464 jnz L10240 /* check loop termination, proceed if required */ 02465 /* ** Shift all bytes of the image ** */ 02466 mov eax, Src1 /* load Src1 address into eax */ 02467 mov edi, Dest /* load Dest address into edi */ 02468 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 02469 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 02470 align 16 /* 16 byte alignment of the loop entry */ 02471 L10241: 02472 movq mm0, [eax] /* load 8 bytes from SrcDest into MM0 */ 02473 psrlw mm0, mm3 /* shift 4 WORDS of MM0 (N) bits to the right */ 02474 pand mm0, mm1 // apply proper bit-Mask to 8 BYTES of MM0 */ 02475 /* byte 0x0f, 0xdb, 0xc1 */ 02476 movq [edi], mm0 /* store result in SrcDest */ 02477 add eax, 8 /* increase Src1 register pointer by 8 */ 02478 add edi, 8 /* increase Dest register pointer by 8 */ 02479 dec ecx /* decrease loop counter */ 02480 jnz L10241 /* check loop termination, proceed if required */ 02481 emms /* exit MMX state */ 02482 popa 02483 } 02484 #else 02485 asm volatile 02486 ("pusha \n\t" "movl %4, %%edx \n\t" /* load Mask address into edx */ 02487 "movq (%%edx), %%mm0 \n\t" /* load Mask into mm0 */ 02488 "xor %%ecx, %%ecx \n\t" /* zero ECX */ 02489 "mov %3, %%cl \n\t" /* load loop counter (N) into CL */ 02490 "movd %%ecx, %%mm3 \n\t" /* copy (N) into MM3 */ 02491 "pcmpeqb %%mm1, %%mm1 \n\t" /* generate all 1's in mm1 */ 02492 "1: \n\t" /* ** Prepare proper bit-Mask in MM1 ** */ 02493 "psrlw $1, %%mm1 \n\t" /* shift 4 WORDS of MM1 1 bit to the right */ 02494 /* "pand %%mm0, %%mm1 \n\t" // apply Mask to 8 BYTES of MM1 */ 02495 ".byte 0x0f, 0xdb, 0xc8 \n\t" 02496 "dec %%cl \n\t" /* decrease loop counter */ 02497 "jnz 1b \n\t" /* check loop termination, proceed if required */ 02498 /* ** Shift all bytes of the image ** */ 02499 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 02500 "mov %0, %%edi \n\t" /* load Dest address into edi */ 02501 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 02502 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 02503 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 02504 "2: \n\t" 02505 "movq (%%eax), %%mm0 \n\t" /* load 8 bytes from SrcDest into MM0 */ 02506 "psrlw %%mm3, %%mm0 \n\t" /* shift 4 WORDS of MM0 (N) bits to the right */ 02507 /* "pand %%mm1, %%mm0 \n\t" // apply proper bit-Mask to 8 BYTES of MM0 */ 02508 ".byte 0x0f, 0xdb, 0xc1 \n\t" 02509 "movq %%mm0, (%%edi) \n\t" /* store result in SrcDest */ 02510 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 02511 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 02512 "dec %%ecx \n\t" /* decrease loop counter */ 02513 "jnz 2b \n\t" /* check loop termination, proceed if required */ 02514 "emms \n\t" /* exit MMX state */ 02515 "popa \n\t":"=m" (Dest) /* %0 */ 02516 :"m"(Src1), /* %1 */ 02517 "m"(SrcLength), /* %2 */ 02518 "m"(N), /* %3 */ 02519 "m"(Mask) /* %4 */ 02520 ); 02521 #endif 02522 return (0); 02523 #else 02524 return (-1); 02525 #endif 02526 } 02527 02538 int SDL_imageFilterShiftRight(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N) 02539 { 02540 static unsigned char Mask[8] = { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F }; 02541 unsigned int i, istart; 02542 unsigned char *cursrc1; 02543 unsigned char *curdest; 02544 02545 /* Validate input parameters */ 02546 if ((Src1 == NULL) || (Dest == NULL)) 02547 return(-1); 02548 if (length == 0) 02549 return(0); 02550 02551 /* Check shift */ 02552 if (N > 8) { 02553 return (-1); 02554 } 02555 02556 /* Special case: N==0 */ 02557 if (N == 0) { 02558 memcpy(Src1, Dest, length); 02559 return (0); 02560 } 02561 02562 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 02563 02564 /* MMX routine */ 02565 SDL_imageFilterShiftRightMMX(Src1, Dest, length, N, Mask); 02566 02567 /* Check for unaligned bytes */ 02568 if ((length & 7) > 0) { 02569 /* Setup to process unaligned bytes */ 02570 istart = length & 0xfffffff8; 02571 cursrc1 = &Src1[istart]; 02572 curdest = &Dest[istart]; 02573 } else { 02574 /* No unaligned bytes - we are done */ 02575 return (0); 02576 } 02577 } else { 02578 /* Setup to process whole image */ 02579 istart = 0; 02580 cursrc1 = Src1; 02581 curdest = Dest; 02582 } 02583 02584 /* C routine to process image */ 02585 for (i = istart; i < length; i++) { 02586 *curdest = (unsigned char) *cursrc1 >> N; 02587 /* Advance pointers */ 02588 cursrc1++; 02589 curdest++; 02590 } 02591 02592 return (0); 02593 } 02594 02605 int SDL_imageFilterShiftRightUintMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char N) 02606 { 02607 #ifdef USE_MMX 02608 #if !defined(GCC__) 02609 __asm 02610 { 02611 pusha 02612 mov eax, Src1 /* load Src1 address into eax */ 02613 mov edi, Dest /* load Dest address into edi */ 02614 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 02615 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 02616 align 16 /* 16 byte alignment of the loop entry */ 02617 L13023: 02618 movq mm0, [eax] /* load 8 bytes from SrcDest into MM0 */ 02619 psrld mm0, N 02620 movq [edi], mm0 /* store result in SrcDest */ 02621 add eax, 8 /* increase Src1 register pointer by 8 */ 02622 add edi, 8 /* increase Dest register pointer by 8 */ 02623 dec ecx /* decrease loop counter */ 02624 jnz L13023 /* check loop termination, proceed if required */ 02625 emms /* exit MMX state */ 02626 popa 02627 } 02628 #else 02629 asm volatile 02630 ("pusha \n\t" 02631 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 02632 "mov %0, %%edi \n\t" /* load Dest address into edi */ 02633 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 02634 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 02635 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 02636 "1: movq (%%eax), %%mm0 \n\t" /* load 8 bytes from SrcDest into MM0 */ 02637 "psrld %3, %%mm0 \n\t" 02638 "movq %%mm0, (%%edi) \n\t" /* store result in SrcDest */ 02639 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 02640 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 02641 "dec %%ecx \n\t" /* decrease loop counter */ 02642 "jnz 1b \n\t" /* check loop termination, proceed if required */ 02643 "emms \n\t" /* exit MMX state */ 02644 "popa \n\t":"=m" (Dest) /* %0 */ 02645 :"m"(Src1), /* %1 */ 02646 "m"(SrcLength), /* %2 */ 02647 "m"(N) /* %3 */ 02648 ); 02649 #endif 02650 return (0); 02651 #else 02652 return (-1); 02653 #endif 02654 } 02655 02666 int SDL_imageFilterShiftRightUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N) 02667 { 02668 unsigned int i, istart; 02669 unsigned char *cursrc1, *curdest; 02670 unsigned int *icursrc1, *icurdest; 02671 unsigned int result; 02672 02673 /* Validate input parameters */ 02674 if ((Src1 == NULL) || (Dest == NULL)) 02675 return(-1); 02676 if (length == 0) 02677 return(0); 02678 02679 if (N > 32) { 02680 return (-1); 02681 } 02682 02683 /* Special case: N==0 */ 02684 if (N == 0) { 02685 memcpy(Src1, Dest, length); 02686 return (0); 02687 } 02688 02689 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 02690 02691 SDL_imageFilterShiftRightUintMMX(Src1, Dest, length, N); 02692 02693 /* Check for unaligned bytes */ 02694 if ((length & 7) > 0) { 02695 /* Setup to process unaligned bytes */ 02696 istart = length & 0xfffffff8; 02697 cursrc1 = &Src1[istart]; 02698 curdest = &Dest[istart]; 02699 } else { 02700 /* No unaligned bytes - we are done */ 02701 return (0); 02702 } 02703 } else { 02704 /* Setup to process whole image */ 02705 istart = 0; 02706 cursrc1 = Src1; 02707 curdest = Dest; 02708 } 02709 02710 /* C routine to process image */ 02711 icursrc1=(unsigned int *)cursrc1; 02712 icurdest=(unsigned int *)curdest; 02713 for (i = istart; i < length; i += 4) { 02714 if ((i+4)<length) { 02715 result = ((unsigned int)*icursrc1 >> N); 02716 *icurdest = result; 02717 } 02718 /* Advance pointers */ 02719 icursrc1++; 02720 icurdest++; 02721 } 02722 02723 return (0); 02724 } 02725 02736 int SDL_imageFilterMultByByteMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char C) 02737 { 02738 #ifdef USE_MMX 02739 #if !defined(GCC__) 02740 __asm 02741 { 02742 pusha 02743 /* ** Duplicate C in 4 words of MM1 ** */ 02744 mov al, C /* load C into AL */ 02745 xor ah, ah /* zero AH */ 02746 mov bx, ax /* copy AX into BX */ 02747 shl eax, 16 /* shift 2 bytes of EAX left */ 02748 mov ax, bx /* copy BX into AX */ 02749 movd mm1, eax /* copy EAX into MM1 */ 02750 movd mm2, eax /* copy EAX into MM2 */ 02751 punpckldq mm1, mm2 /* fill higher words of MM1 with C */ 02752 pxor mm0, mm0 /* zero MM0 register */ 02753 mov eax, Src1 /* load Src1 address into eax */ 02754 mov edi, Dest /* load Dest address into edi */ 02755 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 02756 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 02757 cmp al, 128 /* if (C <= 128) execute more efficient code */ 02758 jg L10251 02759 align 16 /* 16 byte alignment of the loop entry */ 02760 L10250: 02761 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 02762 movq mm4, mm3 /* copy MM3 into MM4 */ 02763 punpcklbw mm3, mm0 /* unpack low bytes of SrcDest into words */ 02764 punpckhbw mm4, mm0 /* unpack high bytes of SrcDest into words */ 02765 pmullw mm3, mm1 /* mul low bytes of SrcDest and MM1 */ 02766 pmullw mm4, mm1 /* mul high bytes of SrcDest and MM1 */ 02767 packuswb mm3, mm4 /* pack words back into bytes with saturation */ 02768 movq [edi], mm3 /* store result in Dest */ 02769 add eax, 8 /* increase Src1 register pointer by 8 */ 02770 add edi, 8 /* increase Dest register pointer by 8 */ 02771 dec ecx /* decrease loop counter */ 02772 jnz L10250 /* check loop termination, proceed if required */ 02773 jmp L10252 02774 align 16 /* 16 byte alignment of the loop entry */ 02775 L10251: 02776 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 02777 movq mm4, mm3 /* copy MM3 into MM4 */ 02778 punpcklbw mm3, mm0 /* unpack low bytes of SrcDest into words */ 02779 punpckhbw mm4, mm0 /* unpack high bytes of SrcDest into words */ 02780 pmullw mm3, mm1 /* mul low bytes of SrcDest and MM1 */ 02781 pmullw mm4, mm1 /* mul high bytes of SrcDest and MM1 */ 02782 /* ** Take abs value of the results (signed words) ** */ 02783 movq mm5, mm3 /* copy mm3 into mm5 */ 02784 movq mm6, mm4 /* copy mm4 into mm6 */ 02785 psraw mm5, 15 /* fill mm5 words with word sign bit */ 02786 psraw mm6, 15 /* fill mm6 words with word sign bit */ 02787 pxor mm3, mm5 /* take 1's compliment of only neg words */ 02788 pxor mm4, mm6 /* take 1's compliment of only neg words */ 02789 psubsw mm3, mm5 /* add 1 to only neg words, W-(-1) or W-0 */ 02790 psubsw mm4, mm6 /* add 1 to only neg words, W-(-1) or W-0 */ 02791 packuswb mm3, mm4 /* pack words back into bytes with saturation */ 02792 movq [edi], mm3 /* store result in Dest */ 02793 add eax, 8 /* increase Src1 register pointer by 8 */ 02794 add edi, 8 /* increase Dest register pointer by 8 */ 02795 dec ecx /* decrease loop counter */ 02796 jnz L10251 /* check loop termination, proceed if required */ 02797 L10252: 02798 emms /* exit MMX state */ 02799 popa 02800 } 02801 #else 02802 asm volatile 02803 ("pusha \n\t" 02804 /* ** Duplicate C in 4 words of MM1 ** */ 02805 "mov %3, %%al \n\t" /* load C into AL */ 02806 "xor %%ah, %%ah \n\t" /* zero AH */ 02807 "mov %%ax, %%bx \n\t" /* copy AX into BX */ 02808 "shl $16, %%eax \n\t" /* shift 2 bytes of EAX left */ 02809 "mov %%bx, %%ax \n\t" /* copy BX into AX */ 02810 "movd %%eax, %%mm1 \n\t" /* copy EAX into MM1 */ 02811 "movd %%eax, %%mm2 \n\t" /* copy EAX into MM2 */ 02812 "punpckldq %%mm2, %%mm1 \n\t" /* fill higher words of MM1 with C */ 02813 "pxor %%mm0, %%mm0 \n\t" /* zero MM0 register */ 02814 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 02815 "mov %0, %%edi \n\t" /* load Dest address into edi */ 02816 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 02817 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 02818 "cmp $128, %%al \n\t" /* if (C <= 128) execute more efficient code */ 02819 "jg 2f \n\t" ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 02820 "1: movq (%%eax), %%mm3 \n\t" /* load 8 bytes from Src1 into MM3 */ 02821 "movq %%mm3, %%mm4 \n\t" /* copy MM3 into MM4 */ 02822 "punpcklbw %%mm0, %%mm3 \n\t" /* unpack low bytes of SrcDest into words */ 02823 "punpckhbw %%mm0, %%mm4 \n\t" /* unpack high bytes of SrcDest into words */ 02824 "pmullw %%mm1, %%mm3 \n\t" /* mul low bytes of SrcDest and MM1 */ 02825 "pmullw %%mm1, %%mm4 \n\t" /* mul high bytes of SrcDest and MM1 */ 02826 "packuswb %%mm4, %%mm3 \n\t" /* pack words back into bytes with saturation */ 02827 "movq %%mm3, (%%edi) \n\t" /* store result in Dest */ 02828 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 02829 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 02830 "dec %%ecx \n\t" /* decrease loop counter */ 02831 "jnz 1b \n\t" /* check loop termination, proceed if required */ 02832 "jmp 3f \n\t" ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 02833 "2: movq (%%eax), %%mm3 \n\t" /* load 8 bytes from Src1 into MM3 */ 02834 "movq %%mm3, %%mm4 \n\t" /* copy MM3 into MM4 */ 02835 "punpcklbw %%mm0, %%mm3 \n\t" /* unpack low bytes of SrcDest into words */ 02836 "punpckhbw %%mm0, %%mm4 \n\t" /* unpack high bytes of SrcDest into words */ 02837 "pmullw %%mm1, %%mm3 \n\t" /* mul low bytes of SrcDest and MM1 */ 02838 "pmullw %%mm1, %%mm4 \n\t" /* mul high bytes of SrcDest and MM1 */ 02839 /* ** Take abs value of the results (signed words) ** */ 02840 "movq %%mm3, %%mm5 \n\t" /* copy mm3 into mm5 */ 02841 "movq %%mm4, %%mm6 \n\t" /* copy mm4 into mm6 */ 02842 "psraw $15, %%mm5 \n\t" /* fill mm5 words with word sign bit */ 02843 "psraw $15, %%mm6 \n\t" /* fill mm6 words with word sign bit */ 02844 "pxor %%mm5, %%mm3 \n\t" /* take 1's compliment of only neg. words */ 02845 "pxor %%mm6, %%mm4 \n\t" /* take 1's compliment of only neg. words */ 02846 "psubsw %%mm5, %%mm3 \n\t" /* add 1 to only neg. words, W-(-1) or W-0 */ 02847 "psubsw %%mm6, %%mm4 \n\t" /* add 1 to only neg. words, W-(-1) or W-0 */ 02848 "packuswb %%mm4, %%mm3 \n\t" /* pack words back into bytes with saturation */ 02849 "movq %%mm3, (%%edi) \n\t" /* store result in Dest */ 02850 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 02851 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 02852 "dec %%ecx \n\t" /* decrease loop counter */ 02853 "jnz 2b \n\t" /* check loop termination, proceed if required */ 02854 "3: emms \n\t" /* exit MMX state */ 02855 "popa \n\t":"=m" (Dest) /* %0 */ 02856 :"m"(Src1), /* %1 */ 02857 "m"(SrcLength), /* %2 */ 02858 "m"(C) /* %3 */ 02859 ); 02860 #endif 02861 return (0); 02862 #else 02863 return (-1); 02864 #endif 02865 } 02866 02877 int SDL_imageFilterMultByByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C) 02878 { 02879 unsigned int i, istart; 02880 int iC; 02881 unsigned char *cursrc1; 02882 unsigned char *curdest; 02883 int result; 02884 02885 /* Validate input parameters */ 02886 if ((Src1 == NULL) || (Dest == NULL)) 02887 return(-1); 02888 if (length == 0) 02889 return(0); 02890 02891 /* Special case: C==1 */ 02892 if (C == 1) { 02893 memcpy(Src1, Dest, length); 02894 return (0); 02895 } 02896 02897 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 02898 02899 SDL_imageFilterMultByByteMMX(Src1, Dest, length, C); 02900 02901 /* Check for unaligned bytes */ 02902 if ((length & 7) > 0) { 02903 /* Setup to process unaligned bytes */ 02904 istart = length & 0xfffffff8; 02905 cursrc1 = &Src1[istart]; 02906 curdest = &Dest[istart]; 02907 } else { 02908 /* No unaligned bytes - we are done */ 02909 return (0); 02910 } 02911 } else { 02912 /* Setup to process whole image */ 02913 istart = 0; 02914 cursrc1 = Src1; 02915 curdest = Dest; 02916 } 02917 02918 /* C routine to process image */ 02919 iC = (int) C; 02920 for (i = istart; i < length; i++) { 02921 result = (int) *cursrc1 * iC; 02922 if (result > 255) 02923 result = 255; 02924 *curdest = (unsigned char) result; 02925 /* Advance pointers */ 02926 cursrc1++; 02927 curdest++; 02928 } 02929 02930 return (0); 02931 } 02932 02944 int SDL_imageFilterShiftRightAndMultByByteMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char N, 02945 unsigned char C) 02946 { 02947 #ifdef USE_MMX 02948 #if !defined(GCC__) 02949 __asm 02950 { 02951 pusha 02952 /* ** Duplicate C in 4 words of MM1 ** */ 02953 mov al, C /* load C into AL */ 02954 xor ah, ah /* zero AH */ 02955 mov bx, ax /* copy AX into BX */ 02956 shl eax, 16 /* shift 2 bytes of EAX left */ 02957 mov ax, bx /* copy BX into AX */ 02958 movd mm1, eax /* copy EAX into MM1 */ 02959 movd mm2, eax /* copy EAX into MM2 */ 02960 punpckldq mm1, mm2 /* fill higher words of MM1 with C */ 02961 xor ecx, ecx /* zero ECX */ 02962 mov cl, N /* load N into CL */ 02963 movd mm7, ecx /* copy N into MM7 */ 02964 pxor mm0, mm0 /* zero MM0 register */ 02965 mov eax, Src1 /* load Src1 address into eax */ 02966 mov edi, Dest /* load Dest address into edi */ 02967 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 02968 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 02969 align 16 /* 16 byte alignment of the loop entry */ 02970 L1026: 02971 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 02972 movq mm4, mm3 /* copy MM3 into MM4 */ 02973 punpcklbw mm3, mm0 /* unpack low bytes of SrcDest into words */ 02974 punpckhbw mm4, mm0 /* unpack high bytes of SrcDest into words */ 02975 psrlw mm3, mm7 /* shift 4 WORDS of MM3 (N) bits to the right */ 02976 psrlw mm4, mm7 /* shift 4 WORDS of MM4 (N) bits to the right */ 02977 pmullw mm3, mm1 /* mul low bytes of SrcDest by MM1 */ 02978 pmullw mm4, mm1 /* mul high bytes of SrcDest by MM1 */ 02979 packuswb mm3, mm4 /* pack words back into bytes with saturation */ 02980 movq [edi], mm3 /* store result in Dest */ 02981 add eax, 8 /* increase Src1 register pointer by 8 */ 02982 add edi, 8 /* increase Dest register pointer by 8 */ 02983 dec ecx /* decrease loop counter */ 02984 jnz L1026 /* check loop termination, proceed if required */ 02985 emms /* exit MMX state */ 02986 popa 02987 } 02988 #else 02989 asm volatile 02990 ("pusha \n\t" 02991 /* ** Duplicate C in 4 words of MM1 ** */ 02992 "mov %4, %%al \n\t" /* load C into AL */ 02993 "xor %%ah, %%ah \n\t" /* zero AH */ 02994 "mov %%ax, %%bx \n\t" /* copy AX into BX */ 02995 "shl $16, %%eax \n\t" /* shift 2 bytes of EAX left */ 02996 "mov %%bx, %%ax \n\t" /* copy BX into AX */ 02997 "movd %%eax, %%mm1 \n\t" /* copy EAX into MM1 */ 02998 "movd %%eax, %%mm2 \n\t" /* copy EAX into MM2 */ 02999 "punpckldq %%mm2, %%mm1 \n\t" /* fill higher words of MM1 with C */ 03000 "xor %%ecx, %%ecx \n\t" /* zero ECX */ 03001 "mov %3, %%cl \n\t" /* load N into CL */ 03002 "movd %%ecx, %%mm7 \n\t" /* copy N into MM7 */ 03003 "pxor %%mm0, %%mm0 \n\t" /* zero MM0 register */ 03004 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 03005 "mov %0, %%edi \n\t" /* load Dest address into edi */ 03006 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 03007 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 03008 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 03009 "1: movq (%%eax), %%mm3 \n\t" /* load 8 bytes from Src1 into MM3 */ 03010 "movq %%mm3, %%mm4 \n\t" /* copy MM3 into MM4 */ 03011 "punpcklbw %%mm0, %%mm3 \n\t" /* unpack low bytes of SrcDest into words */ 03012 "punpckhbw %%mm0, %%mm4 \n\t" /* unpack high bytes of SrcDest into words */ 03013 "psrlw %%mm7, %%mm3 \n\t" /* shift 4 WORDS of MM3 (N) bits to the right */ 03014 "psrlw %%mm7, %%mm4 \n\t" /* shift 4 WORDS of MM4 (N) bits to the right */ 03015 "pmullw %%mm1, %%mm3 \n\t" /* mul low bytes of SrcDest by MM1 */ 03016 "pmullw %%mm1, %%mm4 \n\t" /* mul high bytes of SrcDest by MM1 */ 03017 "packuswb %%mm4, %%mm3 \n\t" /* pack words back into bytes with saturation */ 03018 "movq %%mm3, (%%edi) \n\t" /* store result in Dest */ 03019 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 03020 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 03021 "dec %%ecx \n\t" /* decrease loop counter */ 03022 "jnz 1b \n\t" /* check loop termination, proceed if required */ 03023 "emms \n\t" /* exit MMX state */ 03024 "popa \n\t":"=m" (Dest) /* %0 */ 03025 :"m"(Src1), /* %1 */ 03026 "m"(SrcLength), /* %2 */ 03027 "m"(N), /* %3 */ 03028 "m"(C) /* %4 */ 03029 ); 03030 #endif 03031 return (0); 03032 #else 03033 return (-1); 03034 #endif 03035 } 03036 03048 int SDL_imageFilterShiftRightAndMultByByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N, 03049 unsigned char C) 03050 { 03051 unsigned int i, istart; 03052 int iC; 03053 unsigned char *cursrc1; 03054 unsigned char *curdest; 03055 int result; 03056 03057 /* Validate input parameters */ 03058 if ((Src1 == NULL) || (Dest == NULL)) 03059 return(-1); 03060 if (length == 0) 03061 return(0); 03062 03063 /* Check shift */ 03064 if (N > 8) { 03065 return (-1); 03066 } 03067 03068 /* Special case: N==0 && C==1 */ 03069 if ((N == 0) && (C == 1)) { 03070 memcpy(Src1, Dest, length); 03071 return (0); 03072 } 03073 03074 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 03075 03076 SDL_imageFilterShiftRightAndMultByByteMMX(Src1, Dest, length, N, C); 03077 03078 /* Check for unaligned bytes */ 03079 if ((length & 7) > 0) { 03080 /* Setup to process unaligned bytes */ 03081 istart = length & 0xfffffff8; 03082 cursrc1 = &Src1[istart]; 03083 curdest = &Dest[istart]; 03084 } else { 03085 /* No unaligned bytes - we are done */ 03086 return (0); 03087 } 03088 } else { 03089 /* Setup to process whole image */ 03090 istart = 0; 03091 cursrc1 = Src1; 03092 curdest = Dest; 03093 } 03094 03095 /* C routine to process image */ 03096 iC = (int) C; 03097 for (i = istart; i < length; i++) { 03098 result = (int) (*cursrc1 >> N) * iC; 03099 if (result > 255) 03100 result = 255; 03101 *curdest = (unsigned char) result; 03102 /* Advance pointers */ 03103 cursrc1++; 03104 curdest++; 03105 } 03106 03107 return (0); 03108 } 03109 03121 int SDL_imageFilterShiftLeftByteMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char N, 03122 unsigned char *Mask) 03123 { 03124 #ifdef USE_MMX 03125 #if !defined(GCC__) 03126 __asm 03127 { 03128 pusha 03129 mov edx, Mask /* load Mask address into edx */ 03130 movq mm0, [edx] /* load Mask into mm0 */ 03131 xor ecx, ecx /* zero ECX */ 03132 mov cl, N /* load loop counter (N) into CL */ 03133 movd mm3, ecx /* copy (N) into MM3 */ 03134 pcmpeqb mm1, mm1 /* generate all 1's in mm1 */ 03135 L10270: /* ** Prepare proper bit-Mask in MM1 ** */ 03136 psllw mm1, 1 /* shift 4 WORDS of MM1 1 bit to the left */ 03137 pand mm1, mm0 // apply Mask to 8 BYTES of MM1 */ 03138 /* byte 0x0f, 0xdb, 0xc8 */ 03139 dec cl /* decrease loop counter */ 03140 jnz L10270 /* check loop termination, proceed if required */ 03141 /* ** Shift all bytes of the image ** */ 03142 mov eax, Src1 /* load Src1 address into eax */ 03143 mov edi, Dest /* load SrcDest address into edi */ 03144 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03145 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03146 align 16 /* 16 byte alignment of the loop entry */ 03147 L10271: 03148 movq mm0, [eax] /* load 8 bytes from Src1 into MM0 */ 03149 psllw mm0, mm3 /* shift 4 WORDS of MM0 (N) bits to the left */ 03150 pand mm0, mm1 // apply proper bit-Mask to 8 BYTES of MM0 */ 03151 /* byte 0x0f, 0xdb, 0xc1 */ 03152 movq [edi], mm0 /* store result in Dest */ 03153 add eax, 8 /* increase Src1 register pointer by 8 */ 03154 add edi, 8 /* increase Dest register pointer by 8 */ 03155 dec ecx /* decrease loop counter */ 03156 jnz L10271 /* check loop termination, proceed if required */ 03157 emms /* exit MMX state */ 03158 popa 03159 } 03160 #else 03161 asm volatile 03162 ("pusha \n\t" "movl %4, %%edx \n\t" /* load Mask address into edx */ 03163 "movq (%%edx), %%mm0 \n\t" /* load Mask into mm0 */ 03164 "xor %%ecx, %%ecx \n\t" /* zero ECX */ 03165 "mov %3, %%cl \n\t" /* load loop counter (N) into CL */ 03166 "movd %%ecx, %%mm3 \n\t" /* copy (N) into MM3 */ 03167 "pcmpeqb %%mm1, %%mm1 \n\t" /* generate all 1's in mm1 */ 03168 "1: \n\t" /* ** Prepare proper bit-Mask in MM1 ** */ 03169 "psllw $1, %%mm1 \n\t" /* shift 4 WORDS of MM1 1 bit to the left */ 03170 /* "pand %%mm0, %%mm1 \n\t" // apply Mask to 8 BYTES of MM1 */ 03171 ".byte 0x0f, 0xdb, 0xc8 \n\t" "dec %%cl \n\t" /* decrease loop counter */ 03172 "jnz 1b \n\t" /* check loop termination, proceed if required */ 03173 /* ** Shift all bytes of the image ** */ 03174 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 03175 "mov %0, %%edi \n\t" /* load SrcDest address into edi */ 03176 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 03177 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 03178 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 03179 "2: movq (%%eax), %%mm0 \n\t" /* load 8 bytes from Src1 into MM0 */ 03180 "psllw %%mm3, %%mm0 \n\t" /* shift 4 WORDS of MM0 (N) bits to the left */ 03181 /* "pand %%mm1, %%mm0 \n\t" // apply proper bit-Mask to 8 BYTES of MM0 */ 03182 ".byte 0x0f, 0xdb, 0xc1 \n\t" "movq %%mm0, (%%edi) \n\t" /* store result in Dest */ 03183 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 03184 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 03185 "dec %%ecx \n\t" /* decrease loop counter */ 03186 "jnz 2b \n\t" /* check loop termination, proceed if required */ 03187 "emms \n\t" /* exit MMX state */ 03188 "popa \n\t":"=m" (Dest) /* %0 */ 03189 :"m"(Src1), /* %1 */ 03190 "m"(SrcLength), /* %2 */ 03191 "m"(N), /* %3 */ 03192 "m"(Mask) /* %4 */ 03193 ); 03194 #endif 03195 return (0); 03196 #else 03197 return (-1); 03198 #endif 03199 } 03200 03211 int SDL_imageFilterShiftLeftByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N) 03212 { 03213 static unsigned char Mask[8] = { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }; 03214 unsigned int i, istart; 03215 unsigned char *cursrc1, *curdest; 03216 int result; 03217 03218 /* Validate input parameters */ 03219 if ((Src1 == NULL) || (Dest == NULL)) 03220 return(-1); 03221 if (length == 0) 03222 return(0); 03223 03224 if (N > 8) { 03225 return (-1); 03226 } 03227 03228 /* Special case: N==0 */ 03229 if (N == 0) { 03230 memcpy(Src1, Dest, length); 03231 return (0); 03232 } 03233 03234 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 03235 03236 SDL_imageFilterShiftLeftByteMMX(Src1, Dest, length, N, Mask); 03237 03238 /* Check for unaligned bytes */ 03239 if ((length & 7) > 0) { 03240 /* Setup to process unaligned bytes */ 03241 istart = length & 0xfffffff8; 03242 cursrc1 = &Src1[istart]; 03243 curdest = &Dest[istart]; 03244 } else { 03245 /* No unaligned bytes - we are done */ 03246 return (0); 03247 } 03248 } else { 03249 /* Setup to process whole image */ 03250 istart = 0; 03251 cursrc1 = Src1; 03252 curdest = Dest; 03253 } 03254 03255 /* C routine to process image */ 03256 for (i = istart; i < length; i++) { 03257 result = ((int) *cursrc1 << N) & 0xff; 03258 *curdest = (unsigned char) result; 03259 /* Advance pointers */ 03260 cursrc1++; 03261 curdest++; 03262 } 03263 03264 return (0); 03265 } 03266 03277 int SDL_imageFilterShiftLeftUintMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char N) 03278 { 03279 #ifdef USE_MMX 03280 #if !defined(GCC__) 03281 __asm 03282 { 03283 pusha 03284 mov eax, Src1 /* load Src1 address into eax */ 03285 mov edi, Dest /* load Dest address into edi */ 03286 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03287 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03288 align 16 /* 16 byte alignment of the loop entry */ 03289 L12023: 03290 movq mm0, [eax] /* load 8 bytes from SrcDest into MM0 */ 03291 pslld mm0, N /* MM0=SrcDest+C (add 8 bytes with saturation) */ 03292 movq [edi], mm0 /* store result in SrcDest */ 03293 add eax, 8 /* increase Src1 register pointer by 8 */ 03294 add edi, 8 /* increase Dest register pointer by 8 */ 03295 dec ecx /* decrease loop counter */ 03296 jnz L12023 /* check loop termination, proceed if required */ 03297 emms /* exit MMX state */ 03298 popa 03299 } 03300 #else 03301 asm volatile 03302 ("pusha \n\t" 03303 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 03304 "mov %0, %%edi \n\t" /* load Dest address into edi */ 03305 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 03306 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 03307 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 03308 "1: movq (%%eax), %%mm0 \n\t" /* load 8 bytes from SrcDest into MM0 */ 03309 "pslld %3, %%mm0 \n\t" /* MM0=SrcDest+C (add 8 bytes with saturation) */ 03310 "movq %%mm0, (%%edi) \n\t" /* store result in SrcDest */ 03311 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 03312 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 03313 "dec %%ecx \n\t" /* decrease loop counter */ 03314 "jnz 1b \n\t" /* check loop termination, proceed if required */ 03315 "emms \n\t" /* exit MMX state */ 03316 "popa \n\t":"=m" (Dest) /* %0 */ 03317 :"m"(Src1), /* %1 */ 03318 "m"(SrcLength), /* %2 */ 03319 "m"(N) /* %3 */ 03320 ); 03321 #endif 03322 return (0); 03323 #else 03324 return (-1); 03325 #endif 03326 } 03327 03338 int SDL_imageFilterShiftLeftUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N) 03339 { 03340 unsigned int i, istart; 03341 unsigned char *cursrc1, *curdest; 03342 unsigned int *icursrc1, *icurdest; 03343 unsigned int result; 03344 03345 /* Validate input parameters */ 03346 if ((Src1 == NULL) || (Dest == NULL)) 03347 return(-1); 03348 if (length == 0) 03349 return(0); 03350 03351 if (N > 32) { 03352 return (-1); 03353 } 03354 03355 /* Special case: N==0 */ 03356 if (N == 0) { 03357 memcpy(Src1, Dest, length); 03358 return (0); 03359 } 03360 03361 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 03362 03363 SDL_imageFilterShiftLeftUintMMX(Src1, Dest, length, N); 03364 03365 /* Check for unaligned bytes */ 03366 if ((length & 7) > 0) { 03367 /* Setup to process unaligned bytes */ 03368 istart = length & 0xfffffff8; 03369 cursrc1 = &Src1[istart]; 03370 curdest = &Dest[istart]; 03371 } else { 03372 /* No unaligned bytes - we are done */ 03373 return (0); 03374 } 03375 } else { 03376 /* Setup to process whole image */ 03377 istart = 0; 03378 cursrc1 = Src1; 03379 curdest = Dest; 03380 } 03381 03382 /* C routine to process image */ 03383 icursrc1=(unsigned int *)cursrc1; 03384 icurdest=(unsigned int *)curdest; 03385 for (i = istart; i < length; i += 4) { 03386 if ((i+4)<length) { 03387 result = ((unsigned int)*icursrc1 << N); 03388 *icurdest = result; 03389 } 03390 /* Advance pointers */ 03391 icursrc1++; 03392 icurdest++; 03393 } 03394 03395 return (0); 03396 } 03397 03408 int SDL_imageFilterShiftLeftMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char N) 03409 { 03410 #ifdef USE_MMX 03411 #if !defined(GCC__) 03412 __asm 03413 { 03414 pusha 03415 xor eax, eax /* zero EAX */ 03416 mov al, N /* load N into AL */ 03417 movd mm7, eax /* copy N into MM7 */ 03418 pxor mm0, mm0 /* zero MM0 register */ 03419 mov eax, Src1 /* load Src1 address into eax */ 03420 mov edi, Dest /* load Dest address into edi */ 03421 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03422 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03423 cmp al, 7 /* if (N <= 7) execute more efficient code */ 03424 jg L10281 03425 align 16 /* 16 byte alignment of the loop entry */ 03426 L10280: 03427 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03428 movq mm4, mm3 /* copy MM3 into MM4 */ 03429 punpcklbw mm3, mm0 /* unpack low bytes of SrcDest into words */ 03430 punpckhbw mm4, mm0 /* unpack high bytes of SrcDest into words */ 03431 psllw mm3, mm7 /* shift 4 WORDS of MM3 (N) bits to the right */ 03432 psllw mm4, mm7 /* shift 4 WORDS of MM4 (N) bits to the right */ 03433 packuswb mm3, mm4 /* pack words back into bytes with saturation */ 03434 movq [edi], mm3 /* store result in Dest */ 03435 add eax, 8 /* increase Src1 register pointer by 8 */ 03436 add edi, 8 /* increase Dest register pointer by 8 */ 03437 dec ecx /* decrease loop counter */ 03438 jnz L10280 /* check loop termination, proceed if required */ 03439 jmp L10282 03440 align 16 /* 16 byte alignment of the loop entry */ 03441 L10281: 03442 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03443 movq mm4, mm3 /* copy MM3 into MM4 */ 03444 punpcklbw mm3, mm0 /* unpack low bytes of SrcDest into words */ 03445 punpckhbw mm4, mm0 /* unpack high bytes of SrcDest into words */ 03446 psllw mm3, mm7 /* shift 4 WORDS of MM3 (N) bits to the right */ 03447 psllw mm4, mm7 /* shift 4 WORDS of MM4 (N) bits to the right */ 03448 /* ** Take abs value of the signed words ** */ 03449 movq mm5, mm3 /* copy mm3 into mm5 */ 03450 movq mm6, mm4 /* copy mm4 into mm6 */ 03451 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03452 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03453 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03454 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03455 psubsw mm3, mm5 /* add 1 to only neg words, W-(-1) or W-0 */ 03456 psubsw mm4, mm6 /* add 1 to only neg words, W-(-1) or W-0 */ 03457 packuswb mm3, mm4 /* pack words back into bytes with saturation */ 03458 movq [edi], mm3 /* store result in Dest */ 03459 add eax, 8 /* increase Src1 register pointer by 8 */ 03460 add edi, 8 /* increase Dest register pointer by 8 */ 03461 dec ecx /* decrease loop counter */ 03462 jnz L10281 /* check loop termination, proceed if required */ 03463 L10282: 03464 emms /* exit MMX state */ 03465 popa 03466 } 03467 #else 03468 asm volatile 03469 ("pusha \n\t" "xor %%eax, %%eax \n\t" /* zero EAX */ 03470 "mov %3, %%al \n\t" /* load N into AL */ 03471 "movd %%eax, %%mm7 \n\t" /* copy N into MM7 */ 03472 "pxor %%mm0, %%mm0 \n\t" /* zero MM0 register */ 03473 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 03474 "mov %0, %%edi \n\t" /* load Dest address into edi */ 03475 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 03476 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 03477 "cmp $7, %%al \n\t" /* if (N <= 7) execute more efficient code */ 03478 "jg 2f \n\t" ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 03479 "1: movq (%%eax), %%mm3 \n\t" /* load 8 bytes from Src1 into MM3 */ 03480 "movq %%mm3, %%mm4 \n\t" /* copy MM3 into MM4 */ 03481 "punpcklbw %%mm0, %%mm3 \n\t" /* unpack low bytes of SrcDest into words */ 03482 "punpckhbw %%mm0, %%mm4 \n\t" /* unpack high bytes of SrcDest into words */ 03483 "psllw %%mm7, %%mm3 \n\t" /* shift 4 WORDS of MM3 (N) bits to the right */ 03484 "psllw %%mm7, %%mm4 \n\t" /* shift 4 WORDS of MM4 (N) bits to the right */ 03485 "packuswb %%mm4, %%mm3 \n\t" /* pack words back into bytes with saturation */ 03486 "movq %%mm3, (%%edi) \n\t" /* store result in Dest */ 03487 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 03488 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 03489 "dec %%ecx \n\t" /* decrease loop counter */ 03490 "jnz 1b \n\t" /* check loop termination, proceed if required */ 03491 "jmp 3f \n\t" ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 03492 "2: movq (%%eax), %%mm3 \n\t" /* load 8 bytes from Src1 into MM3 */ 03493 "movq %%mm3, %%mm4 \n\t" /* copy MM3 into MM4 */ 03494 "punpcklbw %%mm0, %%mm3 \n\t" /* unpack low bytes of SrcDest into words */ 03495 "punpckhbw %%mm0, %%mm4 \n\t" /* unpack high bytes of SrcDest into words */ 03496 "psllw %%mm7, %%mm3 \n\t" /* shift 4 WORDS of MM3 (N) bits to the right */ 03497 "psllw %%mm7, %%mm4 \n\t" /* shift 4 WORDS of MM4 (N) bits to the right */ 03498 /* ** Take abs value of the signed words ** */ 03499 "movq %%mm3, %%mm5 \n\t" /* copy mm3 into mm5 */ 03500 "movq %%mm4, %%mm6 \n\t" /* copy mm4 into mm6 */ 03501 "psraw $15, %%mm5 \n\t" /* fill mm5 words with word sign bit */ 03502 "psraw $15, %%mm6 \n\t" /* fill mm6 words with word sign bit */ 03503 "pxor %%mm5, %%mm3 \n\t" /* take 1's compliment of only neg. words */ 03504 "pxor %%mm6, %%mm4 \n\t" /* take 1's compliment of only neg. words */ 03505 "psubsw %%mm5, %%mm3 \n\t" /* add 1 to only neg. words, W-(-1) or W-0 */ 03506 "psubsw %%mm6, %%mm4 \n\t" /* add 1 to only neg. words, W-(-1) or W-0 */ 03507 "packuswb %%mm4, %%mm3 \n\t" /* pack words back into bytes with saturation */ 03508 "movq %%mm3, (%%edi) \n\t" /* store result in Dest */ 03509 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 03510 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 03511 "dec %%ecx \n\t" /* decrease loop counter */ 03512 "jnz 2b \n\t" /* check loop termination, proceed if required */ 03513 "3: emms \n\t" /* exit MMX state */ 03514 "popa \n\t":"=m" (Dest) /* %0 */ 03515 :"m"(Src1), /* %1 */ 03516 "m"(SrcLength), /* %2 */ 03517 "m"(N) /* %3 */ 03518 ); 03519 #endif 03520 return (0); 03521 #else 03522 return (-1); 03523 #endif 03524 } 03525 03536 int SDL_imageFilterShiftLeft(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N) 03537 { 03538 unsigned int i, istart; 03539 unsigned char *cursrc1, *curdest; 03540 int result; 03541 03542 /* Validate input parameters */ 03543 if ((Src1 == NULL) || (Dest == NULL)) 03544 return(-1); 03545 if (length == 0) 03546 return(0); 03547 03548 if (N > 8) { 03549 return (-1); 03550 } 03551 03552 /* Special case: N==0 */ 03553 if (N == 0) { 03554 memcpy(Src1, Dest, length); 03555 return (0); 03556 } 03557 03558 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 03559 03560 SDL_imageFilterShiftLeftMMX(Src1, Dest, length, N); 03561 03562 /* Check for unaligned bytes */ 03563 if ((length & 7) > 0) { 03564 /* Setup to process unaligned bytes */ 03565 istart = length & 0xfffffff8; 03566 cursrc1 = &Src1[istart]; 03567 curdest = &Dest[istart]; 03568 } else { 03569 /* No unaligned bytes - we are done */ 03570 return (0); 03571 } 03572 } else { 03573 /* Setup to process whole image */ 03574 istart = 0; 03575 cursrc1 = Src1; 03576 curdest = Dest; 03577 } 03578 03579 /* C routine to process image */ 03580 for (i = istart; i < length; i++) { 03581 result = (int) *cursrc1 << N; 03582 if (result > 255) 03583 result = 255; 03584 *curdest = (unsigned char) result; 03585 /* Advance pointers */ 03586 cursrc1++; 03587 curdest++; 03588 } 03589 03590 return (0); 03591 } 03592 03603 int SDL_imageFilterBinarizeUsingThresholdMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char T) 03604 { 03605 #ifdef USE_MMX 03606 #if !defined(GCC__) 03607 __asm 03608 { 03609 pusha 03610 /* ** Duplicate T in 8 bytes of MM3 ** */ 03611 pcmpeqb mm1, mm1 /* generate all 1's in mm1 */ 03612 pcmpeqb mm2, mm2 /* generate all 1's in mm2 */ 03613 mov al, T /* load T into AL */ 03614 mov ah, al /* copy AL into AH */ 03615 mov bx, ax /* copy AX into BX */ 03616 shl eax, 16 /* shift 2 bytes of EAX left */ 03617 mov ax, bx /* copy BX into AX */ 03618 movd mm3, eax /* copy EAX into MM3 */ 03619 movd mm4, eax /* copy EAX into MM4 */ 03620 punpckldq mm3, mm4 /* fill higher bytes of MM3 with T */ 03621 psubusb mm2, mm3 /* store 0xFF - T in MM2 */ 03622 mov eax, Src1 /* load Src1 address into eax */ 03623 mov edi, Dest /* load Dest address into edi */ 03624 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03625 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03626 align 16 /* 16 byte alignment of the loop entry */ 03627 L1029: 03628 movq mm0, [eax] /* load 8 bytes from SrcDest into MM0 */ 03629 paddusb mm0, mm2 /* MM0=SrcDest+(0xFF-T) (add 8 bytes with saturation) */ 03630 pcmpeqb mm0, mm1 /* binarize 255:0, comparing to 255 */ 03631 movq [edi], mm0 /* store result in SrcDest */ 03632 add eax, 8 /* increase Src1 register pointer by 8 */ 03633 add edi, 8 /* increase Dest register pointer by 8 */ 03634 dec ecx /* decrease loop counter */ 03635 jnz L1029 /* check loop termination, proceed if required */ 03636 emms /* exit MMX state */ 03637 popa 03638 } 03639 #else 03640 asm volatile 03641 ("pusha \n\t" 03642 /* ** Duplicate T in 8 bytes of MM3 ** */ 03643 "pcmpeqb %%mm1, %%mm1 \n\t" /* generate all 1's in mm1 */ 03644 "pcmpeqb %%mm2, %%mm2 \n\t" /* generate all 1's in mm2 */ 03645 "mov %3, %%al \n\t" /* load T into AL */ 03646 "mov %%al, %%ah \n\t" /* copy AL into AH */ 03647 "mov %%ax, %%bx \n\t" /* copy AX into BX */ 03648 "shl $16, %%eax \n\t" /* shift 2 bytes of EAX left */ 03649 "mov %%bx, %%ax \n\t" /* copy BX into AX */ 03650 "movd %%eax, %%mm3 \n\t" /* copy EAX into MM3 */ 03651 "movd %%eax, %%mm4 \n\t" /* copy EAX into MM4 */ 03652 "punpckldq %%mm4, %%mm3 \n\t" /* fill higher bytes of MM3 with T */ 03653 "psubusb %%mm3, %%mm2 \n\t" /* store 0xFF - T in MM2 */ 03654 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 03655 "mov %0, %%edi \n\t" /* load Dest address into edi */ 03656 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 03657 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 03658 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 03659 "1: \n\t" 03660 "movq (%%eax), %%mm0 \n\t" /* load 8 bytes from SrcDest into MM0 */ 03661 "paddusb %%mm2, %%mm0 \n\t" /* MM0=SrcDest+(0xFF-T) (add 8 bytes with saturation) */ 03662 "pcmpeqb %%mm1, %%mm0 \n\t" /* binarize 255:0, comparing to 255 */ 03663 "movq %%mm0, (%%edi) \n\t" /* store result in SrcDest */ 03664 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 03665 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 03666 "dec %%ecx \n\t" /* decrease loop counter */ 03667 "jnz 1b \n\t" /* check loop termination, proceed if required */ 03668 "emms \n\t" /* exit MMX state */ 03669 "popa \n\t":"=m" (Dest) /* %0 */ 03670 :"m"(Src1), /* %1 */ 03671 "m"(SrcLength), /* %2 */ 03672 "m"(T) /* %3 */ 03673 ); 03674 #endif 03675 return (0); 03676 #else 03677 return (-1); 03678 #endif 03679 } 03680 03691 int SDL_imageFilterBinarizeUsingThreshold(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char T) 03692 { 03693 unsigned int i, istart; 03694 unsigned char *cursrc1; 03695 unsigned char *curdest; 03696 03697 /* Validate input parameters */ 03698 if ((Src1 == NULL) || (Dest == NULL)) 03699 return(-1); 03700 if (length == 0) 03701 return(0); 03702 03703 /* Special case: T==0 */ 03704 if (T == 0) { 03705 memset(Dest, 255, length); 03706 return (0); 03707 } 03708 03709 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 03710 03711 SDL_imageFilterBinarizeUsingThresholdMMX(Src1, Dest, length, T); 03712 03713 /* Check for unaligned bytes */ 03714 if ((length & 7) > 0) { 03715 /* Setup to process unaligned bytes */ 03716 istart = length & 0xfffffff8; 03717 cursrc1 = &Src1[istart]; 03718 curdest = &Dest[istart]; 03719 } else { 03720 /* No unaligned bytes - we are done */ 03721 return (0); 03722 } 03723 } else { 03724 /* Setup to process whole image */ 03725 istart = 0; 03726 cursrc1 = Src1; 03727 curdest = Dest; 03728 } 03729 03730 /* C routine to process image */ 03731 for (i = istart; i < length; i++) { 03732 *curdest = (unsigned char)(((unsigned char)*cursrc1 >= T) ? 255 : 0); 03733 /* Advance pointers */ 03734 cursrc1++; 03735 curdest++; 03736 } 03737 03738 return (0); 03739 } 03740 03752 int SDL_imageFilterClipToRangeMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, unsigned char Tmin, 03753 unsigned char Tmax) 03754 { 03755 #ifdef USE_MMX 03756 #if !defined(GCC__) 03757 __asm 03758 { 03759 pusha 03760 pcmpeqb mm1, mm1 /* generate all 1's in mm1 */ 03761 /* ** Duplicate Tmax in 8 bytes of MM3 ** */ 03762 mov al, Tmax /* load Tmax into AL */ 03763 mov ah, al /* copy AL into AH */ 03764 mov bx, ax /* copy AX into BX */ 03765 shl eax, 16 /* shift 2 bytes of EAX left */ 03766 mov ax, bx /* copy BX into AX */ 03767 movd mm3, eax /* copy EAX into MM3 */ 03768 movd mm4, eax /* copy EAX into MM4 */ 03769 punpckldq mm3, mm4 /* fill higher bytes of MM3 with Tmax */ 03770 psubusb mm1, mm3 /* store 0xFF - Tmax in MM1 */ 03771 /* ** Duplicate Tmin in 8 bytes of MM5 ** */ 03772 mov al, Tmin /* load Tmin into AL */ 03773 mov ah, al /* copy AL into AH */ 03774 mov bx, ax /* copy AX into BX */ 03775 shl eax, 16 /* shift 2 bytes of EAX left */ 03776 mov ax, bx /* copy BX into AX */ 03777 movd mm5, eax /* copy EAX into MM5 */ 03778 movd mm4, eax /* copy EAX into MM4 */ 03779 punpckldq mm5, mm4 /* fill higher bytes of MM5 with Tmin */ 03780 movq mm7, mm5 /* copy MM5 into MM7 */ 03781 paddusb mm7, mm1 /* store 0xFF - Tmax + Tmin in MM7 */ 03782 mov eax, Src1 /* load Src1 address into eax */ 03783 mov edi, Dest /* load Dest address into edi */ 03784 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03785 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03786 align 16 /* 16 byte alignment of the loop entry */ 03787 L1030: 03788 movq mm0, [eax] /* load 8 bytes from Src1 into MM0 */ 03789 paddusb mm0, mm1 /* MM0=SrcDest+(0xFF-Tmax) */ 03790 psubusb mm0, mm7 /* MM0=MM0-(0xFF-Tmax+Tmin) */ 03791 paddusb mm0, mm5 /* MM0=MM0+Tmin */ 03792 movq [edi], mm0 /* store result in Dest */ 03793 add eax, 8 /* increase Src1 register pointer by 8 */ 03794 add edi, 8 /* increase Dest register pointer by 8 */ 03795 dec ecx /* decrease loop counter */ 03796 jnz L1030 /* check loop termination, proceed if required */ 03797 emms /* exit MMX state */ 03798 popa 03799 } 03800 #else 03801 asm volatile 03802 ("pusha \n\t" "pcmpeqb %%mm1, %%mm1 \n\t" /* generate all 1's in mm1 */ 03803 /* ** Duplicate Tmax in 8 bytes of MM3 ** */ 03804 "mov %4, %%al \n\t" /* load Tmax into AL */ 03805 "mov %%al, %%ah \n\t" /* copy AL into AH */ 03806 "mov %%ax, %%bx \n\t" /* copy AX into BX */ 03807 "shl $16, %%eax \n\t" /* shift 2 bytes of EAX left */ 03808 "mov %%bx, %%ax \n\t" /* copy BX into AX */ 03809 "movd %%eax, %%mm3 \n\t" /* copy EAX into MM3 */ 03810 "movd %%eax, %%mm4 \n\t" /* copy EAX into MM4 */ 03811 "punpckldq %%mm4, %%mm3 \n\t" /* fill higher bytes of MM3 with Tmax */ 03812 "psubusb %%mm3, %%mm1 \n\t" /* store 0xFF - Tmax in MM1 */ 03813 /* ** Duplicate Tmin in 8 bytes of MM5 ** */ 03814 "mov %3, %%al \n\t" /* load Tmin into AL */ 03815 "mov %%al, %%ah \n\t" /* copy AL into AH */ 03816 "mov %%ax, %%bx \n\t" /* copy AX into BX */ 03817 "shl $16, %%eax \n\t" /* shift 2 bytes of EAX left */ 03818 "mov %%bx, %%ax \n\t" /* copy BX into AX */ 03819 "movd %%eax, %%mm5 \n\t" /* copy EAX into MM5 */ 03820 "movd %%eax, %%mm4 \n\t" /* copy EAX into MM4 */ 03821 "punpckldq %%mm4, %%mm5 \n\t" /* fill higher bytes of MM5 with Tmin */ 03822 "movq %%mm5, %%mm7 \n\t" /* copy MM5 into MM7 */ 03823 "paddusb %%mm1, %%mm7 \n\t" /* store 0xFF - Tmax + Tmin in MM7 */ 03824 "mov %1, %%eax \n\t" /* load Src1 address into eax */ 03825 "mov %0, %%edi \n\t" /* load Dest address into edi */ 03826 "mov %2, %%ecx \n\t" /* load loop counter (SIZE) into ecx */ 03827 "shr $3, %%ecx \n\t" /* counter/8 (MMX loads 8 bytes at a time) */ 03828 ".align 16 \n\t" /* 16 byte alignment of the loop entry */ 03829 "1: \n\t" 03830 "movq (%%eax), %%mm0 \n\t" /* load 8 bytes from Src1 into MM0 */ 03831 "paddusb %%mm1, %%mm0 \n\t" /* MM0=SrcDest+(0xFF-Tmax) */ 03832 "psubusb %%mm7, %%mm0 \n\t" /* MM0=MM0-(0xFF-Tmax+Tmin) */ 03833 "paddusb %%mm5, %%mm0 \n\t" /* MM0=MM0+Tmin */ 03834 "movq %%mm0, (%%edi) \n\t" /* store result in Dest */ 03835 "add $8, %%eax \n\t" /* increase Src1 register pointer by 8 */ 03836 "add $8, %%edi \n\t" /* increase Dest register pointer by 8 */ 03837 "dec %%ecx \n\t" /* decrease loop counter */ 03838 "jnz 1b \n\t" /* check loop termination, proceed if required */ 03839 "emms \n\t" /* exit MMX state */ 03840 "popa \n\t":"=m" (Dest) /* %0 */ 03841 :"m"(Src1), /* %1 */ 03842 "m"(SrcLength), /* %2 */ 03843 "m"(Tmin), /* %3 */ 03844 "m"(Tmax) /* %4 */ 03845 ); 03846 #endif 03847 return (0); 03848 #else 03849 return (-1); 03850 #endif 03851 } 03852 03864 int SDL_imageFilterClipToRange(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char Tmin, 03865 unsigned char Tmax) 03866 { 03867 unsigned int i, istart; 03868 unsigned char *cursrc1; 03869 unsigned char *curdest; 03870 03871 /* Validate input parameters */ 03872 if ((Src1 == NULL) || (Dest == NULL)) 03873 return(-1); 03874 if (length == 0) 03875 return(0); 03876 03877 /* Special case: Tmin==0 && Tmax = 255 */ 03878 if ((Tmin == 0) && (Tmax == 25)) { 03879 memcpy(Src1, Dest, length); 03880 return (0); 03881 } 03882 03883 if ((SDL_imageFilterMMXdetect()) && (length > 7)) { 03884 03885 SDL_imageFilterClipToRangeMMX(Src1, Dest, length, Tmin, Tmax); 03886 03887 /* Check for unaligned bytes */ 03888 if ((length & 7) > 0) { 03889 /* Setup to process unaligned bytes */ 03890 istart = length & 0xfffffff8; 03891 cursrc1 = &Src1[istart]; 03892 curdest = &Dest[istart]; 03893 } else { 03894 /* No unaligned bytes - we are done */ 03895 return (0); 03896 } 03897 } else { 03898 /* Setup to process whole image */ 03899 istart = 0; 03900 cursrc1 = Src1; 03901 curdest = Dest; 03902 } 03903 03904 /* C routine to process image */ 03905 for (i = istart; i < length; i++) { 03906 if (*cursrc1 < Tmin) { 03907 *curdest = Tmin; 03908 } else if (*cursrc1 > Tmax) { 03909 *curdest = Tmax; 03910 } else { 03911 *curdest = *cursrc1; 03912 } 03913 /* Advance pointers */ 03914 cursrc1++; 03915 curdest++; 03916 } 03917 03918 return (0); 03919 } 03920 03934 int SDL_imageFilterNormalizeLinearMMX(unsigned char *Src1, unsigned char *Dest, unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /* ** Take abs value of the signed words ** */ 03993 movq mm5, mm3 /* copy mm3 into mm5 */ 03994 movq mm6, mm4 /* copy mm4 into mm6 */ 03995 psraw mm5, 15 /* fill mm5 words with word sign bit */ 03996 psraw mm6, 15 /* fill mm6 words with word sign bit */ 03997 pxor mm3, mm5 /* take 1's compliment of only neg words */ 03998 pxor mm4, mm6 /* take 1's compliment of only neg words */ 03999 psubsw mm3, mm5 /* add 1 to unsigned int SrcLength, int Cmin, int Cmax, 03935 int Nmin, int Nmax) 03936 { 03937 #ifdef USE_MMX 03938 #if !defined(GCC__) 03939 __asm 03940 { 03941 pusha 03942 mov ax, WORD PTR Nmax /* load Nmax in AX */ 03943 mov bx, WORD PTR Cmax /* load Cmax in BX */ 03944 sub ax, WORD PTR Nmin /* AX = Nmax - Nmin */ 03945 sub bx, WORD PTR Cmin /* BX = Cmax - Cmin */ 03946 jz L10311 /* check division by zero */ 03947 xor dx, dx /* prepare for division, zero DX */ 03948 div bx /* AX = AX/BX */ 03949 jmp L10312 03950 L10311: 03951 mov ax, 255 /* if div by zero, assume result max byte value */ 03952 L10312: /* ** Duplicate AX in 4 words of MM0 ** */ 03953 mov bx, ax /* copy AX into BX */ 03954 shl eax, 16 /* shift 2 bytes of EAX left */ 03955 mov ax, bx /* copy BX into AX */ 03956 movd mm0, eax /* copy EAX into MM0 */ 03957 movd mm1, eax /* copy EAX into MM1 */ 03958 punpckldq mm0, mm1 /* fill higher words of MM0 with AX */ 03959 /* ** Duplicate Cmin in 4 words of MM1 ** */ 03960 mov ax, WORD PTR Cmin /* load Cmin into AX */ 03961 mov bx, ax /* copy AX into BX */ 03962 shl eax, 16 /* shift 2 bytes of EAX left */ 03963 mov ax, bx /* copy BX into AX */ 03964 movd mm1, eax /* copy EAX into MM1 */ 03965 movd mm2, eax /* copy EAX into MM2 */ 03966 punpckldq mm1, mm2 /* fill higher words of MM1 with Cmin */ 03967 /* ** Duplicate Nmin in 4 words of MM2 ** */ 03968 mov ax, WORD PTR Nmin /* load Nmin into AX */ 03969 mov bx, ax /* copy AX into BX */ 03970 shl eax, 16 /* shift 2 bytes of EAX left */ 03971 mov ax, bx /* copy BX into AX */ 03972 movd mm2, eax /* copy EAX into MM2 */ 03973 movd mm3, eax /* copy EAX into MM3 */ 03974 punpckldq mm2, mm3 /* fill higher words of MM2 with Nmin */ 03975 pxor mm7, mm7 /* zero MM7 register */ 03976 mov eax, Src1 /* load Src1 address into eax */ 03977 mov edi, Dest /* load Dest address into edi */ 03978 mov ecx, SrcLength /* load loop counter (SIZE) into ecx */ 03979 shr ecx, 3 /* counter/8 (MMX loads 8 bytes at a time) */ 03980 align 16 /* 16 byte alignment of the loop entry */ 03981 L1031: 03982 movq mm3, [eax] /* load 8 bytes from Src1 into MM3 */ 03983 movq mm4, mm3 /* copy MM3 into MM4 */ 03984 punpcklbw mm3, mm7 /* unpack low bytes of SrcDest into words */ 03985 punpckhbw mm4, mm7 /* unpack high bytes of SrcDest into words */ 03986 psubusb mm3, mm1 /* S-Cmin, low bytes */ 03987 psubusb mm4, mm1 /* S-Cmin, high bytes */ 03988 pmullw mm3, mm0 /* MM0*(S-Cmin), low bytes */ 03989 pmullw mm4, mm0 /* MM0*(S-Cmin), high bytes */ 03990 paddusb mm3, mm2 /* MM0*(S-Cmin)+Nmin, low bytes */ 03991 paddusb mm4, mm2 /* MM0*(S-Cmin)+Nmin, high bytes */ 03992 /*