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