src/stdlib/SDL_stdlib.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 08 Apr 2011 13:03:26 -0700
changeset 5535 96594ac5fd1a
parent 5455 5fbf5fc81aa8
child 6138 4c64952a58fb
permissions -rw-r--r--
SDL 1.3 is now under the zlib license.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2011 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 
    27 #ifndef HAVE_LIBC
    28 /* These are some C runtime intrinsics that need to be defined */
    29 
    30 #if defined(_MSC_VER)
    31 
    32 #ifndef __FLTUSED__
    33 #define __FLTUSED__
    34 __declspec(selectany) int _fltused = 1;
    35 #endif
    36 
    37 /* The optimizer on Visual Studio 2010 generates memcpy() calls */
    38 #if _MSC_VER == 1600 && defined(_WIN64) && !defined(_DEBUG)
    39 #include <intrin.h>
    40 
    41 #pragma function(memcpy)
    42 void * memcpy ( void * destination, const void * source, size_t num )
    43 {
    44     const Uint8 *src = (const Uint8 *)source;
    45     Uint8 *dst = (Uint8 *)destination;
    46     size_t i;
    47     
    48     /* All WIN64 architectures have SSE, right? */
    49     if (!((uintptr_t) src & 15) && !((uintptr_t) dst & 15)) {
    50         __m128 values[4];
    51         for (i = num / 64; i--;) {
    52             _mm_prefetch(src, _MM_HINT_NTA);
    53             values[0] = *(__m128 *) (src + 0);
    54             values[1] = *(__m128 *) (src + 16);
    55             values[2] = *(__m128 *) (src + 32);
    56             values[3] = *(__m128 *) (src + 48);
    57             _mm_stream_ps((float *) (dst + 0), values[0]);
    58             _mm_stream_ps((float *) (dst + 16), values[1]);
    59             _mm_stream_ps((float *) (dst + 32), values[2]);
    60             _mm_stream_ps((float *) (dst + 48), values[3]);
    61             src += 64;
    62             dst += 64;
    63         }
    64         num &= 63;
    65     }
    66 
    67     while (num--) {
    68         *dst++ = *src++;
    69     }
    70     return destination;
    71 }
    72 #endif /* _MSC_VER == 1600 && defined(_WIN64) && !defined(_DEBUG) */
    73 
    74 #ifdef _M_IX86
    75 
    76 void
    77 __declspec(naked)
    78 _chkstk()
    79 {
    80 }
    81 
    82 /* Float to long */
    83 void
    84 __declspec(naked)
    85 _ftol()
    86 {
    87     /* *INDENT-OFF* */
    88     __asm {
    89         push        ebp
    90         mov         ebp,esp
    91         sub         esp,20h
    92         and         esp,0FFFFFFF0h
    93         fld         st(0)
    94         fst         dword ptr [esp+18h]
    95         fistp       qword ptr [esp+10h]
    96         fild        qword ptr [esp+10h]
    97         mov         edx,dword ptr [esp+18h]
    98         mov         eax,dword ptr [esp+10h]
    99         test        eax,eax
   100         je          integer_QnaN_or_zero
   101 arg_is_not_integer_QnaN:
   102         fsubp       st(1),st
   103         test        edx,edx
   104         jns         positive
   105         fstp        dword ptr [esp]
   106         mov         ecx,dword ptr [esp]
   107         xor         ecx,80000000h
   108         add         ecx,7FFFFFFFh
   109         adc         eax,0
   110         mov         edx,dword ptr [esp+14h]
   111         adc         edx,0
   112         jmp         localexit
   113 positive:
   114         fstp        dword ptr [esp]
   115         mov         ecx,dword ptr [esp]
   116         add         ecx,7FFFFFFFh
   117         sbb         eax,0
   118         mov         edx,dword ptr [esp+14h]
   119         sbb         edx,0
   120         jmp         localexit
   121 integer_QnaN_or_zero:
   122         mov         edx,dword ptr [esp+14h]
   123         test        edx,7FFFFFFFh
   124         jne         arg_is_not_integer_QnaN
   125         fstp        dword ptr [esp+18h]
   126         fstp        dword ptr [esp+18h]
   127 localexit:
   128         leave
   129         ret
   130     }
   131     /* *INDENT-ON* */
   132 }
   133 
   134 void
   135 _ftol2_sse()
   136 {
   137     _ftol();
   138 }
   139 
   140 /* 64-bit math operators for 32-bit systems */
   141 void
   142 __declspec(naked)
   143 _allmul()
   144 {
   145     /* *INDENT-OFF* */
   146     __asm {
   147         push        ebp
   148         mov         ebp,esp
   149         push        edi
   150         push        esi
   151         push        ebx
   152         sub         esp,0Ch
   153         mov         eax,dword ptr [ebp+10h]
   154         mov         edi,dword ptr [ebp+8]
   155         mov         ebx,eax
   156         mov         esi,eax
   157         sar         esi,1Fh
   158         mov         eax,dword ptr [ebp+8]
   159         mul         ebx
   160         imul        edi,esi
   161         mov         ecx,edx
   162         mov         dword ptr [ebp-18h],eax
   163         mov         edx,dword ptr [ebp+0Ch]
   164         add         ecx,edi
   165         imul        ebx,edx
   166         mov         eax,dword ptr [ebp-18h]
   167         lea         ebx,[ebx+ecx]
   168         mov         dword ptr [ebp-14h],ebx
   169         mov         edx,dword ptr [ebp-14h]
   170         add         esp,0Ch
   171         pop         ebx
   172         pop         esi
   173         pop         edi
   174         pop         ebp
   175         ret
   176     }
   177     /* *INDENT-ON* */
   178 }
   179 
   180 void
   181 __declspec(naked)
   182 _alldiv()
   183 {
   184     /* *INDENT-OFF* */
   185     __asm {
   186         push        edi
   187         push        esi
   188         push        ebx
   189         xor         edi,edi
   190         mov         eax,dword ptr [esp+14h]
   191         or          eax,eax
   192         jge         L1
   193         inc         edi
   194         mov         edx,dword ptr [esp+10h]
   195         neg         eax
   196         neg         edx
   197         sbb         eax,0
   198         mov         dword ptr [esp+14h],eax
   199         mov         dword ptr [esp+10h],edx
   200 L1:
   201         mov         eax,dword ptr [esp+1Ch]
   202         or          eax,eax
   203         jge         L2
   204         inc         edi
   205         mov         edx,dword ptr [esp+18h]
   206         neg         eax
   207         neg         edx
   208         sbb         eax,0
   209         mov         dword ptr [esp+1Ch],eax
   210         mov         dword ptr [esp+18h],edx
   211 L2:
   212         or          eax,eax
   213         jne         L3
   214         mov         ecx,dword ptr [esp+18h]
   215         mov         eax,dword ptr [esp+14h]
   216         xor         edx,edx
   217         div         ecx
   218         mov         ebx,eax
   219         mov         eax,dword ptr [esp+10h]
   220         div         ecx
   221         mov         edx,ebx
   222         jmp         L4
   223 L3:
   224         mov         ebx,eax
   225         mov         ecx,dword ptr [esp+18h]
   226         mov         edx,dword ptr [esp+14h]
   227         mov         eax,dword ptr [esp+10h]
   228 L5:
   229         shr         ebx,1
   230         rcr         ecx,1
   231         shr         edx,1
   232         rcr         eax,1
   233         or          ebx,ebx
   234         jne         L5
   235         div         ecx
   236         mov         esi,eax
   237         mul         dword ptr [esp+1Ch]
   238         mov         ecx,eax
   239         mov         eax,dword ptr [esp+18h]
   240         mul         esi
   241         add         edx,ecx
   242         jb          L6
   243         cmp         edx,dword ptr [esp+14h]
   244         ja          L6
   245         jb          L7
   246         cmp         eax,dword ptr [esp+10h]
   247         jbe         L7
   248 L6:
   249         dec         esi
   250 L7:
   251         xor         edx,edx
   252         mov         eax,esi
   253 L4:
   254         dec         edi
   255         jne         L8
   256         neg         edx
   257         neg         eax
   258         sbb         edx,0
   259 L8:
   260         pop         ebx
   261         pop         esi
   262         pop         edi
   263         ret         10h
   264     }
   265     /* *INDENT-ON* */
   266 }
   267 
   268 void
   269 __declspec(naked)
   270 _aulldiv()
   271 {
   272     /* *INDENT-OFF* */
   273     __asm {
   274         push        ebx
   275         push        esi
   276         mov         eax,dword ptr [esp+18h]
   277         or          eax,eax
   278         jne         L1
   279         mov         ecx,dword ptr [esp+14h]
   280         mov         eax,dword ptr [esp+10h]
   281         xor         edx,edx
   282         div         ecx
   283         mov         ebx,eax
   284         mov         eax,dword ptr [esp+0Ch]
   285         div         ecx
   286         mov         edx,ebx
   287         jmp         L2
   288 L1:
   289         mov         ecx,eax
   290         mov         ebx,dword ptr [esp+14h]
   291         mov         edx,dword ptr [esp+10h]
   292         mov         eax,dword ptr [esp+0Ch]
   293 L3:
   294         shr         ecx,1
   295         rcr         ebx,1
   296         shr         edx,1
   297         rcr         eax,1
   298         or          ecx,ecx
   299         jne         L3
   300         div         ebx
   301         mov         esi,eax
   302         mul         dword ptr [esp+18h]
   303         mov         ecx,eax
   304         mov         eax,dword ptr [esp+14h]
   305         mul         esi
   306         add         edx,ecx
   307         jb          L4
   308         cmp         edx,dword ptr [esp+10h]
   309         ja          L4
   310         jb          L5
   311         cmp         eax,dword ptr [esp+0Ch]
   312         jbe         L5
   313 L4:
   314         dec         esi
   315 L5:
   316         xor         edx,edx
   317         mov         eax,esi
   318 L2:
   319         pop         esi
   320         pop         ebx
   321         ret         10h
   322     }
   323     /* *INDENT-ON* */
   324 }
   325 
   326 void
   327 __declspec(naked)
   328 _allrem()
   329 {
   330     /* *INDENT-OFF* */
   331     __asm {
   332         push        ebx
   333         push        edi
   334         xor         edi,edi
   335         mov         eax,dword ptr [esp+10h]
   336         or          eax,eax
   337         jge         L1
   338         inc         edi
   339         mov         edx,dword ptr [esp+0Ch]
   340         neg         eax
   341         neg         edx
   342         sbb         eax,0
   343         mov         dword ptr [esp+10h],eax
   344         mov         dword ptr [esp+0Ch],edx
   345 L1:
   346         mov         eax,dword ptr [esp+18h]
   347         or          eax,eax
   348         jge         L2
   349         mov         edx,dword ptr [esp+14h]
   350         neg         eax
   351         neg         edx
   352         sbb         eax,0
   353         mov         dword ptr [esp+18h],eax
   354         mov         dword ptr [esp+14h],edx
   355 L2:
   356         or          eax,eax
   357         jne         L3
   358         mov         ecx,dword ptr [esp+14h]
   359         mov         eax,dword ptr [esp+10h]
   360         xor         edx,edx
   361         div         ecx
   362         mov         eax,dword ptr [esp+0Ch]
   363         div         ecx
   364         mov         eax,edx
   365         xor         edx,edx
   366         dec         edi
   367         jns         L4
   368         jmp         L8
   369 L3:
   370         mov         ebx,eax
   371         mov         ecx,dword ptr [esp+14h]
   372         mov         edx,dword ptr [esp+10h]
   373         mov         eax,dword ptr [esp+0Ch]
   374 L5:
   375         shr         ebx,1
   376         rcr         ecx,1
   377         shr         edx,1
   378         rcr         eax,1
   379         or          ebx,ebx
   380         jne         L5
   381         div         ecx
   382         mov         ecx,eax
   383         mul         dword ptr [esp+18h]
   384         xchg        eax,ecx
   385         mul         dword ptr [esp+14h]
   386         add         edx,ecx
   387         jb          L6
   388         cmp         edx,dword ptr [esp+10h]
   389         ja          L6
   390         jb          L7
   391         cmp         eax,dword ptr [esp+0Ch]
   392         jbe         L7
   393 L6:
   394         sub         eax,dword ptr [esp+14h]
   395         sbb         edx,dword ptr [esp+18h]
   396 L7:
   397         sub         eax,dword ptr [esp+0Ch]
   398         sbb         edx,dword ptr [esp+10h]
   399         dec         edi
   400         jns         L8
   401 L4:
   402         neg         edx
   403         neg         eax
   404         sbb         edx,0
   405 L8:
   406         pop         edi
   407         pop         ebx
   408         ret         10h
   409     }
   410     /* *INDENT-ON* */
   411 }
   412 
   413 void
   414 __declspec(naked)
   415 _aullrem()
   416 {
   417     /* *INDENT-OFF* */
   418     __asm {
   419         push        ebx
   420         mov         eax,dword ptr [esp+14h]
   421         or          eax,eax
   422         jne         L1
   423         mov         ecx,dword ptr [esp+10h]
   424         mov         eax,dword ptr [esp+0Ch]
   425         xor         edx,edx
   426         div         ecx
   427         mov         eax,dword ptr [esp+8]
   428         div         ecx
   429         mov         eax,edx
   430         xor         edx,edx
   431         jmp         L2
   432 L1:
   433         mov         ecx,eax
   434         mov         ebx,dword ptr [esp+10h]
   435         mov         edx,dword ptr [esp+0Ch]
   436         mov         eax,dword ptr [esp+8]
   437 L3:
   438         shr         ecx,1
   439         rcr         ebx,1
   440         shr         edx,1
   441         rcr         eax,1
   442         or          ecx,ecx
   443         jne         L3
   444         div         ebx
   445         mov         ecx,eax
   446         mul         dword ptr [esp+14h]
   447         xchg        eax,ecx
   448         mul         dword ptr [esp+10h]
   449         add         edx,ecx
   450         jb          L4
   451         cmp         edx,dword ptr [esp+0Ch]
   452         ja          L4
   453         jb          L5
   454         cmp         eax,dword ptr [esp+8]
   455         jbe         L5
   456 L4:
   457         sub         eax,dword ptr [esp+10h]
   458         sbb         edx,dword ptr [esp+14h]
   459 L5:
   460         sub         eax,dword ptr [esp+8]
   461         sbb         edx,dword ptr [esp+0Ch]
   462         neg         edx
   463         neg         eax
   464         sbb         edx,0
   465 L2:
   466         pop         ebx
   467         ret         10h
   468     }
   469     /* *INDENT-ON* */
   470 }
   471 
   472 void
   473 __declspec(naked)
   474 _alldvrm()
   475 {
   476     /* *INDENT-OFF* */
   477     __asm {
   478         push        edi
   479         push        esi
   480         push        ebp
   481         xor         edi,edi
   482         xor         ebp,ebp
   483         mov         eax,dword ptr [esp+14h]
   484         or          eax,eax
   485         jge         L1
   486         inc         edi
   487         inc         ebp
   488         mov         edx,dword ptr [esp+10h]
   489         neg         eax
   490         neg         edx
   491         sbb         eax,0
   492         mov         dword ptr [esp+14h],eax
   493         mov         dword ptr [esp+10h],edx
   494 L1:
   495         mov         eax,dword ptr [esp+1Ch]
   496         or          eax,eax
   497         jge         L2
   498         inc         edi
   499         mov         edx,dword ptr [esp+18h]
   500         neg         eax
   501         neg         edx
   502         sbb         eax,0
   503         mov         dword ptr [esp+1Ch],eax
   504         mov         dword ptr [esp+18h],edx
   505 L2:
   506         or          eax,eax
   507         jne         L3
   508         mov         ecx,dword ptr [esp+18h]
   509         mov         eax,dword ptr [esp+14h]
   510         xor         edx,edx
   511         div         ecx
   512         mov         ebx,eax
   513         mov         eax,dword ptr [esp+10h]
   514         div         ecx
   515         mov         esi,eax
   516         mov         eax,ebx
   517         mul         dword ptr [esp+18h]
   518         mov         ecx,eax
   519         mov         eax,esi
   520         mul         dword ptr [esp+18h]
   521         add         edx,ecx
   522         jmp         L4
   523 L3:
   524         mov         ebx,eax
   525         mov         ecx,dword ptr [esp+18h]
   526         mov         edx,dword ptr [esp+14h]
   527         mov         eax,dword ptr [esp+10h]
   528 L5:
   529         shr         ebx,1
   530         rcr         ecx,1
   531         shr         edx,1
   532         rcr         eax,1
   533         or          ebx,ebx
   534         jne         L5
   535         div         ecx
   536         mov         esi,eax
   537         mul         dword ptr [esp+1Ch]
   538         mov         ecx,eax
   539         mov         eax,dword ptr [esp+18h]
   540         mul         esi
   541         add         edx,ecx
   542         jb          L6
   543         cmp         edx,dword ptr [esp+14h]
   544         ja          L6
   545         jb          L7
   546         cmp         eax,dword ptr [esp+10h]
   547         jbe         L7
   548 L6:
   549         dec         esi
   550         sub         eax,dword ptr [esp+18h]
   551         sbb         edx,dword ptr [esp+1Ch]
   552 L7:
   553         xor         ebx,ebx
   554 L4:
   555         sub         eax,dword ptr [esp+10h]
   556         sbb         edx,dword ptr [esp+14h]
   557         dec         ebp
   558         jns         L9
   559         neg         edx
   560         neg         eax
   561         sbb         edx,0
   562 L9:
   563         mov         ecx,edx
   564         mov         edx,ebx
   565         mov         ebx,ecx
   566         mov         ecx,eax
   567         mov         eax,esi
   568         dec         edi
   569         jne         L8
   570         neg         edx
   571         neg         eax
   572         sbb         edx,0
   573 L8:
   574         pop         ebp
   575         pop         esi
   576         pop         edi
   577         ret         10h
   578     }
   579     /* *INDENT-ON* */
   580 }
   581 
   582 void
   583 __declspec(naked)
   584 _aulldvrm()
   585 {
   586     /* *INDENT-OFF* */
   587     __asm {
   588         push        esi
   589         mov         eax,dword ptr [esp+14h]
   590         or          eax,eax
   591         jne         L1
   592         mov         ecx,dword ptr [esp+10h]
   593         mov         eax,dword ptr [esp+0Ch]
   594         xor         edx,edx
   595         div         ecx
   596         mov         ebx,eax
   597         mov         eax,dword ptr [esp+8]
   598         div         ecx
   599         mov         esi,eax
   600         mov         eax,ebx
   601         mul         dword ptr [esp+10h]
   602         mov         ecx,eax
   603         mov         eax,esi
   604         mul         dword ptr [esp+10h]
   605         add         edx,ecx
   606         jmp         L2
   607 L1:
   608         mov         ecx,eax
   609         mov         ebx,dword ptr [esp+10h]
   610         mov         edx,dword ptr [esp+0Ch]
   611         mov         eax,dword ptr [esp+8]
   612 L3:
   613         shr         ecx,1
   614         rcr         ebx,1
   615         shr         edx,1
   616         rcr         eax,1
   617         or          ecx,ecx
   618         jne         L3
   619         div         ebx
   620         mov         esi,eax
   621         mul         dword ptr [esp+14h]
   622         mov         ecx,eax
   623         mov         eax,dword ptr [esp+10h]
   624         mul         esi
   625         add         edx,ecx
   626         jb          L4
   627         cmp         edx,dword ptr [esp+0Ch]
   628         ja          L4
   629         jb          L5
   630         cmp         eax,dword ptr [esp+8]
   631         jbe         L5
   632 L4:
   633         dec         esi
   634         sub         eax,dword ptr [esp+10h]
   635         sbb         edx,dword ptr [esp+14h]
   636 L5:
   637         xor         ebx,ebx
   638 L2:
   639         sub         eax,dword ptr [esp+8]
   640         sbb         edx,dword ptr [esp+0Ch]
   641         neg         edx
   642         neg         eax
   643         sbb         edx,0
   644         mov         ecx,edx
   645         mov         edx,ebx
   646         mov         ebx,ecx
   647         mov         ecx,eax
   648         mov         eax,esi
   649         pop         esi
   650         ret         10h
   651     }
   652     /* *INDENT-ON* */
   653 }
   654 
   655 void
   656 __declspec(naked)
   657 _allshl()
   658 {
   659     /* *INDENT-OFF* */
   660     __asm {
   661         cmp         cl,40h
   662         jae         RETZERO
   663         cmp         cl,20h
   664         jae         MORE32
   665         shld        edx,eax,cl
   666         shl         eax,cl
   667         ret
   668 MORE32:
   669         mov         edx,eax
   670         xor         eax,eax
   671         and         cl,1Fh
   672         shl         edx,cl
   673         ret
   674 RETZERO:
   675         xor         eax,eax
   676         xor         edx,edx
   677         ret
   678     }
   679     /* *INDENT-ON* */
   680 }
   681 
   682 void
   683 __declspec(naked)
   684 _allshr()
   685 {
   686     /* *INDENT-OFF* */
   687     __asm {
   688         cmp         cl,40h
   689         jae         RETZERO
   690         cmp         cl,20h
   691         jae         MORE32
   692         shrd        eax,edx,cl
   693         sar         edx,cl
   694         ret
   695 MORE32:
   696         mov         eax,edx
   697         xor         edx,edx
   698         and         cl,1Fh
   699         sar         eax,cl
   700         ret
   701 RETZERO:
   702         xor         eax,eax
   703         xor         edx,edx
   704         ret
   705     }
   706     /* *INDENT-ON* */
   707 }
   708 
   709 void
   710 __declspec(naked)
   711 _aullshr()
   712 {
   713     /* *INDENT-OFF* */
   714     __asm {
   715         cmp         cl,40h
   716         jae         RETZERO
   717         cmp         cl,20h
   718         jae         MORE32
   719         shrd        eax,edx,cl
   720         shr         edx,cl
   721         ret
   722 MORE32:
   723         mov         eax,edx
   724         xor         edx,edx
   725         and         cl,1Fh
   726         shr         eax,cl
   727         ret
   728 RETZERO:
   729         xor         eax,eax
   730         xor         edx,edx
   731         ret
   732     }
   733     /* *INDENT-ON* */
   734 }
   735 
   736 #endif /* _M_IX86 */
   737 
   738 #endif /* MSC_VER */
   739 
   740 #endif /* !HAVE_LIBC */
   741 
   742 /* vi: set ts=4 sw=4 expandtab: */