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