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