1/*
2    SDL - Simple DirectMedia Layer
3    Copyright (C) 1997-2012 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#ifdef __cplusplus
36   extern "C"
37#endif
38	   __declspec(selectany) int _fltused=1;
39#endif
40
41/* Float to long */
42void __declspec(naked) _ftol()
43{
44	__asm {
45		push        ebp
46		mov         ebp,esp
47		sub         esp,20h
48		and         esp,0FFFFFFF0h
49		fld         st(0)
50		fst         dword ptr [esp+18h]
51		fistp       qword ptr [esp+10h]
52		fild        qword ptr [esp+10h]
53		mov         edx,dword ptr [esp+18h]
54		mov         eax,dword ptr [esp+10h]
55		test        eax,eax
56		je          integer_QnaN_or_zero
57arg_is_not_integer_QnaN:
58		fsubp       st(1),st
59		test        edx,edx
60		jns         positive
61		fstp        dword ptr [esp]
62		mov         ecx,dword ptr [esp]
63		xor         ecx,80000000h
64		add         ecx,7FFFFFFFh
65		adc         eax,0
66		mov         edx,dword ptr [esp+14h]
67		adc         edx,0
68		jmp         localexit
69positive:
70		fstp        dword ptr [esp]
71		mov         ecx,dword ptr [esp]
72		add         ecx,7FFFFFFFh
73		sbb         eax,0
74		mov         edx,dword ptr [esp+14h]
75		sbb         edx,0
76		jmp         localexit
77integer_QnaN_or_zero:
78		mov         edx,dword ptr [esp+14h]
79		test        edx,7FFFFFFFh
80		jne         arg_is_not_integer_QnaN
81		fstp        dword ptr [esp+18h]
82		fstp        dword ptr [esp+18h]
83localexit:
84		leave
85		ret
86	}
87}
88void __declspec(naked) _ftol2_sse()
89{
90	_ftol();
91}
92
93/* 64-bit math operators for 32-bit systems */
94void __declspec(naked) _allmul()
95{
96	__asm {
97		push        ebp
98		mov         ebp,esp
99		push        edi
100		push        esi
101		push        ebx
102		sub         esp,0Ch
103		mov         eax,dword ptr [ebp+10h]
104		mov         edi,dword ptr [ebp+8]
105		mov         ebx,eax
106		mov         esi,eax
107		sar         esi,1Fh
108		mov         eax,dword ptr [ebp+8]
109		mul         ebx
110		imul        edi,esi
111		mov         ecx,edx
112		mov         dword ptr [ebp-18h],eax
113		mov         edx,dword ptr [ebp+0Ch]
114		add         ecx,edi
115		imul        ebx,edx
116		mov         eax,dword ptr [ebp-18h]
117		lea         ebx,[ebx+ecx]
118		mov         dword ptr [ebp-14h],ebx
119		mov         edx,dword ptr [ebp-14h]
120		add         esp,0Ch
121		pop         ebx
122		pop         esi
123		pop         edi
124		pop         ebp
125		ret
126	}
127}
128void __declspec(naked) _alldiv()
129{
130	__asm {
131		push        edi
132		push        esi
133		push        ebx
134		xor         edi,edi
135		mov         eax,dword ptr [esp+14h]
136		or          eax,eax
137		jge         L1
138		inc         edi
139		mov         edx,dword ptr [esp+10h]
140		neg         eax
141		neg         edx
142		sbb         eax,0
143		mov         dword ptr [esp+14h],eax
144		mov         dword ptr [esp+10h],edx
145L1:
146		mov         eax,dword ptr [esp+1Ch]
147		or          eax,eax
148		jge         L2
149		inc         edi
150		mov         edx,dword ptr [esp+18h]
151		neg         eax
152		neg         edx
153		sbb         eax,0
154		mov         dword ptr [esp+1Ch],eax
155		mov         dword ptr [esp+18h],edx
156L2:
157		or          eax,eax
158		jne         L3
159		mov         ecx,dword ptr [esp+18h]
160		mov         eax,dword ptr [esp+14h]
161		xor         edx,edx
162		div         ecx
163		mov         ebx,eax
164		mov         eax,dword ptr [esp+10h]
165		div         ecx
166		mov         edx,ebx
167		jmp         L4
168L3:
169		mov         ebx,eax
170		mov         ecx,dword ptr [esp+18h]
171		mov         edx,dword ptr [esp+14h]
172		mov         eax,dword ptr [esp+10h]
173L5:
174		shr         ebx,1
175		rcr         ecx,1
176		shr         edx,1
177		rcr         eax,1
178		or          ebx,ebx
179		jne         L5
180		div         ecx
181		mov         esi,eax
182		mul         dword ptr [esp+1Ch]
183		mov         ecx,eax
184		mov         eax,dword ptr [esp+18h]
185		mul         esi
186		add         edx,ecx
187		jb          L6
188		cmp         edx,dword ptr [esp+14h]
189		ja          L6
190		jb          L7
191		cmp         eax,dword ptr [esp+10h]
192		jbe         L7
193L6:
194		dec         esi
195L7:
196		xor         edx,edx
197		mov         eax,esi
198L4:
199		dec         edi
200		jne         L8
201		neg         edx
202		neg         eax
203		sbb         edx,0
204L8:
205		pop         ebx
206		pop         esi
207		pop         edi
208		ret         10h
209	}
210}
211void __declspec(naked) _aulldiv()
212{
213	__asm {
214		push        ebx
215		push        esi
216		mov         eax,dword ptr [esp+18h]
217		or          eax,eax
218		jne         L1
219		mov         ecx,dword ptr [esp+14h]
220		mov         eax,dword ptr [esp+10h]
221		xor         edx,edx
222		div         ecx
223		mov         ebx,eax
224		mov         eax,dword ptr [esp+0Ch]
225		div         ecx
226		mov         edx,ebx
227		jmp         L2
228L1:
229		mov         ecx,eax
230		mov         ebx,dword ptr [esp+14h]
231		mov         edx,dword ptr [esp+10h]
232		mov         eax,dword ptr [esp+0Ch]
233L3:
234		shr         ecx,1
235		rcr         ebx,1
236		shr         edx,1
237		rcr         eax,1
238		or          ecx,ecx
239		jne         L3
240		div         ebx
241		mov         esi,eax
242		mul         dword ptr [esp+18h]
243		mov         ecx,eax
244		mov         eax,dword ptr [esp+14h]
245		mul         esi
246		add         edx,ecx
247		jb          L4
248		cmp         edx,dword ptr [esp+10h]
249		ja          L4
250		jb          L5
251		cmp         eax,dword ptr [esp+0Ch]
252		jbe         L5
253L4:
254		dec         esi
255L5:
256		xor         edx,edx
257		mov         eax,esi
258L2:
259		pop         esi
260		pop         ebx
261		ret         10h
262	}
263}
264void __declspec(naked) _allrem()
265{
266	__asm {
267		push        ebx
268		push        edi
269		xor         edi,edi
270		mov         eax,dword ptr [esp+10h]
271		or          eax,eax
272		jge         L1
273		inc         edi
274		mov         edx,dword ptr [esp+0Ch]
275		neg         eax
276		neg         edx
277		sbb         eax,0
278		mov         dword ptr [esp+10h],eax
279		mov         dword ptr [esp+0Ch],edx
280L1:
281		mov         eax,dword ptr [esp+18h]
282		or          eax,eax
283		jge         L2
284		mov         edx,dword ptr [esp+14h]
285		neg         eax
286		neg         edx
287		sbb         eax,0
288		mov         dword ptr [esp+18h],eax
289		mov         dword ptr [esp+14h],edx
290L2:
291		or          eax,eax
292		jne         L3
293		mov         ecx,dword ptr [esp+14h]
294		mov         eax,dword ptr [esp+10h]
295		xor         edx,edx
296		div         ecx
297		mov         eax,dword ptr [esp+0Ch]
298		div         ecx
299		mov         eax,edx
300		xor         edx,edx
301		dec         edi
302		jns         L4
303		jmp         L8
304L3:
305		mov         ebx,eax
306		mov         ecx,dword ptr [esp+14h]
307		mov         edx,dword ptr [esp+10h]
308		mov         eax,dword ptr [esp+0Ch]
309L5:
310		shr         ebx,1
311		rcr         ecx,1
312		shr         edx,1
313		rcr         eax,1
314		or          ebx,ebx
315		jne         L5
316		div         ecx
317		mov         ecx,eax
318		mul         dword ptr [esp+18h]
319		xchg        eax,ecx
320		mul         dword ptr [esp+14h]
321		add         edx,ecx
322		jb          L6
323		cmp         edx,dword ptr [esp+10h]
324		ja          L6
325		jb          L7
326		cmp         eax,dword ptr [esp+0Ch]
327		jbe         L7
328L6:
329		sub         eax,dword ptr [esp+14h]
330		sbb         edx,dword ptr [esp+18h]
331L7:
332		sub         eax,dword ptr [esp+0Ch]
333		sbb         edx,dword ptr [esp+10h]
334		dec         edi
335		jns         L8
336L4:
337		neg         edx
338		neg         eax
339		sbb         edx,0
340L8:
341		pop         edi
342		pop         ebx
343		ret         10h
344	}
345}
346void __declspec(naked) _aullrem()
347{
348	__asm {
349		push        ebx
350		mov         eax,dword ptr [esp+14h]
351		or          eax,eax
352		jne         L1
353		mov         ecx,dword ptr [esp+10h]
354		mov         eax,dword ptr [esp+0Ch]
355		xor         edx,edx
356		div         ecx
357		mov         eax,dword ptr [esp+8]
358		div         ecx
359		mov         eax,edx
360		xor         edx,edx
361		jmp         L2
362L1:
363		mov         ecx,eax
364		mov         ebx,dword ptr [esp+10h]
365		mov         edx,dword ptr [esp+0Ch]
366		mov         eax,dword ptr [esp+8]
367L3:
368		shr         ecx,1
369		rcr         ebx,1
370		shr         edx,1
371		rcr         eax,1
372		or          ecx,ecx
373		jne         L3
374		div         ebx
375		mov         ecx,eax
376		mul         dword ptr [esp+14h]
377		xchg        eax,ecx
378		mul         dword ptr [esp+10h]
379		add         edx,ecx
380		jb          L4
381		cmp         edx,dword ptr [esp+0Ch]
382		ja          L4
383		jb          L5
384		cmp         eax,dword ptr [esp+8]
385		jbe         L5
386L4:
387		sub         eax,dword ptr [esp+10h]
388		sbb         edx,dword ptr [esp+14h]
389L5:
390		sub         eax,dword ptr [esp+8]
391		sbb         edx,dword ptr [esp+0Ch]
392		neg         edx
393		neg         eax
394		sbb         edx,0
395L2:
396		pop         ebx
397		ret         10h
398	}
399}
400void __declspec(naked) _alldvrm()
401{
402	__asm {
403		push        edi
404		push        esi
405		push        ebp
406		xor         edi,edi
407		xor         ebp,ebp
408		mov         eax,dword ptr [esp+14h]
409		or          eax,eax
410		jge         L1
411		inc         edi
412		inc         ebp
413		mov         edx,dword ptr [esp+10h]
414		neg         eax
415		neg         edx
416		sbb         eax,0
417		mov         dword ptr [esp+14h],eax
418		mov         dword ptr [esp+10h],edx
419L1:
420		mov         eax,dword ptr [esp+1Ch]
421		or          eax,eax
422		jge         L2
423		inc         edi
424		mov         edx,dword ptr [esp+18h]
425		neg         eax
426		neg         edx
427		sbb         eax,0
428		mov         dword ptr [esp+1Ch],eax
429		mov         dword ptr [esp+18h],edx
430L2:
431		or          eax,eax
432		jne         L3
433		mov         ecx,dword ptr [esp+18h]
434		mov         eax,dword ptr [esp+14h]
435		xor         edx,edx
436		div         ecx
437		mov         ebx,eax
438		mov         eax,dword ptr [esp+10h]
439		div         ecx
440		mov         esi,eax
441		mov         eax,ebx
442		mul         dword ptr [esp+18h]
443		mov         ecx,eax
444		mov         eax,esi
445		mul         dword ptr [esp+18h]
446		add         edx,ecx
447		jmp         L4
448L3:
449		mov         ebx,eax
450		mov         ecx,dword ptr [esp+18h]
451		mov         edx,dword ptr [esp+14h]
452		mov         eax,dword ptr [esp+10h]
453L5:
454		shr         ebx,1
455		rcr         ecx,1
456		shr         edx,1
457		rcr         eax,1
458		or          ebx,ebx
459		jne         L5
460		div         ecx
461		mov         esi,eax
462		mul         dword ptr [esp+1Ch]
463		mov         ecx,eax
464		mov         eax,dword ptr [esp+18h]
465		mul         esi
466		add         edx,ecx
467		jb          L6
468		cmp         edx,dword ptr [esp+14h]
469		ja          L6
470		jb          L7
471		cmp         eax,dword ptr [esp+10h]
472		jbe         L7
473L6:
474		dec         esi
475		sub         eax,dword ptr [esp+18h]
476		sbb         edx,dword ptr [esp+1Ch]
477L7:
478		xor         ebx,ebx
479L4:
480		sub         eax,dword ptr [esp+10h]
481		sbb         edx,dword ptr [esp+14h]
482		dec         ebp
483		jns         L9
484		neg         edx
485		neg         eax
486		sbb         edx,0
487L9:
488		mov         ecx,edx
489		mov         edx,ebx
490		mov         ebx,ecx
491		mov         ecx,eax
492		mov         eax,esi
493		dec         edi
494		jne         L8
495		neg         edx
496		neg         eax
497		sbb         edx,0
498L8:
499		pop         ebp
500		pop         esi
501		pop         edi
502		ret         10h
503	}
504}
505void __declspec(naked) _aulldvrm()
506{
507	__asm {
508		push        esi
509		mov         eax,dword ptr [esp+14h]
510		or          eax,eax
511		jne         L1
512		mov         ecx,dword ptr [esp+10h]
513		mov         eax,dword ptr [esp+0Ch]
514		xor         edx,edx
515		div         ecx
516		mov         ebx,eax
517		mov         eax,dword ptr [esp+8]
518		div         ecx
519		mov         esi,eax
520		mov         eax,ebx
521		mul         dword ptr [esp+10h]
522		mov         ecx,eax
523		mov         eax,esi
524		mul         dword ptr [esp+10h]
525		add         edx,ecx
526		jmp         L2
527L1:
528		mov         ecx,eax
529		mov         ebx,dword ptr [esp+10h]
530		mov         edx,dword ptr [esp+0Ch]
531		mov         eax,dword ptr [esp+8]
532L3:
533		shr         ecx,1
534		rcr         ebx,1
535		shr         edx,1
536		rcr         eax,1
537		or          ecx,ecx
538		jne         L3
539		div         ebx
540		mov         esi,eax
541		mul         dword ptr [esp+14h]
542		mov         ecx,eax
543		mov         eax,dword ptr [esp+10h]
544		mul         esi
545		add         edx,ecx
546		jb          L4
547		cmp         edx,dword ptr [esp+0Ch]
548		ja          L4
549		jb          L5
550		cmp         eax,dword ptr [esp+8]
551		jbe         L5
552L4:
553		dec         esi
554		sub         eax,dword ptr [esp+10h]
555		sbb         edx,dword ptr [esp+14h]
556L5:
557		xor         ebx,ebx
558L2:
559		sub         eax,dword ptr [esp+8]
560		sbb         edx,dword ptr [esp+0Ch]
561		neg         edx
562		neg         eax
563		sbb         edx,0
564		mov         ecx,edx
565		mov         edx,ebx
566		mov         ebx,ecx
567		mov         ecx,eax
568		mov         eax,esi
569		pop         esi
570		ret         10h
571	}
572}
573void __declspec(naked) _allshl()
574{
575	__asm {
576		cmp         cl,40h
577		jae         RETZERO
578		cmp         cl,20h
579		jae         MORE32
580		shld        edx,eax,cl
581		shl         eax,cl
582		ret
583MORE32:
584		mov         edx,eax
585		xor         eax,eax
586		and         cl,1Fh
587		shl         edx,cl
588		ret
589RETZERO:
590		xor         eax,eax
591		xor         edx,edx
592		ret
593	}
594}
595void __declspec(naked) _aullshr()
596{
597	__asm {
598		cmp         cl,40h
599		jae         RETZERO
600		cmp         cl,20h
601		jae         MORE32
602		shrd        eax,edx,cl
603		shr         edx,cl
604		ret
605MORE32:
606		mov         eax,edx
607		xor         edx,edx
608		and         cl,1Fh
609		shr         eax,cl
610		ret
611RETZERO:
612		xor         eax,eax
613		xor         edx,edx
614		ret
615	}
616}
617
618#endif /* MSC_VER */
619
620#endif /* !HAVE_LIBC */
621