1
0

SDL_mslibc.c 19 KB

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