src/stdlib/SDL_stdlib.c
author Sam Lantinga
Fri, 27 Nov 2020 18:57:42 -0800
changeset 14413 0ba75e4da3e1
parent 14284 ecea01fb884e
permissions -rw-r--r--
Remember to close the game controller when we're done with it
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2020 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_exp(double x)
   205 {
   206 #if defined(HAVE_EXP)
   207     return exp(x);
   208 #else
   209     return SDL_uclibc_exp(x);
   210 #endif
   211 }
   212 
   213 float
   214 SDL_expf(float x)
   215 {
   216 #if defined(HAVE_EXPF)
   217     return expf(x);
   218 #else
   219     return (float)SDL_exp((double)x);
   220 #endif
   221 }
   222 
   223 double
   224 SDL_fabs(double x)
   225 {
   226 #if defined(HAVE_FABS)
   227     return fabs(x);
   228 #else
   229     return SDL_uclibc_fabs(x);
   230 #endif
   231 }
   232 
   233 float
   234 SDL_fabsf(float x)
   235 {
   236 #if defined(HAVE_FABSF)
   237     return fabsf(x);
   238 #else
   239     return (float)SDL_fabs((double)x);
   240 #endif
   241 }
   242 
   243 double
   244 SDL_floor(double x)
   245 {
   246 #if defined(HAVE_FLOOR)
   247     return floor(x);
   248 #else
   249     return SDL_uclibc_floor(x);
   250 #endif
   251 }
   252 
   253 float
   254 SDL_floorf(float x)
   255 {
   256 #if defined(HAVE_FLOORF)
   257     return floorf(x);
   258 #else
   259     return (float)SDL_floor((double)x);
   260 #endif
   261 }
   262 
   263 double
   264 SDL_trunc(double x)
   265 {
   266 #if defined(HAVE_TRUNC)
   267     return trunc(x);
   268 #else
   269     if (x >= 0.0f) {
   270         return SDL_floor(x);
   271     } else {
   272         return SDL_ceil(x);
   273     }
   274 #endif
   275 }
   276 
   277 float
   278 SDL_truncf(float x)
   279 {
   280 #if defined(HAVE_TRUNCF)
   281     return truncf(x);
   282 #else
   283     return (float)SDL_trunc((double)x);
   284 #endif
   285 }
   286 
   287 double
   288 SDL_fmod(double x, double y)
   289 {
   290 #if defined(HAVE_FMOD)
   291     return fmod(x, y);
   292 #else
   293     return SDL_uclibc_fmod(x, y);
   294 #endif
   295 }
   296 
   297 float
   298 SDL_fmodf(float x, float y)
   299 {
   300 #if defined(HAVE_FMODF)
   301     return fmodf(x, y);
   302 #else
   303     return (float)SDL_fmod((double)x, (double)y);
   304 #endif
   305 }
   306 
   307 double
   308 SDL_log(double x)
   309 {
   310 #if defined(HAVE_LOG)
   311     return log(x);
   312 #else
   313     return SDL_uclibc_log(x);
   314 #endif
   315 }
   316 
   317 float
   318 SDL_logf(float x)
   319 {
   320 #if defined(HAVE_LOGF)
   321     return logf(x);
   322 #else
   323     return (float)SDL_log((double)x);
   324 #endif
   325 }
   326 
   327 double
   328 SDL_log10(double x)
   329 {
   330 #if defined(HAVE_LOG10)
   331     return log10(x);
   332 #else
   333     return SDL_uclibc_log10(x);
   334 #endif
   335 }
   336 
   337 float
   338 SDL_log10f(float x)
   339 {
   340 #if defined(HAVE_LOG10F)
   341     return log10f(x);
   342 #else
   343     return (float)SDL_log10((double)x);
   344 #endif
   345 }
   346 
   347 double
   348 SDL_pow(double x, double y)
   349 {
   350 #if defined(HAVE_POW)
   351     return pow(x, y);
   352 #else
   353     return SDL_uclibc_pow(x, y);
   354 #endif
   355 }
   356 
   357 float
   358 SDL_powf(float x, float y)
   359 {
   360 #if defined(HAVE_POWF)
   361     return powf(x, y);
   362 #else
   363     return (float)SDL_pow((double)x, (double)y);
   364 #endif
   365 }
   366 
   367 double
   368 SDL_scalbn(double x, int n)
   369 {
   370 #if defined(HAVE_SCALBN)
   371     return scalbn(x, n);
   372 #elif defined(HAVE__SCALB)
   373     return _scalb(x, n);
   374 #elif defined(HAVE_LIBC) && defined(HAVE_FLOAT_H) && (FLT_RADIX == 2)
   375 /* from scalbn(3): If FLT_RADIX equals 2 (which is
   376  * usual), then scalbn() is equivalent to ldexp(3). */
   377     return ldexp(x, n);
   378 #else
   379     return SDL_uclibc_scalbn(x, n);
   380 #endif
   381 }
   382 
   383 float
   384 SDL_scalbnf(float x, int n)
   385 {
   386 #if defined(HAVE_SCALBNF)
   387     return scalbnf(x, n);
   388 #else
   389     return (float)SDL_scalbn((double)x, n);
   390 #endif
   391 }
   392 
   393 double
   394 SDL_sin(double x)
   395 {
   396 #if defined(HAVE_SIN)
   397     return sin(x);
   398 #else
   399     return SDL_uclibc_sin(x);
   400 #endif
   401 }
   402 
   403 float 
   404 SDL_sinf(float x)
   405 {
   406 #if defined(HAVE_SINF)
   407     return sinf(x);
   408 #else
   409     return (float)SDL_sin((double)x);
   410 #endif
   411 }
   412 
   413 double
   414 SDL_sqrt(double x)
   415 {
   416 #if defined(HAVE_SQRT)
   417     return sqrt(x);
   418 #else
   419     return SDL_uclibc_sqrt(x);
   420 #endif
   421 }
   422 
   423 float
   424 SDL_sqrtf(float x)
   425 {
   426 #if defined(HAVE_SQRTF)
   427     return sqrtf(x);
   428 #else
   429     return (float)SDL_sqrt((double)x);
   430 #endif
   431 }
   432 
   433 double
   434 SDL_tan(double x)
   435 {
   436 #if defined(HAVE_TAN)
   437     return tan(x);
   438 #else
   439     return SDL_uclibc_tan(x);
   440 #endif
   441 }
   442 
   443 float
   444 SDL_tanf(float x)
   445 {
   446 #if defined(HAVE_TANF)
   447     return tanf(x);
   448 #else
   449     return (float)SDL_tan((double)x);
   450 #endif
   451 }
   452 
   453 int SDL_abs(int x)
   454 {
   455 #if defined(HAVE_ABS)
   456     return abs(x);
   457 #else
   458     return ((x) < 0 ? -(x) : (x));
   459 #endif
   460 }
   461 
   462 #if defined(HAVE_CTYPE_H)
   463 int SDL_isdigit(int x) { return isdigit(x); }
   464 int SDL_isspace(int x) { return isspace(x); }
   465 int SDL_isupper(int x) { return isupper(x); }
   466 int SDL_islower(int x) { return islower(x); }
   467 int SDL_toupper(int x) { return toupper(x); }
   468 int SDL_tolower(int x) { return tolower(x); }
   469 #else
   470 int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); }
   471 int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); }
   472 int SDL_isupper(int x) { return ((x) >= 'A') && ((x) <= 'Z'); }
   473 int SDL_islower(int x) { return ((x) >= 'a') && ((x) <= 'z'); }
   474 int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); }
   475 int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); }
   476 #endif
   477 
   478 
   479 #ifndef HAVE_LIBC
   480 /* These are some C runtime intrinsics that need to be defined */
   481 
   482 #if defined(_MSC_VER)
   483 
   484 #ifndef __FLTUSED__
   485 #define __FLTUSED__
   486 __declspec(selectany) int _fltused = 1;
   487 #endif
   488 
   489 /* The optimizer on Visual Studio 2005 and later generates memcpy() and memset() calls */
   490 #if _MSC_VER >= 1400
   491 extern void *memcpy(void* dst, const void* src, size_t len);
   492 #pragma intrinsic(memcpy)
   493 
   494 #pragma function(memcpy)
   495 void *
   496 memcpy(void *dst, const void *src, size_t len)
   497 {
   498     return SDL_memcpy(dst, src, len);
   499 }
   500 
   501 extern void *memset(void* dst, int c, size_t len);
   502 #pragma intrinsic(memset)
   503 
   504 #pragma function(memset)
   505 void *
   506 memset(void *dst, int c, size_t len)
   507 {
   508     return SDL_memset(dst, c, len);
   509 }
   510 #endif /* _MSC_VER >= 1400 */
   511 
   512 #ifdef _M_IX86
   513 
   514 /* Float to long */
   515 void
   516 __declspec(naked)
   517 _ftol()
   518 {
   519     /* *INDENT-OFF* */
   520     __asm {
   521         push        ebp
   522         mov         ebp,esp
   523         sub         esp,20h
   524         and         esp,0FFFFFFF0h
   525         fld         st(0)
   526         fst         dword ptr [esp+18h]
   527         fistp       qword ptr [esp+10h]
   528         fild        qword ptr [esp+10h]
   529         mov         edx,dword ptr [esp+18h]
   530         mov         eax,dword ptr [esp+10h]
   531         test        eax,eax
   532         je          integer_QnaN_or_zero
   533 arg_is_not_integer_QnaN:
   534         fsubp       st(1),st
   535         test        edx,edx
   536         jns         positive
   537         fstp        dword ptr [esp]
   538         mov         ecx,dword ptr [esp]
   539         xor         ecx,80000000h
   540         add         ecx,7FFFFFFFh
   541         adc         eax,0
   542         mov         edx,dword ptr [esp+14h]
   543         adc         edx,0
   544         jmp         localexit
   545 positive:
   546         fstp        dword ptr [esp]
   547         mov         ecx,dword ptr [esp]
   548         add         ecx,7FFFFFFFh
   549         sbb         eax,0
   550         mov         edx,dword ptr [esp+14h]
   551         sbb         edx,0
   552         jmp         localexit
   553 integer_QnaN_or_zero:
   554         mov         edx,dword ptr [esp+14h]
   555         test        edx,7FFFFFFFh
   556         jne         arg_is_not_integer_QnaN
   557         fstp        dword ptr [esp+18h]
   558         fstp        dword ptr [esp+18h]
   559 localexit:
   560         leave
   561         ret
   562     }
   563     /* *INDENT-ON* */
   564 }
   565 
   566 void
   567 _ftol2_sse()
   568 {
   569     _ftol();
   570 }
   571 
   572 /* 64-bit math operators for 32-bit systems */
   573 void
   574 __declspec(naked)
   575 _allmul()
   576 {
   577     /* *INDENT-OFF* */
   578     __asm {
   579         mov         eax, dword ptr[esp+8]
   580         mov         ecx, dword ptr[esp+10h]
   581         or          ecx, eax
   582         mov         ecx, dword ptr[esp+0Ch]
   583         jne         hard
   584         mov         eax, dword ptr[esp+4]
   585         mul         ecx
   586         ret         10h
   587 hard:
   588         push        ebx
   589         mul         ecx
   590         mov         ebx, eax
   591         mov         eax, dword ptr[esp+8]
   592         mul         dword ptr[esp+14h]
   593         add         ebx, eax
   594         mov         eax, dword ptr[esp+8]
   595         mul         ecx
   596         add         edx, ebx
   597         pop         ebx
   598         ret         10h
   599     }
   600     /* *INDENT-ON* */
   601 }
   602 
   603 void
   604 __declspec(naked)
   605 _alldiv()
   606 {
   607     /* *INDENT-OFF* */
   608     __asm {
   609         push        edi
   610         push        esi
   611         push        ebx
   612         xor         edi,edi
   613         mov         eax,dword ptr [esp+14h]
   614         or          eax,eax
   615         jge         L1
   616         inc         edi
   617         mov         edx,dword ptr [esp+10h]
   618         neg         eax
   619         neg         edx
   620         sbb         eax,0
   621         mov         dword ptr [esp+14h],eax
   622         mov         dword ptr [esp+10h],edx
   623 L1:
   624         mov         eax,dword ptr [esp+1Ch]
   625         or          eax,eax
   626         jge         L2
   627         inc         edi
   628         mov         edx,dword ptr [esp+18h]
   629         neg         eax
   630         neg         edx
   631         sbb         eax,0
   632         mov         dword ptr [esp+1Ch],eax
   633         mov         dword ptr [esp+18h],edx
   634 L2:
   635         or          eax,eax
   636         jne         L3
   637         mov         ecx,dword ptr [esp+18h]
   638         mov         eax,dword ptr [esp+14h]
   639         xor         edx,edx
   640         div         ecx
   641         mov         ebx,eax
   642         mov         eax,dword ptr [esp+10h]
   643         div         ecx
   644         mov         edx,ebx
   645         jmp         L4
   646 L3:
   647         mov         ebx,eax
   648         mov         ecx,dword ptr [esp+18h]
   649         mov         edx,dword ptr [esp+14h]
   650         mov         eax,dword ptr [esp+10h]
   651 L5:
   652         shr         ebx,1
   653         rcr         ecx,1
   654         shr         edx,1
   655         rcr         eax,1
   656         or          ebx,ebx
   657         jne         L5
   658         div         ecx
   659         mov         esi,eax
   660         mul         dword ptr [esp+1Ch]
   661         mov         ecx,eax
   662         mov         eax,dword ptr [esp+18h]
   663         mul         esi
   664         add         edx,ecx
   665         jb          L6
   666         cmp         edx,dword ptr [esp+14h]
   667         ja          L6
   668         jb          L7
   669         cmp         eax,dword ptr [esp+10h]
   670         jbe         L7
   671 L6:
   672         dec         esi
   673 L7:
   674         xor         edx,edx
   675         mov         eax,esi
   676 L4:
   677         dec         edi
   678         jne         L8
   679         neg         edx
   680         neg         eax
   681         sbb         edx,0
   682 L8:
   683         pop         ebx
   684         pop         esi
   685         pop         edi
   686         ret         10h
   687     }
   688     /* *INDENT-ON* */
   689 }
   690 
   691 void
   692 __declspec(naked)
   693 _aulldiv()
   694 {
   695     /* *INDENT-OFF* */
   696     __asm {
   697         push        ebx
   698         push        esi
   699         mov         eax,dword ptr [esp+18h]
   700         or          eax,eax
   701         jne         L1
   702         mov         ecx,dword ptr [esp+14h]
   703         mov         eax,dword ptr [esp+10h]
   704         xor         edx,edx
   705         div         ecx
   706         mov         ebx,eax
   707         mov         eax,dword ptr [esp+0Ch]
   708         div         ecx
   709         mov         edx,ebx
   710         jmp         L2
   711 L1:
   712         mov         ecx,eax
   713         mov         ebx,dword ptr [esp+14h]
   714         mov         edx,dword ptr [esp+10h]
   715         mov         eax,dword ptr [esp+0Ch]
   716 L3:
   717         shr         ecx,1
   718         rcr         ebx,1
   719         shr         edx,1
   720         rcr         eax,1
   721         or          ecx,ecx
   722         jne         L3
   723         div         ebx
   724         mov         esi,eax
   725         mul         dword ptr [esp+18h]
   726         mov         ecx,eax
   727         mov         eax,dword ptr [esp+14h]
   728         mul         esi
   729         add         edx,ecx
   730         jb          L4
   731         cmp         edx,dword ptr [esp+10h]
   732         ja          L4
   733         jb          L5
   734         cmp         eax,dword ptr [esp+0Ch]
   735         jbe         L5
   736 L4:
   737         dec         esi
   738 L5:
   739         xor         edx,edx
   740         mov         eax,esi
   741 L2:
   742         pop         esi
   743         pop         ebx
   744         ret         10h
   745     }
   746     /* *INDENT-ON* */
   747 }
   748 
   749 void
   750 __declspec(naked)
   751 _allrem()
   752 {
   753     /* *INDENT-OFF* */
   754     __asm {
   755         push        ebx
   756         push        edi
   757         xor         edi,edi
   758         mov         eax,dword ptr [esp+10h]
   759         or          eax,eax
   760         jge         L1
   761         inc         edi
   762         mov         edx,dword ptr [esp+0Ch]
   763         neg         eax
   764         neg         edx
   765         sbb         eax,0
   766         mov         dword ptr [esp+10h],eax
   767         mov         dword ptr [esp+0Ch],edx
   768 L1:
   769         mov         eax,dword ptr [esp+18h]
   770         or          eax,eax
   771         jge         L2
   772         mov         edx,dword ptr [esp+14h]
   773         neg         eax
   774         neg         edx
   775         sbb         eax,0
   776         mov         dword ptr [esp+18h],eax
   777         mov         dword ptr [esp+14h],edx
   778 L2:
   779         or          eax,eax
   780         jne         L3
   781         mov         ecx,dword ptr [esp+14h]
   782         mov         eax,dword ptr [esp+10h]
   783         xor         edx,edx
   784         div         ecx
   785         mov         eax,dword ptr [esp+0Ch]
   786         div         ecx
   787         mov         eax,edx
   788         xor         edx,edx
   789         dec         edi
   790         jns         L4
   791         jmp         L8
   792 L3:
   793         mov         ebx,eax
   794         mov         ecx,dword ptr [esp+14h]
   795         mov         edx,dword ptr [esp+10h]
   796         mov         eax,dword ptr [esp+0Ch]
   797 L5:
   798         shr         ebx,1
   799         rcr         ecx,1
   800         shr         edx,1
   801         rcr         eax,1
   802         or          ebx,ebx
   803         jne         L5
   804         div         ecx
   805         mov         ecx,eax
   806         mul         dword ptr [esp+18h]
   807         xchg        eax,ecx
   808         mul         dword ptr [esp+14h]
   809         add         edx,ecx
   810         jb          L6
   811         cmp         edx,dword ptr [esp+10h]
   812         ja          L6
   813         jb          L7
   814         cmp         eax,dword ptr [esp+0Ch]
   815         jbe         L7
   816 L6:
   817         sub         eax,dword ptr [esp+14h]
   818         sbb         edx,dword ptr [esp+18h]
   819 L7:
   820         sub         eax,dword ptr [esp+0Ch]
   821         sbb         edx,dword ptr [esp+10h]
   822         dec         edi
   823         jns         L8
   824 L4:
   825         neg         edx
   826         neg         eax
   827         sbb         edx,0
   828 L8:
   829         pop         edi
   830         pop         ebx
   831         ret         10h
   832     }
   833     /* *INDENT-ON* */
   834 }
   835 
   836 void
   837 __declspec(naked)
   838 _aullrem()
   839 {
   840     /* *INDENT-OFF* */
   841     __asm {
   842         push        ebx
   843         mov         eax,dword ptr [esp+14h]
   844         or          eax,eax
   845         jne         L1
   846         mov         ecx,dword ptr [esp+10h]
   847         mov         eax,dword ptr [esp+0Ch]
   848         xor         edx,edx
   849         div         ecx
   850         mov         eax,dword ptr [esp+8]
   851         div         ecx
   852         mov         eax,edx
   853         xor         edx,edx
   854         jmp         L2
   855 L1:
   856         mov         ecx,eax
   857         mov         ebx,dword ptr [esp+10h]
   858         mov         edx,dword ptr [esp+0Ch]
   859         mov         eax,dword ptr [esp+8]
   860 L3:
   861         shr         ecx,1
   862         rcr         ebx,1
   863         shr         edx,1
   864         rcr         eax,1
   865         or          ecx,ecx
   866         jne         L3
   867         div         ebx
   868         mov         ecx,eax
   869         mul         dword ptr [esp+14h]
   870         xchg        eax,ecx
   871         mul         dword ptr [esp+10h]
   872         add         edx,ecx
   873         jb          L4
   874         cmp         edx,dword ptr [esp+0Ch]
   875         ja          L4
   876         jb          L5
   877         cmp         eax,dword ptr [esp+8]
   878         jbe         L5
   879 L4:
   880         sub         eax,dword ptr [esp+10h]
   881         sbb         edx,dword ptr [esp+14h]
   882 L5:
   883         sub         eax,dword ptr [esp+8]
   884         sbb         edx,dword ptr [esp+0Ch]
   885         neg         edx
   886         neg         eax
   887         sbb         edx,0
   888 L2:
   889         pop         ebx
   890         ret         10h
   891     }
   892     /* *INDENT-ON* */
   893 }
   894 
   895 void
   896 __declspec(naked)
   897 _alldvrm()
   898 {
   899     /* *INDENT-OFF* */
   900     __asm {
   901         push        edi
   902         push        esi
   903         push        ebp
   904         xor         edi,edi
   905         xor         ebp,ebp
   906         mov         eax,dword ptr [esp+14h]
   907         or          eax,eax
   908         jge         L1
   909         inc         edi
   910         inc         ebp
   911         mov         edx,dword ptr [esp+10h]
   912         neg         eax
   913         neg         edx
   914         sbb         eax,0
   915         mov         dword ptr [esp+14h],eax
   916         mov         dword ptr [esp+10h],edx
   917 L1:
   918         mov         eax,dword ptr [esp+1Ch]
   919         or          eax,eax
   920         jge         L2
   921         inc         edi
   922         mov         edx,dword ptr [esp+18h]
   923         neg         eax
   924         neg         edx
   925         sbb         eax,0
   926         mov         dword ptr [esp+1Ch],eax
   927         mov         dword ptr [esp+18h],edx
   928 L2:
   929         or          eax,eax
   930         jne         L3
   931         mov         ecx,dword ptr [esp+18h]
   932         mov         eax,dword ptr [esp+14h]
   933         xor         edx,edx
   934         div         ecx
   935         mov         ebx,eax
   936         mov         eax,dword ptr [esp+10h]
   937         div         ecx
   938         mov         esi,eax
   939         mov         eax,ebx
   940         mul         dword ptr [esp+18h]
   941         mov         ecx,eax
   942         mov         eax,esi
   943         mul         dword ptr [esp+18h]
   944         add         edx,ecx
   945         jmp         L4
   946 L3:
   947         mov         ebx,eax
   948         mov         ecx,dword ptr [esp+18h]
   949         mov         edx,dword ptr [esp+14h]
   950         mov         eax,dword ptr [esp+10h]
   951 L5:
   952         shr         ebx,1
   953         rcr         ecx,1
   954         shr         edx,1
   955         rcr         eax,1
   956         or          ebx,ebx
   957         jne         L5
   958         div         ecx
   959         mov         esi,eax
   960         mul         dword ptr [esp+1Ch]
   961         mov         ecx,eax
   962         mov         eax,dword ptr [esp+18h]
   963         mul         esi
   964         add         edx,ecx
   965         jb          L6
   966         cmp         edx,dword ptr [esp+14h]
   967         ja          L6
   968         jb          L7
   969         cmp         eax,dword ptr [esp+10h]
   970         jbe         L7
   971 L6:
   972         dec         esi
   973         sub         eax,dword ptr [esp+18h]
   974         sbb         edx,dword ptr [esp+1Ch]
   975 L7:
   976         xor         ebx,ebx
   977 L4:
   978         sub         eax,dword ptr [esp+10h]
   979         sbb         edx,dword ptr [esp+14h]
   980         dec         ebp
   981         jns         L9
   982         neg         edx
   983         neg         eax
   984         sbb         edx,0
   985 L9:
   986         mov         ecx,edx
   987         mov         edx,ebx
   988         mov         ebx,ecx
   989         mov         ecx,eax
   990         mov         eax,esi
   991         dec         edi
   992         jne         L8
   993         neg         edx
   994         neg         eax
   995         sbb         edx,0
   996 L8:
   997         pop         ebp
   998         pop         esi
   999         pop         edi
  1000         ret         10h
  1001     }
  1002     /* *INDENT-ON* */
  1003 }
  1004 
  1005 void
  1006 __declspec(naked)
  1007 _aulldvrm()
  1008 {
  1009     /* *INDENT-OFF* */
  1010     __asm {
  1011         push        esi
  1012         mov         eax,dword ptr [esp+14h]
  1013         or          eax,eax
  1014         jne         L1
  1015         mov         ecx,dword ptr [esp+10h]
  1016         mov         eax,dword ptr [esp+0Ch]
  1017         xor         edx,edx
  1018         div         ecx
  1019         mov         ebx,eax
  1020         mov         eax,dword ptr [esp+8]
  1021         div         ecx
  1022         mov         esi,eax
  1023         mov         eax,ebx
  1024         mul         dword ptr [esp+10h]
  1025         mov         ecx,eax
  1026         mov         eax,esi
  1027         mul         dword ptr [esp+10h]
  1028         add         edx,ecx
  1029         jmp         L2
  1030 L1:
  1031         mov         ecx,eax
  1032         mov         ebx,dword ptr [esp+10h]
  1033         mov         edx,dword ptr [esp+0Ch]
  1034         mov         eax,dword ptr [esp+8]
  1035 L3:
  1036         shr         ecx,1
  1037         rcr         ebx,1
  1038         shr         edx,1
  1039         rcr         eax,1
  1040         or          ecx,ecx
  1041         jne         L3
  1042         div         ebx
  1043         mov         esi,eax
  1044         mul         dword ptr [esp+14h]
  1045         mov         ecx,eax
  1046         mov         eax,dword ptr [esp+10h]
  1047         mul         esi
  1048         add         edx,ecx
  1049         jb          L4
  1050         cmp         edx,dword ptr [esp+0Ch]
  1051         ja          L4
  1052         jb          L5
  1053         cmp         eax,dword ptr [esp+8]
  1054         jbe         L5
  1055 L4:
  1056         dec         esi
  1057         sub         eax,dword ptr [esp+10h]
  1058         sbb         edx,dword ptr [esp+14h]
  1059 L5:
  1060         xor         ebx,ebx
  1061 L2:
  1062         sub         eax,dword ptr [esp+8]
  1063         sbb         edx,dword ptr [esp+0Ch]
  1064         neg         edx
  1065         neg         eax
  1066         sbb         edx,0
  1067         mov         ecx,edx
  1068         mov         edx,ebx
  1069         mov         ebx,ecx
  1070         mov         ecx,eax
  1071         mov         eax,esi
  1072         pop         esi
  1073         ret         10h
  1074     }
  1075     /* *INDENT-ON* */
  1076 }
  1077 
  1078 void
  1079 __declspec(naked)
  1080 _allshl()
  1081 {
  1082     /* *INDENT-OFF* */
  1083     __asm {
  1084         cmp         cl,40h
  1085         jae         RETZERO
  1086         cmp         cl,20h
  1087         jae         MORE32
  1088         shld        edx,eax,cl
  1089         shl         eax,cl
  1090         ret
  1091 MORE32:
  1092         mov         edx,eax
  1093         xor         eax,eax
  1094         and         cl,1Fh
  1095         shl         edx,cl
  1096         ret
  1097 RETZERO:
  1098         xor         eax,eax
  1099         xor         edx,edx
  1100         ret
  1101     }
  1102     /* *INDENT-ON* */
  1103 }
  1104 
  1105 void
  1106 __declspec(naked)
  1107 _allshr()
  1108 {
  1109     /* *INDENT-OFF* */
  1110     __asm {
  1111         cmp         cl,3Fh
  1112         jae         RETSIGN
  1113         cmp         cl,20h
  1114         jae         MORE32
  1115         shrd        eax,edx,cl
  1116         sar         edx,cl
  1117         ret
  1118 MORE32:
  1119         mov         eax,edx
  1120         sar         edx,1Fh
  1121         and         cl,1Fh
  1122         sar         eax,cl
  1123         ret
  1124 RETSIGN:
  1125         sar         edx,1Fh
  1126         mov         eax,edx
  1127         ret
  1128     }
  1129     /* *INDENT-ON* */
  1130 }
  1131 
  1132 void
  1133 __declspec(naked)
  1134 _aullshr()
  1135 {
  1136     /* *INDENT-OFF* */
  1137     __asm {
  1138         cmp         cl,40h
  1139         jae         RETZERO
  1140         cmp         cl,20h
  1141         jae         MORE32
  1142         shrd        eax,edx,cl
  1143         shr         edx,cl
  1144         ret
  1145 MORE32:
  1146         mov         eax,edx
  1147         xor         edx,edx
  1148         and         cl,1Fh
  1149         shr         eax,cl
  1150         ret
  1151 RETZERO:
  1152         xor         eax,eax
  1153         xor         edx,edx
  1154         ret
  1155     }
  1156     /* *INDENT-ON* */
  1157 }
  1158 
  1159 #endif /* _M_IX86 */
  1160 
  1161 #endif /* MSC_VER */
  1162 
  1163 #endif /* !HAVE_LIBC */
  1164 
  1165 /* vi: set ts=4 sw=4 expandtab: */