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 |
39 | void __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 |
55 | arg_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 |
67 | positive: |
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 |
75 | integer_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] |
81 | localexit: |
82 | leave |
83 | ret |
84 | } |
85 | /* *INDENT-ON* */ |
86 | } |
87 | |
88 | void _ftol2_sse() |
89 | { |
90 | _ftol(); |
91 | } |
92 | |
93 | void _ftol2() |
94 | { |
95 | _ftol(); |
96 | } |
97 | |
98 | // 64-bit math operators for 32-bit systems |
99 | void __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 |
111 | hard: |
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 | |
127 | void __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 |
145 | L1: |
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 |
156 | L2: |
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 |
168 | L3: |
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] |
173 | L5: |
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 |
193 | L6: |
194 | dec esi |
195 | L7: |
196 | xor edx,edx |
197 | mov eax,esi |
198 | L4: |
199 | dec edi |
200 | jne L8 |
201 | neg edx |
202 | neg eax |
203 | sbb edx,0 |
204 | L8: |
205 | pop ebx |
206 | pop esi |
207 | pop edi |
208 | ret 10h |
209 | } |
210 | /* *INDENT-ON* */ |
211 | } |
212 | |
213 | void __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 |
231 | L1: |
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] |
236 | L3: |
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 |
256 | L4: |
257 | dec esi |
258 | L5: |
259 | xor edx,edx |
260 | mov eax,esi |
261 | L2: |
262 | pop esi |
263 | pop ebx |
264 | ret 10h |
265 | } |
266 | /* *INDENT-ON* */ |
267 | } |
268 | |
269 | void __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 |
286 | L1: |
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 |
296 | L2: |
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 |
310 | L3: |
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] |
315 | L5: |
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 |
334 | L6: |
335 | sub eax,dword ptr [esp+14h] |
336 | sbb edx,dword ptr [esp+18h] |
337 | L7: |
338 | sub eax,dword ptr [esp+0Ch] |
339 | sbb edx,dword ptr [esp+10h] |
340 | dec edi |
341 | jns L8 |
342 | L4: |
343 | neg edx |
344 | neg eax |
345 | sbb edx,0 |
346 | L8: |
347 | pop edi |
348 | pop ebx |
349 | ret 10h |
350 | } |
351 | /* *INDENT-ON* */ |
352 | } |
353 | |
354 | void __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 |
371 | L1: |
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] |
376 | L3: |
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 |
395 | L4: |
396 | sub eax,dword ptr [esp+10h] |
397 | sbb edx,dword ptr [esp+14h] |
398 | L5: |
399 | sub eax,dword ptr [esp+8] |
400 | sbb edx,dword ptr [esp+0Ch] |
401 | neg edx |
402 | neg eax |
403 | sbb edx,0 |
404 | L2: |
405 | pop ebx |
406 | ret 10h |
407 | } |
408 | /* *INDENT-ON* */ |
409 | } |
410 | |
411 | void __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 |
431 | L1: |
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 |
442 | L2: |
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 |
460 | L3: |
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] |
465 | L5: |
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 |
485 | L6: |
486 | dec esi |
487 | sub eax,dword ptr [esp+18h] |
488 | sbb edx,dword ptr [esp+1Ch] |
489 | L7: |
490 | xor ebx,ebx |
491 | L4: |
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 |
499 | L9: |
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 |
510 | L8: |
511 | pop ebp |
512 | pop esi |
513 | pop edi |
514 | ret 10h |
515 | } |
516 | /* *INDENT-ON* */ |
517 | } |
518 | |
519 | void __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 |
542 | L1: |
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] |
547 | L3: |
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 |
567 | L4: |
568 | dec esi |
569 | sub eax,dword ptr [esp+10h] |
570 | sbb edx,dword ptr [esp+14h] |
571 | L5: |
572 | xor ebx,ebx |
573 | L2: |
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 | |
590 | void __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 |
601 | MORE32: |
602 | mov edx,eax |
603 | xor eax,eax |
604 | and cl,1Fh |
605 | shl edx,cl |
606 | ret |
607 | RETZERO: |
608 | xor eax,eax |
609 | xor edx,edx |
610 | ret |
611 | } |
612 | /* *INDENT-ON* */ |
613 | } |
614 | |
615 | void __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 |
626 | MORE32: |
627 | mov eax,edx |
628 | sar edx,1Fh |
629 | and cl,1Fh |
630 | sar eax,cl |
631 | ret |
632 | RETSIGN: |
633 | sar edx,1Fh |
634 | mov eax,edx |
635 | ret |
636 | } |
637 | /* *INDENT-ON* */ |
638 | } |
639 | |
640 | void __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 |
651 | MORE32: |
652 | mov eax,edx |
653 | xor edx,edx |
654 | and cl,1Fh |
655 | shr eax,cl |
656 | ret |
657 | RETZERO: |
658 | xor eax,eax |
659 | xor edx,edx |
660 | ret |
661 | } |
662 | /* *INDENT-ON* */ |
663 | } |
664 | |
665 | void __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 |
677 | L1: |
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 |
686 | L2: |
687 | sub eax,0x1000 |
688 | test dword ptr [eax],eax |
689 | jmp short L1 |
690 | } |
691 | } |
692 | |
693 | void __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 | |
711 | void __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 */ |
736 | void *_intel_fast_memcpy(void *dst, const void *src, size_t len) |
737 | { |
738 | return SDL_memcpy(dst, src, len); |
739 | } |
740 | void *_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 | |