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