| /* |
| SDL - Simple DirectMedia Layer |
| Copyright (C) 1997-2012 Sam Lantinga |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| |
| Sam Lantinga |
| slouken@libsdl.org |
| */ |
| #include "SDL_config.h" |
| |
| /* This file contains portable stdlib functions for SDL */ |
| |
| #include "SDL_stdinc.h" |
| |
| #ifndef HAVE_LIBC |
| /* These are some C runtime intrinsics that need to be defined */ |
| |
| #if defined(_MSC_VER) |
| |
| #ifndef __FLTUSED__ |
| #define __FLTUSED__ |
| #ifdef __cplusplus |
| extern "C" |
| #endif |
| __declspec(selectany) int _fltused=1; |
| #endif |
| |
| /* Float to long */ |
| void __declspec(naked) _ftol() |
| { |
| __asm { |
| push ebp |
| mov ebp,esp |
| sub esp,20h |
| and esp,0FFFFFFF0h |
| fld st(0) |
| fst dword ptr [esp+18h] |
| fistp qword ptr [esp+10h] |
| fild qword ptr [esp+10h] |
| mov edx,dword ptr [esp+18h] |
| mov eax,dword ptr [esp+10h] |
| test eax,eax |
| je integer_QnaN_or_zero |
| arg_is_not_integer_QnaN: |
| fsubp st(1),st |
| test edx,edx |
| jns positive |
| fstp dword ptr [esp] |
| mov ecx,dword ptr [esp] |
| xor ecx,80000000h |
| add ecx,7FFFFFFFh |
| adc eax,0 |
| mov edx,dword ptr [esp+14h] |
| adc edx,0 |
| jmp localexit |
| positive: |
| fstp dword ptr [esp] |
| mov ecx,dword ptr [esp] |
| add ecx,7FFFFFFFh |
| sbb eax,0 |
| mov edx,dword ptr [esp+14h] |
| sbb edx,0 |
| jmp localexit |
| integer_QnaN_or_zero: |
| mov edx,dword ptr [esp+14h] |
| test edx,7FFFFFFFh |
| jne arg_is_not_integer_QnaN |
| fstp dword ptr [esp+18h] |
| fstp dword ptr [esp+18h] |
| localexit: |
| leave |
| ret |
| } |
| } |
| void __declspec(naked) _ftol2_sse() |
| { |
| _ftol(); |
| } |
| |
| /* 64-bit math operators for 32-bit systems */ |
| void __declspec(naked) _allmul() |
| { |
| __asm { |
| push ebp |
| mov ebp,esp |
| push edi |
| push esi |
| push ebx |
| sub esp,0Ch |
| mov eax,dword ptr [ebp+10h] |
| mov edi,dword ptr [ebp+8] |
| mov ebx,eax |
| mov esi,eax |
| sar esi,1Fh |
| mov eax,dword ptr [ebp+8] |
| mul ebx |
| imul edi,esi |
| mov ecx,edx |
| mov dword ptr [ebp-18h],eax |
| mov edx,dword ptr [ebp+0Ch] |
| add ecx,edi |
| imul ebx,edx |
| mov eax,dword ptr [ebp-18h] |
| lea ebx,[ebx+ecx] |
| mov dword ptr [ebp-14h],ebx |
| mov edx,dword ptr [ebp-14h] |
| add esp,0Ch |
| pop ebx |
| pop esi |
| pop edi |
| pop ebp |
| ret |
| } |
| } |
| void __declspec(naked) _alldiv() |
| { |
| __asm { |
| push edi |
| push esi |
| push ebx |
| xor edi,edi |
| mov eax,dword ptr [esp+14h] |
| or eax,eax |
| jge L1 |
| inc edi |
| mov edx,dword ptr [esp+10h] |
| neg eax |
| neg edx |
| sbb eax,0 |
| mov dword ptr [esp+14h],eax |
| mov dword ptr [esp+10h],edx |
| L1: |
| mov eax,dword ptr [esp+1Ch] |
| or eax,eax |
| jge L2 |
| inc edi |
| mov edx,dword ptr [esp+18h] |
| neg eax |
| neg edx |
| sbb eax,0 |
| mov dword ptr [esp+1Ch],eax |
| mov dword ptr [esp+18h],edx |
| L2: |
| or eax,eax |
| jne L3 |
| mov ecx,dword ptr [esp+18h] |
| mov eax,dword ptr [esp+14h] |
| xor edx,edx |
| div ecx |
| mov ebx,eax |
| mov eax,dword ptr [esp+10h] |
| div ecx |
| mov edx,ebx |
| jmp L4 |
| L3: |
| mov ebx,eax |
| mov ecx,dword ptr [esp+18h] |
| mov edx,dword ptr [esp+14h] |
| mov eax,dword ptr [esp+10h] |
| L5: |
| shr ebx,1 |
| rcr ecx,1 |
| shr edx,1 |
| rcr eax,1 |
| or ebx,ebx |
| jne L5 |
| div ecx |
| mov esi,eax |
| mul dword ptr [esp+1Ch] |
| mov ecx,eax |
| mov eax,dword ptr [esp+18h] |
| mul esi |
| add edx,ecx |
| jb L6 |
| cmp edx,dword ptr [esp+14h] |
| ja L6 |
| jb L7 |
| cmp eax,dword ptr [esp+10h] |
| jbe L7 |
| L6: |
| dec esi |
| L7: |
| xor edx,edx |
| mov eax,esi |
| L4: |
| dec edi |
| jne L8 |
| neg edx |
| neg eax |
| sbb edx,0 |
| L8: |
| pop ebx |
| pop esi |
| pop edi |
| ret 10h |
| } |
| } |
| void __declspec(naked) _aulldiv() |
| { |
| __asm { |
| push ebx |
| push esi |
| mov eax,dword ptr [esp+18h] |
| or eax,eax |
| jne L1 |
| mov ecx,dword ptr [esp+14h] |
| mov eax,dword ptr [esp+10h] |
| xor edx,edx |
| div ecx |
| mov ebx,eax |
| mov eax,dword ptr [esp+0Ch] |
| div ecx |
| mov edx,ebx |
| jmp L2 |
| L1: |
| mov ecx,eax |
| mov ebx,dword ptr [esp+14h] |
| mov edx,dword ptr [esp+10h] |
| mov eax,dword ptr [esp+0Ch] |
| L3: |
| shr ecx,1 |
| rcr ebx,1 |
| shr edx,1 |
| rcr eax,1 |
| or ecx,ecx |
| jne L3 |
| div ebx |
| mov esi,eax |
| mul dword ptr [esp+18h] |
| mov ecx,eax |
| mov eax,dword ptr [esp+14h] |
| mul esi |
| add edx,ecx |
| jb L4 |
| cmp edx,dword ptr [esp+10h] |
| ja L4 |
| jb L5 |
| cmp eax,dword ptr [esp+0Ch] |
| jbe L5 |
| L4: |
| dec esi |
| L5: |
| xor edx,edx |
| mov eax,esi |
| L2: |
| pop esi |
| pop ebx |
| ret 10h |
| } |
| } |
| void __declspec(naked) _allrem() |
| { |
| __asm { |
| push ebx |
| push edi |
| xor edi,edi |
| mov eax,dword ptr [esp+10h] |
| or eax,eax |
| jge L1 |
| inc edi |
| mov edx,dword ptr [esp+0Ch] |
| neg eax |
| neg edx |
| sbb eax,0 |
| mov dword ptr [esp+10h],eax |
| mov dword ptr [esp+0Ch],edx |
| L1: |
| mov eax,dword ptr [esp+18h] |
| or eax,eax |
| jge L2 |
| mov edx,dword ptr [esp+14h] |
| neg eax |
| neg edx |
| sbb eax,0 |
| mov dword ptr [esp+18h],eax |
| mov dword ptr [esp+14h],edx |
| L2: |
| or eax,eax |
| jne L3 |
| mov ecx,dword ptr [esp+14h] |
| mov eax,dword ptr [esp+10h] |
| xor edx,edx |
| div ecx |
| mov eax,dword ptr [esp+0Ch] |
| div ecx |
| mov eax,edx |
| xor edx,edx |
| dec edi |
| jns L4 |
| jmp L8 |
| L3: |
| mov ebx,eax |
| mov ecx,dword ptr [esp+14h] |
| mov edx,dword ptr [esp+10h] |
| mov eax,dword ptr [esp+0Ch] |
| L5: |
| shr ebx,1 |
| rcr ecx,1 |
| shr edx,1 |
| rcr eax,1 |
| or ebx,ebx |
| jne L5 |
| div ecx |
| mov ecx,eax |
| mul dword ptr [esp+18h] |
| xchg eax,ecx |
| mul dword ptr [esp+14h] |
| add edx,ecx |
| jb L6 |
| cmp edx,dword ptr [esp+10h] |
| ja L6 |
| jb L7 |
| cmp eax,dword ptr [esp+0Ch] |
| jbe L7 |
| L6: |
| sub eax,dword ptr [esp+14h] |
| sbb edx,dword ptr [esp+18h] |
| L7: |
| sub eax,dword ptr [esp+0Ch] |
| sbb edx,dword ptr [esp+10h] |
| dec edi |
| jns L8 |
| L4: |
| neg edx |
| neg eax |
| sbb edx,0 |
| L8: |
| pop edi |
| pop ebx |
| ret 10h |
| } |
| } |
| void __declspec(naked) _aullrem() |
| { |
| __asm { |
| push ebx |
| mov eax,dword ptr [esp+14h] |
| or eax,eax |
| jne L1 |
| mov ecx,dword ptr [esp+10h] |
| mov eax,dword ptr [esp+0Ch] |
| xor edx,edx |
| div ecx |
| mov eax,dword ptr [esp+8] |
| div ecx |
| mov eax,edx |
| xor edx,edx |
| jmp L2 |
| L1: |
| mov ecx,eax |
| mov ebx,dword ptr [esp+10h] |
| mov edx,dword ptr [esp+0Ch] |
| mov eax,dword ptr [esp+8] |
| L3: |
| shr ecx,1 |
| rcr ebx,1 |
| shr edx,1 |
| rcr eax,1 |
| or ecx,ecx |
| jne L3 |
| div ebx |
| mov ecx,eax |
| mul dword ptr [esp+14h] |
| xchg eax,ecx |
| mul dword ptr [esp+10h] |
| add edx,ecx |
| jb L4 |
| cmp edx,dword ptr [esp+0Ch] |
| ja L4 |
| jb L5 |
| cmp eax,dword ptr [esp+8] |
| jbe L5 |
| L4: |
| sub eax,dword ptr [esp+10h] |
| sbb edx,dword ptr [esp+14h] |
| L5: |
| sub eax,dword ptr [esp+8] |
| sbb edx,dword ptr [esp+0Ch] |
| neg edx |
| neg eax |
| sbb edx,0 |
| L2: |
| pop ebx |
| ret 10h |
| } |
| } |
| void __declspec(naked) _alldvrm() |
| { |
| __asm { |
| push edi |
| push esi |
| push ebp |
| xor edi,edi |
| xor ebp,ebp |
| mov eax,dword ptr [esp+14h] |
| or eax,eax |
| jge L1 |
| inc edi |
| inc ebp |
| mov edx,dword ptr [esp+10h] |
| neg eax |
| neg edx |
| sbb eax,0 |
| mov dword ptr [esp+14h],eax |
| mov dword ptr [esp+10h],edx |
| L1: |
| mov eax,dword ptr [esp+1Ch] |
| or eax,eax |
| jge L2 |
| inc edi |
| mov edx,dword ptr [esp+18h] |
| neg eax |
| neg edx |
| sbb eax,0 |
| mov dword ptr [esp+1Ch],eax |
| mov dword ptr [esp+18h],edx |
| L2: |
| or eax,eax |
| jne L3 |
| mov ecx,dword ptr [esp+18h] |
| mov eax,dword ptr [esp+14h] |
| xor edx,edx |
| div ecx |
| mov ebx,eax |
| mov eax,dword ptr [esp+10h] |
| div ecx |
| mov esi,eax |
| mov eax,ebx |
| mul dword ptr [esp+18h] |
| mov ecx,eax |
| mov eax,esi |
| mul dword ptr [esp+18h] |
| add edx,ecx |
| jmp L4 |
| L3: |
| mov ebx,eax |
| mov ecx,dword ptr [esp+18h] |
| mov edx,dword ptr [esp+14h] |
| mov eax,dword ptr [esp+10h] |
| L5: |
| shr ebx,1 |
| rcr ecx,1 |
| shr edx,1 |
| rcr eax,1 |
| or ebx,ebx |
| jne L5 |
| div ecx |
| mov esi,eax |
| mul dword ptr [esp+1Ch] |
| mov ecx,eax |
| mov eax,dword ptr [esp+18h] |
| mul esi |
| add edx,ecx |
| jb L6 |
| cmp edx,dword ptr [esp+14h] |
| ja L6 |
| jb L7 |
| cmp eax,dword ptr [esp+10h] |
| jbe L7 |
| L6: |
| dec esi |
| sub eax,dword ptr [esp+18h] |
| sbb edx,dword ptr [esp+1Ch] |
| L7: |
| xor ebx,ebx |
| L4: |
| sub eax,dword ptr [esp+10h] |
| sbb edx,dword ptr [esp+14h] |
| dec ebp |
| jns L9 |
| neg edx |
| neg eax |
| sbb edx,0 |
| L9: |
| mov ecx,edx |
| mov edx,ebx |
| mov ebx,ecx |
| mov ecx,eax |
| mov eax,esi |
| dec edi |
| jne L8 |
| neg edx |
| neg eax |
| sbb edx,0 |
| L8: |
| pop ebp |
| pop esi |
| pop edi |
| ret 10h |
| } |
| } |
| void __declspec(naked) _aulldvrm() |
| { |
| __asm { |
| push esi |
| mov eax,dword ptr [esp+14h] |
| or eax,eax |
| jne L1 |
| mov ecx,dword ptr [esp+10h] |
| mov eax,dword ptr [esp+0Ch] |
| xor edx,edx |
| div ecx |
| mov ebx,eax |
| mov eax,dword ptr [esp+8] |
| div ecx |
| mov esi,eax |
| mov eax,ebx |
| mul dword ptr [esp+10h] |
| mov ecx,eax |
| mov eax,esi |
| mul dword ptr [esp+10h] |
| add edx,ecx |
| jmp L2 |
| L1: |
| mov ecx,eax |
| mov ebx,dword ptr [esp+10h] |
| mov edx,dword ptr [esp+0Ch] |
| mov eax,dword ptr [esp+8] |
| L3: |
| shr ecx,1 |
| rcr ebx,1 |
| shr edx,1 |
| rcr eax,1 |
| or ecx,ecx |
| jne L3 |
| div ebx |
| mov esi,eax |
| mul dword ptr [esp+14h] |
| mov ecx,eax |
| mov eax,dword ptr [esp+10h] |
| mul esi |
| add edx,ecx |
| jb L4 |
| cmp edx,dword ptr [esp+0Ch] |
| ja L4 |
| jb L5 |
| cmp eax,dword ptr [esp+8] |
| jbe L5 |
| L4: |
| dec esi |
| sub eax,dword ptr [esp+10h] |
| sbb edx,dword ptr [esp+14h] |
| L5: |
| xor ebx,ebx |
| L2: |
| sub eax,dword ptr [esp+8] |
| sbb edx,dword ptr [esp+0Ch] |
| neg edx |
| neg eax |
| sbb edx,0 |
| mov ecx,edx |
| mov edx,ebx |
| mov ebx,ecx |
| mov ecx,eax |
| mov eax,esi |
| pop esi |
| ret 10h |
| } |
| } |
| void __declspec(naked) _allshl() |
| { |
| __asm { |
| cmp cl,40h |
| jae RETZERO |
| cmp cl,20h |
| jae MORE32 |
| shld edx,eax,cl |
| shl eax,cl |
| ret |
| MORE32: |
| mov edx,eax |
| xor eax,eax |
| and cl,1Fh |
| shl edx,cl |
| ret |
| RETZERO: |
| xor eax,eax |
| xor edx,edx |
| ret |
| } |
| } |
| void __declspec(naked) _aullshr() |
| { |
| __asm { |
| cmp cl,40h |
| jae RETZERO |
| cmp cl,20h |
| jae MORE32 |
| shrd eax,edx,cl |
| shr edx,cl |
| ret |
| MORE32: |
| mov eax,edx |
| xor edx,edx |
| and cl,1Fh |
| shr eax,cl |
| ret |
| RETZERO: |
| xor eax,eax |
| xor edx,edx |
| ret |
| } |
| } |
| |
| #endif /* MSC_VER */ |
| |
| #endif /* !HAVE_LIBC */ |