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