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