SDL_mslibc.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  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. void __declspec(naked) _ftoul2_legacy()
  86. {
  87. static const Uint64 LLONG_MAX_PLUS_ONE = 0x43e0000000000000ULL;
  88. /* *INDENT-OFF* */
  89. __asm {
  90. fld qword ptr [LLONG_MAX_PLUS_ONE]
  91. fcom
  92. fnstsw ax
  93. test ah, 41h
  94. jnp greater_than_int64
  95. fstp st(0)
  96. jmp _ftol
  97. greater_than_int64:
  98. fsub st(1), st(0)
  99. fcomp
  100. fnstsw ax
  101. test ah, 41h
  102. jnz greater_than_uint64
  103. call _ftol
  104. add edx, 80000000h
  105. ret
  106. greater_than_uint64:
  107. xor eax, eax
  108. mov edx, 80000000h
  109. ret
  110. }
  111. /* *INDENT-ON* */
  112. }
  113. // 64-bit math operators for 32-bit systems
  114. void __declspec(naked) _allmul()
  115. {
  116. /* *INDENT-OFF* */
  117. __asm {
  118. mov eax, dword ptr[esp+8]
  119. mov ecx, dword ptr[esp+10h]
  120. or ecx, eax
  121. mov ecx, dword ptr[esp+0Ch]
  122. jne hard
  123. mov eax, dword ptr[esp+4]
  124. mul ecx
  125. ret 10h
  126. hard:
  127. push ebx
  128. mul ecx
  129. mov ebx, eax
  130. mov eax, dword ptr[esp+8]
  131. mul dword ptr[esp+14h]
  132. add ebx, eax
  133. mov eax, dword ptr[esp+8]
  134. mul ecx
  135. add edx, ebx
  136. pop ebx
  137. ret 10h
  138. }
  139. /* *INDENT-ON* */
  140. }
  141. void __declspec(naked) _alldiv()
  142. {
  143. /* *INDENT-OFF* */
  144. __asm {
  145. push edi
  146. push esi
  147. push ebx
  148. xor edi,edi
  149. mov eax,dword ptr [esp+14h]
  150. or eax,eax
  151. jge L1
  152. inc edi
  153. mov edx,dword ptr [esp+10h]
  154. neg eax
  155. neg edx
  156. sbb eax,0
  157. mov dword ptr [esp+14h],eax
  158. mov dword ptr [esp+10h],edx
  159. L1:
  160. mov eax,dword ptr [esp+1Ch]
  161. or eax,eax
  162. jge L2
  163. inc edi
  164. mov edx,dword ptr [esp+18h]
  165. neg eax
  166. neg edx
  167. sbb eax,0
  168. mov dword ptr [esp+1Ch],eax
  169. mov dword ptr [esp+18h],edx
  170. L2:
  171. or eax,eax
  172. jne L3
  173. mov ecx,dword ptr [esp+18h]
  174. mov eax,dword ptr [esp+14h]
  175. xor edx,edx
  176. div ecx
  177. mov ebx,eax
  178. mov eax,dword ptr [esp+10h]
  179. div ecx
  180. mov edx,ebx
  181. jmp L4
  182. L3:
  183. mov ebx,eax
  184. mov ecx,dword ptr [esp+18h]
  185. mov edx,dword ptr [esp+14h]
  186. mov eax,dword ptr [esp+10h]
  187. L5:
  188. shr ebx,1
  189. rcr ecx,1
  190. shr edx,1
  191. rcr eax,1
  192. or ebx,ebx
  193. jne L5
  194. div ecx
  195. mov esi,eax
  196. mul dword ptr [esp+1Ch]
  197. mov ecx,eax
  198. mov eax,dword ptr [esp+18h]
  199. mul esi
  200. add edx,ecx
  201. jb L6
  202. cmp edx,dword ptr [esp+14h]
  203. ja L6
  204. jb L7
  205. cmp eax,dword ptr [esp+10h]
  206. jbe L7
  207. L6:
  208. dec esi
  209. L7:
  210. xor edx,edx
  211. mov eax,esi
  212. L4:
  213. dec edi
  214. jne L8
  215. neg edx
  216. neg eax
  217. sbb edx,0
  218. L8:
  219. pop ebx
  220. pop esi
  221. pop edi
  222. ret 10h
  223. }
  224. /* *INDENT-ON* */
  225. }
  226. void __declspec(naked) _aulldiv()
  227. {
  228. /* *INDENT-OFF* */
  229. __asm {
  230. push ebx
  231. push esi
  232. mov eax,dword ptr [esp+18h]
  233. or eax,eax
  234. jne L1
  235. mov ecx,dword ptr [esp+14h]
  236. mov eax,dword ptr [esp+10h]
  237. xor edx,edx
  238. div ecx
  239. mov ebx,eax
  240. mov eax,dword ptr [esp+0Ch]
  241. div ecx
  242. mov edx,ebx
  243. jmp L2
  244. L1:
  245. mov ecx,eax
  246. mov ebx,dword ptr [esp+14h]
  247. mov edx,dword ptr [esp+10h]
  248. mov eax,dword ptr [esp+0Ch]
  249. L3:
  250. shr ecx,1
  251. rcr ebx,1
  252. shr edx,1
  253. rcr eax,1
  254. or ecx,ecx
  255. jne L3
  256. div ebx
  257. mov esi,eax
  258. mul dword ptr [esp+18h]
  259. mov ecx,eax
  260. mov eax,dword ptr [esp+14h]
  261. mul esi
  262. add edx,ecx
  263. jb L4
  264. cmp edx,dword ptr [esp+10h]
  265. ja L4
  266. jb L5
  267. cmp eax,dword ptr [esp+0Ch]
  268. jbe L5
  269. L4:
  270. dec esi
  271. L5:
  272. xor edx,edx
  273. mov eax,esi
  274. L2:
  275. pop esi
  276. pop ebx
  277. ret 10h
  278. }
  279. /* *INDENT-ON* */
  280. }
  281. void __declspec(naked) _allrem()
  282. {
  283. /* *INDENT-OFF* */
  284. __asm {
  285. push ebx
  286. push edi
  287. xor edi,edi
  288. mov eax,dword ptr [esp+10h]
  289. or eax,eax
  290. jge L1
  291. inc edi
  292. mov edx,dword ptr [esp+0Ch]
  293. neg eax
  294. neg edx
  295. sbb eax,0
  296. mov dword ptr [esp+10h],eax
  297. mov dword ptr [esp+0Ch],edx
  298. L1:
  299. mov eax,dword ptr [esp+18h]
  300. or eax,eax
  301. jge L2
  302. mov edx,dword ptr [esp+14h]
  303. neg eax
  304. neg edx
  305. sbb eax,0
  306. mov dword ptr [esp+18h],eax
  307. mov dword ptr [esp+14h],edx
  308. L2:
  309. or eax,eax
  310. jne L3
  311. mov ecx,dword ptr [esp+14h]
  312. mov eax,dword ptr [esp+10h]
  313. xor edx,edx
  314. div ecx
  315. mov eax,dword ptr [esp+0Ch]
  316. div ecx
  317. mov eax,edx
  318. xor edx,edx
  319. dec edi
  320. jns L4
  321. jmp L8
  322. L3:
  323. mov ebx,eax
  324. mov ecx,dword ptr [esp+14h]
  325. mov edx,dword ptr [esp+10h]
  326. mov eax,dword ptr [esp+0Ch]
  327. L5:
  328. shr ebx,1
  329. rcr ecx,1
  330. shr edx,1
  331. rcr eax,1
  332. or ebx,ebx
  333. jne L5
  334. div ecx
  335. mov ecx,eax
  336. mul dword ptr [esp+18h]
  337. xchg eax,ecx
  338. mul dword ptr [esp+14h]
  339. add edx,ecx
  340. jb L6
  341. cmp edx,dword ptr [esp+10h]
  342. ja L6
  343. jb L7
  344. cmp eax,dword ptr [esp+0Ch]
  345. jbe L7
  346. L6:
  347. sub eax,dword ptr [esp+14h]
  348. sbb edx,dword ptr [esp+18h]
  349. L7:
  350. sub eax,dword ptr [esp+0Ch]
  351. sbb edx,dword ptr [esp+10h]
  352. dec edi
  353. jns L8
  354. L4:
  355. neg edx
  356. neg eax
  357. sbb edx,0
  358. L8:
  359. pop edi
  360. pop ebx
  361. ret 10h
  362. }
  363. /* *INDENT-ON* */
  364. }
  365. void __declspec(naked) _aullrem()
  366. {
  367. /* *INDENT-OFF* */
  368. __asm {
  369. push ebx
  370. mov eax,dword ptr [esp+14h]
  371. or eax,eax
  372. jne L1
  373. mov ecx,dword ptr [esp+10h]
  374. mov eax,dword ptr [esp+0Ch]
  375. xor edx,edx
  376. div ecx
  377. mov eax,dword ptr [esp+8]
  378. div ecx
  379. mov eax,edx
  380. xor edx,edx
  381. jmp L2
  382. L1:
  383. mov ecx,eax
  384. mov ebx,dword ptr [esp+10h]
  385. mov edx,dword ptr [esp+0Ch]
  386. mov eax,dword ptr [esp+8]
  387. L3:
  388. shr ecx,1
  389. rcr ebx,1
  390. shr edx,1
  391. rcr eax,1
  392. or ecx,ecx
  393. jne L3
  394. div ebx
  395. mov ecx,eax
  396. mul dword ptr [esp+14h]
  397. xchg eax,ecx
  398. mul dword ptr [esp+10h]
  399. add edx,ecx
  400. jb L4
  401. cmp edx,dword ptr [esp+0Ch]
  402. ja L4
  403. jb L5
  404. cmp eax,dword ptr [esp+8]
  405. jbe L5
  406. L4:
  407. sub eax,dword ptr [esp+10h]
  408. sbb edx,dword ptr [esp+14h]
  409. L5:
  410. sub eax,dword ptr [esp+8]
  411. sbb edx,dword ptr [esp+0Ch]
  412. neg edx
  413. neg eax
  414. sbb edx,0
  415. L2:
  416. pop ebx
  417. ret 10h
  418. }
  419. /* *INDENT-ON* */
  420. }
  421. void __declspec(naked) _alldvrm()
  422. {
  423. /* *INDENT-OFF* */
  424. __asm {
  425. push edi
  426. push esi
  427. push ebp
  428. xor edi,edi
  429. xor ebp,ebp
  430. mov eax,dword ptr [esp+14h]
  431. or eax,eax
  432. jge L1
  433. inc edi
  434. inc ebp
  435. mov edx,dword ptr [esp+10h]
  436. neg eax
  437. neg edx
  438. sbb eax,0
  439. mov dword ptr [esp+14h],eax
  440. mov dword ptr [esp+10h],edx
  441. L1:
  442. mov eax,dword ptr [esp+1Ch]
  443. or eax,eax
  444. jge L2
  445. inc edi
  446. mov edx,dword ptr [esp+18h]
  447. neg eax
  448. neg edx
  449. sbb eax,0
  450. mov dword ptr [esp+1Ch],eax
  451. mov dword ptr [esp+18h],edx
  452. L2:
  453. or eax,eax
  454. jne L3
  455. mov ecx,dword ptr [esp+18h]
  456. mov eax,dword ptr [esp+14h]
  457. xor edx,edx
  458. div ecx
  459. mov ebx,eax
  460. mov eax,dword ptr [esp+10h]
  461. div ecx
  462. mov esi,eax
  463. mov eax,ebx
  464. mul dword ptr [esp+18h]
  465. mov ecx,eax
  466. mov eax,esi
  467. mul dword ptr [esp+18h]
  468. add edx,ecx
  469. jmp L4
  470. L3:
  471. mov ebx,eax
  472. mov ecx,dword ptr [esp+18h]
  473. mov edx,dword ptr [esp+14h]
  474. mov eax,dword ptr [esp+10h]
  475. L5:
  476. shr ebx,1
  477. rcr ecx,1
  478. shr edx,1
  479. rcr eax,1
  480. or ebx,ebx
  481. jne L5
  482. div ecx
  483. mov esi,eax
  484. mul dword ptr [esp+1Ch]
  485. mov ecx,eax
  486. mov eax,dword ptr [esp+18h]
  487. mul esi
  488. add edx,ecx
  489. jb L6
  490. cmp edx,dword ptr [esp+14h]
  491. ja L6
  492. jb L7
  493. cmp eax,dword ptr [esp+10h]
  494. jbe L7
  495. L6:
  496. dec esi
  497. sub eax,dword ptr [esp+18h]
  498. sbb edx,dword ptr [esp+1Ch]
  499. L7:
  500. xor ebx,ebx
  501. L4:
  502. sub eax,dword ptr [esp+10h]
  503. sbb edx,dword ptr [esp+14h]
  504. dec ebp
  505. jns L9
  506. neg edx
  507. neg eax
  508. sbb edx,0
  509. L9:
  510. mov ecx,edx
  511. mov edx,ebx
  512. mov ebx,ecx
  513. mov ecx,eax
  514. mov eax,esi
  515. dec edi
  516. jne L8
  517. neg edx
  518. neg eax
  519. sbb edx,0
  520. L8:
  521. pop ebp
  522. pop esi
  523. pop edi
  524. ret 10h
  525. }
  526. /* *INDENT-ON* */
  527. }
  528. void __declspec(naked) _aulldvrm()
  529. {
  530. /* *INDENT-OFF* */
  531. __asm {
  532. push esi
  533. mov eax,dword ptr [esp+14h]
  534. or eax,eax
  535. jne L1
  536. mov ecx,dword ptr [esp+10h]
  537. mov eax,dword ptr [esp+0Ch]
  538. xor edx,edx
  539. div ecx
  540. mov ebx,eax
  541. mov eax,dword ptr [esp+8]
  542. div ecx
  543. mov esi,eax
  544. mov eax,ebx
  545. mul dword ptr [esp+10h]
  546. mov ecx,eax
  547. mov eax,esi
  548. mul dword ptr [esp+10h]
  549. add edx,ecx
  550. jmp L2
  551. L1:
  552. mov ecx,eax
  553. mov ebx,dword ptr [esp+10h]
  554. mov edx,dword ptr [esp+0Ch]
  555. mov eax,dword ptr [esp+8]
  556. L3:
  557. shr ecx,1
  558. rcr ebx,1
  559. shr edx,1
  560. rcr eax,1
  561. or ecx,ecx
  562. jne L3
  563. div ebx
  564. mov esi,eax
  565. mul dword ptr [esp+14h]
  566. mov ecx,eax
  567. mov eax,dword ptr [esp+10h]
  568. mul esi
  569. add edx,ecx
  570. jb L4
  571. cmp edx,dword ptr [esp+0Ch]
  572. ja L4
  573. jb L5
  574. cmp eax,dword ptr [esp+8]
  575. jbe L5
  576. L4:
  577. dec esi
  578. sub eax,dword ptr [esp+10h]
  579. sbb edx,dword ptr [esp+14h]
  580. L5:
  581. xor ebx,ebx
  582. L2:
  583. sub eax,dword ptr [esp+8]
  584. sbb edx,dword ptr [esp+0Ch]
  585. neg edx
  586. neg eax
  587. sbb edx,0
  588. mov ecx,edx
  589. mov edx,ebx
  590. mov ebx,ecx
  591. mov ecx,eax
  592. mov eax,esi
  593. pop esi
  594. ret 10h
  595. }
  596. /* *INDENT-ON* */
  597. }
  598. void __declspec(naked) _allshl()
  599. {
  600. /* *INDENT-OFF* */
  601. __asm {
  602. cmp cl,40h
  603. jae RETZERO
  604. cmp cl,20h
  605. jae MORE32
  606. shld edx,eax,cl
  607. shl eax,cl
  608. ret
  609. MORE32:
  610. mov edx,eax
  611. xor eax,eax
  612. and cl,1Fh
  613. shl edx,cl
  614. ret
  615. RETZERO:
  616. xor eax,eax
  617. xor edx,edx
  618. ret
  619. }
  620. /* *INDENT-ON* */
  621. }
  622. void __declspec(naked) _allshr()
  623. {
  624. /* *INDENT-OFF* */
  625. __asm {
  626. cmp cl,3Fh
  627. jae RETSIGN
  628. cmp cl,20h
  629. jae MORE32
  630. shrd eax,edx,cl
  631. sar edx,cl
  632. ret
  633. MORE32:
  634. mov eax,edx
  635. sar edx,1Fh
  636. and cl,1Fh
  637. sar eax,cl
  638. ret
  639. RETSIGN:
  640. sar edx,1Fh
  641. mov eax,edx
  642. ret
  643. }
  644. /* *INDENT-ON* */
  645. }
  646. void __declspec(naked) _aullshr()
  647. {
  648. /* *INDENT-OFF* */
  649. __asm {
  650. cmp cl,40h
  651. jae RETZERO
  652. cmp cl,20h
  653. jae MORE32
  654. shrd eax,edx,cl
  655. shr edx,cl
  656. ret
  657. MORE32:
  658. mov eax,edx
  659. xor edx,edx
  660. and cl,1Fh
  661. shr eax,cl
  662. ret
  663. RETZERO:
  664. xor eax,eax
  665. xor edx,edx
  666. ret
  667. }
  668. /* *INDENT-ON* */
  669. }
  670. void __declspec(naked) _chkstk(void)
  671. {
  672. __asm {
  673. push ecx
  674. mov ecx,esp ; lea ecx,dword ptr [esp]+4
  675. add ecx,4
  676. sub ecx,eax
  677. sbb eax,eax
  678. not eax
  679. and ecx,eax
  680. mov eax,esp
  681. and eax,0xfffff000
  682. L1:
  683. cmp ecx,eax
  684. jb short L2
  685. mov eax,ecx
  686. pop ecx
  687. xchg esp,eax
  688. mov eax,dword ptr [eax]
  689. mov dword ptr [esp],eax
  690. ret
  691. L2:
  692. sub eax,0x1000
  693. test dword ptr [eax],eax
  694. jmp short L1
  695. }
  696. }
  697. void __declspec(naked) _alloca_probe_8(void)
  698. {
  699. /* *INDENT-OFF* */
  700. __asm {
  701. push ecx
  702. mov ecx,esp ; lea ecx,dword ptr [esp]+8
  703. add ecx,8
  704. sub ecx,eax
  705. and ecx,0x7
  706. add eax,ecx
  707. sbb ecx,ecx
  708. or eax,ecx
  709. pop ecx
  710. jmp _chkstk
  711. }
  712. /* *INDENT-ON* */
  713. }
  714. void __declspec(naked) _alloca_probe_16(void)
  715. {
  716. /* *INDENT-OFF* */
  717. __asm {
  718. push ecx
  719. mov ecx,esp ; lea ecx,dword ptr [esp]+8
  720. add ecx,8
  721. sub ecx,eax
  722. and ecx,0xf
  723. add eax,ecx
  724. sbb ecx,ecx
  725. or eax,ecx
  726. pop ecx
  727. jmp _chkstk
  728. }
  729. /* *INDENT-ON* */
  730. }
  731. #endif // _M_IX86
  732. #endif // MSC_VER
  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. #endif // !HAVE_LIBC && !SDL_STATIC_LIB