src/stdlib/SDL_stdlib.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 29 Aug 2017 00:36:17 -0400
changeset 11404 bd5b569b2a1b
parent 11341 8b3231952c22
child 11682 b26412a89fbb
permissions -rw-r--r--
stdlib: An implementation of SDL_scalbn using ldexp() (thanks, Ozkan!).

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