src/stdlib/SDL_stdlib.c
author David Ludwig <dludwig@pobox.com>
Thu, 28 Nov 2013 22:09:21 -0500
changeset 8543 b9dd3cf38585
parent 8478 337b5dc0797b
parent 8033 8181c3a4a055
child 8583 fb2933ca805f
permissions -rw-r--r--
WinRT: merged with latest SDL 2.x/HG code

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