src/stdlib/SDL_stdlib.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 27 Nov 2013 00:29:46 -0800
changeset 8033 8181c3a4a055
parent 7357 9bd0b241c941
child 8056 abd9434c5d3e
child 8543 b9dd3cf38585
permissions -rw-r--r--
Fixed bug 2274 - SDL_ceil is incorrectly implemented when HAVE_LIBC is not defined

Ghassan Al-Mashareqa

The SDL_ceil function is implemented incorrectly when HAVE_CEIL is not defined (HAVE_LIBC not defined).

The following code:

double val = SDL_ceil(2.3);
printf("%g", val);

prints "2.0", as STD_ceil is defined as:

double
SDL_ceil(double x)
{
#ifdef HAVE_CEIL
return ceil(x);
#else
return (double)(int)((x)+0.5);
#endif /* HAVE_CEIL */
}

This functions is used in the SDL_BuildAudioResampleCVT function of the audio subsystem (SDL_audiocvt.c), and causes a bug in that function.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 
    23 /* This file contains portable stdlib functions for SDL */
    24 
    25 #include "SDL_stdinc.h"
    26 #include "../libm/math_libm.h"
    27 
    28 
    29 double
    30 SDL_atan(double x)
    31 {
    32 #ifdef HAVE_ATAN
    33     return atan(x);
    34 #else
    35     return SDL_uclibc_atan(x);
    36 #endif /* HAVE_ATAN */
    37 }
    38 
    39 double
    40 SDL_atan2(double x, double y)
    41 {
    42 #if defined(HAVE_ATAN2)
    43     return atan2(x, y);
    44 #else
    45     return SDL_uclibc_atan2(x, y);
    46 #endif /* HAVE_ATAN2 */
    47 }
    48 
    49 double
    50 SDL_ceil(double x)
    51 {
    52 #ifdef HAVE_CEIL
    53     return ceil(x);
    54 #else
    55     double integer = SDL_floor(x);
    56     double fraction = x - integer;
    57     if (fraction > 0.0) {
    58         integer += 1.0;
    59     }
    60     return integer;
    61 #endif /* HAVE_CEIL */
    62 }
    63 
    64 double
    65 SDL_copysign(double x, double y)
    66 {
    67 #if defined(HAVE_COPYSIGN)
    68     return copysign(x, y);
    69 #else
    70     return SDL_uclibc_copysign(x, y);
    71 #endif /* HAVE_COPYSIGN */
    72 }
    73 
    74 double
    75 SDL_cos(double x)
    76 {
    77 #if defined(HAVE_COS)
    78     return cos(x);
    79 #else
    80     return SDL_uclibc_cos(x);
    81 #endif /* HAVE_COS */
    82 }
    83 
    84 float
    85 SDL_cosf(float x)
    86 {
    87 #ifdef HAVE_COSF
    88     return cosf(x);
    89 #else
    90     return (float)SDL_cos((double)x);
    91 #endif
    92 }
    93 
    94 double
    95 SDL_fabs(double x)
    96 {
    97 #if defined(HAVE_FABS)
    98     return fabs(x); 
    99 #else
   100     return SDL_uclibc_fabs(x);
   101 #endif /* HAVE_FABS */
   102 }
   103 
   104 double
   105 SDL_floor(double x)
   106 {
   107 #if defined(HAVE_FLOOR)
   108     return floor(x);
   109 #else
   110     return SDL_uclibc_floor(x);
   111 #endif /* HAVE_FLOOR */
   112 }
   113 
   114 double
   115 SDL_log(double x)
   116 {
   117 #if defined(HAVE_LOG)
   118     return log(x);
   119 #else
   120     return SDL_uclibc_log(x);
   121 #endif /* HAVE_LOG */
   122 }
   123 
   124 double
   125 SDL_pow(double x, double y)
   126 {
   127 #if defined(HAVE_POW)
   128     return pow(x, y);
   129 #else
   130     return SDL_uclibc_pow(x, y);
   131 #endif /* HAVE_POW */
   132 }
   133 
   134 double
   135 SDL_scalbn(double x, int n)
   136 {
   137 #if defined(HAVE_SCALBN)
   138     return scalbn(x, n);
   139 #else
   140     return SDL_uclibc_scalbn(x, n);
   141 #endif /* HAVE_SCALBN */
   142 }
   143 
   144 double
   145 SDL_sin(double x)
   146 {
   147 #if defined(HAVE_SIN)
   148     return sin(x);
   149 #else
   150     return SDL_uclibc_sin(x);
   151 #endif /* HAVE_SIN */
   152 }
   153 
   154 float 
   155 SDL_sinf(float x)
   156 {
   157 #ifdef HAVE_SINF
   158     return sinf(x);
   159 #else
   160     return (float)SDL_sin((double)x);
   161 #endif /* HAVE_SINF */
   162 }
   163 
   164 double
   165 SDL_sqrt(double x)
   166 {
   167 #if defined(HAVE_SQRT)
   168     return sqrt(x);
   169 #else
   170     return SDL_uclibc_sqrt(x);
   171 #endif
   172 }
   173 
   174 int SDL_abs(int x)
   175 {
   176 #ifdef HAVE_ABS
   177     return abs(x);
   178 #else
   179     return ((x) < 0 ? -(x) : (x));
   180 #endif
   181 }
   182 
   183 #ifdef HAVE_CTYPE_H
   184 int SDL_isdigit(int x) { return isdigit(x); }
   185 int SDL_isspace(int x) { return isspace(x); }
   186 int SDL_toupper(int x) { return toupper(x); }
   187 int SDL_tolower(int x) { return tolower(x); }
   188 #else
   189 int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); }
   190 int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); }
   191 int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); }
   192 int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); }
   193 #endif
   194 
   195 
   196 #ifndef HAVE_LIBC
   197 /* These are some C runtime intrinsics that need to be defined */
   198 
   199 #if defined(_MSC_VER)
   200 
   201 #ifndef __FLTUSED__
   202 #define __FLTUSED__
   203 __declspec(selectany) int _fltused = 1;
   204 #endif
   205 
   206 /* The optimizer on Visual Studio 2010/2012 generates memcpy() calls */
   207 #if _MSC_VER >= 1600 && defined(_WIN64) && !defined(_DEBUG)
   208 #include <intrin.h>
   209 
   210 #pragma function(memcpy)
   211 void * memcpy ( void * destination, const void * source, size_t num )
   212 {
   213     const Uint8 *src = (const Uint8 *)source;
   214     Uint8 *dst = (Uint8 *)destination;
   215     size_t i;
   216     
   217     /* All WIN64 architectures have SSE, right? */
   218     if (!((uintptr_t) src & 15) && !((uintptr_t) dst & 15)) {
   219         __m128 values[4];
   220         for (i = num / 64; i--;) {
   221             _mm_prefetch(src, _MM_HINT_NTA);
   222             values[0] = *(__m128 *) (src + 0);
   223             values[1] = *(__m128 *) (src + 16);
   224             values[2] = *(__m128 *) (src + 32);
   225             values[3] = *(__m128 *) (src + 48);
   226             _mm_stream_ps((float *) (dst + 0), values[0]);
   227             _mm_stream_ps((float *) (dst + 16), values[1]);
   228             _mm_stream_ps((float *) (dst + 32), values[2]);
   229             _mm_stream_ps((float *) (dst + 48), values[3]);
   230             src += 64;
   231             dst += 64;
   232         }
   233         num &= 63;
   234     }
   235 
   236     while (num--) {
   237         *dst++ = *src++;
   238     }
   239     return destination;
   240 }
   241 #endif /* _MSC_VER == 1600 && defined(_WIN64) && !defined(_DEBUG) */
   242 
   243 #ifdef _M_IX86
   244 
   245 void
   246 __declspec(naked)
   247 _chkstk()
   248 {
   249 }
   250 
   251 /* Float to long */
   252 void
   253 __declspec(naked)
   254 _ftol()
   255 {
   256     /* *INDENT-OFF* */
   257     __asm {
   258         push        ebp
   259         mov         ebp,esp
   260         sub         esp,20h
   261         and         esp,0FFFFFFF0h
   262         fld         st(0)
   263         fst         dword ptr [esp+18h]
   264         fistp       qword ptr [esp+10h]
   265         fild        qword ptr [esp+10h]
   266         mov         edx,dword ptr [esp+18h]
   267         mov         eax,dword ptr [esp+10h]
   268         test        eax,eax
   269         je          integer_QnaN_or_zero
   270 arg_is_not_integer_QnaN:
   271         fsubp       st(1),st
   272         test        edx,edx
   273         jns         positive
   274         fstp        dword ptr [esp]
   275         mov         ecx,dword ptr [esp]
   276         xor         ecx,80000000h
   277         add         ecx,7FFFFFFFh
   278         adc         eax,0
   279         mov         edx,dword ptr [esp+14h]
   280         adc         edx,0
   281         jmp         localexit
   282 positive:
   283         fstp        dword ptr [esp]
   284         mov         ecx,dword ptr [esp]
   285         add         ecx,7FFFFFFFh
   286         sbb         eax,0
   287         mov         edx,dword ptr [esp+14h]
   288         sbb         edx,0
   289         jmp         localexit
   290 integer_QnaN_or_zero:
   291         mov         edx,dword ptr [esp+14h]
   292         test        edx,7FFFFFFFh
   293         jne         arg_is_not_integer_QnaN
   294         fstp        dword ptr [esp+18h]
   295         fstp        dword ptr [esp+18h]
   296 localexit:
   297         leave
   298         ret
   299     }
   300     /* *INDENT-ON* */
   301 }
   302 
   303 void
   304 _ftol2_sse()
   305 {
   306     _ftol();
   307 }
   308 
   309 /* 64-bit math operators for 32-bit systems */
   310 void
   311 __declspec(naked)
   312 _allmul()
   313 {
   314     /* *INDENT-OFF* */
   315     __asm {
   316         push        ebp
   317         mov         ebp,esp
   318         push        edi
   319         push        esi
   320         push        ebx
   321         sub         esp,0Ch
   322         mov         eax,dword ptr [ebp+10h]
   323         mov         edi,dword ptr [ebp+8]
   324         mov         ebx,eax
   325         mov         esi,eax
   326         sar         esi,1Fh
   327         mov         eax,dword ptr [ebp+8]
   328         mul         ebx
   329         imul        edi,esi
   330         mov         ecx,edx
   331         mov         dword ptr [ebp-18h],eax
   332         mov         edx,dword ptr [ebp+0Ch]
   333         add         ecx,edi
   334         imul        ebx,edx
   335         mov         eax,dword ptr [ebp-18h]
   336         lea         ebx,[ebx+ecx]
   337         mov         dword ptr [ebp-14h],ebx
   338         mov         edx,dword ptr [ebp-14h]
   339         add         esp,0Ch
   340         pop         ebx
   341         pop         esi
   342         pop         edi
   343         pop         ebp
   344         ret         10h
   345     }
   346     /* *INDENT-ON* */
   347 }
   348 
   349 void
   350 __declspec(naked)
   351 _alldiv()
   352 {
   353     /* *INDENT-OFF* */
   354     __asm {
   355         push        edi
   356         push        esi
   357         push        ebx
   358         xor         edi,edi
   359         mov         eax,dword ptr [esp+14h]
   360         or          eax,eax
   361         jge         L1
   362         inc         edi
   363         mov         edx,dword ptr [esp+10h]
   364         neg         eax
   365         neg         edx
   366         sbb         eax,0
   367         mov         dword ptr [esp+14h],eax
   368         mov         dword ptr [esp+10h],edx
   369 L1:
   370         mov         eax,dword ptr [esp+1Ch]
   371         or          eax,eax
   372         jge         L2
   373         inc         edi
   374         mov         edx,dword ptr [esp+18h]
   375         neg         eax
   376         neg         edx
   377         sbb         eax,0
   378         mov         dword ptr [esp+1Ch],eax
   379         mov         dword ptr [esp+18h],edx
   380 L2:
   381         or          eax,eax
   382         jne         L3
   383         mov         ecx,dword ptr [esp+18h]
   384         mov         eax,dword ptr [esp+14h]
   385         xor         edx,edx
   386         div         ecx
   387         mov         ebx,eax
   388         mov         eax,dword ptr [esp+10h]
   389         div         ecx
   390         mov         edx,ebx
   391         jmp         L4
   392 L3:
   393         mov         ebx,eax
   394         mov         ecx,dword ptr [esp+18h]
   395         mov         edx,dword ptr [esp+14h]
   396         mov         eax,dword ptr [esp+10h]
   397 L5:
   398         shr         ebx,1
   399         rcr         ecx,1
   400         shr         edx,1
   401         rcr         eax,1
   402         or          ebx,ebx
   403         jne         L5
   404         div         ecx
   405         mov         esi,eax
   406         mul         dword ptr [esp+1Ch]
   407         mov         ecx,eax
   408         mov         eax,dword ptr [esp+18h]
   409         mul         esi
   410         add         edx,ecx
   411         jb          L6
   412         cmp         edx,dword ptr [esp+14h]
   413         ja          L6
   414         jb          L7
   415         cmp         eax,dword ptr [esp+10h]
   416         jbe         L7
   417 L6:
   418         dec         esi
   419 L7:
   420         xor         edx,edx
   421         mov         eax,esi
   422 L4:
   423         dec         edi
   424         jne         L8
   425         neg         edx
   426         neg         eax
   427         sbb         edx,0
   428 L8:
   429         pop         ebx
   430         pop         esi
   431         pop         edi
   432         ret         10h
   433     }
   434     /* *INDENT-ON* */
   435 }
   436 
   437 void
   438 __declspec(naked)
   439 _aulldiv()
   440 {
   441     /* *INDENT-OFF* */
   442     __asm {
   443         push        ebx
   444         push        esi
   445         mov         eax,dword ptr [esp+18h]
   446         or          eax,eax
   447         jne         L1
   448         mov         ecx,dword ptr [esp+14h]
   449         mov         eax,dword ptr [esp+10h]
   450         xor         edx,edx
   451         div         ecx
   452         mov         ebx,eax
   453         mov         eax,dword ptr [esp+0Ch]
   454         div         ecx
   455         mov         edx,ebx
   456         jmp         L2
   457 L1:
   458         mov         ecx,eax
   459         mov         ebx,dword ptr [esp+14h]
   460         mov         edx,dword ptr [esp+10h]
   461         mov         eax,dword ptr [esp+0Ch]
   462 L3:
   463         shr         ecx,1
   464         rcr         ebx,1
   465         shr         edx,1
   466         rcr         eax,1
   467         or          ecx,ecx
   468         jne         L3
   469         div         ebx
   470         mov         esi,eax
   471         mul         dword ptr [esp+18h]
   472         mov         ecx,eax
   473         mov         eax,dword ptr [esp+14h]
   474         mul         esi
   475         add         edx,ecx
   476         jb          L4
   477         cmp         edx,dword ptr [esp+10h]
   478         ja          L4
   479         jb          L5
   480         cmp         eax,dword ptr [esp+0Ch]
   481         jbe         L5
   482 L4:
   483         dec         esi
   484 L5:
   485         xor         edx,edx
   486         mov         eax,esi
   487 L2:
   488         pop         esi
   489         pop         ebx
   490         ret         10h
   491     }
   492     /* *INDENT-ON* */
   493 }
   494 
   495 void
   496 __declspec(naked)
   497 _allrem()
   498 {
   499     /* *INDENT-OFF* */
   500     __asm {
   501         push        ebx
   502         push        edi
   503         xor         edi,edi
   504         mov         eax,dword ptr [esp+10h]
   505         or          eax,eax
   506         jge         L1
   507         inc         edi
   508         mov         edx,dword ptr [esp+0Ch]
   509         neg         eax
   510         neg         edx
   511         sbb         eax,0
   512         mov         dword ptr [esp+10h],eax
   513         mov         dword ptr [esp+0Ch],edx
   514 L1:
   515         mov         eax,dword ptr [esp+18h]
   516         or          eax,eax
   517         jge         L2
   518         mov         edx,dword ptr [esp+14h]
   519         neg         eax
   520         neg         edx
   521         sbb         eax,0
   522         mov         dword ptr [esp+18h],eax
   523         mov         dword ptr [esp+14h],edx
   524 L2:
   525         or          eax,eax
   526         jne         L3
   527         mov         ecx,dword ptr [esp+14h]
   528         mov         eax,dword ptr [esp+10h]
   529         xor         edx,edx
   530         div         ecx
   531         mov         eax,dword ptr [esp+0Ch]
   532         div         ecx
   533         mov         eax,edx
   534         xor         edx,edx
   535         dec         edi
   536         jns         L4
   537         jmp         L8
   538 L3:
   539         mov         ebx,eax
   540         mov         ecx,dword ptr [esp+14h]
   541         mov         edx,dword ptr [esp+10h]
   542         mov         eax,dword ptr [esp+0Ch]
   543 L5:
   544         shr         ebx,1
   545         rcr         ecx,1
   546         shr         edx,1
   547         rcr         eax,1
   548         or          ebx,ebx
   549         jne         L5
   550         div         ecx
   551         mov         ecx,eax
   552         mul         dword ptr [esp+18h]
   553         xchg        eax,ecx
   554         mul         dword ptr [esp+14h]
   555         add         edx,ecx
   556         jb          L6
   557         cmp         edx,dword ptr [esp+10h]
   558         ja          L6
   559         jb          L7
   560         cmp         eax,dword ptr [esp+0Ch]
   561         jbe         L7
   562 L6:
   563         sub         eax,dword ptr [esp+14h]
   564         sbb         edx,dword ptr [esp+18h]
   565 L7:
   566         sub         eax,dword ptr [esp+0Ch]
   567         sbb         edx,dword ptr [esp+10h]
   568         dec         edi
   569         jns         L8
   570 L4:
   571         neg         edx
   572         neg         eax
   573         sbb         edx,0
   574 L8:
   575         pop         edi
   576         pop         ebx
   577         ret         10h
   578     }
   579     /* *INDENT-ON* */
   580 }
   581 
   582 void
   583 __declspec(naked)
   584 _aullrem()
   585 {
   586     /* *INDENT-OFF* */
   587     __asm {
   588         push        ebx
   589         mov         eax,dword ptr [esp+14h]
   590         or          eax,eax
   591         jne         L1
   592         mov         ecx,dword ptr [esp+10h]
   593         mov         eax,dword ptr [esp+0Ch]
   594         xor         edx,edx
   595         div         ecx
   596         mov         eax,dword ptr [esp+8]
   597         div         ecx
   598         mov         eax,edx
   599         xor         edx,edx
   600         jmp         L2
   601 L1:
   602         mov         ecx,eax
   603         mov         ebx,dword ptr [esp+10h]
   604         mov         edx,dword ptr [esp+0Ch]
   605         mov         eax,dword ptr [esp+8]
   606 L3:
   607         shr         ecx,1
   608         rcr         ebx,1
   609         shr         edx,1
   610         rcr         eax,1
   611         or          ecx,ecx
   612         jne         L3
   613         div         ebx
   614         mov         ecx,eax
   615         mul         dword ptr [esp+14h]
   616         xchg        eax,ecx
   617         mul         dword ptr [esp+10h]
   618         add         edx,ecx
   619         jb          L4
   620         cmp         edx,dword ptr [esp+0Ch]
   621         ja          L4
   622         jb          L5
   623         cmp         eax,dword ptr [esp+8]
   624         jbe         L5
   625 L4:
   626         sub         eax,dword ptr [esp+10h]
   627         sbb         edx,dword ptr [esp+14h]
   628 L5:
   629         sub         eax,dword ptr [esp+8]
   630         sbb         edx,dword ptr [esp+0Ch]
   631         neg         edx
   632         neg         eax
   633         sbb         edx,0
   634 L2:
   635         pop         ebx
   636         ret         10h
   637     }
   638     /* *INDENT-ON* */
   639 }
   640 
   641 void
   642 __declspec(naked)
   643 _alldvrm()
   644 {
   645     /* *INDENT-OFF* */
   646     __asm {
   647         push        edi
   648         push        esi
   649         push        ebp
   650         xor         edi,edi
   651         xor         ebp,ebp
   652         mov         eax,dword ptr [esp+14h]
   653         or          eax,eax
   654         jge         L1
   655         inc         edi
   656         inc         ebp
   657         mov         edx,dword ptr [esp+10h]
   658         neg         eax
   659         neg         edx
   660         sbb         eax,0
   661         mov         dword ptr [esp+14h],eax
   662         mov         dword ptr [esp+10h],edx
   663 L1:
   664         mov         eax,dword ptr [esp+1Ch]
   665         or          eax,eax
   666         jge         L2
   667         inc         edi
   668         mov         edx,dword ptr [esp+18h]
   669         neg         eax
   670         neg         edx
   671         sbb         eax,0
   672         mov         dword ptr [esp+1Ch],eax
   673         mov         dword ptr [esp+18h],edx
   674 L2:
   675         or          eax,eax
   676         jne         L3
   677         mov         ecx,dword ptr [esp+18h]
   678         mov         eax,dword ptr [esp+14h]
   679         xor         edx,edx
   680         div         ecx
   681         mov         ebx,eax
   682         mov         eax,dword ptr [esp+10h]
   683         div         ecx
   684         mov         esi,eax
   685         mov         eax,ebx
   686         mul         dword ptr [esp+18h]
   687         mov         ecx,eax
   688         mov         eax,esi
   689         mul         dword ptr [esp+18h]
   690         add         edx,ecx
   691         jmp         L4
   692 L3:
   693         mov         ebx,eax
   694         mov         ecx,dword ptr [esp+18h]
   695         mov         edx,dword ptr [esp+14h]
   696         mov         eax,dword ptr [esp+10h]
   697 L5:
   698         shr         ebx,1
   699         rcr         ecx,1
   700         shr         edx,1
   701         rcr         eax,1
   702         or          ebx,ebx
   703         jne         L5
   704         div         ecx
   705         mov         esi,eax
   706         mul         dword ptr [esp+1Ch]
   707         mov         ecx,eax
   708         mov         eax,dword ptr [esp+18h]
   709         mul         esi
   710         add         edx,ecx
   711         jb          L6
   712         cmp         edx,dword ptr [esp+14h]
   713         ja          L6
   714         jb          L7
   715         cmp         eax,dword ptr [esp+10h]
   716         jbe         L7
   717 L6:
   718         dec         esi
   719         sub         eax,dword ptr [esp+18h]
   720         sbb         edx,dword ptr [esp+1Ch]
   721 L7:
   722         xor         ebx,ebx
   723 L4:
   724         sub         eax,dword ptr [esp+10h]
   725         sbb         edx,dword ptr [esp+14h]
   726         dec         ebp
   727         jns         L9
   728         neg         edx
   729         neg         eax
   730         sbb         edx,0
   731 L9:
   732         mov         ecx,edx
   733         mov         edx,ebx
   734         mov         ebx,ecx
   735         mov         ecx,eax
   736         mov         eax,esi
   737         dec         edi
   738         jne         L8
   739         neg         edx
   740         neg         eax
   741         sbb         edx,0
   742 L8:
   743         pop         ebp
   744         pop         esi
   745         pop         edi
   746         ret         10h
   747     }
   748     /* *INDENT-ON* */
   749 }
   750 
   751 void
   752 __declspec(naked)
   753 _aulldvrm()
   754 {
   755     /* *INDENT-OFF* */
   756     __asm {
   757         push        esi
   758         mov         eax,dword ptr [esp+14h]
   759         or          eax,eax
   760         jne         L1
   761         mov         ecx,dword ptr [esp+10h]
   762         mov         eax,dword ptr [esp+0Ch]
   763         xor         edx,edx
   764         div         ecx
   765         mov         ebx,eax
   766         mov         eax,dword ptr [esp+8]
   767         div         ecx
   768         mov         esi,eax
   769         mov         eax,ebx
   770         mul         dword ptr [esp+10h]
   771         mov         ecx,eax
   772         mov         eax,esi
   773         mul         dword ptr [esp+10h]
   774         add         edx,ecx
   775         jmp         L2
   776 L1:
   777         mov         ecx,eax
   778         mov         ebx,dword ptr [esp+10h]
   779         mov         edx,dword ptr [esp+0Ch]
   780         mov         eax,dword ptr [esp+8]
   781 L3:
   782         shr         ecx,1
   783         rcr         ebx,1
   784         shr         edx,1
   785         rcr         eax,1
   786         or          ecx,ecx
   787         jne         L3
   788         div         ebx
   789         mov         esi,eax
   790         mul         dword ptr [esp+14h]
   791         mov         ecx,eax
   792         mov         eax,dword ptr [esp+10h]
   793         mul         esi
   794         add         edx,ecx
   795         jb          L4
   796         cmp         edx,dword ptr [esp+0Ch]
   797         ja          L4
   798         jb          L5
   799         cmp         eax,dword ptr [esp+8]
   800         jbe         L5
   801 L4:
   802         dec         esi
   803         sub         eax,dword ptr [esp+10h]
   804         sbb         edx,dword ptr [esp+14h]
   805 L5:
   806         xor         ebx,ebx
   807 L2:
   808         sub         eax,dword ptr [esp+8]
   809         sbb         edx,dword ptr [esp+0Ch]
   810         neg         edx
   811         neg         eax
   812         sbb         edx,0
   813         mov         ecx,edx
   814         mov         edx,ebx
   815         mov         ebx,ecx
   816         mov         ecx,eax
   817         mov         eax,esi
   818         pop         esi
   819         ret         10h
   820     }
   821     /* *INDENT-ON* */
   822 }
   823 
   824 void
   825 __declspec(naked)
   826 _allshl()
   827 {
   828     /* *INDENT-OFF* */
   829     __asm {
   830         cmp         cl,40h
   831         jae         RETZERO
   832         cmp         cl,20h
   833         jae         MORE32
   834         shld        edx,eax,cl
   835         shl         eax,cl
   836         ret
   837 MORE32:
   838         mov         edx,eax
   839         xor         eax,eax
   840         and         cl,1Fh
   841         shl         edx,cl
   842         ret
   843 RETZERO:
   844         xor         eax,eax
   845         xor         edx,edx
   846         ret
   847     }
   848     /* *INDENT-ON* */
   849 }
   850 
   851 void
   852 __declspec(naked)
   853 _allshr()
   854 {
   855     /* *INDENT-OFF* */
   856     __asm {
   857         cmp         cl,40h
   858         jae         RETZERO
   859         cmp         cl,20h
   860         jae         MORE32
   861         shrd        eax,edx,cl
   862         sar         edx,cl
   863         ret
   864 MORE32:
   865         mov         eax,edx
   866         xor         edx,edx
   867         and         cl,1Fh
   868         sar         eax,cl
   869         ret
   870 RETZERO:
   871         xor         eax,eax
   872         xor         edx,edx
   873         ret
   874     }
   875     /* *INDENT-ON* */
   876 }
   877 
   878 void
   879 __declspec(naked)
   880 _aullshr()
   881 {
   882     /* *INDENT-OFF* */
   883     __asm {
   884         cmp         cl,40h
   885         jae         RETZERO
   886         cmp         cl,20h
   887         jae         MORE32
   888         shrd        eax,edx,cl
   889         shr         edx,cl
   890         ret
   891 MORE32:
   892         mov         eax,edx
   893         xor         edx,edx
   894         and         cl,1Fh
   895         shr         eax,cl
   896         ret
   897 RETZERO:
   898         xor         eax,eax
   899         xor         edx,edx
   900         ret
   901     }
   902     /* *INDENT-ON* */
   903 }
   904 
   905 #endif /* _M_IX86 */
   906 
   907 #endif /* MSC_VER */
   908 
   909 #endif /* !HAVE_LIBC */
   910 
   911 /* vi: set ts=4 sw=4 expandtab: */