• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

SDL_imageFilter.c

Go to the documentation of this file.
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                         /*