Compare commits

...
975 Commits
Author SHA1 Message Date
ptitSeb 03d220b1d2 Bumped version to v0.3.6 2025-06-06 15:31:49 +02:00
ptitSeb 053c4fd6bb [RCFILE] Added a new game profile 2025-06-06 14:45:43 +02:00
ptitSeb 7b0fada974 Fixed a regression on syscall 2025-06-05 16:37:01 +02:00
ptitSeb d09b46c1bf [TRACE][DYNAREC] Enlarged buffer for instruction metadata again 2025-06-05 13:00:40 +02:00
Yang Liu 294178b598 [WOW64] The official file name is wowbox64.dll (#2709) 2025-06-05 09:52:42 +02:00
Yang Liu e9242b8849 [WOW64] Added rcfile support (#2708)
* [WOW64] Fixed more compilation warnings

* [WOW64] Messing around with file APIs

* [WOW64] Added rcfile support

* [DOCS] Update rcfile usage on WowBox64
2025-06-05 09:43:30 +02:00
Yang Liu c5755c8241 [WOW64] More cleanups and implemented a few more BTCpu functions (#2702)
* [WOW64] Reformatted with our .clang-format

* [WOW64] Removed some useless code

* [WOW64] Sort wowbox64.def in alphabet order

* [WOW64] Implemented more functions to invalidate code cache

* [WOW64] Added trace log for all BTCpu* functions
2025-06-04 17:38:33 +02:00
ptitSeb 75dcfb225a [WRAPPER][BOX32] Added a couple more 32bits wrpped functions to libc 2025-06-03 16:02:19 +02:00
ptitSeb 067e84eb05 [BOX32][WRAPPER] Added/Fixed some more wrapped function to libsdl2 2025-06-02 14:21:19 +02:00
ptitSeb faffa2a4d0 [WRAPPER][TRACE] Cleanup some trace on DLSYM_ERROR=1 2025-06-02 14:20:51 +02:00
ptitSeb c3659df777 Realigned some code 2025-06-02 14:20:12 +02:00
ptitSeb 5aac024868 [BOX32][WRAPPER] Added 1 more function to libc 2025-06-02 13:33:38 +02:00
ptitSeb a4523caf81 [TRACE][BOX32] Fixed some and cleaup detailed function call trace 2025-06-02 13:33:14 +02:00
Yang Liu db1c2cedbf [DOCS] Updated COMPILE.md about WowBox64 (#2701) 2025-06-02 12:41:55 +02:00
Yang Liu 4b96a74fc3 [ENV][WOW64] Not every env var applies to WowBox64 (#2700)
* [ENV] Not every env var applies to WowBox64

* [DOCS] Updated env docs for WowBox64
2025-06-02 12:28:35 +02:00
ptitSeb 1b131d28df [BOX32][WRAPPER] Added wrapped 32bits libcurl (need testing) 2025-06-02 12:09:21 +02:00
ptitSeb ec2e94249b [TRACE][ARM64_DYNAREC] Make dynarec_log=1 less chatty 2025-06-02 12:08:49 +02:00
ptitSeb 0ffb15fce3 [RCFILE] Added 1 more game profile 2025-06-02 12:08:03 +02:00
ptitSeb 61a62645e8 Revert using getProtection_fast in CheckExec to avoid rare (or less rare in Interp) lockup 2025-06-02 12:07:36 +02:00
Yang Liu e4edb65c2b [WOW64] The name is WowBox64 (#2699) 2025-06-02 11:03:02 +02:00
Chi-Kuan Chiu b49bcbf68b [RBTREE] Update comments on red-black tree usage (#2694)
- Remove outdated information
- Document the seven red-black trees that Box64 currently uses:
  1. memprot
  2. mapallmem
  3. blockstree
  4. db_sizes
  5. envmap
  6. rbt_dynmem
  7. volatileRanges
- Clarify each tree's role

The original intention was to help future contributors who want
to propose a faster lookup mechanism to replace rbtrees in the
future, as understanding the current usage patterns is a
necessary first step.
2025-06-02 11:02:03 +02:00
Yang Liu eb69484bd6 [WOW64] Override DOS stub to Wine builtin DLL (#2698) 2025-06-01 11:35:16 +02:00
Yang Liu 195ac02ea1 [WRAPPER] Fixed some xcb-image wrappings (#2697) 2025-06-01 10:08:22 +02:00
Yang Liu 8ebe32257e [CI] Upload libwowbox64.dll to CI artifacts (#2696)
* [CI] Upload libwowbox64.dll to CI artifacts

* [CI] Remove regular Box64 binaries from artifacts
2025-06-01 08:50:42 +02:00
André Zwing 89e470d59c Merge pull request #2692 from ksco/wow64
[WOW64] Improved RIP handling on INT n
2025-05-30 23:58:48 +02:00
Yang Liu 7a76430e87 [DYNAREC] Fixed a prefix typo in dynarec dump (#2693) 2025-05-30 23:34:48 +02:00
ptitSeb 60890a550b This should fix the WoW build 2025-05-30 23:33:56 +02:00
ptitSeb 2038df85c0 [ARM64_DYNAREC] Try to optimise Windows INT n version on 64bits (TODO: Interp and 32bits and wowbox64) 2025-05-30 21:38:43 +02:00
Yang Liu ab5d2eba64 [WOW64] Improved RIP handling on INT n 2025-05-31 03:18:22 +08:00
Yang Liu b142c5a181 [DYNAREC] Ported 37ed49cb to RV64 and LA64 (#2690) 2025-05-30 16:49:10 +02:00
ptitSeb 37ed49cbb8 [TRACE][ARM64_DYNAREC] Fixed potential buffer overflow on dynarec_dump scenario 2025-05-30 14:19:16 +02:00
ptitSeb 94ed2596c0 [RCFILE] Added a couple of game profiles 2025-05-30 11:07:26 +02:00
ptitSeb 84498707dd [ARM64_DYNAREC] Small improvment on Wine INT n handling 2025-05-30 10:43:39 +02:00
Yang Liu d29be5fd14 [WOW64] Added support for cosim (#2683) 2025-05-30 10:23:10 +02:00
Leslie Zhai 53bb00a769 [WRAPPER] Implement myStackAlignGVariantNew for g_variant_new (#2687) 2025-05-30 07:57:01 +02:00
liuli 038e9511d1 fix: env BOX64_EMULATED_LIBS triggers sigsegv (#2686) 2025-05-30 07:53:02 +02:00
Yang Liu 94789d6705 [WOW64] Print banner at startup (#2685) 2025-05-29 15:15:58 +02:00
Yang Liu 67b15f09cf [WOW64] Added more missing pieces and the interpreter works (#2682)
* [WOW64] Added more missing pieces and the interpreter works

Ported from AndreRH/hangover

* review
2025-05-29 11:41:36 +02:00
ptitSeb a0693590bd [ARM64_DYNAREC] More optimisation of unused XMM/YMM purge 2025-05-28 18:19:52 +02:00
Yang Liu f1df65d88f [WOW64][ENV] Clean up a bit (#2681) 2025-05-28 17:40:00 +02:00
ptitSeb 6697c7d229 [ARM64_DYNAREC] Optimized a bit CVTTPS2DQ on fastround=0 when frintts is not supported on the cpu 2025-05-28 17:25:23 +02:00
ptitSeb 6a41f33bf3 [INTERP] Added 64/65 67 89/8B 64bits opcodes 2025-05-28 17:11:55 +02:00
Yang Liu 67f7c988d5 [ARM64_DYNAREC] Small optim to modreg CMPXCHG (#2680)
* [ARM64_DYNAREC] Small optim to modreg CMPXCHG

* review
2025-05-28 15:34:37 +02:00
Yang Liu 01da6215de [WOW64] Supported logging to stdout (#2679) 2025-05-28 14:29:58 +02:00
Yang Liu 1fc558fcab [ARM64_DYNAREC] Fixed a warning (#2678) 2025-05-28 11:08:30 +02:00
Yang Liu c835881a77 [DYNAREC] Fixed expected return address in bridged native call (#2677) 2025-05-28 08:19:46 +02:00
Yang Liu a9f4e72c4b [RV64_DYNAREC] Fixed regression introduced in #2669 (#2676) 2025-05-27 11:29:33 +02:00
ptitSeb 1f46ca81af Merge pull request #2675 from AndreRH/wowbox64
wow64 final (dont squash)
2025-05-26 23:12:44 +02:00
André Zwing 8dbeee5dcb [WOW64] Implement BTCpuNotifyMemoryFree 2025-05-26 22:03:17 +02:00
André Zwing 7a4cf9fc9e [WOW64] Implement BTCpuNotifyUnmapViewOfSection 2025-05-26 22:01:02 +02:00
André Zwing 2fdd7f6188 [WOW64] Implement BTCpuNotifyMemoryProtect 2025-05-26 21:51:51 +02:00
André Zwing 803d8ac28a [WOW64] Convert floating point values 2025-05-26 21:50:01 +02:00
Yang Liu 77c2683762 [RV64_DYNAREC] Removed useless zero-ups in some emit_* functions (#2672) 2025-05-26 13:16:54 +02:00
Yang Liu ae9ee3d9d8 [CMAKE] Fixed dependency issues introduced recently (#2673) 2025-05-26 13:16:12 +02:00
Yang Liu 6947a5bb94 [RV64_DYNAREC] Added more opcodes to printer (#2671) 2025-05-26 11:57:00 +02:00
ptitSeb 103875b487 [BOX32][WRAPPER] Added some time64 functions (for #2655) 2025-05-26 11:56:41 +02:00
Yang Liu 4c234b0418 [RV64_DYNAREC] Improved ret_to_epilog with xtheadmemidx (#2670) 2025-05-26 11:18:21 +02:00
Yang Liu abd1ebb425 [RV64_DYNAREC] Minor nativeflags optim to LEA and CMOVcc opcodes (#2669) 2025-05-26 10:39:19 +02:00
ptitSeb e994c65116 Merge pull request #2667 from AndreRH/wowbox64
wow64 part5(dont squash)
2025-05-25 22:23:42 +02:00
André Zwing c52b36abd4 [WOW64] Implement my_cpuid 2025-05-25 21:57:23 +02:00
André Zwing a42936d998 [WOW64] Implement getBoxCpuName 2025-05-25 21:41:25 +02:00
André Zwing e09adad1b9 [WOW64] Partially implement BTCpuResetToConsistentState 2025-05-25 21:41:23 +02:00
André Zwing b6429edf09 [WOW64] Implement get_random32 and get_random64 2025-05-25 18:27:42 +02:00
Yang Liu 1e2bae9237 [RV64_DYNAREC] Improved emit_pf with Zbb (#2665) 2025-05-23 17:54:36 +02:00
Yang Liu b7ddb92c80 [RV64_DYNAREC] Optimized CLZ macro with xtheadbb (#2664) 2025-05-23 16:33:02 +02:00
Yang Liu d40f51bdc5 [RV64_DYNAREC] Optimized some opcodes with xtheadbb (#2663)
* [RV64_DYNAREC] Optimized *EXTH macros with xtheadbb

* fix

* [RV64_DYNAREC] Optimized scalar version of PCMPEQB with xtheadbb
2025-05-23 13:40:13 +02:00
Yang Liu b78ffcfad8 Added -k option to kill all box64 instances (#2661) 2025-05-23 11:55:26 +02:00
ptitSeb 3f9c5c496c Merge pull request #2662 from ksco/cmake
[CMAKE] Removed the hard dependency between dynarec and main executable to speed up build
2025-05-23 10:03:46 +02:00
Yang Liu 37068c4f36 [CMAKE] Removed the hard dependency between dynarec and main executable to speed up build 2025-05-23 15:26:52 +08:00
ptitSeb 18a02fafb1 Merge pull request #2660 from AndreRH/wowbox64
wow64 part4 (dont squash)
2025-05-22 23:02:12 +02:00
André Zwing 06d4fc79ec [WOW64] Remove debug messages 2025-05-22 21:27:02 +02:00
André Zwing fa874ffcbc [WOW64] Implement syscalls 2025-05-22 21:27:02 +02:00
André Zwing b729e3e37b [WOW64] Initialize db_sizes 2025-05-22 21:27:02 +02:00
André Zwing 73e7c6b480 [WOW64] Don't check the protection on win32 2025-05-22 21:27:02 +02:00
ptitSeb 5916869329 [ARM64_DYNAREC] Try to avoid Load/Unload of XMM/YMM regs when possible on intrablock jump 2025-05-22 20:07:23 +02:00
Yang Liu c9f3b990b4 [RV64_DYNAREC] Enable nativeflags optimization for more patterns (#2659) 2025-05-22 18:57:09 +02:00
ptitSeb 6592b63800 [BOX32][WRAPPER][TRACE] Fixed some DLSYM_ERROR traces 2025-05-22 14:25:03 +02:00
ptitSeb 1898d35c53 [WRAPPER][TRACE] Fixed some DLSYM_ERROR traces 2025-05-22 14:24:46 +02:00
ptitSeb 77f7c1278b [INTERP] Added unaligned path for F0 FF /1 32bits opcode 2025-05-21 17:06:42 +02:00
ptitSeb 1c7a7c9895 [ARM64_DYNAREC] Fix (and small optim) on VPMASKMOVD/VPMASKMOVQ opcodes 2025-05-21 16:39:09 +02:00
Yang Liu bd23f259cc [RV64_DYNAREC] Fixed a typo in 66 F0 0F LOCK CMPXCHG opcode (#2658) 2025-05-21 16:25:25 +02:00
Yang Liu efe1eb73dc Reprint env configs when special libraries detected (#2657) 2025-05-21 15:38:56 +02:00
Yang Liu 8c51be6985 [RV64_DYNAREC] Implemented unaligned path for LOCK INC/DEC opcodes (#2656) 2025-05-21 12:36:36 +02:00
ptitSeb f25af13f79 Better mmap file tracking when loading multiple file with same name (like 32bits and 64bits version of a same dll in wine wow64) 2025-05-21 11:54:48 +02:00
ptitSeb 019f85e4a3 {BOX32][WRAPPER] More fixes on libdbus-1 wrapping 2025-05-20 18:27:25 +02:00
Yang Liu 7af5f625d7 [DYNAREC] Removed unnecessary volatile metadata barriers (#2653) 2025-05-20 17:17:34 +02:00
Yang Liu a1ac9cccc4 [RV64_DYNAREC] Fixed more potential scratch register conflicts (#2652) 2025-05-20 17:01:45 +02:00
ptitSeb b13811259a [BOX32][WRAPPER] Try to fix some of the issues with wrapped libdbus-1 and arrays/strings 2025-05-20 16:40:04 +02:00
ptitSeb a7f4041604 [INTERP] Small change on 0F 2E/2F opcode, and alows Interp->Dynarec on 80..8F opcodes 2025-05-20 14:52:48 +02:00
ptitSeb 72e05a52b2 [INTERP] Fixed D9 F5/F8 (for #2644) 2025-05-20 14:51:31 +02:00
Yang Liu e1e3122a1f [RV64_DYNAREC] Improved POPCNT and fixed some scratch conflicts (#2651) 2025-05-20 14:45:50 +02:00
ptitSeb 4f88b2bdd7 Merge pull request #2648 from ksco/thead
[RV64] Improved vendor extension detection to avoid conflicts (for #2645)
2025-05-20 09:44:37 +02:00
Yang Liu 5b8a71d720 [RV64] Improved vendor extension detection to avoid conflicts (for #2645) 2025-05-20 15:24:09 +08:00
ptitSeb 58021bbf42 Merge pull request #2647 from AndreRH/wowbox64
wow64 part3 (dont squash)
2025-05-20 00:39:33 +02:00
André Zwing 45d3cbd1b4 [WOW64] Implement BTCpuTurboThunkControl 2025-05-19 23:46:29 +02:00
André Zwing e07ec82344 [WOW64] Implement BTCpuSimulate 2025-05-19 23:46:29 +02:00
ptitSeb 37eb5492ba [BOX32][WRAPPER] Fixed issue with wrapping of libdbus-1 2025-05-19 16:39:16 +02:00
ptitSeb 0e7b986116 [TRACE] Slight better trace when running with custommem memory tracker 2025-05-19 16:02:15 +02:00
ptitSeb be16c14dcb [BOX32][WRAPPER] This should fix RV64 and LA64 builds 2025-05-19 15:57:11 +02:00
ptitSeb a1c29448a3 [BOX32][WRAPPER] Added 32bits wrapping for libdbus-1 2025-05-19 15:12:41 +02:00
ptitSeb 16bdcc0c93 [ARM64_DYNAREC] Added fastnan=0 handling to 0F 52 opcode 2025-05-18 19:26:32 +02:00
Yang Liu 2798c3c8cd [RV64_DYNAREC] Enabled native flags optimization for SETcc opcodes (#2640) 2025-05-16 14:12:56 +02:00
ptitSeb d7538334e0 [RCFILE] Added/modified some more profiles 2025-05-15 18:26:50 +02:00
ptitSeb 5dbcc4ad0d [TRACE] Reduce the noise when using SHOWSEGV=1 on Winde programs 2025-05-15 18:26:50 +02:00
Yang Liu 2cd4d60325 [RV64_DYNAREC] Added F2 0F F0 LDDQU opcode for vector (#2639) 2025-05-15 14:30:18 +02:00
Yang Liu 3dc00e9262 [DYNAREC] Fixed alternate address testing when retriving dynablock (#2638) 2025-05-15 14:19:33 +02:00
Yang Liu 649af04fa5 [RV64_DYNAREC] Added more opcodes for vector (#2637) 2025-05-15 13:00:09 +02:00
Yang Liu 3b97efb9ca [DYNAREC] More minor changes to missing VEX prefixed opcodes (#2636) 2025-05-15 11:08:08 +02:00
ptitSeb 8005af1387 [ARM64_DYNAREC][TRACE] Yet another small change on DYNAREC_MISSING=1 handling of missing VEX prefixed opcodes 2025-05-15 10:50:05 +02:00
ptitSeb 5b45329968 [ARM64_DYNAREC][TRACE] Anothor small change on DYNAREC_MISSING=1 handling of missing VEX prefixed opcodes 2025-05-15 10:47:47 +02:00
ptitSeb b1379c88d4 [ARM64_DYNAREC][TRACE] Improved DYNAREC_MISSING=1 handling of missing VEX prefixed opcodes 2025-05-15 10:41:21 +02:00
Yang Liu 274949f9d0 [RV64_DYNAREC] Added and optimized some SSE/MMX opcodes (#2635) 2025-05-15 09:00:50 +02:00
ptitSeb 4a70577e6f [WRAPPER] added arm64 special case to of_unconvert helper function 2025-05-14 17:55:02 +02:00
ptitSeb b818a29499 [WRAPPER] Reduce the warning on of_unconvert helper function 2025-05-14 14:39:34 +02:00
Yang Liu 69c88442b4 [RV64_DYNAREC] Fixed a typo introduced lately (#2634) 2025-05-14 14:16:51 +02:00
Yang Liu 3d0b4ac9e1 [DOCS] Align usage.json and env.h (#2633)
* [DOCS] Align usage.json and env.h

* Removed BOX64_FUTEX_WAITV

* review

* gen
2025-05-14 10:15:01 +02:00
ptitSeb 4be5149b8d [RCFILE] Made VOLATILE_METADATA default, and added/finetuned some game profiles 2025-05-14 09:27:08 +02:00
Yang Liu 76ba181d98 [RV64_DYNAREC] Added more mmx opcodes (#2629) 2025-05-14 09:06:24 +02:00
Hypothalamus 4542244c4f [DOCS] improve consistency between documentation and code (#2631)
* [fix][Docs] is `XXXX` consistantly

* [feat][Docs] add simple validation script that checks consistency between `usage.json` and `env.h`

* [DOCS] include `validate.py` in `gen.py`
2025-05-13 18:34:55 +02:00
Yang Liu a58e9d1dc9 [RV64_DYNAREC] Added more mmx opcodes (#2630) 2025-05-13 14:28:43 +02:00
Yang Liu 938a2379c6 [RV64_DYNAREC] Added more mmx opcodes (#2627) 2025-05-13 11:48:11 +02:00
Yang Liu 881814b21c [RV64_DYNAREC] Added more mmx opcodes 2025-05-13 10:24:43 +02:00
André Zwing 915c4bf3b7 rbtree needs initialized mutexes 2025-05-12 22:33:22 +02:00
André Zwing 7a8a1a7791 [WOW64] Implement BTCpuProcessInit 2025-05-12 22:33:22 +02:00
André Zwing e38d20e610 [WOW64] Implement BTCpuThreadInit 2025-05-12 22:33:22 +02:00
ptitSeb 3d18e9c9e2 Improved libdl error message handling 2025-05-12 18:25:12 +02:00
ptitSeb 27685a4680 Small improvment on printf_trace utility function 2025-05-12 18:24:17 +02:00
ptitSeb 81b26569e5 [WRAPPER] Added libOpenCL.so as synonym 2025-05-12 12:43:03 +02:00
ptitSeb 76bbca2808 [WRAPPER] Improved handling of multiple vulkan devices 2025-05-12 12:21:03 +02:00
Yang Liu b435966bd0 [CI] Check WOW64 build in the CI (#2623) 2025-05-12 09:41:18 +02:00
Chi-Kuan Chiu be0839a478 [Docs]Fix the format of Commit 816c4bd (#2622) 2025-05-11 20:15:12 +02:00
ptitSeb f81f29b19a [BOX32][WRAPPER] Added 1 more libc wrapped function 2025-05-11 18:29:28 +02:00
Chi-Kuan Chiu 816c4bdb61 [DOCS] Include RV64 and LARCH64 DynaRec options (#2621)
Previously the README only mentioned `-DARM_DYNAREC=1`.
CMakeLists.txt also defines `RV64_DYNAREC` and `LARCH64_DYNAREC`, so
this expands the docs to list all dynamic-recompilation flags.
2025-05-11 18:18:43 +02:00
André Zwing a9ddd396c4 [WOW64] Initial implementation patches (#2619)
* [WOW64] Add stub for VolatileRangesContains

* [WOW64] Implement BTCpu[GS]etContext

* [WOW64] Add env support
2025-05-11 16:55:19 +02:00
ptitSeb f0b060dadd [BOX32] Fixed an issue with *printf format handling missing # (help Borderlands 2 / PreSequel Linux version, probably other too) 2025-05-11 15:54:32 +02:00
ptitSeb b1eabd7583 [WRAPPER] Added more wrapped function to ffmpeg, and disable it with NOGTK=1, as wrapping needs more work on structure callbacks 2025-05-11 14:01:46 +02:00
ptitSeb 7a2d9967f5 Improved custom gstreamer-1.0 installation (for new Proton launched from linux Steam) 2025-05-11 10:19:21 +02:00
ptitSeb 2aeddc8829 [BOX32][WRAPPER] Added some more 32bits wrapped libGL functions 2025-05-10 17:28:46 +02:00
ptitSeb df4dcf88da [WRAPPER] Added 1 more function to wrapped fontconfig 2025-05-10 16:01:14 +02:00
ptitSeb 8160a90fd5 [ARM64_DYNAREC] Fixed a regression introduced with e7b71cba5f (fixed broken rendering with American Truck Simulator linux version, probably others too) 2025-05-10 12:03:39 +02:00
ptitSeb a8adde9234 [WRAPPER] Added a few more wrapped function to ffmpegs libs 2025-05-09 18:38:12 +02:00
ptitSeb daa3fca1f1 [RCFIEL] Fine tuned and added a few games profile 2025-05-09 16:55:40 +02:00
ptitSeb d744026819 [RCFILE] Put back WEAKBARRIER 1 as default 2025-05-09 16:55:12 +02:00
ptitSeb 689d6b9330 Fixed a potential deadlock on custom memory managment (mostly for Box32) 2025-05-09 13:39:15 +02:00
Yang Liu 22fdc90fe2 [GDBJIT] Added a new option to register debuginfo only after trapped into signalhandler (#2614) 2025-05-09 10:21:41 +02:00
Yang Liu 78193c5f1a [ENV] Refactored file-mapping handling (#2612)
* [ENV] Refactored file-mapping handling

* fix
2025-05-08 16:49:48 +02:00
ptitSeb 51d2b73cd7 [RCFILE] Fixed WEAKBARRIER=2 never taken into account 2025-05-08 16:41:02 +02:00
ptitSeb 7b5200094c [WRAPPER] Added a couple of wrapped function to glib2 (for #71) 2025-05-08 11:48:53 +02:00
Yang Liu 5d14413b89 [DYNAREC] Use PE volatile metadata in dynarec (#2610) 2025-05-07 16:50:37 +02:00
ptitSeb ec54969094 [WRAPPER] Better handling of secure_getenv, but still not perfect 2025-05-07 16:26:25 +02:00
Leslie Zhai 11513d662d [NON4KPAGE] Fix AllocLoadElfMemory multiblocks wrong alignment (#2608) (#2609) 2025-05-07 15:36:37 +02:00
ptitSeb 6487ee0eda [WRAPPER] Added 1 more wrapped function to glib2 (for #71) 2025-05-06 16:38:20 +02:00
Yang Liu 8d7db7f1fb Added a simple PE loaded dedicated for volatileMetadata (#2607) 2025-05-06 13:45:38 +02:00
ptitSeb 11563f3b62 [BOX32][WRAPPER] Fix wrapping of XGetKeyboardMapping return (for #2135) 2025-05-06 11:30:21 +02:00
ptitSeb ff566e8116 Try to fix some remaining regression with customme rbtree refactor (for #2600) 2025-05-05 16:48:57 +02:00
ptitSeb 1ddf9a0a00 [RCFILE] Fixed all regression of BOX64_ADDLIBS settings 2025-05-05 13:03:00 +02:00
ptitSeb 35fa13899a [TRACE] Better log for unsetenv and putenv functions 2025-05-03 16:57:14 +02:00
Chi-Kuan Chiu 5ee4385477 Use setProtection_mmap in NewBrick (#2599)
NewBrick() currently uses setProtection() after box_mmap(), which fails
to mark the region with the `MEM_MMAP` label. As a result, getMmapped()
returns 0, even though the memory was allocated via mmap.

Closes #2598
2025-05-03 11:40:29 +02:00
ptitSeb 25000d0903 [ARM64_DYNAREC] Fixed a regression on 256bits VBROADCAST[B/W] opcodes 2025-05-03 10:47:54 +02:00
ptitSeb b96e410f53 [ARM64_DYNAREC] Fixed generic case of VPSHUFD opcode on memory 2025-05-03 10:34:50 +02:00
ptitSeb 6203880a5f [ARM64_DYNAREC] Better log for scratch after ymm warning 2025-05-03 10:33:55 +02:00
ptitSeb 889dd64c5f [ARM64_DYNAREC] Fixed an issue introduced with fastnan=0 handling of SQRTSS (for #2593) 2025-05-02 13:26:25 +02:00
ptitSeb 198eea49a8 [ARM64_DYNAREC] Small changes in a few AVX shift opcodes 2025-05-01 12:11:10 +02:00
ptitSeb b500a6ebc2 [ARM64_DYNAREC] Added missing instruction name 2025-05-01 11:44:10 +02:00
ptitSeb cb26a742ff [INTERP] Added missing opcode nae in comment 2025-05-01 11:43:15 +02:00
ptitSeb 4b44501d17 [ARM64_DYNAREC] Fixed edge-case for VPERM2[F/I]128 opcodes 2025-05-01 11:13:25 +02:00
ptitSeb 830cc8a498 [INTERP] Fixed edge-case for VPERM2[F/I]128 opcodes 2025-05-01 11:13:01 +02:00
ptitSeb 16b0922ec5 [ARM_DYNAREC] Small improvments to VMASKMOVP[S/D] opcodes 2025-05-01 10:45:00 +02:00
ptitSeb 9791016c74 [INTERP] VMASKMOVP[S/D] opcodes have no register only path 2025-05-01 10:42:41 +02:00
ptitSeb ced1157132 [ARM64_DYNAREC] Cosmetic change to VGATHER[D/Q]P[D/S] opcodes 2025-04-30 18:35:22 +02:00
ptitSeb 56982e4c05 [ARM64_DYNAREC] Small rework on VFMAD*S[S/D] opcodes 2025-04-30 17:50:44 +02:00
ptitSeb f5e93a14a2 [INTERP] Fixed another instruction name comment 2025-04-30 17:49:48 +02:00
ptitSeb eae608f35c [ARM64_DYNAREC] Small improvment to VPBROADCAST[B/W] opcodes 2025-04-30 17:17:08 +02:00
ptitSeb 89dbd81f27 [INTERP] Improved NAN handling on VSUBPD opcode 2025-04-30 16:15:34 +02:00
ptitSeb c835227b8b [ARM64_DYNAREC] Fixed a potential issue with (V)STMXCSR opcodes 2025-04-30 15:58:09 +02:00
ptitSeb 57f07446ea [ARM64_DYNAREC] Add fastnan=0 handling in (V)SQRTSS opcodes 2025-04-30 15:47:48 +02:00
ptitSeb 7b2e084170 [INTERP] Improved NAN handling for some (V)SQRTS[S/D] opcodes 2025-04-30 15:46:08 +02:00
ptitSeb ab70523b39 [INTERP] Improve NAN handling on SQRTPS opcode 2025-04-30 15:22:01 +02:00
ptitSeb f0859e6462 [ARM64_DYNAREC] Switched RSQRTPS to precise instead of aproximate 2025-04-29 18:03:15 +02:00
ptitSeb 737a93a77c [INTERP] Improved (V)RSQRTSS opcodes 2025-04-29 17:56:08 +02:00
ptitSeb 17cbeab0be [ARM64_DYNAREC] Switched RPCPS opcode to precise 1/A instead of approximate 2025-04-29 17:33:52 +02:00
ptitSeb 313e16d2bc [ARM64_DYNAREC] Small optim on PTEST opcode 2025-04-29 15:58:28 +02:00
ptitSeb ae8b5b4239 [INTERP] Fixed some more instruction name comments 2025-04-29 15:54:00 +02:00
rajdakin 1aa29ec1d3 [WRAPPERHELPER] Fixed 02423c2 (#2584) 2025-04-28 20:33:47 +02:00
Yang Liu f72d43b77e [RV64_DYNAREC] Minor optim to 8 bit TEST opcode (#2583) 2025-04-28 20:32:54 +02:00
Yang Liu 25de8bd35c [RV64_DYNAREC] Small optimization to LEA opcode (#2582) 2025-04-28 12:31:15 +02:00
ptitSeb 5c9dc159d2 [ARM64_DYNAREC] Mostly cosmetic changes to SSE/AVX packed shift opcodes 2025-04-28 11:37:35 +02:00
ptitSeb 5a4021d72b [INTERP] Fixes and improvments to SSE/AVX packed shift opcodes 2025-04-28 11:36:50 +02:00
Yang Liu ebaea69204 [RV64_DYNAREC] Optimized rv64 printer for pseudo and jump instructions (#2581) 2025-04-28 09:40:47 +02:00
Yang Liu a221d50c17 Show Dynarec architecture in version string (#2580) 2025-04-28 09:39:22 +02:00
Yang Liu 4441be7a02 [RV64_DYNAREC] Minor adjustment to dynarec_missing=2 (#2578) 2025-04-28 08:11:28 +02:00
ptitSeb bb7dfd395f [ARM64_DYNAREC] Small optim for PSIGN[B/W/D] opcodes 2025-04-27 19:39:01 +02:00
ptitSeb b552de33f9 [ARM64_DYNAREC] Some work on UD flags on (66) F3 0F BC/BD opcodes 2025-04-27 17:37:44 +02:00
ptitSeb 35c8beb15f [ARM64_DYNAREC] More work on UD flags for (66) F3 0F BC/BD opcodes 2025-04-27 16:18:57 +02:00
ptitSeb e1fd56123c [ARM64_DYNAREC] Minor fox to F6 /7 opcode 2025-04-27 16:18:23 +02:00
ptitSeb b7ae6ebc27 [INTERP] More work on UD flags 2025-04-27 15:51:17 +02:00
ptitSeb 9b904c622a [INTERP] Fixed some potential issue with LOCK ADC/SBB on Dynarec build 2025-04-27 15:41:22 +02:00
ptitSeb 950371427d [INTERP] Added 66 F3 0F BC opcode 2025-04-27 14:15:29 +02:00
ptitSeb be63129179 [WRAPPER] Reworked libssh2 wrapping, to make it more complete 2025-04-27 14:07:31 +02:00
ptitSeb 02423c2d7d [WRAPPERHELPER] Fixed a small issue with the parser 2025-04-27 14:07:01 +02:00
ptitSeb 4add55aa45 [ELFLOADER] Fixed an issue were fail to load a library might endup unloading used libraries 2025-04-27 12:38:32 +02:00
ptitSeb 7334bb46c6 [ELFLOADER] Added lib loading/unloading logs to DLSYM_ERROR 2025-04-27 11:53:33 +02:00
ptitSeb 9c962f8b2c [RCFILE] Fixed BOX64_ROLLING_LOG not being a boolean but an integer value 2025-04-27 11:06:40 +02:00
ptitSeb 1f73944603 [ARM64_DYNAREC] Refactored (V)PSHUFD opcodes 2025-04-26 15:57:38 +02:00
ptitSeb e844c5baa3 [INTERP] Cosmetic change to VPSHUFD opocde 2025-04-26 15:43:56 +02:00
ptitSeb c849178bf8 [WRAPPER] Fixed some potential sagfault on my_backtrace wrapped function 2025-04-26 15:43:01 +02:00
ptitSeb ff4ae1f4d8 [ARM64_DYNAREC] Allow shift with saturation on (V)PMULH(U)W because it will never saturate 2025-04-26 10:46:11 +02:00
ptitSeb f7acb78743 [ARM64_DYNAREC] Small fix for edge cases on (V)PMULHUW opcodes 2025-04-26 10:39:44 +02:00
ptitSeb 6796b9ca02 [WRAPPER] Added some missing function to wrapped libgio-2 (for #2575) 2025-04-26 10:12:28 +02:00
ptitSeb e4da025dc0 [ARM64_DYNAREC] Fixed (rarely used) some edge case for (V)PMULHRSW opcode (and improved tests) 2025-04-25 20:03:58 +02:00
ptitSeb b6b069cf8d [ARM64_DYNAREC] Small optim on some 256bits VPMOV[S/Z]X* opcodes 2025-04-25 17:28:28 +02:00
ptitSeb f9475aa540 [ARM64_DYNAREC] Allow bigger block to be built 2025-04-25 16:43:23 +02:00
ptitSeb c6f0872e50 [ARM64_DYNAREC] Minor change, (V)PMOVMSKB is only valid on register, not memory 2025-04-25 16:10:16 +02:00
ptitSeb 71dc02e06f [INTERP] Another fix for a opcode name in comment 2025-04-25 16:05:50 +02:00
ptitSeb e9715e4f0f [INTERP] Fixed a small issue where VPCMP[E/I]STRM would not wipe upper 128bits of ymm0 2025-04-25 11:14:02 +02:00
ptitSeb 8f197a7c08 [ARM64_DYNAREC] Fixed a potential issue with PCMPEQQ opcodes, and many missing space in instruction name 2025-04-25 10:56:38 +02:00
ptitSeb 3542c88dc1 [ARM64_DYNAREC] Improved and fixed software fallback for (V)PCLMULQDQ opcodes 2025-04-24 19:50:32 +02:00
ptitSeb 4585b74310 [ARM64_DYNAREC] Some optimisation to some (V)(P)BLEND* opcodes 2025-04-24 19:04:42 +02:00
ptitSeb 768dfd37bb [INTERP] Yet another opcode name comment fix 2025-04-24 19:03:03 +02:00
Yang Liu d8212fab48 [SIGNAL] Better signal logging when trace enabled (#2572)
* [SIGNAL] Better signal logging when trace enabled

* fix
2025-04-24 16:40:39 +02:00
Yang Liu 740f4a19dc [RV64_DYNAREC] Fixed x87 cache swapping (#2571) 2025-04-24 16:07:43 +02:00
ptitSeb c469ed867a [ARM64_DYNAREC] Small optim on (V)PACKUSDW opcodes 2025-04-24 15:38:30 +02:00
phorcys 37dcb1a77b [LA64_DYNAREC] Add/Opt more mmx/sse ops (#2565)
* [LA64_DYNAREC] Add/Opt PEXTR{B,W,D,Q}/PINSR{B,W,D,Q} .
  * 0f.c4/c5 PINSRW/PEXTRW mmx ops.
  * 66.0f.3a.14/15/16 PEXTR{B,W,D/Q} SSE4 ops.
  * 66.0f.c4/c5 PINSRW/PEXTRW sse ops.

* [LA64_DYNAREC] Add more SSE3/SSE4 ops
66.0f.38.28 PMULDQ
66.0f.38.2a MOVNTDQA
66.0f.38.37 PCMPGTQ
66.0f.38.38/3b/3c/3f PMINSB/PMINUD/PMAXSB/PMAXUD
66.0f.3a.17 EXTRACTPS
66.0f.3a.41 DPPD
opt 66.0f.3a.40 DPPS
2025-04-24 13:26:57 +02:00
ptitSeb 2e90a5dbaf [INTERP] Cosmetic change to 0F 1C..1E opcodes 2025-04-24 12:07:45 +02:00
ptitSeb d988a39456 [INTERP] Added nan handling on AVX.F3.0F 59 opcode 2025-04-24 11:54:55 +02:00
ptitSeb fc381e744e [ARM64_DYNAREC] Simplified code for MOVS[H/L]DUP opcodes 2025-04-24 11:38:20 +02:00
ptitSeb e52b24b615 [INTERP] Fixed another opcode name comment 2025-04-24 11:37:17 +02:00
phorcys 7158405b73 [LA64_DYNAREC] Add POPCNT/TZCNT/LZCNT ops. (#2566)
66.f3.0f.b8/bc/bd POPCNT/TZCNT/LZCNT 16bits ops
f3.0f.bd LZCNT
fix f3.0f.bc TZCNT (GETED/RESTORE_EFLAGS x1 conflict)
2025-04-24 11:28:42 +02:00
ptitSeb e059506d5e [ARM64_DYNAREC] Small iùprovments to some (V)MOVQ opcodes 2025-04-24 11:15:06 +02:00
ptitSeb 6da3a1265d [INTERP] Fixed a comment 2025-04-24 11:14:28 +02:00
ptitSeb d51997bc77 [ARM64_DYNAREC] Small change and optims to various (V)MOVNT* opcodes 2025-04-24 10:58:56 +02:00
ptitSeb af555abb6f [INTERP] Small change to various (V)MOVNT* opcodes, forbidding reg -> reg form 2025-04-24 10:58:23 +02:00
Yang Liu 926e4b2da8 [DYNAREC] Added ranged Dynablock dump (#2570) 2025-04-24 10:37:24 +02:00
Yang Liu 4903177bab [ARM64_DYNAREC] Minor optim to MOVNTDQA (#2568) 2025-04-24 09:17:52 +02:00
Yang Liu d8a6fa0395 Added some missing newlines (#2567) 2025-04-24 09:16:49 +02:00
ptitSeb 69127efae9 [ARM64_DYNAREC] Small fixes and improvments to (V)MOVMSKP[S/D] opcodes 2025-04-23 18:43:13 +02:00
ptitSeb 6f0db360a4 [ARM64_DYNAREC] Few fixes and small cosmetic changes to some partial (V)MOV opcodes 2025-04-23 18:21:15 +02:00
ptitSeb 223de50ec9 [INTERP] Fex fixes and small cosmetic changes to some partial (V)MOV opcodes 2025-04-23 18:20:38 +02:00
ptitSeb 5cfad22165 [ARM64_DYNAREC] Made REP MOVSB optimisation flagless 2025-04-23 12:54:04 +02:00
ptitSeb 815836d285 [ARM64_DYNAREC] Optimized REP STOSB 2025-04-23 12:47:56 +02:00
ptitSeb 468a3c2165 [PERFMAP] Added x86 address of code when function name cannot be found, instead of ??? 2025-04-23 11:48:37 +02:00
ptitSeb 3afe87bcce [ARM64_DYNAREC] Various improvment to various SSE/AVX 128bits/256bits mov opcodes 2025-04-23 10:57:07 +02:00
ptitSeb d79d6bd6c2 [INTERP] RaZ upper 128bits on vmov* Ex, Gx if Ex is a registry (unused?) 2025-04-23 10:55:17 +02:00
rajdakin cc6500b7dd [RBTREE] Fixed an edge case (#2562) 2025-04-22 13:52:01 +02:00
Yang Liu ad494480ce [DYNAREC] Added a x87pc test and some cosmetic changes too (#2561) 2025-04-22 13:31:04 +02:00
phorcys 854f6675db [LA64_DYNAREC] Add SSSE3's mmx ops. (#2559)
0f.38.00 PSHUFB
      01 PHADDW
      02 PHADDD
      03 PHADDSW
      04 PMADDUBSW
      05 PHSUBW
      06 PHSUBD
      07 PHSUBSW
      08 PSIGNB
      09 PSIGNW
      0a PSIGND
      0b PMULHRSW
      1c PABSB
      1d PABSW
      1e PABSD
2025-04-22 13:26:51 +02:00
ptitSeb fc15743ff9 [ARM64_DYNAREC] Improved (V)[MIN/MAX][S/P][S/D] opcodes 2025-04-22 12:20:23 +02:00
ptitSeb 91ead3b12a [INTERP] Improved (V)[MIN/MAX][S/P][S/D] opcodes 2025-04-22 12:20:03 +02:00
Chi-Kuan Chiu 75aaf7aa64 [RBTREE] Cache boundary nodes and remove add_range() (#2557)
* Cache leftmost and rightmost node

Add two fields to `rbtree`: `lefter` and `righter`, to cache the
leftmost and rightmost nodes respectively. This eliminates the need for
O(log N) traversals in `rb_get_lefter()` and `rb_get_righter()`.

Motivated by the Linux kernel's use of cached pointers for `rb_first()`
and `rb_last()`, this change improves efficiency of boundary queries by
replacing repeated tree walks with direct pointer dereference.

Experiment: running `chess.exe` with Box64 + Wine (#2511)
- ~3,500 insertions into the tree
- 607 lightweight cache updates (single assignment)
- 397 full tree traversals avoided

This results in reduced runtime overhead for boundary checks, with
memory cost (+2 pointer  per tree). Expected benefits increase
in larger or more dynamic workloads.

Ref: https://docs.kernel.org/core-api/rbtree.html

* Remove redundant add_range() wrapper

The function `add_range()` was only called when `tree->root == NULL`.
In such cases, the while-loop inside `add_range()` never runs,
resulting in a call to `add_range_next_to()` with `prev == NULL`.

Replaced it with direct calls to `add_range_next_to(tree, NULL, ...)`.
2025-04-22 11:51:57 +02:00
Yang Liu 39a66e25ee [RV64_DYNAREC] Better handling of x87double=2 (#2560) 2025-04-22 11:07:34 +02:00
ptitSeb 574d6f9dab [ARM64_DYNAREC] Small improvements to (V)MASKMOVDQU opcode 2025-04-21 17:41:04 +02:00
ptitSeb c39869b770 [ARM64_DYNAREC] Better handling of x87double=2 2025-04-21 16:07:05 +02:00
ptitSeb 302b6493e2 [ARM64_DYNAREC] Fixed potential issue with (V)LDDQU opcode 2025-04-21 14:13:56 +02:00
Yang Liu 20ea2987a8 [DYNAREC] More handling of low precision x87 flag change (#2556) 2025-04-21 14:09:26 +02:00
ptitSeb eee547d50a [INTERP] More fixes to INSERTQ/EXTRQ opcodes 2025-04-21 14:01:56 +02:00
Yang Liu a19f4b9eca [RV64_DYNAREC][TRACE][COSIM] Improve x87 fiability in dynarec trace and cosim scenario (#2555) 2025-04-21 13:18:40 +02:00
ptitSeb 6f3f3e0e85 [ARM64_DYNAREC] Add/Improved (V)H[ADD/SUB]P[S/D] opcodes 2025-04-21 12:22:06 +02:00
Yang Liu 2384462f61 [ENV][COSIM] Enable x87double only if it's off (#2554) 2025-04-21 11:54:42 +02:00
ptitSeb e6e6c3ac65 [ARM64_DYNAREC] Small change to 66 0F 3A 17 opcode 2025-04-21 11:45:09 +02:00
ptitSeb 102e6a1f61 [INTERP] Fixed EXTRQ opcode 2025-04-21 11:44:11 +02:00
ptitSeb 460e6c517d [ARM64_DYNAREC] Minor cosmetic changes 2025-04-21 11:27:20 +02:00
ptitSeb 965105c08a [INTERP] Better NAN handling for (V)DIV[P/S][S/D] opcodes 2025-04-21 11:27:01 +02:00
ptitSeb 3fef880a7d [INTERP] VDPPD has no 256bits version 2025-04-21 11:26:01 +02:00
Yang Liu e7b4c79d12 [RV64_DYNAREC] Added X87DOUBLE=2 support (#2553) 2025-04-21 10:19:44 +02:00
ptitSeb 7cdfa187c5 [ARM64_DYNAREC] Another potential fix for X87DOUBLE=2 2025-04-21 09:25:24 +02:00
ptitSeb d0da57547e [ARM64_DYNAREC] Fixed some potential issues with BOX64_DYNAREC_DOUBLE=2 2025-04-21 08:58:08 +02:00
ptitSeb e60fd72672 [TRACE] Fixed an issue with a trace on dynablock exiting execution 2025-04-21 08:57:33 +02:00
ptitSeb c6ae7d36dd [TRACE] Better trace, using maplile name if available, and better write on a dynablock memory log 2025-04-20 16:23:30 +02:00
ptitSeb 3836625017 Fixed an issue with custom memory when a map is created for an blockstree node, avoiding re-entrance on blockstree handling and tree corruption 2025-04-20 16:22:32 +02:00
ptitSeb 319f67d577 [DEBUG] Exposed a debug function to print an rbtree 2025-04-20 16:19:36 +02:00
Chi-Kuan Chiu 28d12f6785 Merge mmapmem into mapallmem (#2550)
This commit removes the separate `mmapmem` red-black tree and
merges its into `mapallmem`, reducing overall memory usage.

To distinguish memory regions that were previously tracked
separately in `mmapmem`,
we now use a new `mem_flag_t` bitmask enum in the data field
of `mapallmem`:

    MEM_ALLOCATED = 1  // allocated
    MEM_RESERVED  = 2  // reserved
    MEM_MMAP      = 3  // allocated via mmap()

Resolves #2546
2025-04-20 14:24:22 +02:00
ptitSeb e7113b228f [BOX32][WRAPPER] Removed a debug leftover 2025-04-19 22:44:49 +02:00
ptitSeb bc3cfe82cf [BOX32][WRAPPER] Added a workaround on XF86VidModeGetAllModeLines for 12 labors of Hercules 6 2025-04-19 21:04:02 +02:00
ptitSeb 6ccac8ab5a [BOX32][WRAPPER] Added 32bits wrapped ftime function 2025-04-19 20:33:07 +02:00
ptitSeb c9d756eeea [RCFILE] Better profile for Cyberpunk 2077 2025-04-19 20:32:45 +02:00
ptitSeb 549b57ee30 [INTERP] Added F2 0F BA opcode (for 2547) 2025-04-19 15:44:37 +02:00
ptitSeb 660dbfc3ad Another fix for non-dynarec build 2025-04-18 18:33:00 +02:00
ptitSeb d89ad5f1b9 This should fix non-dynarec build 2025-04-18 18:17:40 +02:00
ptitSeb 00a7d321a7 [DYNAREC] Better dynablock mempry handling, and fixed a regression introduced when improving dynmem rbtree 2025-04-18 17:57:39 +02:00
ptitSeb 4c9765cd5e Also preserve flags stuffs on signal handling when needed 2025-04-18 17:57:39 +02:00
ptitSeb fe307dbc96 [DYNAREC][TRACE] Slightly better trace message on creating dynablock 2025-04-18 17:57:39 +02:00
phorcys 518c860e5d [LA64_DYNAREC]Add/opt more SSE/MMX ops (#2543)
* Add SSE2 op MASKMOVDQU.
 * Opt PSADBW.
 * Add SSE3 HSUBPD op.
 * Add mmx PALIGNR op.
 * Fix PSRLDQ.
 * Fix PSRAW Gx,Ex PSRAW Gm,Em.
     mmx/sse get COUNT from Em/Ex as an 64bit unsigned...
     testsuite with shift 0x4,0x4,0x4,0x4, result COUNT as 0x04040404.
2025-04-18 17:09:34 +02:00
ptitSeb 053c389cfb [DYNAREC] Small improvment to callret=2 handling of path to regen a block 2025-04-18 11:58:37 +02:00
ptitSeb 81be6b1f30 Removed a function not used anymore 2025-04-18 11:57:27 +02:00
ptitSeb 3d975b090e [MMAP] Better guessing of wine process mapping regions 2025-04-18 11:56:59 +02:00
Yang Liu 882d933d84 [WOW64] Finished skeleton code for PE build (#2542)
* [WOW64] Finished skeleton code for PE build

* move musl to external
2025-04-17 12:30:59 +02:00
phorcys 9579dd9ff1 [LA64_DYNAREC] Add SSE1/SSE2's cvt mmx ops. (#2538) 2025-04-17 08:12:28 +02:00
Yang Liu 46a91e0ad9 [WOW64] More tweaks to CMake PE build (#2541) 2025-04-16 15:12:02 +02:00
ptitSeb b26a20e709 [ARM64_DYNAREC] More handling of low precision x87 flag change 2025-04-16 15:08:56 +02:00
ptitSeb d7eb87129e [DYNAREC] Introduce BOX64_DYNAREC_X87DOUBLE=2 to handle Low Precision x87 ([ARM64_DYNAREC] only for now) 2025-04-16 14:53:54 +02:00
ptitSeb 7f569247d5 Motsly commetic change in internal SIGILL handling 2025-04-16 14:51:50 +02:00
ptitSeb 1ba0ea157f [INTERP] Added x87 Precision Control set to 24bits handling 2025-04-16 12:03:13 +02:00
ptitSeb 1e64476f31 [TRACE] Better x87 infos on reg dumps 2025-04-16 12:03:13 +02:00
phorcys 96080e48cf [LA64_DYNAREC] Add mmx pack/unpack ops. (#2536)
add PUNPCKL{BW,WD,DQ}, PUNPCKH{BW,WD,DQ} mmx ops.
  add PACKSSWB PACKUSWB PACKSSDW mmx ops.
  * fix some merge mistake in prev mmx commit.
2025-04-16 08:07:08 +02:00
Yang Liu 4695a4ff3c [WOW64] Added PE build to the build system (#2537) 2025-04-15 16:50:58 +02:00
ptitSeb 8f3018e10c [ARM64_DYNAREC][TRACE][COSIM] Improve x87 fiability in dynarec trace and cosim scenario 2025-04-15 14:15:03 +02:00
ptitSeb 24b0ba9885 [ARM64_DYNAREC][TRACE] Changed TBZ/TBNZ printer to print bit offset in decimal 2025-04-15 14:14:01 +02:00
ptitSeb 4f04deadfe [ARM64_DYNAREC] Added 67 0F 29 opcode 2025-04-15 14:12:29 +02:00
ptitSeb 064c2b037e [DYNAREC] Fix on strongmem mode were last write on a seq on 1 write could be ignored 2025-04-15 13:57:55 +02:00
Yang Liu 12a90ebe98 Eliminated many compilation warnings (#2535) 2025-04-15 13:35:58 +02:00
phorcys 5cd201241b [LA64_DYNAREC] Add mmx cmp ops. (#2533) 2025-04-15 09:32:19 +02:00
Yang Liu 6b2373af93 [WOW64] Added non-functional PE build (#2532) 2025-04-14 13:34:43 +02:00
phorcys cf32412f98 [RV64_DYNAREC] fix MASKMOVQ. (#2531)
maskmovq write when sign bit == 1.
if mask byte = 0x00, should skip.
replace BLT with BLE.
2025-04-14 13:32:14 +02:00
phorcys f559bc48a4 [LA64_DYNAREC] Add mmx arith ops. (#2530) 2025-04-14 13:30:37 +02:00
phorcys 0021fbbea3 [LA64_DYNAREC] Add mmx shift ops. (#2529) 2025-04-14 11:30:02 +02:00
Yang Liu ee530a7331 [WOW64] More tweaks for PE build (#2528) 2025-04-14 11:29:22 +02:00
phorcys b7cb36d362 [LA64_DYNAREC] Optimize sse_setround (#2527) 2025-04-14 09:14:45 +02:00
phorcys 1bd471bf13 [LA64_DYNAREC] Add mmx related mov op (#2526)
* [LA64_DYNAREC] Add SSE2's MOVQ2DQ/MOVDQ2Q mmx op

* [LA64_DYNAREC] Add mmx mov ops.
2025-04-14 09:14:34 +02:00
ptitSeb 21911620c8 [INTERP] Fixed pure 32bits iretd not behaving correctly 2025-04-13 10:33:43 +02:00
ptitSeb 56f58501ec [BOX32][WRAPPER] Added a few more 32bits symbols to libc 2025-04-12 18:47:34 +02:00
ptitSeb a89748e9e5 [BOX32][WRAPPER] Added wrapped libmount and libblkid, plus 1 new wrapped function on libgbm 2025-04-12 18:34:03 +02:00
ptitSeb 91f9a58b30 [BOX32][WRAPPER] Added 32bits wrapped libselinux 2025-04-12 17:53:56 +02:00
ptitSeb fea05a30e8 [BOX32][WRAPPER] Some fixes to a few 32bits wrapped libc functions 2025-04-12 17:47:27 +02:00
ptitSeb e678e8428b [BOX32][WRAPPER] Added a few more wrapped functions to libdrm 2025-04-12 16:11:41 +02:00
ptitSeb 20377b9927 [BOX32][WRAPPER] Added 32bits wrapped libGLX 2025-04-12 15:22:14 +02:00
ptitSeb 163689d2bb [BOX32][WRAPPER] Added 32bits wrapped libEGL 2025-04-12 15:08:27 +02:00
ptitSeb e49551bda5 [BOX32][WRAPPER] Added 32bits wrapped libgbm 2025-04-12 14:54:06 +02:00
ptitSeb 514427cf8a [BOX32][WRAPPER] Added 32bits wrapped pselect function 2025-04-12 14:40:43 +02:00
ptitSeb 68f5512ee7 [BOX32][WRAPPER] Fixed 32bits wrapping for XRenderQueryFilters function 2025-04-12 14:31:54 +02:00
phorcysandphorcys b3165e62ab [LA64_DYNAREC] Update la64 mmx infra. (#2524)
Co-authored-by: phorcys <[email protected]>
2025-04-12 13:12:50 +02:00
ptitSeb 0fbf5f1896 [ANDROID] Another change on some internal structure for Android 2025-04-12 09:45:42 +02:00
ptitSeb 592a2a75bb [ANDROID] Adjusted some signals structure for Android/Bionic 2025-04-11 18:13:26 +02:00
Yang Liu 6c46e3d9b1 [WOW64] Splitted freq and cleanup functions from x64emu (#2521) 2025-04-11 12:26:51 +02:00
ptitSeb fa85d4d900 [ARM64_DYNAREC] Some more FRINTTS and AVX/SSE fixes (might help #2520) 2025-04-11 11:22:27 +02:00
ptitSeb 51d9eb966d [DYNAREC] Speedup a bit DYNAREC_DIRTY=1 2025-04-10 19:00:47 +02:00
ptitSeb 310d4016fa [BOX32] Fix a potential build issue 2025-04-10 19:00:36 +02:00
Yang Liu 0bb41a73c2 [WOW64] More tweaks towards PE build (#2519) 2025-04-10 14:09:23 +02:00
Yang Liu f9f082ee53 [WOW64] More work on the PE wow64 build (#2518)
* [WOW64] More work on the PE wow64 build

* added a TODO
2025-04-10 12:14:50 +02:00
ptitSeb 66bb1aeb89 [DYNAREC] Improved handling of db_size rbtree 2025-04-09 18:05:15 +02:00
ptitSeb 91848efa34 Reduced usage of the rbtree in FindDynablockFromAddress by creating node only on first query (in response to #2511 analysis) 2025-04-09 15:51:31 +02:00
Yang Liu 5ea247b84c Made custommem OS-independent (#2517) 2025-04-09 15:21:55 +02:00
ptitSeb 8c991cb676 [DYNAREC] Better handling of self-loop and added CALLRET=2 settings (ARM64 only, RV64 and LA64 todo) 2025-04-09 15:19:45 +02:00
ptitSeb 70770db8be Small change on Steam game launch handling 2025-04-09 14:28:23 +02:00
Yang Liu d0a5352c1a Moved emit functions to seperate files from signals.h (#2516) 2025-04-09 11:57:16 +02:00
ptitSeb 7391befb7e [BOX32][WRAPPER] Added 2 more spawn_ wrapped functions 2025-04-09 11:54:29 +02:00
Yang Liu c9b6b5fbe0 Added backtrace.h for holding backtrace-related functions (#2515) 2025-04-09 11:16:32 +02:00
Yang Liu 62765f151a [ARM64_DYNAREC] Fixed some dangling else warnings (#2514) 2025-04-09 10:35:34 +02:00
Yang Liu d592c1996d [WOW64] Add wow64 PE build scaffolding (#2513) 2025-04-08 19:12:55 +02:00
ptitSeb 8b3d4404d7 [DYNAREC] Do not mark a dynablock as always_test for loop on itself that are not alive 2025-04-08 14:22:07 +02:00
ptitSeb b060fca66c [TRACE] Change log level for wine_main_preload_info not found, as it's not always relevent on later version of wine and may disturb scipt like winetricks 2025-04-07 11:09:31 +02:00
cjy880927andchenjiangyi 4aab7a02f4 [CMAKE]: Fix arm64 build (#2507)
Log: Ensure successful compilation on devices that do not support
     cortex-a77.cortex-a55, such as those with CPU Model Cortex-A55.

Signed-off-by: chenjiangyi <[email protected]>
Co-authored-by: chenjiangyi <[email protected]>
2025-04-07 09:34:42 +02:00
ptitSeb 6d7af8674a [WRAPPER] Update generated files missing from previous PR 2025-04-06 12:25:09 +02:00
Krzysztof Aleksander Pyrkosz 5fc3188bc8 Add __localtime64 and __time64 in box32 mode (#2502) 2025-04-05 16:10:17 +02:00
Krzysztof Aleksander Pyrkosz f4f868831a Corrected arguments of my_epoll_pwait2 (#2501) 2025-04-05 15:50:56 +02:00
ptitSeb 1e89ccb17e [ARM4_DYNAREC] A few changes to seem SSE/AVX comparison and convertions opcodes, and more FRINTTS usage too 2025-04-04 16:59:44 +02:00
ptitSeb e80b595e8e [INTERP] Small changes in a few SSE/AVX convertions opcodes 2025-04-04 16:58:53 +02:00
ptitSeb ecc5375615 [ARM64_DYNAREC] Small adjustement to 2 AVX opcodes 2025-04-04 11:20:52 +02:00
phorcysandphorcys 8da0fab674 [LA64_DYNAREC] Optimize la64 MAXPD/MAXPS. (#2499)
Co-authored-by: phorcys <[email protected]>
2025-04-03 19:13:12 +02:00
Yang Liu fb955a3975 Decoupled alternate functions from bridge (#2500) 2025-04-03 19:12:33 +02:00
Yang Liu 8cd3ba8c9e [INTERP] Fixed a nan propagation issue on RISC-V (#2498) 2025-04-03 18:11:32 +02:00
Yang Liu 8cba915bca Moved more functions to os.h (#2497)
* Removed some unused function declarations

* Moved more functions to os.h

* review
2025-04-03 15:48:04 +02:00
ptitSeb cd3163a785 [INTERP] Better handling of default NAN for a few opcodes, more to come 2025-04-03 13:54:07 +02:00
ptitSeb b472459a22 [ARM64_DYNAREC] Removed some condition on vex.l that shouldn't be here on a few AVX opcodes 2025-04-03 13:53:18 +02:00
Yang Liu 42c241ee4e [CI] Enable cppThreads_32bits in the CI (#2496)
* [CI] Enable cppThreads_32bits in the CI

* switch to a specific termux mirror
2025-04-03 11:18:04 +02:00
phorcysandphorcys fb6ee29539 [LA64_DYNAREC] Add more sse ops (#2493)
fix 0F.5D/5F MINPS/MAXPS    fix unordered.
    fix 66.0F.5D/5F MINPD/MAXPD	fix unordered.
    66.0F.3A.08/09/0A ROUNDPS/ROUNDPD/ROUNDSS
    66.0F.3A.0C/0D BLENDPS/BLENDPD
    66.0F.3A.21 INSERTPS
    66.0F.C2 CMPPD
    printer add VFCMP.cond.s/d, vbitsel.v:

Co-authored-by: phorcys <[email protected]>
2025-04-03 09:48:24 +02:00
ptitSeb be6104c2ed [ARM64_DYNAREC] Small optim for VBLENDPS opcode 2025-04-02 14:25:47 +02:00
ptitSeb 3f90221b18 [ARM64_DYNAREC] Fixed an optim in BLENDPS opcode 2025-04-02 14:21:46 +02:00
Yang Liu b5c792f5f0 Moved some emit functions to os.h (#2494) 2025-04-02 13:13:07 +02:00
ptitSeb b45d75f0c4 [BOX32][WRAPPER] Added wrapped 32bits wctype to libc (for steam #2478) 2025-04-02 08:49:15 +02:00
Yang Liu b68d46311d Moved more OS-dependent functions to os.h (#2491) 2025-04-01 21:12:15 +02:00
Yang Liu 2c7a2082e6 Introduced box64cpu.h for exported interpreter and dynarec functions (#2490) 2025-04-01 19:02:07 +02:00
phorcysandphorcys 3230265646 [LA64_DYNAREC] Fix f0.80.1 LOCK OR, LoongArch ANDI is zero-extended. (#2489)
Co-authored-by: phorcys <[email protected]>
2025-04-01 15:13:45 +02:00
Yang Liu c2a77fca27 Added os.h for future usage (#2488) 2025-04-01 13:50:49 +02:00
Yang Liu 670876112e Some cosmetic changes to C header files (#2487)
* [DYNAREC] Move cosim functions to a new header

* Moved isNativeCall to elfloader
2025-04-01 12:36:12 +02:00
ptitSeb 495d3cc4c0 [CMAKE] Changed how CFLAGS and ASLFLAGS are setup and applied (for #2483) 2025-03-31 17:47:08 +02:00
ptitSeb b7ab26073e [TRACE] Do not print opcode at SIGBUS if x64pc or pc is not readable 2025-03-31 13:14:26 +02:00
ptitSeb 1c3df4b92c [DEBUG] Fixed debug tool testAllBlocks() to correctly handle new map128 custom alloc 2025-03-31 13:13:48 +02:00
ptitSeb b1ba548d62 [INTERP] Added support for F2 0F A5 opcode, ignoring F2 (for #2459) 2025-03-31 11:37:44 +02:00
ptitSeb da4f574bdd [WRAPPER] Added 2 new funciton towrapped libgdkpixbuf (for #2460) 2025-03-31 11:21:34 +02:00
ptitSeb 8561a4a833 [ARM64] Use crc32 hardware support (if available) for dynablock signature 2025-03-31 10:29:57 +02:00
ptitSeb c40f9651bc Optimized and fixed custom 128bytes allocator 2025-03-30 18:35:27 +02:00
ptitSeb 104e582253 [ARM64_DYNAREC] Another attempt to get correct assembly file handling 2025-03-30 16:00:25 +02:00
ptitSeb 03c69338f5 [ARM64_DYNAREC] Added atomic support for various lock helpers 2025-03-30 14:56:16 +02:00
ptitSeb 0fa28b87f1 [INTERP] Fixed a warning 2025-03-30 14:45:18 +02:00
ptitSeb 4ae94c5168 [CI] Another atempted fix for arm64 asm handling 2025-03-30 14:23:47 +02:00
ptitSeb a429ca70e7 [CI] Try to fix arm64/Clang build 2025-03-30 13:54:40 +02:00
ptitSeb ee760fced1 [CMAKE] Small rework on how asm file are handled 2025-03-30 13:27:23 +02:00
ptitSeb a80659075d Introduced a bitmap based allocator for <= 128bits customMalloc (not lockfree yet) 2025-03-30 11:32:49 +02:00
ptitSeb da0d0c1fc2 [RV64] Improved rv64_lock_cas[b/h] helpers 2025-03-30 11:31:55 +02:00
ptitSeb 5ea2c245d6 [LA64] Fixed la64_lock_cas_[h/b]_slow helper (rarely used) 2025-03-30 11:31:18 +02:00
ptitSeb e7b71cba5f [ARM64_DYNAREC] Fixed a potential issue with SSE regs when internal jumping to a native call 2025-03-29 10:04:19 +01:00
ptitSeb d2817e7246 [BOX32] Small changes in pthread_cond_timedwait wrapping to handle malformed timespec 2025-03-29 10:03:21 +01:00
Yang Liu 7ae8e9a86f [LA64_DYNAREC] Added more MMX opcodes (#2479) 2025-03-28 19:45:38 +01:00
Yang Liu 0a59695fb3 [LA64_DYNAREC] Added more MMX opcodes (#2477) 2025-03-28 14:32:10 +01:00
Yang Liu cfdeb3685c [LA64_DYNAREC] Added preliminary MMX support (#2476) 2025-03-28 10:54:24 +01:00
Yang Liu fdf01ace3f [LA64_DYNAREC] Added more opcodes (#2475) 2025-03-28 09:08:16 +01:00
Yang Liu 30689882f0 [LA64_DYNAREC] Added more opcodes (#2473) 2025-03-27 15:43:02 +01:00
Yang Liu d2e8ff5118 [LA64_DYNAREC] Added more opcodes (#2472) 2025-03-27 14:37:00 +01:00
Yang Liu ec385c8e75 [INTERP] Fixed Interpreter to have new test30 running on RISC-V (#2470) 2025-03-27 10:21:34 +01:00
ptitSeb 3aed032738 Some fixes to ncurses / tinfo wrapped lib (for dialog shell helper, used in some installer) 2025-03-27 10:16:37 +01:00
ptitSeb 409b5a37fb [INTERP] More NA Sign fixes for a few AVX.0F opcodes 2025-03-26 19:57:55 +01:00
ptitSeb 9587e490cc [INTERP] Fixed Interpreter to have new test30 running 2025-03-26 19:27:19 +01:00
ptitSeb ad40638345 [CI] Improved test30 (might break rv64/la64 dynarec) 2025-03-26 18:42:57 +01:00
ptitSeb 443fe043e4 [ARM64_DYNAREC] Added fastnan=0 path for HSUBPS opcode 2025-03-26 18:29:53 +01:00
ptitSeb 6d9560870d [ARM64_DYNAREC] Improved VHSUBPS opcode, and added fastnan=0 path 2025-03-26 18:29:24 +01:00
ptitSeb 95d6106e3a [ARM64_DYNAREC] Commented a message that doesn't seems relevent 2025-03-26 18:15:10 +01:00
ptitSeb 5fb1ee033e [COSIM] Changed how F0 LOCK opcodes are skipped in COSIM 2025-03-26 18:14:23 +01:00
ptitSeb fed73858c6 [ARM64_DYNAREC] Improved (V)HADDPS with fastnan=0 2025-03-26 17:59:25 +01:00
ptitSeb cb5a52bf40 [ARM64_DYNAREC] Addedfastnan=0 code to (V)SQRTPS opcodes 2025-03-26 17:41:44 +01:00
ptitSeb eaa5f8feec [ARM64_DYNAREC] Improved (V)MAXP[S/D] and (V)MINP[S/D] opcodes to more closely match x6 behavior when using fastnan=0 (for #1046) 2025-03-26 17:33:37 +01:00
ptitSeb 8c6d9f04ec [ARM64_DYNAREC] Small change on AVX.66.0F38 BA opcode to more closely match x86 behavior (for #1046) 2025-03-26 17:26:51 +01:00
Yang Liu 45f7b4991f [RV64_DYNAREC] Fixed 66 0F 6A PUNPCKHDQ opcodes (#2468) 2025-03-26 16:15:06 +01:00
Yang Liu 98151eaebf [RV64_DYNAREC] Minor improvement to DD /7 FNSTSW opcode (#2467) 2025-03-25 13:51:03 +01:00
Yang Liu 933381f5fa [RV64_DYNAREC] Fixed D9 E5 FXAM opcode (#2466) 2025-03-25 12:25:56 +01:00
Yang Liu a021fc2005 [RV64_DYNAREC] Small optim to vsetvli usage (#2465) 2025-03-25 08:59:34 +01:00
Yang Liu 75e9aae281 [RV64_DYNAREC] Fixed scratch conflicts with fastround=0 in some x87 opcodes (#2464)
* [RV64_DYNAREC] Fixed scratch conflicts with fastround=0 in some x87 opcodes

* another fix

* more fix
2025-03-24 20:23:34 +01:00
Yang Liu b0de73852c [RV64_DYNAREC] Fixed some DD prefixed x87 opcodes (#2463) 2025-03-24 13:54:01 +01:00
ptitSeb d7744ea22d [DYNAREC] Better handling of blocksize limit when generating very large dynablocks 2025-03-24 12:03:18 +01:00
ptitSeb d3d3fa25f5 [ARM64_DYNAREC] Better log for arch_populate buffer being undersized 2025-03-22 22:26:50 +01:00
ptitSeb 98162e395f [ARM64_DYNAREC] Fixed potential issue on unligned path being marked while dynablock is building 2025-03-22 22:25:56 +01:00
ptitSeb 9511d83955 [ARM64_DYNAREC][TRACE] Added a message on Dump for Unaligned path on opcodes 2025-03-22 22:24:41 +01:00
ptitSeb 10cbb3c8a9 [ARM64_DYNAREC] Added 67 66 0F 76/EF opcodes (for #1046) 2025-03-21 11:30:50 +01:00
ptitSeb 0a3fa1c918 [RCFILE] Added a few more game profiles 2025-03-21 11:30:04 +01:00
ptitSeb 75e8b9961b [WRAPPER] Reverted previus commit 2025-03-20 18:38:47 +01:00
ptitSeb 5ab56ee172 [WRAPPER] Forgot those file in previous commit 2025-03-20 18:34:33 +01:00
ptitSeb 7873b70306 [WRAPPER] Added wrapping for libavutil.so.56, libavformat.so.58 and libavcodec.so.58 (for new winedmo.so MediaFundation ffmpeg backend) 2025-03-20 18:33:42 +01:00
rajdakin 86d9d851c6 [WRAPPERHELPER] Fixed a bug due to variadic arguments (#2455) 2025-03-20 17:30:01 +01:00
ptitSeb aed08d428e [RCFILE] Fixed BOX64_EMULATED_LIBS that was broken when used inside an rcfile 2025-03-20 11:01:18 +01:00
ptitSeb affeef2380 [WRAPPER] Added a couple of GL extensions 2025-03-20 10:44:03 +01:00
Yang Liu a6c1e4126e [RCFILE] Update steamwebhelper profile (#2452) 2025-03-20 07:57:14 +01:00
Yang Liu ba630300b6 [RV64_DYNAREC] Fixed many minor issues (#2451) 2025-03-19 13:51:04 +01:00
shenmo 0e32c17076 [RCFILE] Added profile for HSR Game (#2450) 2025-03-19 12:41:26 +01:00
Yang Liu 14569db74d [DYNAREC] Fixed minor issues for F0 0F B0/B1 LOCK CMPXCHG opcodes (#2448) 2025-03-19 08:51:04 +01:00
ptitSeb c519556962 [BOX32] Small change on memory managment again 2025-03-18 17:04:06 +01:00
Yang Liu c7280d9312 [RV64_DYNAREC] Added 66 F0 0F B1 LOCK CMPXCHG opcode (#2447) 2025-03-18 12:10:24 +01:00
FZXO11 daca99017b Note about binfmt_misc (#2445)
* Note about binfmt_misc

* Notify its working on CHRoot
2025-03-18 08:10:57 +01:00
Yang Liu 546238681e [RV64_DYNAREC] More minor changes and fixes to x87 opcodes (#2443) 2025-03-17 21:58:29 +01:00
ptitSeb 87327b182f This should fix non-Dynarec build 2025-03-17 17:17:27 +01:00
ptitSeb 5b9951e1bd [BOX32] Small refactor on memory managment 2025-03-17 16:10:09 +01:00
ptitSeb 6ce22546fe [DYNAREC] Small change in strongmem to end a SEQ with a Brrier at last_write directly 2025-03-17 16:08:07 +01:00
ptitSeb 2da064d04d [DYNAREC] Change in strongmem managment to end a SEQ on jump arrival and not forget the SEQ 2025-03-17 15:54:36 +01:00
ptitSeb 77141304f6 [BOX32] Change to get all created bricks to be conitgus on 32bits, as address space is pretty small 2025-03-17 15:52:45 +01:00
ptitSeb 3336cb6248 [ARM64_DYNAREC] Small optim on special case of LOCK OR [RSP], 0 2025-03-17 15:40:20 +01:00
ptitSeb 7fa3a1e627 [ARM64_DYNAREC] Simplified 8F opcode, so special cases will be handled in signal directly if needed 2025-03-17 15:39:02 +01:00
ptitSeb d28c8aa41a [ARM64_DYNAREC] Added missing SMWRITE2 to another AVX opcode 2025-03-17 15:37:37 +01:00
ptitSeb 7b065eb17a [TRACE] Improved native backtrace, and create a function so it can be use elsewhere 2025-03-17 15:36:23 +01:00
ptitSeb 7f23664566 [ARM64_DYNAREC] Added some missing SMWRITE2 for strongmem=2 on a few AVX opcodes 2025-03-17 15:30:52 +01:00
ptitSeb d555d9661f [ARM64_DYNAREC] Added printer for RET opcodes 2025-03-17 15:29:44 +01:00
Yang Liu 18888e404e [RV64_DYNAREC] Minor D8..DF opcodes refactor (#2442) 2025-03-17 10:46:30 +01:00
Yang Liu 394513971c [RV64_DYNAREC] Minor x87 changes to enable test31 (#2441) 2025-03-17 08:12:31 +01:00
Yang Liu 8b75020036 [DOCS] Added ranged gdbjit documentation (#2440) 2025-03-17 08:09:39 +01:00
ptitSeb e1d121aa6b [BOX32][WRAPPER] Fixed signature of the ctime wrapped function 2025-03-15 15:45:56 +01:00
ptitSeb 30285d9ec6 [SYSCALL] Don't make it fatal when a unkown syscall is called, like for libc syscall 2025-03-14 11:12:32 +01:00
ptitSeb 9795027988 [RCFILE] Added one more game profile 2025-03-13 19:23:08 +01:00
ptitSeb d49fb1568e [RCFILE] Added profile for Linux Paradox Launcher 2025-03-13 18:32:29 +01:00
ptitSeb ea067beac2 [BOX32] Small changes in Signal32 handling 2025-03-13 18:09:25 +01:00
ptitSeb 8905a31469 [SYSCALL] Fixed/Improved a few syscall (help Go programs) 2025-03-13 18:08:55 +01:00
ptitSeb e6fd9c05f1 [INTERP] Fixed AVX.F2.0F38 F0 opcode 2025-03-13 15:42:14 +01:00
ptitSeb a79128e951 [CI] Repeat test for all Box32 build instead of just ARM64 one 2025-03-13 11:21:43 +01:00
Yang Liu 1793c2a182 [RV64_DYNAREC] Fixed some x87 rounding cases for fastround=0 (#2437) 2025-03-13 10:37:22 +01:00
Yang Liu b72002703e [COSIM] Show hex values in STx diff logs (#2436) 2025-03-13 10:34:29 +01:00
ptitSeb a17a97a545 [CI] Made ARM64 Box32 test to repeat a bit to avoid false negative 2025-03-13 10:27:11 +01:00
ptitSeb 0d73fc7228 [BOX32][WRAPPER] Small change on glGetStringi signature 2025-03-13 09:48:43 +01:00
Luke Short 8aab7296b8 Bundle more libs (#2419)
* [DOCS] Arch Linux does have an archive

* [BUNDLE] Simplify unsupported package message

* [BUNDLE] Archive Void Linux XBPS packages

This was an oversight to not include these but not XBPS packages
are used (yet).

* [DOCS] Fedora dependencies

List Fedora dependencies for the 'box64-bundle-x86-libs.sh' script.

* [DOCS] Fedora 34 hints

Use Fedora 34 to find missing 32-bit packages that are compatible
with Enterprise Linux 9.

* [DOCS] Add better 'dnf provides' hint

Use wildcards. This works on all versions of DNF.

* [BUNDLE] Add common libraries

as reported by various GitHub Issues.

Resolves #2390

* [DOCS] Mention essential libraries

and libraries with large dependencies. These should not be bundled.

* [BUNDLE] Remove essential libraries

and libraries with large dependencies.
2025-03-13 09:21:26 +01:00
ptitSeb 4aa7eb1187 [VULKAN] Added support for Vulkan 1.4 2025-03-12 18:53:46 +01:00
ptitSeb 1af85c69a1 [DYNAREC] Introduced DYNAREC_DIRTY=2 and changed a profile to use it 2025-03-12 14:39:07 +01:00
ptitSeb 3087ea0e61 [ENV] Fixed a crash when BOX64_ROLLING_LOG is used on command line 2025-03-11 17:38:47 +01:00
ptitSeb b0ad333ea4 [TRACE] Better logs for vulkan functions wrappers 2025-03-11 17:38:19 +01:00
ptitSeb 835ecf8a19 [WRAPPER] Added a few more Vulkan extensions 2025-03-11 16:50:00 +01:00
ptitSeb 470ff6e652 [TRACE] Small work on trace 2025-03-11 16:30:35 +01:00
ptitSeb 3ef6d28108 [RCFILE] Added 1 more game profile 2025-03-11 16:30:18 +01:00
ptitSeb fb701d8e39 [DOCS] Added BOX32 option in COMPILE.md 2025-03-11 13:00:30 +01:00
ptitSeb d4a539b957 [WRAPPER] Completed and fixed VK_NV_cooperative_vector extension 2025-03-11 10:40:25 +01:00
airidosas252 7c4c6823fe [WRAPPER] missing functions and features (#2434)
* [WRAPPER] add missing Android specific shmem symbols

It can't create X server without these symbols, it works after adding them.

* [WRAPPER] add missing android_set_abort_message symbol

* [WRAPPER] wrap VK_NV_cooperative_vector

Seems like it's needed for newer versions of Wine
2025-03-11 10:37:34 +01:00
ptitSeb 3fc677cb85 Start of a new dev. cyvcle 2025-03-11 10:09:06 +01:00
ptitSeb 2b300bd199 Bumped version to v0.3.4 2025-03-10 17:01:37 +01:00
ptitSeb 9c69ebd717 [RV64_DYNAREC] Added 66 F0 81/83 /4 opcode 2025-03-10 14:55:23 +01:00
ptitSeb ea01b56422 [RV64_DYNAREC] Reduce the number of false-positive for dynarec missing opcode 2025-03-10 14:41:40 +01:00
ptitSeb 216cf51d4a [RV64_DYNAREC] Added 66 F0 81/83 /1 opcode 2025-03-10 14:33:40 +01:00
ptitSeb 1476b502a2 [RV64_DYNAREC] Small change in F0 0F C7 opcode 2025-03-10 14:21:18 +01:00
ptitSeb bc53ae8925 [RCFIEL] Add/Adjust more game profiles 2025-03-10 12:18:24 +01:00
ptitSeb 9cef52a1fc [DYNAREC] Reduced lifetime of hotpage when using DIRTY=1 2025-03-10 12:16:05 +01:00
ptitSeb 5ed60d99a8 [DYNAREC] Don't continue a dynablock if entering an hotpage 2025-03-10 12:15:30 +01:00
Yang Liu d7c7a716fe [RV64_DYNAREC] Optimized PMOVZX and PMOVSX opcodes for vector 1.0 (#2430) 2025-03-10 09:54:20 +01:00
ptitSeb 41bee35634 [DYNAREC] Fixed some potential issue with NEVERCLEAN on memory mapping tracking 2025-03-09 11:19:52 +01:00
ptitSeb e764029cae [LA64_DYNAREC] This should fix the build 2025-03-09 07:58:50 +01:00
ptitSeb b110623103 [ARM64_DYNAREC] Improced arch_build helpers function to only compute build steps 1 time per dynablock 2025-03-08 22:38:22 +01:00
ptitSeb 35c1f97115 [ARM64_DYNAREC] Removed obsolete comment 2025-03-08 20:59:08 +01:00
ptitSeb e8a7bef5a0 [ARM64_DYNAREC] Fixed a potential issue with AVX.0F 50 opcode 2025-03-08 20:58:04 +01:00
ptitSeb c2f73e6de0 [ARM64_DYNAREC] Fixed a few potential issue with some AVX opcodes 2025-03-08 20:57:21 +01:00
ptitSeb 0724f52d5f [ARM64_DYNAREC] Fixed inlined ClearCache, re-enabling it 2025-03-08 20:33:32 +01:00
ptitSeb 61a605a2dc [ARM64_DYNAREC] Disabled inlined ClearCache as it seems not 100% efficient 2025-03-08 20:30:52 +01:00
ptitSeb 7a058c9194 [RCFILE] More game profile plus adjustment to existing ones 2025-03-08 16:03:13 +01:00
ptitSeb 99971e94c0 [TRACE] Improved a bit a few traces 2025-03-08 13:46:28 +01:00
ptitSeb 445d885090 [RCFILE] Added a game profile 2025-03-08 10:43:29 +01:00
ptitSeb fc02f0d140 [BOX32][WRAPPER] Fixed some gnutls wrapped functions (help NFS Payback from Steam) 2025-03-08 10:43:12 +01:00
ptitSeb c2d02977f8 Added F0 F7 /2 opcode ([ARM64_DYNAREC] too) 2025-03-07 20:13:41 +01:00
Yang Liu 946c999e25 [RV64_DYNAREC] Rollback some falsy optimization in the xtheadvector path (#2426) 2025-03-07 16:36:53 +01:00
ptitSeb c8b6f80f99 Removed isDBFromAddressRange and added that function to cleanDBFromAddressRange as it was used only 1 time and followed by that function anyway 2025-03-07 13:45:41 +01:00
ptitSeb 9444ce0b89 Use getProtection_fast for check_exec test, as it can be used a lot on interpreter mode 2025-03-07 11:24:27 +01:00
ptitSeb 401d2ae0b9 [WRAPPER] Do not reference epoll_pwait2 directly, to fix issues with Android and old glibc based system (also for #2425) 2025-03-07 10:59:44 +01:00
ptitSeb 8dde796103 [ARM64_DYNAREC] Small change to AVX.66.0F 7F opcode 2025-03-06 20:04:22 +01:00
ptitSeb 7ba0e7a055 [DOC] Fixed default for strongmem in docs 2025-03-06 20:03:08 +01:00
Leslie Zhai eb039c0449 Fix undefined reference to `epoll_pwait2' for LA64 ABI 1.0 (#2422) 2025-03-06 08:08:09 +01:00
ptitSeb 0c0f5263e1 [ARM64_DYNAREC] Added unaligned path for AVX.F3.0F 7F opcode 2025-03-05 11:50:35 +01:00
ptitSeb ad70febaac [ANDROID] Fixed wrapping of epoll_pwait2 to epoll_pwait timeout parameter 2025-03-04 22:44:18 +01:00
ptitSeb 39583c6da4 [ANDROID] Fix build, as epoll_pwait2 doesn't seems to exist 2025-03-04 14:36:25 +01:00
ptitSeb 1bf4851cf6 [WRAPPER] Added epoll_pwait2 wrapped function 2025-03-04 14:11:42 +01:00
liuli 2129e98b0e [WRAPPER] add gnutls_fips140_set_mode (#2417)
Change-Id: I8e9db9b5bbc16459154f30c4c29a4b1ec77c416a
2025-03-04 10:41:22 +01:00
Yang Liu b015f33376 [RV64_DYNAREC] Minor optimizations to sign mask extraction instructions for vector (#2416) 2025-03-04 08:07:45 +01:00
Yang Liu 2636e7e8b5 [RCFILE] Added range gdbjit support (#2414) 2025-03-03 10:08:50 +01:00
Yang Liu b0e726d953 [RCFILE] Fixed load addr parse issue (#2413) 2025-03-03 10:07:00 +01:00
Yang Liu eb40c49132 [CORE] Limited some syscalls for Android build (#2412) 2025-03-03 10:05:58 +01:00
ptitSeb 5dadc513db [WRAPPER] Updated auto-generated files 2025-02-26 17:56:29 +01:00
alexvorxx 4120dc10bd Fixed Box32 for Winlator Glibc (#2404)
* 1

* 2

* 3

* 4

* Fix

* 5

* 6

* 7

* 8

* revert 8

* 9
2025-02-26 17:47:42 +01:00
ptitSeb 48f51bd5fe [BOX32][WRAPPER] Use a temp xcb when converting an unknown xcb_connection instead of adding it 2025-02-25 11:46:37 +01:00
Yang Liu 940317949a [RV64_DYNAREC] Fixed some minor typos (#2406) 2025-02-23 20:29:49 +01:00
Yang Liu f9b6ea48e9 [RV64_DYNAREC] Fixed swapCache scratch register usage (#2405) 2025-02-23 19:29:59 +01:00
Hugh Cole-Baker 3567c6da2b [DEBIAN] fix typo and add box64-bash in shlibdeps excludes (#2403) 2025-02-22 22:23:51 +01:00
ptitSeb f3fe72b541 [RCFILE] Added 1 more game profile 2025-02-21 20:47:00 +01:00
ptitSeb 14966e48a6 [ARM64_DYNAREC] Fixed potential issue with SUBSET with a DF still present 2025-02-21 20:43:48 +01:00
ptitSeb 91b282235b [BOX32][ANDROID][TERMUX] revert previous commit and added a new test for shmat wrapped function (still for #2227) 2025-02-21 15:42:21 +01:00
ptitSeb 63c3e4fcf5 [INTERP] Fixed ror/rol flags on cputype=0 2025-02-21 15:28:31 +01:00
ptitSeb c740590bcd [BOX32][ANDROID][TERMUX] Use simple wrapper for shmat function on Android/Termux (for #2227) 2025-02-21 12:13:43 +01:00
ptitSeb e868c89233 [INTERP] Work on UD flags 2025-02-21 11:40:15 +01:00
Yang Liu c517d7196d [RV64_DYNAREC] Added more opcodes (#2400)
* [RV64_DYNAREC] Added more 66 0F 38 opcodes for vector

* [RV64_DYNAREC] Added more opcodes
2025-02-21 10:50:08 +01:00
Yang Liu cb42b3b00f [RV64_DYNAREC] Added more MMX opcodes for vector and fixes too (#2399)
* [RV64_DYNAREC] Fixed fallback to scalar messge

* [RV64_DYNAREC] Added more MMX opcodes for vector and fixes too
2025-02-21 09:03:19 +01:00
Yang Liu 61362b06ec Made some tweaks to banner and help message (#2397)
* Made some tweaks to banner and help message

* more tweaks

* fix nobanner
2025-02-20 18:55:37 +01:00
Yang Liu bb8559933f Made error logs prefix has red color (#2396) 2025-02-20 15:25:14 +01:00
ptitSeb c2cb333261 [ARM64_DYNAREC] More work on UD flags 2025-02-20 13:47:04 +01:00
ptitSeb b7e4cc4f50 [ARM64_DYNAREC] Fixed a typo in flag computation for PCMPESTRI and BZHI opcodes 2025-02-20 13:29:50 +01:00
Yang Liu a4908f1407 [ARM64_DYNAREC] Fixed a regression in LOCK XADD opcode (#2394) 2025-02-20 12:24:34 +01:00
ptitSeb a252e87fa9 [BOX32][INTERP] Added some support for BOUND opcode ([ARM64_DYNAREC] too) 2025-02-20 10:45:11 +01:00
ptitSeb ee3ee539e0 [BOX32][WRAPPING] Do not convert stream private field of FT_FaceRec structure 2025-02-19 20:31:28 +01:00
Yang Liu c4b79374fe [RCFILE] Added support for perfile dynarec dump (#2393) 2025-02-19 15:54:40 +01:00
Yang Liu 5dfa27ea58 [DYNAREC] Minor optimizations to SHL/SHR Ed, CL fastpath (#2392)
* [DYNAREC] Minor optimizations to SHL/SHR Ed, CL fastpath

* Fixed build

* Partially revert some fake optimizations
2025-02-19 15:04:20 +01:00
Yang Liu 49cba432c2 [CORE] Rework on function hookMangoHud (#2387) 2025-02-18 20:59:02 +01:00
Yang Liu 39a9cf903f [CORE] Display Box64 version info in mangohud (#2386)
* [CORE] Display Box64 version info in mangohud

* check for config files
2025-02-18 20:00:31 +01:00
ptitSeb 611ac3933c [LA64][WRAPPING][BOX32] Added alt name for libnsl 2025-02-18 18:12:38 +01:00
xctan fdd1509ee5 [WRAPPER] Display Box64 version in Vulkan driver info (#2385) 2025-02-18 17:33:55 +01:00
Yang Liu 52a9443f53 [RV64_DYNAREC] Fixed a regression introduced recently ([LA64_DYNAREC] too) (#2384) 2025-02-18 15:46:32 +01:00
Yang Liu 0d1488b016 Fixed dlsym_error logs prefix (#2383) 2025-02-18 10:41:48 +01:00
Yang Liu fb4662cb28 [RV64_DYNAREC] Small changes to SET_DFNONE to make it safer ([LA64_DYNAREC] too) (#2382) 2025-02-18 10:40:03 +01:00
Yang Liu 32a747979a [RV64_DYNAREC] Optimized REP MOVSB (#2381) 2025-02-18 09:26:33 +01:00
ptitSeb 362a92c158 [RCFILE] Added a setting to Talos2 2025-02-17 22:19:19 +01:00
Luke Short c27b659bce [BUNDLE] Add script to bundle x86 libraries (#2380)
This manages both x86_64 and x86 libraries. It helps with improving
emulation in all of the Box projects.
2025-02-17 21:32:12 +01:00
ptitSeb 049cbd3783 [ARM64_DYNAREC] More work on UD flags 2025-02-17 17:46:03 +01:00
Yang Liu 8b5b5aa3a7 [INTERP] Added more nops ([DYNAREC] too) (#2378) 2025-02-17 17:38:11 +01:00
Yang Liu f85b9ac664 [INTERP] Added more nops ([DYNAREC] too) (#2377) 2025-02-17 17:06:47 +01:00
Yang Liu ee5a41e21e [INTERP] Added 0F 19 NOP opcode ([DYNAREC] too) (#2376) 2025-02-17 16:29:42 +01:00
ptitSeb d49fc43791 [ARM64_DYNAREC] Continue work on UD flags 2025-02-17 14:18:49 +01:00
Yang Liu 9ec7930eb1 [INTERP] Added 66 0F 19 NOP opcode ([DYNAREC] too) (#2375) 2025-02-17 14:14:10 +01:00
Yang Liu 26dd597a1b [LA64_DYNAREC] Added more opcodes (#2374) 2025-02-17 13:49:12 +01:00
Yang Liu 040f8d9a9f [DYNAREC] Print decoded instruction mnemonics for missing opcodes if trace enabled (#2373) 2025-02-17 13:46:07 +01:00
wannacu f107321d06 [ARM64_DYNAREC] Added more AVX opcodes (#2372)
* [ARM64_DYNAREC] Fixed AVX.F2.0F 12 opcode

* [ARM64_DYNAREC] Added more AVX opcodes
2025-02-17 13:42:43 +01:00
Yang Liu 64313d5aa6 [LA64_DYNAREC] Minor optims and fixes to some opcodes (#2371) 2025-02-17 09:16:15 +01:00
Yang Liuandphorcys 71845a11bb [LA64_DYNAREC] Added more SSE4 opcodes (#2370)
Co-authored-by: phorcys <[email protected]>
2025-02-17 08:13:49 +01:00
Yang Liu e3adda8ff9 [LA64_DYNAREC] Added more opcodes (#2366)
* [LA64_DYNAREC] Added more opcodes

* fix
2025-02-17 08:13:18 +01:00
ptitSeb 85e79a8224 [ARM64_DYNAREC] Improved safeflags=2 2025-02-16 14:41:08 +01:00
ptitSeb 9ef3e080fa [ARM64_DYNAREC] More work on UD flags 2025-02-15 13:54:50 +01:00
ptitSeb 4b5f63dc6d [RCFILE] Added 1 more game profile 2025-02-15 09:47:59 +01:00
Lily 730e9d215c [BOX64RC] Add Zenless Zone Zero Config (#2363) 2025-02-15 08:57:29 +01:00
wannacu efa1cbd49a [ARM64_DYNAREC] Add some opcodes (#2358)
* [ARM64_DYNAREC] Added 66 0F 3A 41 opcode

* [ARM64_DYNAREC] Added AVX.66.0F38 DB opcode

* [ARM64_DYNAREC] Added AVX.66.0F3A DF opcode

* [ARM64_DYNAREC] Added AVX.F2.0F38 F5 opcode

* [ARM64_DYNAREC] Added 66 F3 0F BC,B8 opcode
2025-02-14 14:29:43 +01:00
ptitSeb 91798194d5 [ARM64_DYNAREC] Fixed some issue with DF handling on mayset instructions 2025-02-13 22:12:59 +01:00
Yang Liu d550f9384c [COSIM] Print decoded instruction mnemonics if trace enabled (#2357) 2025-02-13 19:08:53 +01:00
Yang Liu d59d531f14 [RV64_DYNAREC] Fixed F3 0F 11,12 opcodes for vector (#2356) 2025-02-13 18:48:33 +01:00
Yang Liu c9369c5ea1 [RV64_DYNAREC] Added a fastpath to SHL/SHR CL opcodes (#2355) 2025-02-13 17:43:59 +01:00
Yang Liu 05fd25d3bb [RV64_DYNAREC] Minor optimization to CMOV opcodes (#2354) 2025-02-13 16:58:15 +01:00
Yang Liu 2b75a0de55 [RV64_DYNAREC] Minor fixes and improvements to CMP opcodes (#2353)
* [RV64_DYNAREC] Minor fixes and improvements to CMP opcodes

* review
2025-02-13 13:51:16 +01:00
ptitSeb 59e1da5f74 [ARM64_DYNAREC] The check on REP MOVSB overlapping memory is done with saflags=1 now 2025-02-13 13:10:24 +01:00
wannacu 639466d45a [ARM64_DYNAREC] Added some BMI.0F38 opcodes (#2347)
* [ARM64_DYNAREC] Fixed BMI.0F38 F5 ocpode

* [ARM64_DYNAREC] Added BMI.0F38 F3 /2,/3 ocpode

* Added BMI.0F38 F7 opcode

* Fixed emitter mistake about CSINVxw
2025-02-13 13:07:36 +01:00
Yang Liu 95bdaf6eca [RV64_DYNAREC] Minor fixes and improvements to TEST opcodes (#2352) 2025-02-13 11:38:19 +01:00
ptitSeb 9dc10bdc47 [ARM64_DYNAREC] Small optims to AVX.66.0F38 16/18/19/36 opcodes 2025-02-13 10:20:40 +01:00
ptitSeb bf212a7b52 [ARM64_DYNAREC] Fixed LD1R and CBN/CBNZ printer 2025-02-13 10:07:36 +01:00
ptitSeb 40d83ad882 [ARM64_DYNAREC] Fixed regression introduced with b8cc8594f6 2025-02-13 09:29:09 +01:00
ptitSeb baa9efeaa6 [RCFILE] Added 2 more game profiles 2025-02-12 19:28:06 +01:00
ptitSeb 0c17b55e28 [ARM64_DYNAREC] Fixed some issue with DF and mayset opcodes 2025-02-12 19:27:39 +01:00
ptitSeb e2f4ab7700 [COSIM] Added commented way to dumps regs whe printing a difference 2025-02-12 19:26:44 +01:00
ptitSeb 84982ff86f Limit to 11 the number of cpuid invalid parameter message 2025-02-12 19:25:59 +01:00
ptitSeb cfd17e59ac [ARM64_DYNAREC] Removed obsolete comment 2025-02-12 19:25:02 +01:00
ptitSeb af0b0c6c9d [ARM64_DYNAREC] Improved some 66 F0 opcode, especially unaligned path 2025-02-12 19:24:27 +01:00
ptitSeb 0e588e444f [RCFILE] Added 2 game profiles 2025-02-12 16:26:44 +01:00
ptitSeb f575a7846e [ARM64_DYNAREC] Improved many LOCK prefixed opcodes, espcialy unaligned path 2025-02-12 15:17:01 +01:00
ptitSeb c7ff0f658b [ARM64_DYNAREC] More work on flag 2025-02-12 11:04:46 +01:00
ye-yeshun b8cc8594f6 fix VPMASKMOV and VMASKMOVP (#2342)
* fix: 0x2C: 'VMASKMOVPS Gx, Vx, Ex'

Log: VMASKMOVPS读取内存时, 如果某些mask位是0则不进行读写避免访问越界

Signed-off-by: YeshunYe <[email protected]>
Change-Id: I197fc356edcac202b5a329c50c334d0166532e93

* fix: 0x2D: 'VMASKMOVPD Gx, Vx, Ex'

Log: VMASKMOVPD读取内存时, 如果某些mask位是0则不进行读写避免访问越界

Signed-off-by: YeshunYe <[email protected]>
Change-Id: Ie11d93971aa92b141540a37bfdae0b3b060e3aea

* fix: 0x2E: 'VMASKMOVPS Ex, Gx, Vx'

Log: VMASKMOVPS写入内存时, 如果某些mask位是0则不进行读写避免访问越界

Signed-off-by: YeshunYe <[email protected]>
Change-Id: Ide5cb36dc03fc56480fdd45e7d96daed8557d849

* fix: 0x2F: 'VMASKMOVPD Ex, Gx, Vx'

Log: VMASKMOVPD写入内存时, 如果某些mask位是0则不进行读写避免访问越界

Signed-off-by: YeshunYe <[email protected]>
Change-Id: I037de8568e9d2d29597fdf08f991d54e3cb2f6d9

* fix: 0x8E: 'VPMASKMOVD/Q Ex, Vx, Gx'

Log: VPMASKMOVD/Q写入内存时, 如果某些mask位是0则不进行读写避免访问越界

Signed-off-by: YeshunYe <[email protected]>
Change-Id: I0dc98a29ed933d953e137e777bc296149d94b10b

* tests: add test for VPMASKMOV and VMASKMOVP

Log:

Signed-off-by: YeshunYe <[email protected]>

---------

Signed-off-by: YeshunYe <[email protected]>
2025-02-12 10:32:57 +01:00
ptitSeb 6197b70a9a [RCFILE] Improved support for windows setup 2025-02-12 09:20:04 +01:00
ptitSeb 60396f58c0 [ARM64_DYNAREC] Fixed F0 0F B1 ocpode (emit_cmp32 can only be used once per opcode, because of the df flags handling) 2025-02-11 22:52:52 +01:00
wannacu ee83ef4c01 [ARM64_DYNAREC] Fixed wrong COUNT operand in VPSLL{W,D,Q} (#2344) 2025-02-11 13:26:24 +01:00
Yang Liu 4b7e116aa7 [LA64_DYNAREC] Added F3 0F 52 RSQRTSS opcode (#2343) 2025-02-11 10:53:33 +01:00
ptitSeb 785d3ed5ab [ARM64_DYNAREC] Added code on safeflags=2 to check if SI/DI memory overlap on fast rep movsb opcode 2025-02-11 09:59:45 +01:00
Yang Liu 33d1727925 [LA64_DYNAREC] Added F2 0F 7D HSUBPS opcode (#2341) 2025-02-11 08:12:50 +01:00
ptitSeb a50d34e4ba [ARM64_DYNAREC] Some changes on shift opcode and OF handling, and added some new profiles 2025-02-10 15:36:43 +01:00
ptitSeb 7e0c4dcee5 [ARM64_DYNAREC] Mostly cosmetic change on (I)DIV 8bits opcode 2025-02-10 15:10:39 +01:00
Yang Liu f5174d12aa [LA64_DYNAREC] Added preliminary optimization for REP MOVSB (#2340) 2025-02-10 11:44:35 +01:00
Yang Liu 2cb25c095a [LA64_DYNAREC] Added more opcodes (#2339) 2025-02-10 08:35:38 +01:00
ptitSeb d0039c65b4 [DYNAREC] Fixed inst_size building that could be wrong when dynablock was stopped for unknown opcode or other various reason 2025-02-09 20:46:46 +01:00
Yang Liu 099bd148cb [LA64_DYNREC] Added more opcodes (#2338) 2025-02-09 16:41:58 +01:00
Yang Liu 20885702b9 [DYNAREC] Fixed diff logging prefix of pass2&3 (#2337) 2025-02-09 14:32:28 +01:00
Yang Liu 751582df05 [LA64_DYNAREC] Fixed newly added 66 0F BA /4 BT opcode (#2336) 2025-02-09 14:24:12 +01:00
ptitSeb 5212de0d66 [ARM64_DYNAREC] Fixed a potential segfault when signal happens while running Interpreter 2025-02-09 09:55:00 +01:00
Yang Liu 056bb38607 [LA64_DYNAREC] Added more opcodes (#2333) 2025-02-08 19:18:12 +01:00
Yang Liu 1a01adb2ef [ARM64_DYNAREC] Minor simplifications with the usage of GETEX (#2332) 2025-02-08 19:16:22 +01:00
Yang Liu 797731e9e2 [RV64_DYNAREC] Minor fixes and improvements on various opcodes (#2331) 2025-02-08 19:14:36 +01:00
Yang Liu 3e2c698710 [LA64_DYNAREC] Added more opcodes (#2330) 2025-02-08 18:01:53 +01:00
Yang Liu 58b24c85a2 [LA64_DYNAREC] Added more opcodes (#2328) 2025-02-08 15:45:21 +01:00
Yang Liu 28ebc1a0b7 [RV64_DYNAREC] Added aligned optim case for REP MOVSB (#2327)
* [RV64_DYNAREC] Added aligned optim case for REP MOVSB

* fixed a typo
2025-02-08 11:30:02 +01:00
ptitSeb 65487dac51 [ARM64_DYNAREC] Optimized unaligned path for REP MOVSB 2025-02-08 10:51:39 +01:00
Yang Liu 592af6db3b [ARM64_DYNAREC] Added more aligned optim cases for REP MOVSB (#2326) 2025-02-08 09:04:50 +01:00
ptitSeb 997140f500 [RCFILE] Fixed ROLLING_LOG when setup in a profile only 2025-02-07 18:55:43 +01:00
Yang Liu 16f0adec6f [LA64_DYNAREC] Added more opcodes (#2324) 2025-02-07 17:01:08 +01:00
Yang Liu ba6ff73c69 [LA64_DYNAREC] Added more opcodes (#2323) 2025-02-07 13:28:02 +01:00
Yang Liu 2bf78ea18c [LA64_DYNAREC] Added more 66 0F 38 opcodes (#2322) 2025-02-07 12:32:05 +01:00
Yang Liu fc6efb220b [LA64_DYNAREC] Fixed F3 0F MOVSLDUP opcode (#2321) 2025-02-07 12:30:04 +01:00
ptitSeb 523bfbdf3b [RCFILE] Added a new profile 2025-02-07 12:20:37 +01:00
ptitSeb 46ad2261e7 [ARM64_DYNAREC] Optimized REP MOVSB 2025-02-07 12:13:21 +01:00
Yang Liu 6c60ad4695 [RV64_DYNAREC] Small optim to 64 A1/A3 opcodes (#2320) 2025-02-07 09:57:56 +01:00
Yang Liu 37697e2ec7 [DYNAREC] Optimized grab_segdata calls on MODREG (#2319) 2025-02-07 09:38:30 +01:00
Yang Liu f5eb3c1e9b [LA64_DYNAREC] Added 64 88 MOV opcode (#2318) 2025-02-07 08:32:53 +01:00
ptitSeb 5cfd379e97 [ARM64_DYNAREC] Small optims/fixes for a few F2 0F prefixed opcodes 2025-02-06 18:11:04 +01:00
ptitSeb fecaf3111b [ARM64_DYNAREC] Added a comment in emitter on FCMP behaviour 2025-02-06 18:06:37 +01:00
ptitSeb ff6f34aadf [INTERPRETER] Small optim on HADDPS and HSUBPS 2025-02-06 18:04:52 +01:00
ptitSeb 4c3d55fb5c [ARM64_DYNAREC] Fixed fstp long double when fastround==0 2025-02-06 17:58:48 +01:00
ptitSeb d2a5005dcc [RCFILE] Adjusted MALLOC_HACK to be an integer between 0 and 2 instead of a Boolean 2025-02-06 14:46:55 +01:00
Yang Liu 05e1b422d3 [DOCS] Added per-file settings documentation (#2317) 2025-02-06 09:22:52 +01:00
ptitSeb 69f49f79e4 [DYNAREC] Fixed a potential SEGFAULT in FindDynablockFromNativeAddress, and added aprofile for BeamNG.drive linux version (for #424) 2025-02-05 23:29:43 +01:00
ptitSeb 2453eb9b2d [RCFILE] Added a new profile 2025-02-05 11:25:58 +01:00
ptitSeb 93b4813ee2 Remove memory location test for traping wine syscall, box64 doesn't need that 2025-02-05 09:48:07 +01:00
ptitSeb 7cbe71c218 [DYNAREC] Fixed a rare issue when flags would not be computed on 1st opcode of a block if a jump go there (and added a profile for fixed MGSV:TPP)" 2025-02-04 21:12:53 +01:00
ptitSeb 8bb53e1001 [ARM64_DYNAREC] Reduce the number of false positive for DYNAREC_MISSING=1 by showing only null-sized block missing opcode 2025-02-03 15:54:32 +01:00
ptitSeb f79af5afd4 [ARM64_DYNAREC] Optmized RCR Eb, CL, and fixed RCL Eb, CL opcode 2025-02-03 13:45:04 +01:00
ptitSeb 7c27085bd3 [ARM64_DYNAREC] Optimized RCL Eb, CL opcode 2025-02-03 12:18:44 +01:00
ptitSeb 53834f2b29 [ARM64_DYNAREC] Added more details on Need optim message for easier grep 2025-02-03 11:47:55 +01:00
ptitSeb 7c09957263 [ARM64_DYNAREC] Small optims on a few 66 prefixed opcodes 2025-02-03 11:34:11 +01:00
Yang Liu 242832fa3c Added auto-generated x64Int3 printer (#2311)
* Added auto-generated x64Int3 printer

* Fixed minor type errors
2025-02-02 16:46:21 +01:00
ptitSeb 9beb6b4f63 [ARM64_DYNAREC] Small improvment on 64 prefixed opcodes 2025-02-02 16:14:33 +01:00
ptitSeb 0861a88d6e [COSIM] Don't do div by 0 signal on interpreter part when testing 2025-02-02 16:11:39 +01:00
ptitSeb 1c0dc8ec7c [COSIM] Reduce false negative on rcl/rcr OF flag 2025-02-02 16:10:56 +01:00
ptitSeb b21776f9b0 [RCFILE] Add some print of NODYNAREC and DYNAREC_TEST when applyed 2025-02-02 16:10:03 +01:00
Yang Liu 998f164aa3 [ENV] More tweaks on recoding env mapping (#2309)
* [ENV] More tweaks on recoding env mapping

* review
2025-02-01 20:03:01 +01:00
Yang Liu 58d8627cea [RV64_DYNAREC] Fixed F2 0F E6 opcode for vector (#2310) 2025-02-01 19:43:10 +01:00
Yang Liu 877ca41451 [ENV] Fixed crash when rcfile does not exist (for #2295) (#2307)
* [ENV] Fixed crash when rcfile does not exist (for #2295)

* review
2025-02-01 17:29:39 +01:00
Yang Liu 94dedd47c6 [CI] Fixed xuantie-qemu build (#2306) 2025-02-01 16:04:15 +01:00
ptitSeb 1173c1d23f [ARM64_DYNAREC] Small optim and fixes to a few MMX opcodes 2025-02-01 12:06:55 +01:00
ptitSeb d9c9575e6a [RCFILE] Added one more profile 2025-02-01 12:04:43 +01:00
ptitSeb 2239f92816 [ARM64_DYNAREC] Various small fixes and optims in a few AVX opcodes 2025-01-31 16:50:51 +01:00
ptitSeb 637e177408 [ARM64_DYNAREC] Fixed mxcsr sync with fpsr on SSE_SLUSHTO0, and added a profile that needs it 2025-01-31 16:31:10 +01:00
ptitSeb bb653e6888 [ARM64_DYNAREC] Small change on defered flag handling to make sure it's marked to None when needed 2025-01-31 16:30:10 +01:00
ptitSeb 09e07973dd [INTERPRETER] Fixed some AVX opcode that would not zero upper part of register when not using vex.w 2025-01-31 16:29:09 +01:00
ptitSeb 6b7afd7f8e [DOCS] Fixed BIGBLOCK is 2 by default now 2025-01-31 14:30:19 +01:00
ptitSeb eb7858d23a [BOX32][WRAPPER] Fixed a 32bits libcups wrapped function 2025-01-30 15:23:23 +01:00
ptitSeb 1db09fe897 More improvmnet to map with fd tracking 2025-01-29 20:37:08 +01:00
ptitSeb 22a5b573d5 [RCFILE] Added some more profiles 2025-01-29 18:36:37 +01:00
ptitSeb f12f366a3d [DYNAREC] Make BIGBLOCK=2 default 2025-01-29 18:35:57 +01:00
ptitSeb b51ab081ae [ANDROID] Nope, re-disable map with fd tracking on Android 2025-01-29 18:22:09 +01:00
ptitSeb 50fcaf04b4 [ANDROID] Try to re-enable map with fd tracking on Android 2025-01-29 18:14:51 +01:00
ptitSeb 96bca6eac3 Improved map with fd tracking 2025-01-29 18:12:29 +01:00
ptitSeb ed7147e598 [WRAPPER] Added 1 wrapped function and fixed one on gstreamer 2025-01-29 11:45:23 +01:00
xctan 4892c68f17 [RV64_DYNAREC] Fixed lui/auipc immediate in the printer (#2299) 2025-01-28 08:07:42 +01:00
ptitSeb 3ab56994da Improved file map tracking, and use file map info in dynarec for bigblock setting 2025-01-27 16:35:50 +01:00
ptitSeb a54afc8e04 [ANDROID] Disable file map tracking on Android for now, as it seems to segfault 2025-01-27 16:05:43 +01:00
ptitSeb 01b5ee9c78 Improved generic mmap tracking 2025-01-27 15:03:52 +01:00
ptitSeb a513cd847b Added elf support to mmap tracking 2025-01-27 15:03:33 +01:00
ptitSeb 06b6871c80 [RCFILE] Add/Modify a few profiles 2025-01-27 13:28:14 +01:00
ptitSeb f5dc038621 [ENV] Improved a bit env var handling and per file env var 2025-01-27 13:27:58 +01:00
ptitSeb 38dce9138d [DYNAREC] Small change on DIRTY=1 to reduce hotpage effect 2025-01-27 13:27:13 +01:00
xctan 2aa5c5f337 [ENV] Fixed the type of BOX64_DYNAREC_STRONGMEM (#2298) 2025-01-27 11:36:07 +01:00
ptitSeb e6d2c12792 [INTERPRETER] Fixed a few warning 2025-01-26 16:46:23 +01:00
ptitSeb c3dbdf419d [BOX32][WRAPPER] Added some minium 32bits wrapping for libcups (helps wine) 2025-01-26 16:42:27 +01:00
ptitSeb c566ba970d [BOX32][WRAPPER] Add some minimum 32bits gnutls wrapping (helps wine) 2025-01-26 14:14:58 +01:00
ptitSeb 81925643e8 [BOX32][WRAPPER] Added some more 32bits wrapped function, and improved wrapping of 32bits ld-linux.so 2025-01-26 13:21:47 +01:00
ptitSeb 285c874e53 [AR64_DYNAREC] Removed a few more use of TABLE64 2025-01-26 13:12:37 +01:00
ptitSeb ba078c63a8 [WRAPPER] Added a few more wrapped function (to emulate recent SDL2) 2025-01-26 13:11:25 +01:00
ptitSeb a54959a6e3 [ARM64_DYNAREC] Added AVX.F3.0F38 F5 opcode 2025-01-26 13:10:36 +01:00
ptitSeb c573742845 Expanded file mapping tracking for future use (might help #2295) 2025-01-25 18:57:02 +01:00
ptitSeb dab01b8b9f [ARM64_DYNAREC] Added experimental synch of fpsr and mxcsr for the flags, when BOX64_SSE_FLUSHTO0 is used 2025-01-25 18:52:02 +01:00
xctan 9e58047980 [RV64_DYNAREC] Added unaligned codegen for MOVSW (#2296) 2025-01-25 16:03:15 +01:00
Yang Liuandxctan 6f8f37e8ff [RV64_DYNAREC] Optimized GETIP (#2294)
Co-authored-by: xctan <[email protected]>
2025-01-24 21:35:47 +01:00
Yang Liu 3ec950726b [RV64_DYNAREC] Removed some TABLE64 usage (#2291) 2025-01-24 16:02:32 +01:00
Yang Liu cec62dad44 [RV64_DYNAREC] Force priv opcode flags to be at least defered if safeflags=2 ([LA64_DYNREC] too) (#2293) 2025-01-24 15:19:18 +01:00
Yang Liu 89eca28d3a [RV64_DYNAREC] Restricted add/sub RSP optimization ([LA64_DYNAREC] too) (#2292) 2025-01-24 15:08:17 +01:00
ptitSeb 313e4854a0 Added syscall 439 (for #2290) 2025-01-24 09:54:14 +01:00
xctan 8c1ffca530 [RV64_DYNAREC] Added codegen for unaligned stores (#2289)
* [RV64_DYNAREC] Added another special SIGBUS case

* [RV64_DYNAREC] Added codegen for unaligned stores
2025-01-24 08:10:45 +01:00
Yang Liu 7099774a3c [DYNAREC] Added preliminary per-file settings (#2288) 2025-01-23 18:46:18 +01:00
ptitSeb 925f6a9922 [WRAPPER] Improved libpcap wrapping (still for #2282) 2025-01-23 14:59:22 +01:00
Yang Liu 356200159a [ENV] Fixed zydis initialization regression (#2287) 2025-01-23 14:07:38 +01:00
Yang Liu f0d8712275 Clean up UnityPlayer.dll detection from my_mmap64 (#2286) 2025-01-23 11:43:24 +01:00
ptitSeb fe3b66b018 [WRAPPER] Reworked libatk wrapping with new wrapperhelper (will help #2280) 2025-01-23 10:19:50 +01:00
ptitSeb 83af8c6cdf [WRAPPER] Added 1 more wrapped function to libnss3 (for #2280) 2025-01-23 10:11:54 +01:00
ptitSeb ad5b5ea617 [WRAPPER] Reworked libcap wrapping with new wrapperhelper 2025-01-23 10:09:58 +01:00
ptitSeb b439817467 [WRAPPER] Added wrapped libpcap with new wrapper helper (should help #2282) 2025-01-23 10:04:26 +01:00
Yang Liu 276191cdcf [LA64_DYNAREC] Added fastnan handling to more 0F opcodes (fixes CI) (#2285) 2025-01-23 08:58:30 +01:00
Yang Liu 8438b61747 [RV64_DYNAREC] Added fastnan handling to more 0F opcodes (fixes CI) (#2284) 2025-01-23 08:08:00 +01:00
ptitSeb f4a9f8dd79 [ARM64_DYNAREC] Added a few AVX opcode and Improved/Fixed some existing SSE and AVX ones 2025-01-22 20:37:17 +01:00
ptitSeb f235c7f702 [INTERPRETER] Improved (V)ADD/MUL/SUB/DIV P(S/D), and improved avx test too 2025-01-22 20:36:31 +01:00
ptitSeb 8e1e2c7840 [ARM64_DYNAREC] Remove another use of Table64 2025-01-22 17:44:52 +01:00
Yang Liu 0b632afbfe [DOCS] Auto-generated USAGE.md and box64.pod (#2283) 2025-01-22 11:56:31 +01:00
Yang Liu 89dcd2566b Fixed various issues introduced in the env infra refactor (#2281)
* Open trace file again after apply env files

* dynrec_df=1 by default

* more fixes

* more fixes

* more
2025-01-22 10:29:21 +01:00
Yang Liu 314edea645 Added [BOX64] prefix for all the stdout logs (#2279)
* Added [BOX64] prefix for all the stdout logs

* Remove some hardcoded prefix

* review
2025-01-21 19:08:09 +01:00
Yang Liu fe28bd93bd Changed some functions name and visibility (#2278) 2025-01-21 17:44:53 +01:00
Yang Liu d882a5c8fe [ENV] Optimized BOX64ENV log a bit (#2277) 2025-01-21 17:13:12 +01:00
Yang Liu 044dec0bfa [ENV] Initial refactor of env variables infrastructure (#2274)
* [ENV] Initial refactor of env variables infrastructure

* Ported BOX64_DYNAREC_LOG

* Ported more options

* Ported BOX64_MALLOC_HACK

* Ported BOX64_DYNAREC_TEST

* Ported more options

* Ported more options

* Ported more options

* Ported all options

* Removed old rcfile parser

* Fix

* review

* fix

* fix

* more fixes
2025-01-21 16:13:51 +01:00
Pablo Labs ed8b6fe9db [RCFILE] Add MiSide Profile (#2276) 2025-01-21 08:12:59 +01:00
ptitSeb c98b4c8f45 [RCFILE] Added 2 new profiles 2025-01-20 19:42:11 +01:00
ptitSeb b78d81d319 [ARM64_DYNAREC] Removed many use of TABLE64 that would just slowdown build of the dynablock for not much memory saved 2025-01-20 19:41:43 +01:00
ptitSeb 9f3be89e12 [ANDROID] Removed the forced NOLOADADDRESS build parameter for Android builds 2025-01-20 16:50:18 +01:00
ptitSeb 9e0b300354 [CI] Fixed a typo 2025-01-20 16:49:14 +01:00
ptitSeb dde6d26236 [CI] Try to use gihub arm runner on linux arm build 2025-01-20 16:41:57 +01:00
ptitSeb e6eac39759 [ARM64_DYNAREC] Small optim for DB E2 opcode 2025-01-19 15:20:43 +01:00
ptitSeb 5654e77625 [INTERPRETER] Fixed AVX.66.0F38 0E/0F opcodes 2025-01-19 13:58:06 +01:00
ptitSeb c9f01d975d [ARM64_DYNAREC] Added 64/65 1B opcode 2025-01-18 15:47:08 +01:00
ptitSeb 1fe213f900 [ARM64_DYNAREC] Fixed OF flags for rcr 8bits and 16bits 2025-01-18 15:46:48 +01:00
ptitSeb 802002b7a3 [TRACE] Added TID on Strange SIGSEGV with Access Error message 2025-01-18 12:20:34 +01:00
ptitSeb 69a7c00841 [ARM64_DYNAREC] Fixed AVX.66.0F38 17 opcode 2025-01-18 12:19:53 +01:00
ptitSeb c24f040888 [INTERPRETER] Fixed AVX.66.0F38 17 opcode and improved AVX.66.0F38 0E/0F opcodes 2025-01-18 12:19:33 +01:00
ptitSeb 0f225fc1a0 [ARM64_DYNAREC] Fixed F0 0F BA opcodes with ip relative addressing 2025-01-18 12:18:31 +01:00
ptitSeb 666506e834 [BOX32] Fixed some issue with previous commit on box32 loading wine/proton 2025-01-17 15:08:41 +01:00
ptitSeb 21c0a2e7d7 Added some hack to simulate seccomp/bpf Windows syscalls handling in proton 2025-01-17 12:24:10 +01:00
ptitSeb 03204f709e [TRACE] Fixed a typo in a debug message 2025-01-17 12:06:19 +01:00
Yang Liu 6827fc6cc9 [RV64_DYNAREC] Refined printer for more thead instructions (#2272) 2025-01-17 11:40:18 +01:00
Yang Liu cff4798249 [RV64_DYNAREC] Optimized 16bit constant RCL/RCR opcodes (#2270) 2025-01-16 13:36:23 +01:00
Yang Liu 93bf308179 [RV64_DYNAREC] Optimized 16bit constant ROR opcodes (#2268) 2025-01-16 13:18:31 +01:00
Yang Liu 166c4858a1 [RV64_DYNAREC] Optimized 16bit constant ROL opcodes (#2267) 2025-01-16 10:20:31 +01:00
Yang Liu 4b8fb02198 [ARM64_DYNAREC] Removed an unused arg in SET_DFNONE (#2266) 2025-01-16 08:20:55 +01:00
ptitSeb 8432f7d8e2 [DYNAREC] Introduce BOX64_DYNAREC_DIRTY and some profile to use it 2025-01-15 18:24:54 +01:00
ptitSeb ec675564c6 [ARM64_DYNAREC] Added one more case of fastround=2 for AVX.F2.0F 5A opcode 2025-01-15 17:05:29 +01:00
ptitSeb 8c71178238 [ARM64_DYNAREC] Added unaligned code for F3 0F 7F opcode 2025-01-15 14:23:37 +01:00
ptitSeb 72df0bd1a0 Fixed dlsym with RTLD_NEXT and preloaded libs 2025-01-15 11:48:58 +01:00
ptitSeb 6035cbd5c1 [ARM64_DYNAREC] Allow new ClearCache also for Android 2025-01-14 20:41:16 +01:00
ptitSeb d7007dd3cc Small changes on envv and arv managment 2025-01-14 20:38:00 +01:00
ptitSeb 9c5daf5954 [RCFILE] Log before applying the change 2025-01-14 20:38:00 +01:00
Yang Liu a57bc9e780 [RV64_DYNAREC] Fixed simm12 overflow in some places ([LA64_DYNAREC] too) (#2264) 2025-01-14 19:04:35 +01:00
ptitSeb 2e2bed4374 [DYNAREC] Better handling of Clear Instruction Cache, also [ARM64_DYNAREC] inlined instruction cache clear (but not for [ANDROID] to keep it safe) 2025-01-14 16:16:21 +01:00
ptitSeb 4eeaddf490 Small improvment on signal handling and db/x64pc fetching 2025-01-14 16:14:51 +01:00
Yang Liu 0cd53ca748 [RV64_DYNAREC] Fixed stack out of sync in native call (#2263) 2025-01-14 14:51:25 +01:00
Yang Liu fa2bd920bd [RV64_DYNAREC] Fixed offsetof(x64emu_t, scratch) usage overflow ([LA64_DYNAREC] too) (#2262) 2025-01-14 12:47:23 +01:00
Yang Liu 613f2cccf1 [CORE] Simplified xhead* detection and standardized extension display (#2261) 2025-01-14 09:20:25 +01:00
Yang Liu d91461f468 [RV64_DYNAREC] Fixed SET_ELEMENT_WIDTH (#2260)
... also removed some unnecessary instructions in vector_loadmask
2025-01-14 08:13:18 +01:00
ptitSeb bcc497c865 This should fix the non-dynarec build 2025-01-13 17:27:36 +01:00
ptitSeb 2414f82c38 Try to improve full x86 state gathering on Signal 2025-01-13 16:12:44 +01:00
Pablo Labs fd7d811b29 [CI] Create Box64 Packages for MiceWine (.rat) (#2256)
* [CI] Create Box64 Packages for MiceWine (.rat)

* Use Default Name on Generated .rat file
2025-01-12 08:33:56 +01:00
Yang Liu e533cd0ea1 [SIGNAL][RV64] Supported more opcodes for special cases (#2253) 2025-01-11 17:07:59 +01:00
ptitSeb 9b7e5d69b2 This should fix non-Dynarec builds 2025-01-11 13:50:54 +01:00
ptitSeb 0c5e6d867f Another attempt at fixing non-Dynarec builds 2025-01-11 13:41:27 +01:00
ptitSeb 32c646d0d2 This should fix non-Dynarec builds 2025-01-11 12:48:36 +01:00
ptitSeb 35a6828209 [ARM64_DYNAREC] Better handling unaligned access to device memory, with regeration of code 2025-01-11 12:38:35 +01:00
Yang Liu 2b66675a08 [RV64_DYNAREC] Fixed a 16bit SHR pastpath edge case (#2251) 2025-01-11 12:03:55 +01:00
ptitSeb 93638ac95a [BOX32][WRAPPER] Added 1 32bits function to libc 2025-01-11 10:26:02 +01:00
ptitSeb f489761e68 [BOX32] Improved elf memory managment for 32bits process 2025-01-11 10:26:02 +01:00
Yang Liu 56ccde005e [RV64_DYNAREC] Disabled dynamic sew on MOVDQA as a workaround (#2249) 2025-01-10 19:51:33 +01:00
Yang Liu 47e4aa0b84 [SIGNAL][RV64] Added special unaligned cases handling (#2248) 2025-01-10 15:56:43 +01:00
ptitSeb b977d84f11 [ARM64_DYNAREC] Reworked a bit DB / 7 opcode 2025-01-10 15:51:08 +01:00
ptitSeb b7f14ff338 [INTERPRETER] Small cosmetic fix for D2LD helper function 2025-01-10 15:50:32 +01:00
ptitSeb 86211e5970 [USAGE] Added some missing settings in documentation 2025-01-10 14:49:48 +01:00
ptitSeb d8669d7c7d [ARM64_DYNAREC] Fixed SQXT(U)N printer 2025-01-10 13:04:28 +01:00
ptitSeb 0d8e02a3fe Don't try to use free a custom block if init is not done 2025-01-10 12:10:57 +01:00
ptitSeb 1e681cead0 Creating an emu structure for a thread will use a minimal stack now ([BOX32] too, also using MAP_32BIT attribute) 2025-01-10 12:10:20 +01:00
ptitSeb 53f2423578 [BOX32] Better handling of pthread_mutex 2025-01-10 12:08:49 +01:00
Yang Liu 6cdfa05604 [RV64_DYNAREC] Fixed MOVMSKPS RVV 1.0 path (#2246) 2025-01-09 18:45:58 +01:00
ptitSeb d55e879879 [BOX32][WRAPPER] Added support of BOX64_MAXCPU in 32bits wrapped SDL2 2025-01-09 16:56:07 +01:00
ptitSeb d377433997 [WRAPPER] Added support of BOX64_MAXCPU in wrapped SDL2, plus some various other CPUInfo fixes 2025-01-09 16:56:07 +01:00
xctan 207073bf36 [RV64_DYNAREC] Fixed some typos (#2244)
* [RV64_DYNAREC] Fixed CMPXCHG8B

* [RV64_DYNAREC] Fixed typo
2025-01-09 08:10:41 +01:00
ptitSeb 316f31a4bb [ARM64_DYNAREC] Small fixes for some 8bits OR and XOR opcodes on regs with no flags (should help #2243 again) 2025-01-08 23:05:42 +01:00
ptitSeb ada8efcdef [ARM64_DYNAREC] Small fix for 80 /4 opcode on regs with no flags (should help #2243) 2025-01-08 19:51:46 +01:00
ptitSeb 99d0889cfd [INTERPRETER] Removed some useless tests on x87 comp 2025-01-08 15:59:14 +01:00
Hagb (Junyu Guo 郭俊余) 653a67c8ad Port rounding of some x87 instructions from Box86 (#2242)
* Port rounding of some x87 instructions from Box86

Ported from https://github.com/ptitSeb/box86/pull/951. The original pull
request and this commit also contain some improvements on precision of
`F2XM1` and `FYL2XP1`.

* Run fpu_rounding test with dynarec only for ARM64

They have been implemented on dynarec only for ARM64.
2025-01-08 15:34:15 +01:00
ptitSeb b99893d1c3 [ARM64_DYNAREC] Remove bloated x87 comp code 2025-01-08 15:08:42 +01:00
ptitSeb a5c4d01649 Updated 32bits test19 too 2025-01-08 15:08:17 +01:00
ptitSeb 82105a1543 [INTERPRETER] Improved x87 emulation a bit ([ARM64_DYNAREC] too) 2025-01-08 14:43:14 +01:00
Leslie Zhai c65910fd25 [WRAPPED] Added monstartup (#2241)
* [WRAPPED] Added monstartup

* [WRAPPED] Added monstartup for not defined STATICBUILD

* [WRAPPED] Fix monstartup wrong signature

* [WRAPPED] Change monstartup signature about STATICBUILD

* [WRAPPED] monstartup is WEAK symbol.
2025-01-08 13:46:02 +01:00
ptitSeb b5de464e85 [ARM64_DYNAREC] Added FCMEQ printer 2025-01-07 20:40:09 +01:00
ptitSeb 81eb0b45b3 [ARM64_DYNAREC]Small optimisation for 8bits and 16bits NOT opcode on register 2025-01-07 20:39:47 +01:00
ptitSeb c772d1ab49 Small fix to program break tracking 2025-01-07 15:39:02 +01:00
ptitSeb 1af7c15801 Trace program program to not allocate memory over there (help TalosPrinciple2, probably other UE5 games too) 2025-01-07 15:34:11 +01:00
ptitSeb e11901a7a6 [TRACE] Small change in Double segfault trace 2025-01-07 15:33:22 +01:00
ptitSeb 0b2f84df54 [ARM64_DYNAREC] Small optim to 8bits AND opcodes with constant and without flags 2025-01-07 15:17:42 +01:00
ptitSeb a1ff40733b [ARM64_DYNAREC] Optimized 8bits XOR when no flags is needed 2025-01-07 10:40:46 +01:00
ptitSeb a61888e06c [ARM64_DYNAREC] Optimized 8bits OR when no flags is needed 2025-01-07 09:58:13 +01:00
ptitSeb 691259ec0d [BOX32] Use 32bits malloc when building LinkMaplib 2025-01-06 20:26:44 +01:00
ptitSeb 91e678da5b [BOX32][WRAPPER] Added a few more 32bts wrapped functions to libc and libresolv 2025-01-06 20:25:54 +01:00
ptitSeb 8a7c2b5228 [INTERPRETER] Added a check of CS validity on IRET opcode 2025-01-06 17:07:19 +01:00
ptitSeb e7710f59fa [BOX32] Fixed some signature issues with wrapped libXrender 2025-01-06 17:06:44 +01:00
Leslie Zhai 4039f3c249 [WRAPPED] Added xdr_string and xdr_free (#2235)
* [WRAPPED] Added xdr_string

* [WRAPPED] Added check rpc/xdr header file

* [WRAPPED] Add xdr_free

* [WRAPPED] Use my->Func instead

* [WRAPPED] Change GOM(xdr_string) to GO(xdr_string)
2025-01-06 10:29:59 +01:00
ValdikSS 6f46ccdd5a Fix crash with incorrect argv[0]: rewrite it only if "box64" is present (#2233) 2025-01-06 08:42:08 +01:00
ptitSeb b79ba11d95 [DYNAREC] Imroved log on signal and flags/sse info gathering. [ARM64_DYNAREC] Fixed some case of nat flags being incorectly used 2025-01-05 14:59:59 +01:00
ptitSeb 5a35184ba7 [INTERPRETER] Added a few more cpu extension and associated opcodes ([ARM64_DYNAREC] added some of the new opcodes too) 2025-01-05 14:57:24 +01:00
ptitSeb db801da658 [ARM64_DYNAREC] Added a new emiter 2025-01-05 14:55:28 +01:00
ptitSeb f160fe3300 [ARM64_DYNAREC] Small improvments on (V)PMOVMSKB opcodes 2025-01-05 14:55:28 +01:00
ValdikSS 5d5dd3a3bc Document BOX64_ARG0 argv[0] rewriting variable (#2234) 2025-01-05 14:08:27 +01:00
ptitSeb 5fa65a4b38 [ARM64_DYNAREC] Small optim on specific case of XOR with -1 const 2025-01-04 12:30:28 +01:00
ptitSeb cc34c75fc3 [INTERPRETER] Fixed opcode name in comment 2025-01-04 12:30:28 +01:00
ptitSeb 7fb1a34947 [ARM64_DYNAREC] Don't simplify flags for add rsp, const when safeflags=2 is used 2025-01-04 12:30:28 +01:00
ptitSeb d087020139 [ARM64_DYNAREC] Small improvment on edge cases double to int x87 conversions 2025-01-04 12:30:28 +01:00
Leslie Zhai 4065e61ec5 [DYNAREC] Appended instruction name to symbol (#2228) 2025-01-03 14:33:45 +01:00
ptitSeb da6b799a10 [ARM64_DYNAREC] Small fixes to sse info retreiving on signal 2025-01-02 20:41:36 +01:00
ptitSeb 967c73efd1 [ARM64_DYNAREC] Fixed native flags with signal, and added sse handling 2025-01-02 19:00:49 +01:00
ptitSeb 6a35cd2a56 [ARM64_DYNAREC] Change native flags handling in signal to make it more extensible 2025-01-02 17:35:43 +01:00
ptitSeb ebf03f8878 [ARM64_DYNAREC] Improved ADCX opcode 2025-01-01 16:39:30 +01:00
ptitSeb d7dbee5126 [ARM64_DYNAREC] Improved native flags handling 2025-01-01 16:39:00 +01:00
ptitSeb 08930381e9 [ARM64_DYNAREC] Improved a bit MULX opcode 2025-01-01 12:12:19 +01:00
ptitSeb 495c98a488 [ARM64_DYNAREC] Small improvements to POPCNT and ADOX opcodes 2025-01-01 09:46:19 +01:00
ptitSeb 80a4b61e5c [BOX32] Fixed build 2024-12-31 22:34:08 +01:00
ptitSeb 1d20968f82 [ARM64_DYNAREC] Improved signal handling and flags handling (tbd on other archs) 2024-12-31 22:27:55 +01:00
ptitSeb ca8d569e63 [ARM64_DYNAREC] Fixed some issue with shrd/shld opcodes 2024-12-31 22:05:42 +01:00
ptitSeb 670770e24a [ARM64_DYNAREC] Small improvement to MULX opcode 2024-12-30 20:38:23 +01:00
ptitSeb b55b138303 [WRAPPER] Fixed a small mystake with latest ALTNAME work 2024-12-28 22:39:13 +01:00
olegos2 d0c7cb46e7 [WRAPPED][ANDROID] Add libGL ALTNAME (#2225) 2024-12-28 22:03:36 +01:00
olegos2 6e1e7de52b [ANDROID] Add a few ALTNAMEs and unwrap ifdefs for lib names (#2224)
* [WRAPPED][ANDROID] A few more ALTNAMEs

* [WRAPPED][ANDROID] Unwrap ifdefs for lib names
2024-12-28 20:13:17 +01:00
olegos2 bb0a445a6b Spelling/typo fixes in code and documentation updates (#2223)
* Fix typo DLOpenned->DLOpened

* Fix a typo in comments: versionned->versioned

* Fix a typo in comment: cleanning->cleaning

* Update COMPILE.md and USAGE.md

* A few more typos in comments
2024-12-28 17:06:51 +01:00
Chi-Kuan Chiu 7157803c03 [DOCS] Improve cross-build instructions (#2196)
Include a note for users utilizing environments
where only the box64 binary is available.
This addition ensures that users can install
the necessary libraries before running box64.
2024-12-28 16:38:11 +01:00
東雲なの b7c5adae3d Use uname -m to get CPU architecture (#2222)
Use uname -m to get CPU architecture is simplier than lscpu
2024-12-28 16:34:19 +01:00
Yang Liu 809b663350 [LA64_DYNAREC] Some minor fixes on bad variable usage (#2221) 2024-12-28 15:37:30 +01:00
ptitSeb 1c4f1cb8c2 [ARM64_DYNAREC][TRACE] Added printer for CNT opcode 2024-12-28 14:33:10 +01:00
ptitSeb cace5f0ccb [INTERPRETER] Fixed 32bits ADCX/ADOX opcodes 2024-12-28 13:50:32 +01:00
ptitSeb 4aaa0b5d24 [ARM64_DYNAREC] Fixed and improved flags for F3 0F B8 opcode 2024-12-28 12:10:13 +01:00
ptitSeb c0829b807c [INTERPRETER] Added 66 F3 0F B8 opcode 2024-12-28 12:05:31 +01:00
ptitSeb 7d3cdb06e3 [INTERPRETER] Small (mostly cosmetic) change to POCNT opcode 2024-12-28 12:05:11 +01:00
ptitSeb 42f3884478 Update README.md 2024-12-28 09:19:44 +01:00
ptitSeb fcd46e2cdc [ANDROID] Another attempt at fixing the build 2024-12-27 22:54:13 +01:00
ptitSeb f36f9d290d [ANDROID] Fix build 2024-12-27 22:43:49 +01:00
ptitSeb ae512cc4ed [ANDROID] Fixed definition of android_sigaction_t 2024-12-27 22:15:01 +01:00
ptitSeb 4fd59da003 [ANDROID] Try to fix signal handling on android 2024-12-27 22:10:24 +01:00
ptitSeb e2d7cc5011 Exposed MMXext for CPUTYPE=1 2024-12-27 18:47:32 +01:00
ptitSeb 79413a4147 [INTERPRETER] Exposed SSE4a for CPUTYPE=1, implemented all 4 opcodes 2024-12-27 18:32:37 +01:00
ptitSeb 80b357da41 [BOX32] Adapted signatures of 2 32bits libc wrapped functions 2024-12-27 18:08:06 +01:00
ptitSeb a54f516447 Introduce BOX64_CPUTYPE to choose emulating Intel or AMD cpus (no AMD specific extension yet) 2024-12-27 18:07:25 +01:00
ptitSeb 26ba1148e8 [ARM64_DYNAREC] Small optim for some specific case of slhd32 emiter 2024-12-27 13:50:19 +01:00
Yang Liu 8b2b96d5c5 [LA64_DYNAREC] Fixed some minor issues on LBT path (#2218) 2024-12-27 10:06:19 +01:00
ptitSeb e21a506936 [WRAPPER] Added 3 more wrapped functions to libxcb and freetype (for #2217) 2024-12-26 19:18:41 +01:00
ptitSeb e86c6359d6 [INTERPRETER] Improved some shift operands nd [AR64_DYNAREC] Improved shift operands and [COSIM] reduce noise on shift operands 2024-12-26 19:10:27 +01:00
ptitSeb acce64b268 [ARM64_DYNAREC] Fixed 67 8D opcode 2024-12-26 17:32:42 +01:00
Leslie Zhai 89713993cb [DYNAREC] Implement perf map (#2212)
* [DYNAREC] Implement perf map

* [DYNAREC] Use function name as the Symbol
2024-12-26 14:43:19 +01:00
Yang Liu cf24eaf9d2 [LA64_DYNAREC] Added hardware wall-clock support (#2216)
* [LA64_DYNAREC] Added hardware wall-clock support

* Refined multi-language support
2024-12-26 14:40:04 +01:00
Yang Liu cd1ac51b79 [LA64_DYNAREC] Added more opcodes (#2215) 2024-12-26 14:37:55 +01:00
Yang Liu a7ded59393 [LA64_DYNAREC] Added more opcodes (#2214) 2024-12-26 10:14:54 +01:00
Yang Liu 205ef4ddeb [LA64_DYNAREC] Added more opcodes (#2213) 2024-12-26 09:30:10 +01:00
Yang Liu 145689783f [LA64_DYNAREC] Added more opcodes and fixed CVTTPD2DQ (#2211) 2024-12-25 21:00:20 +01:00
Yang Liu 21a21b04e6 [LA64_DYNAREC] Added IRET opcode (#2210) 2024-12-25 18:52:32 +01:00
Yang Liu 87e19076ad [DYNAREC] Cleanup modreg (#2209) 2024-12-25 16:59:18 +01:00
Leslie Zhai 9492b6ca66 [LA64_DYNAREC] Added MOVLPD and MOVHPD opcodes (#2198)
* [LA64_DYNAREC] Added MOVLPD and MOVHPD opcodes

* [LA64_DYNAREC] Fix VSTELM_D idx
2024-12-25 15:56:54 +01:00
Yang Liu 4a45db781f [LA64_DYNAREC] Added more opcodes (#2208) 2024-12-25 15:40:45 +01:00
Yang Liu 0329d5fcc2 [RV64_DYNAREC] Added more opcodes ([LA64_DYNAREC] too) (#2205)
* [RV64_DYNAREC] Added 66 8E MOV opcode ([LA64_DYNAREC] too)

* Added more opcodes
2024-12-25 15:40:21 +01:00
Yang Liu f39b5514c5 [RV64_DYNAREC] Fixed various lock usage in geted ([LA64_DYNAREC] too) (#2207) 2024-12-25 15:35:47 +01:00
Yang Liu 4700a6322e [RCFILE] Added sekiro.exe entry (#2206) 2024-12-25 15:30:28 +01:00
Yang Liu 91a8fef1bb [WRAPPED] Always return ENOSYS in the deprecated sysctl (#2204) 2024-12-25 15:28:29 +01:00
Yang Liu a56a66a227 [RV64_DYNAREC] Fixed a regression in #2187 (#2203) 2024-12-24 19:38:00 +01:00
Yang Liu 1b262dac29 [LA64_DYNAREC] Added nativeflags support (#2202) 2024-12-24 18:58:49 +01:00
Yang Liu 3b15ef1cb5 [LA64_DYNAREC] Fixed 66 0F PTEST opcode (#2201) 2024-12-24 17:50:41 +01:00
Yang Liu 9ac695b9be [LA64_DYNAREC] Small optim to MOVHPS (#2200) 2024-12-24 14:19:20 +01:00
Yang Liu 05060803b2 [RV64_DYNAREC] Fixed nativeflags tmp register usage (#2199) 2024-12-24 14:06:52 +01:00
ptitSeb e84f2e4a8b [ARM64_DYNAREC] a bit more work on df=0 (still WIP) 2024-12-24 11:30:32 +01:00
DragonSWDev 6fac9ee35b Add SDL_RenderGeometryRaw wrapped function to SDL2 (#2195)
* Add SDL_RenderGeometryRaw wrapped function to SDL2

* Add missing files
2024-12-23 22:26:53 +01:00
Yang Liu 93cc31bc48 [LA64_DYNAREC] Fixed various issues in LBT path (#2197) 2024-12-23 21:29:49 +01:00
Yang Liu 13ee4acd59 [WRAPPED][BOX32] Redirected a few old symbols (#2194)
* [WRAPPED] Redirected a few old symbols

* More
2024-12-23 18:43:47 +01:00
ptitSeb 1360e7112c [ARM64_DYNAREC] Added work in progress BOX64_DYNAREC_DF env. var. 2024-12-23 13:26:52 +01:00
ptitSeb 12987af561 Fixed a warning 2024-12-23 13:26:04 +01:00
ptitSeb e071a70ec2 [DYNARC] Forgot this file from previous commit 2024-12-23 13:25:38 +01:00
ptitSeb 48db75961e [DYNAREC] Some light rework of the hotpage handling 2024-12-23 12:48:35 +01:00
ptitSeb da0820ce0a Added more rbtrees in dynarec managment, to speedup FindDynablockFromNativeAddress function 2024-12-23 12:25:56 +01:00
ptitSeb ac81132435 Try to improve clone syscal handling ([BOX32] too) 2024-12-23 12:23:18 +01:00
Yang Liu 946da43038 [LA64_DYNAREC] Fixed some LBT path issues (#2193) 2024-12-23 11:32:35 +01:00
Yang Liu cad9450e16 [LA64_DYNAREC] Optimized some 16bit shift opcodes (#2192) 2024-12-23 10:05:05 +01:00
Yang Liu 0c7cc657cc [LA64_DYNAREC] Fixed 32bit ADDIz and SUBz (#2191) 2024-12-23 08:25:29 +01:00
ptitSeb ce4590f5ba Fix build for older system (for #2190) 2024-12-23 08:24:25 +01:00
Yang Liu cd3f5ca97d [RV64_DYNAREC] Small optim to emit_and32c (#2189) 2024-12-22 21:50:05 +01:00
Yang Liu fc2a6d4dd1 [RV64_DYNAREC] Added a fast path to SHR Ew, Ib (#2188) 2024-12-22 21:41:43 +01:00
Yang Liu 85fe4c628e [RV64_DYNAREC] Made nativeflags works with 8/16bit fast path (#2187) 2024-12-22 20:30:40 +01:00
ptitSeb 1bb7d9efd8 [ARM64_DYNAREC] Reworked MUL/IMUL opcodes a bit 2024-12-22 15:22:44 +01:00
Yang Liu 25b4dd1457 [GDBJIT] Display register mapping annotations (#2185) 2024-12-22 11:17:49 +01:00
Yang Liu ea13414083 [GDBJIT] Unified the experience for all the backends (#2183) 2024-12-21 16:20:48 +01:00
ptitSeb 3e745474d3 Improved memory tracking and 32bits memory allocation 2024-12-21 15:32:17 +01:00
ptitSeb 5ad2f155c1 Changed customme block resize to lower the number of realloc 2024-12-21 12:33:22 +01:00
ptitSeb 945b4192b1 [WRAPPER] Fixed a few uninitized value used warning from Vamgrind 2024-12-21 12:33:22 +01:00
ptitSeb 3b71ba6090 [ARM64_DYNAREC] Improved DMB/DSB printer 2024-12-21 12:33:22 +01:00
Leslie Zhai 9fc4697233 [LA64_DYNAREC] Added ROUNDSD and CVTDQ2PD opcodes (#2173)
* [LA64_DYNAREC] Added ROUNDSD and CVTDQ2PD opcodes

* [LA64_DYNAREC] Added round_round

* [LA64_DYNAREC] Remove redundant instruction

* [LA64_DYNAREC] Remove useless assembler

* [LA64_DYNAREC] Made round_round more readable
2024-12-20 16:47:18 +01:00
ptitSeb 8a37b12f81 Simplified ucontext uc_link managment (closer to glibc handling) ([BOX32] too) 2024-12-20 15:39:27 +01:00
Yang Liu 6ac7d7a1db [GDBJIT] Display DynaRec info in source file (#2179)
* [GDBJIT] Display DynaRec info in source file

* fix
2024-12-20 12:59:03 +01:00
ptitSeb 291db1530c [LA64] This should fix static build 2024-12-20 12:38:57 +01:00
ptitSeb e77ea1b45c [WRAPPER] Added 1 more libc wrapped function 2024-12-20 11:43:52 +01:00
ptitSeb 80db0175e0 [WRAPPER] Added a few glib2 wrapped functions 2024-12-20 11:42:14 +01:00
ptitSeb 15f90899eb [BOX32] Don't abort when stack pointer is not correct on new thread, but return an error 2024-12-20 11:21:40 +01:00
ptitSeb e2ce483e0d [BOX32][WRAPPER] Improved obstack handling 2024-12-20 11:04:28 +01:00
ptitSeb 41b31dc58d [BOX32] use malloc_trim when it gives non 32bits pointers 2024-12-20 11:04:28 +01:00
Yang Liu f8b9c7b2b7 [LA64_DYNAREC] A few minor optimizations (#2174) 2024-12-19 16:20:16 +01:00
ptitSeb a8000cb629 [BOX32] More fixes on libc wrapping 2024-12-19 13:57:33 +01:00
ptitSeb 17f2371804 [BOX32] Boosted xcbconnection slot from 8 to 16 2024-12-19 10:35:00 +01:00
Leslie Zhai 4d377de5ab [LA64_DYNAREC] Added CLC and PMOVZXBW opcodes (#2172) 2024-12-19 09:34:54 +01:00
Leslie Zhai 956f6ffc15 [LA64_DYNAREC] Fix VPICKVE2GR_WU typo (#2171)
* [LA64_DYNAREC] Fix VPICKVE2GR_WU typo

* [LA64_DYNAREC] Fix VPICKVE2GR_BU|HU_DU typo
2024-12-19 08:11:39 +01:00
Yang Liu 600ae18d4b [RV64_DYNAREC] Fixed 32bits SUBz (#2170) 2024-12-18 21:47:06 +01:00
Yang Liu 39aa02c19c [RV64_DYNAREC] Added more LOCK prefix opcodes (#2169) 2024-12-18 21:38:17 +01:00
Yang Liu 7dcb86f500 [RV64_DYNAREC] Fixed 32bit ADDIz (#2168) 2024-12-18 20:54:08 +01:00
Yang Liu f873255a19 [RV64_DYNAREC] Fixed CMPXCHG8B (#2167) 2024-12-18 18:43:06 +01:00
Yang Liu 4662ab1c80 [RV64_DYNAREC] Added unaligned support to CMPXCHG8B opcode (#2166) 2024-12-18 18:13:52 +01:00
ptitSeb b0b34e3a2a Improved handling of stack size and addresses attribute for threads ([BOX32] too) 2024-12-18 17:18:26 +01:00
ptitSeb 631da8a532 Added an helper function to abort and backtrace (used in [BOX32] when pointer address not 32bits compatible) 2024-12-18 17:15:21 +01:00
ptitSeb f80886fd68 [ELFLOADER] Do not fornul dlclose remaining libs at exit, just lest dependancies do the unload (help gogdl and nile) 2024-12-18 17:14:04 +01:00
ptitSeb cbe7ced335 Simplfied env var and trace file initial managment 2024-12-18 16:13:30 +01:00
Yang Liu 955f6e74ab [GDBJIT] Refined RV64 and LA64 support (#2165) 2024-12-18 15:26:17 +01:00
Yang Liu 8a982e8b5e [LA64_DYNAREC] Added POPCNT opcode and fixed an issue too (#2164) 2024-12-18 09:15:21 +01:00
Yang Liu 47f5fe7caf [GDBJIT] Show x64pc in gdb, also added documentation (#2163)
* [GDBJIT] Show x64pc in gdb

* Add env. variable and documentation

* typo

* oops
2024-12-18 08:11:09 +01:00
Yang Liu 6e0f32f4ca Added initial GDBJIT support (#2162)
* Added GDBJIT support

* fix

* fix
2024-12-17 22:01:33 +01:00
ptitSeb 62eca11bee [BOX32][TRACE] Improved trace of wrapped functions 2024-12-17 14:49:08 +01:00
ptitSeb 13f5ec1524 [BOX32] Small change on how tls memory is allocated 2024-12-17 14:48:05 +01:00
ptitSeb e751d41ba7 Some (mostly) cosmetic change to x64emu initializers 2024-12-17 14:46:09 +01:00
ptitSeb 7fd884b9c1 [BOX32][WRAPPER] More fixes to sendmsg/rcvmsg wrapping (fixes some wine 32bits stuffs) 2024-12-17 14:42:53 +01:00
ptitSeb a98887589d [BOX32] Improved pre-reserve highmem, and use that memory for dynablocks 2024-12-17 13:22:20 +01:00
ptitSeb 0882f910df [BOX32][WRAPPING] Added 32bits wrapped libxcb-res and fixes some wrapped functions from libxcb 2024-12-17 09:15:59 +01:00
xctan f65c22d329 [RV64_DYNAREC] Extended simple wrapper for more int types (#2160) 2024-12-17 08:23:51 +01:00
xctan 485959195e [CMAKE] Fixed linking issue with mold (#2159) 2024-12-17 08:19:53 +01:00
ptitSeb 28fb1bb0c0 [BOX32][WRAPPER] Silence some conversion warnings 2024-12-16 14:41:44 +01:00
ptitSeb cc12620868 [WRAPPER] Added wrapped libxcb-res with new wrapperhelper 2024-12-16 13:18:26 +01:00
ptitSeb 9c89e64691 [WRAPPER] Reworked libxcb wrapping with new wrapperhelper 2024-12-16 12:52:19 +01:00
ptitSeb d432b18d23 [BOX32][WRAPPER] Added 32bits wrapped libxcb 2024-12-16 12:41:05 +01:00
ptitSeb 98c0811525 [BOX32][WRAPPER] Prepare xcb_connection_t* align functions 2024-12-16 10:52:27 +01:00
ptitSeb 77b16ae30d [BOX32][WRAPPER] Prepare xcb_connection_t* as n on box32 2024-12-16 10:51:41 +01:00
ptitSeb f4a4bdd006 [BOX32][WRAPPER] Added 32bits wrapped libx11-xcb 2024-12-16 10:04:51 +01:00
Leslie Zhai ed7dddc3d8 [LA64_DYNAREC] Added PTEST opcode (#2158) 2024-12-16 15:26:20 +08:00
Yang Liu 4c6401c66b [RV64_DYNAREC] Fixed more regressions (#2157) 2024-12-15 20:05:37 +01:00
ptitSeb 42441c99cc [BOX32][WRAPPER] More fixes on 32bits libc wrapping 2024-12-15 17:48:49 +01:00
ptitSeb f775474062 [BOX32] Try to impove pthread_cond_t handling 2024-12-15 17:04:58 +01:00
ptitSeb c30e012e8d [BOX32][WRAPPER] Some fixes to struct msghdr alignment functions 2024-12-15 17:04:26 +01:00
ptitSeb d90522bc4e [BOX32] Rollback simplied alignment of msghdr as cmsg also needs alignment (some docs are eroneous about cmsg_len field type) 2024-12-15 16:07:25 +01:00
ptitSeb 0f7bec0d38 [BOX32][WRAPPER] Moved all function wrapped from wrappedresolv.c to libc_net32.c (still should help #2156) 2024-12-15 15:39:50 +01:00
ptitSeb 201b971ad7 [BOX32][WRAPPER] Try to fix build issue for older system (for #2156) 2024-12-15 15:36:53 +01:00
ptitSeb 1c72527dc8 [BOX32][WRAPPER] Some work on 32bits xcb_connection 2024-12-15 14:57:07 +01:00
ptitSeb 5ce3e29913 [BOX32][WRAPPER] More work on libc wrapping, and some new syscall too 2024-12-15 14:15:34 +01:00
ptitSeb 1a7cff559a [BOX32][WRAPPER] Added mtrace and muntrace to 32bits wrapped libc (for #2155) 2024-12-15 11:19:04 +01:00
Yang Liu c28b0629fa [WRAPPER] Made gtkclass.c less likely to be recompiled (#2153) 2024-12-15 10:00:22 +01:00
ptitSeb 6a3c56c131 [BOX32][WRAPPER] More fixes to libc and libX11 wrapping 2024-12-14 22:51:31 +01:00
ptitSeb d03c85da90 [BOX32][WRAPPER] More fixes to libc and X11 wrapping 2024-12-14 20:56:07 +01:00
ptitSeb 6a5d831331 [BOX32][WRAPPER] Fixes and improves libc wrapping 2024-12-14 19:43:20 +01:00
ptitSeb 2164c564f2 [DYNAREC] Revert default BOX64_DYNAREC_PAUSE to 0 (for #2152) 2024-12-14 17:05:48 +01:00
ptitSeb 2a33cf4e60 [BOX32][WRAPPER] Many fixes and improvments to X11 wrapping 2024-12-14 17:04:17 +01:00
ptitSeb 6698a844f6 [BOX32][WRAPPER] Added more 32bits wrapped functions 2024-12-13 17:50:05 +01:00
ptitSeb 1c5ccefdef [BOX32][WRAPPER] Added a few more libc 32bits wrapped functions 2024-12-13 16:54:54 +01:00
ptitSeb 64bfd06be4 [BOX32][WRAPPER] Added a few 32bits wrapped function libnsl 2024-12-13 16:46:12 +01:00
ptitSeb 5bf154195d [BOX32][WRAPPER] Added a few more 32bits wrapped libc functions 2024-12-13 16:42:21 +01:00
ptitSeb 0239305f69 [BOX32][WRAPPER] Added empty 32bits wrapped libnsl 2024-12-13 16:31:37 +01:00
ptitSeb 3ee5558c70 [BOX32][WRAPPER] Added a 32bits dummy libvdpau wrapped lib 2024-12-13 16:19:12 +01:00
ptitSeb 059dc12adc [BOX32][WRAPPER] Added 32bits wrapped libdrm with new wrapperhelper 2024-12-13 16:05:50 +01:00
ptitSeb 610c63cd15 [BOX32][WRAPPER] Added a few more libc and libresolv 32bits wrapped functions 2024-12-13 15:38:13 +01:00
ptitSeb fa3db3df11 [BOX32][WRAPPER] Added a arge batch of 32bits wrapped function to X11 and friends 2024-12-13 15:24:11 +01:00
Yang Liu 4b4c0143d9 [RV64_DYNAREC] Optimize push/pop with xtheadmemidx (#2150)
* [RV64_DYNAREC] Optimize push/pop with xtheadmemidx

* fix
2024-12-13 14:57:28 +01:00
ptitSeb fa76ce1f05 [BOX32][WRAPPER] Added 3 more 32bits wrapped function to libcairo 2024-12-13 11:16:37 +01:00
ptitSeb 59bb9c2083 [BOX32][WRAPPER] Added more SDL2 32bts wrapped functions 2024-12-13 10:51:15 +01:00
ptitSeb 689d64b62a [BOX32][WRAPPER] Added 1 more libc 32bits wrapped funciton, and fixed an existing one 2024-12-13 10:30:43 +01:00
Yang Liu f6c3386960 [RV64_DYNAREC] Fixed some TO_NAT usages (#2149) 2024-12-13 08:13:33 +01:00
Yang Liu 5055866a5a [RV64_DYNAREC] Reinitialize sew after callret (#2148) 2024-12-13 08:12:18 +01:00
xctan 9f7d0c4404 [RV64_DYNAREC] Reworked ZEROUP and freed t0 (#2147)
* [RV64_DYNAREC] Reworked ZEROUP and freed t0

* [RV64_DYNAREC] Removed the definition of xMASK
2024-12-12 19:54:08 +01:00
ptitSeb 7e5aa3e7c6 [BOX32][WRAPPER] Added a few more 32bits wrapped function to libc 2024-12-12 13:34:59 +01:00
ptitSeb c7afc0b3df [BOX32][WRAPPER] Added 32bits wrapped libXdamage 2024-12-12 13:15:43 +01:00
ptitSeb 566ff08109 [BOX32][WRAPPER] Added 32bits wrapped libcairo 2024-12-12 13:09:07 +01:00
ptitSeb 2247b61ed3 [BOX32][WRAPPER] Added a few more 32bits wrapped function to libfontconfig 2024-12-12 11:53:13 +01:00
Yang Liu 55d6971a23 [RV64_DYNAREC] New register mapping (#2139)
* [RV64_DYNAREC] New register mapping

* Fix
2024-12-12 11:51:24 +01:00
Leslie Zhai 7168167400 [LA64_DYNAREC] Added more opcodes (#2145)
* [LA64_DYNAREC] Added more opcodes

* [LA64_DYNAREC] Optimize MOVZX Gw, Eb
2024-12-12 11:23:17 +01:00
ptitSeb 7e17c862cf [WRAPPER] Checked pangoft2 wrapping with new wrapperhelper 2024-12-12 10:58:27 +01:00
ptitSeb bb60cc8568 [BOX32][WRAPPER] Added more libc and libresolv 32bits wrapped functions 2024-12-12 10:48:14 +01:00
ptitSeb 857c4600dc [BOX32][WRAPPER] Another fix for older / strict compiler (for #2141) 2024-12-11 20:11:39 +01:00
ptitSeb 88bd65998f [BOX32][WRAPPER] Added one more 32bits libX11 wrapped function 2024-12-11 18:14:28 +01:00
ptitSeb ecbd382ae4 [BOX32] added a few more libc 32bits wrapped functions 2024-12-11 18:09:44 +01:00
ptitSeb 16f63a94c3 [BOX32][WRAPPER] Try to fix some build issue on older system (for #2140) 2024-12-11 18:03:30 +01:00
ptitSeb bd7ff2efd6 [ARM64_DYNAREC] Force flags to be at least defered when priv opcode is run on safeflags=2 2024-12-11 17:56:05 +01:00
ptitSeb ed21342995 [DYNAREC] Small improvments on flags when end of block if trigger early 2024-12-11 17:55:13 +01:00
ptitSeb 4c238f0e17 [ARM64_DYNAREC] Better hadnling of flags on btx opcode familly ([COSIM] and improved undefined flags when running with cosim) 2024-12-11 17:54:17 +01:00
ptitSeb 7c000adb87 [INTERPRETER][COSIM] Better flags for btx opcode familly when running cosim 2024-12-11 17:53:17 +01:00
ptitSeb 2d4f073925 [COSIM] Try to get more stable result on x87 stacks by unwinding status before calling cosim 2024-12-11 11:39:03 +01:00
ptitSeb a25aab1426 [BOX32] Added a workaround for older system (should help #2138) 2024-12-11 10:10:02 +01:00
Leslie Zhai 54f593fa75 [WRAPPER] Added libcairo.so.2 as one of NEEDED_LIBS for gtk3 (#2136) (#2137) 2024-12-11 09:23:17 +01:00
Leslie Zhai 054de8e83f [LA64] SIGRTMAX is 127 for ABI 1.0 (#2134)
* [LA64] SIGRTMAX is 127 for ABI 1.0

* [LA64] Added LARCH64_ABI_1 CMake option

* [LA64] Change MAX_SIGNAL to 128 for ABI 1.0
2024-12-11 08:10:58 +01:00
ptitSeb e6d1bf78a6 [BOX32][WRAPPER] Added 1 more 32bits libX11 wrapped function 2024-12-10 18:19:48 +01:00
ptitSeb b4b8617a92 [BOX32][WRAPPER] Fixed time signature (now steamcmd connect) 2024-12-10 18:06:10 +01:00
ptitSeb 20bad4e126 [BOX32][WRAPER] Improved pthread_mutex handling, and better trace for mutex wrapped on LOG_DEBUG 2024-12-10 18:05:14 +01:00
ptitSeb 3650609975 [BOX32][TRACE] Improved trace for a few libc calls 2024-12-10 18:03:16 +01:00
ptitSeb fe3b30ccbb [RCFILE] Added 1 more profile 2024-12-10 15:25:33 +01:00
ptitSeb ccae82e1f5 [DOC] Small improment on USAGE.md 2024-12-10 15:25:33 +01:00
Leslie ZhaiandYang Liu f1addb8b28 [LA64_DYNAREC] Added more 660F opcodes (#2127)
* [LA64_DYNAREC] Added more 660F opcodes

* [LA64_DYNAREC] Change VREPLGR2VR_D to VXOR_V

* [LA64_DYNAREC] Optimize PMULHRSW

Co-authored-by: Yang Liu <[email protected]>

---------

Co-authored-by: Yang Liu <[email protected]>
2024-12-10 10:48:24 +01:00
ptitSeb 96f5108a37 [INTERPRETER] Added 64bits 67 A1 opcode ([ARM64_DYNAREC] Too) 2024-12-09 13:16:13 +01:00
ptitSeb 3eeb10c0a6 [BOX32][WRAPPER] Better wrapping for shmat 2024-12-09 13:06:50 +01:00
ptitSeb ce3d2afad2 Change log level to INFO for Wine prereserve issues (for #2123) 2024-12-08 16:12:15 +01:00
ptitSeb bdee719767 [BOX32] Improved mutex handling, again 2024-12-08 14:51:29 +01:00
ptitSeb 42263e0be9 [BOX32][WRAPPER] Fixed some more typo on Xcursor wrapping (might help #2109) 2024-12-08 12:03:54 +01:00
ptitSeb ca08012bbf [BOX32][WRAPPER] Added a couple of 32bits wrapped functions to libc 2024-12-08 09:41:31 +01:00
Jim Huang ca47ee273e [CORE] Refine runtime messages (#2125)
This commit addresses inconsistent runtime messages by correcting
grammatical errors and typos, and properly handling singular and plural
forms.
2024-12-07 17:07:14 +01:00
Leslie Zhai eb299f500b [LA64_DYNAREC] Added AES opcodes (#2122)
* [LA64_DYNAREC] Added AES opcodes

* [LA64_DYNAREC] Use LSX instruction instead
2024-12-07 09:58:20 +01:00
ptitSeb a25b50d3aa Start of a new dev. cycle 2024-12-07 09:50:11 +01:00
ptitSeb b735a8663e Update README.md 2024-12-06 16:19:58 +01:00
687 changed files with 75566 additions and 22363 deletions

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@ MaxEmptyLinesToKeep: 2
IndentCaseLabels: true
AlignConsecutiveMacros: true
WhitespaceSensitiveMacros: ['QUOTE']
IfMacros: ['IFX', 'IFXORNAT', 'IFX2', 'IFXA', 'IFX_PENDOR0', 'IFXX', 'IFX2X', 'IFXN', 'UFLAG_IF', 'PASS2IF']
IfMacros: ['IFX', 'IFXORNAT', 'IFX2', 'IFXA', 'IFX_PENDOR0', 'IFXX', 'IFX2X', 'IFXN', 'UFLAG_IF', 'PASS2IF', 'IF_UNALIGNED', 'IF_ALIGNED']
UseTab: Never
IndentPPDirectives: None
---
+75 -19
View File
@@ -27,9 +27,9 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [X64, RISCV, RK3588, ARM64, ANDROID, TERMUX, LARCH64, ANDROID_GLIBC]
platform: [X64, RISCV, RK3588, ARM64, ANDROID, TERMUX, LARCH64, ANDROID_GLIBC, WOW64]
type: [Release, Trace, StaticBuild, Box32]
os: [ubuntu-latest]
os: [ubuntu-latest, ubuntu-22.04-arm]
exclude:
- platform: ANDROID
type: StaticBuild
@@ -41,6 +41,30 @@ jobs:
type: Box32
- platform: TERMUX
type: Box32
- platform: X64
os: ubuntu-22.04-arm
- platform: RISCV
os: ubuntu-22.04-arm
- platform: RK3588
os: ubuntu-latest
- platform: ARM64
os: ubuntu-latest
- platform: ANDROID
os: ubuntu-22.04-arm
- platform: TERMUX
os: ubuntu-22.04-arm
- platform: LARCH64
os: ubuntu-22.04-arm
- platform: ANDROID_GLIBC
os: ubuntu-latest
- platform: WOW64
os: ubuntu-latest
- platform: WOW64
type: Trace
- platform: WOW64
type: StaticBuild
- platform: WOW64
type: Box32
runs-on: ${{ matrix.os }}
steps:
@@ -53,8 +77,9 @@ jobs:
if [[ ${{ matrix.platform }} != 'X64' && ${{ matrix.platform }} != 'RISCV' && ${{ matrix.platform }} != 'LARCH64' ]]; then
sudo apt-get -y install git cmake make python3 patchelf
if [[ ${{ matrix.platform }} == 'ANDROID' || ${{ matrix.platform }} == 'TERMUX' ]]; then
wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip
unzip android-ndk-r26b-linux.zip
sudo apt-get -y install p7zip
wget -q https://dl.google.com/android/repository/android-ndk-r26b-linux.zip
unzip -qq android-ndk-r26b-linux.zip
echo "BOX64_COMPILER=$PWD/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android31-clang" >> $GITHUB_ENV
echo "BOX64_PLATFORM_MARCRO=-DANDROID=1 -DARM_DYNAREC=1 -DBAD_SIGNAL=1" >> $GITHUB_ENV
git clone https://github.com/termux/termux-docker.git
@@ -63,16 +88,23 @@ jobs:
sudo chmod 755 -R /system
elif [[ ${{ matrix.platform }} == 'ANDROID_GLIBC' ]]; then
sudo apt-get -y install git gcc-aarch64-linux-gnu
echo "BOX64_PLATFORM_MARCRO=-DARM64=1 -DARM_DYNAREC=1 -DBAD_SIGNAL=1" >> $GITHUB_ENV
echo "BOX64_PLATFORM_MARCRO=-DARM64=1 -DWINLATOR_GLIBC=1 -DARM_DYNAREC=1 -DBAD_SIGNAL=1" >> $GITHUB_ENV
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
elif [[ ${{ matrix.platform }} == 'WOW64' ]]; then
sudo apt-get -y install git gcc-aarch64-linux-gnu
echo "BOX64_PLATFORM_MARCRO=-DWOW64=1 -DARM_DYNAREC=1" >> $GITHUB_ENV
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
export LLVM_MINGW_VERSION=20250430
wget -q https://github.com/mstorsjo/llvm-mingw/releases/download/${LLVM_MINGW_VERSION}/llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-ubuntu-22.04-aarch64.tar.xz
tar -xf llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-ubuntu-22.04-aarch64.tar.xz
echo "MINGW_COMPILER_PATH=$PWD/llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-ubuntu-22.04-aarch64/bin" >> $GITHUB_ENV
else
sudo apt-get -y install git gcc-aarch64-linux-gnu
echo "BOX64_PLATFORM_MARCRO=-D${{ matrix.platform }}=1" >> $GITHUB_ENV
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
fi
if [[ ${{ matrix.platform }} == 'TERMUX' ]]; then
sudo apt-get -y install p7zip
wget https://mirrors.utermux.dev/termux/termux-main/pool/main/liba/libandroid-sysv-semaphore/libandroid-sysv-semaphore_0.1_aarch64.deb
wget https://packages.termux.dev/apt/termux-main/pool/main/liba/libandroid-sysv-semaphore/libandroid-sysv-semaphore_0.1_aarch64.deb
7z x libandroid-sysv-semaphore_0.1_aarch64.deb
tar -xf data.tar.xz
sudo cp -rf data /
@@ -92,7 +124,7 @@ jobs:
elif [[ ${{ matrix.platform }} == 'RISCV' ]]; then
echo BOX64_PLATFORM_MARCRO="-DRV64=ON" >> $GITHUB_ENV
echo "BOX64_COMPILER=riscv64-linux-gnu-gcc" >> $GITHUB_ENV
sudo apt-get -y install git gcc-riscv64-linux-gnu cmake make python3 ninja-build
sudo apt-get -y install git gcc-riscv64-linux-gnu cmake make python3 ninja-build libglib2.0-dev
elif [[ ${{ matrix.platform }} == 'LARCH64' ]]; then
sudo mkdir /usr/local/larch
wget -O- -q https://github.com/loongson/build-tools/releases/download/2023.08.08/CLFS-loongarch64-8.1-x86_64-cross-tools-gcc-glibc.tar.xz | sudo tar -C /usr/local/larch --strip-components=1 --xz -xf -
@@ -177,6 +209,7 @@ jobs:
- name: "Build Box64"
run: |
export PATH=$PATH:${{ env.MINGW_COMPILER_PATH }}
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=${{ env.BOX64_COMPILER }}\
@@ -241,13 +274,8 @@ jobs:
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS
ctest $CTEST_OPTIONS
elif [[ ${{ matrix.platform }} != 'X64' ]]; then # AArch64
export INTERPRETER=qemu-aarch64-static
export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu/
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS
elif [[ ${{matrix.type}} == 'Box32' ]]; then
ctest $CTEST_OPTIONS
BOX64_DYNAREC_TEST=1 ctest $CTEST_OPTIONS -E nocosim
else
ctest -j$(nproc)
fi
@@ -256,6 +284,9 @@ jobs:
id: git-info
run: echo "SHORT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: "Get Box64 Version"
run: echo "BOX64_VERSION=$(cat src/box64version.h | grep BOX64_MAJOR | cut -d " " -f 3).$(cat src/box64version.h | grep BOX64_MINOR | cut -d " " -f 3).$(cat src/box64version.h | grep BOX64_REVISION | cut -d " " -f 3)" >> $GITHUB_ENV
- name: "Packaging WCP file for Winlator"
if: matrix.platform == 'ANDROID_GLIBC' && matrix.type != 'StaticBuild'
run: |
@@ -277,11 +308,22 @@ jobs:
patchelf --set-interpreter /data/data/com.winlator/files/imagefs/usr/lib/ld-linux-aarch64.so.1 ./box64
tar --zstd -cf box64-latest.wcp box64 profile.json
- name: "Upload Artifact"
uses: actions/upload-artifact@v4
with:
name: box64-${{ matrix.platform }}-${{ matrix.type }}
path: build/box64
- name: "Package Rat File for MiceWine"
if: matrix.platform == 'ANDROID' && matrix.type != 'StaticBuild'
run: |
cd build
mkdir -p files/usr/bin
cp box64 files/usr/bin
echo "name=Box64 (CI Build)" > pkg-header
echo "category=Box64" >> pkg-header
echo "version=${BOX64_VERSION}-${SHORT_COMMIT}" >> pkg-header
echo "architecture=aarch64" >> pkg-header
echo "vkDriverLib=" >> pkg-header
7z -tzip -mx=5 a box64-latest.rat files pkg-header
- name: "Upload WCP file"
if: matrix.platform == 'ANDROID_GLIBC' && matrix.type != 'StaticBuild'
@@ -289,3 +331,17 @@ jobs:
with:
name: box64-latest-${{ matrix.type }}-wcp
path: build/box64-latest.wcp
- name: "Upload Rat File"
if: matrix.platform == 'ANDROID' && matrix.type != 'StaticBuild'
uses: actions/upload-artifact@v4
with:
name: box64-MiceWine-${{ matrix.type }}
path: build/box64-latest.rat
- name: "Upload WowBox64 file"
if: matrix.platform == 'WOW64' && matrix.type == 'Release'
uses: actions/upload-artifact@v4
with:
name: wowbox64-${{ matrix.type }}
path: build/wowbox64-prefix/src/wowbox64-build/wowbox64.dll
+14
View File
@@ -73,3 +73,17 @@ backup/
# macOS
.DS_Store
# Archives
*.7z
*.deb
*.eopkg
*.gz
*.rar
*.rpm
*.tar*
*.xbps
*.xz
*.zip
*.zst
*.zstd
+195 -81
View File
@@ -30,9 +30,10 @@ option(LX2160A "Set to ON if targeting an LX2160A based device" ${LX2160A})
option(ARM64 "Set to ON if targeting a generic ARM64 based device" ${ARM64})
option(ANDROID "Set to ON if targeting an Android device" ${ANDROID})
option(TERMUX "Set to ON if targeting an Android device with Termux" ${TERMUX})
option(WINLATOR_GLIBC "Set to ON if targeting an Android device with Winlator Glibc" ${WINLATOR_GLIBC})
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
option(SAVE_MEM "Set to ON to build dynarec with some slower memory saving optimisations" ${SAVE_MEM})
option(SAVE_MEM "Set to ON to build dynarec with some slower memory saving optimizations" ${SAVE_MEM})
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box64" OFF)
option(NOGIT "Set to ON if not building from a git clone repo (like when building from a zip download from github)" ${NOGIT})
option(BAD_SIGNAL "Set to ON to activate the workaround for incoherent si_info on SIGSEGV" ${BAD_SIGNAL})
@@ -41,6 +42,9 @@ option(CI "Set to ON if running in CI" ${CI})
option(WITH_MOLD "Set to ON to use with mold" ${WITH_MOLD})
option(BOX32 "Set to ON to add Linux 32bits support (experimental, do not use)" ${BOX32})
option(BOX32_BINFMT "Also setup binfmt integration for box32" ${BOX32_BINFMT})
option(LARCH64_ABI_1 "Set to ON if building for Loongarch64 ABI 1.0 system" ${LARCH64_ABI_1})
option(GDBJIT "Set to ON to enable GDB JIT support" ${GDBJIT})
option(WOW64 "Set to ON if you want a WOW64 PE build in addition")
if(TERMUX)
set(TERMUX_PATH "/data/data/com.termux/files")
@@ -52,6 +56,10 @@ if(LARCH64)
set(ARM_DYNAREC OFF CACHE BOOL "")
set(RV64_DYNAREC OFF CACHE BOOL "")
set(LARCH64_DYNAREC ON CACHE BOOL "")
if(LARCH64_ABI_1)
message(STATUS "Build for Loongarch64 ABI 1.0 system")
add_definitions(-DLA64_ABI_1)
endif()
endif()
if(RV64)
set(LD80BITS OFF CACHE BOOL "")
@@ -86,10 +94,15 @@ if(SW64)
endif()
if(ANDROID)
set(TERMUX_PATH "/data/data/com.termux/files")
set(NOLOADADDR ON CACHE BOOL "")
#set(NOLOADADDR ON CACHE BOOL "") #no need to force this setting it seems now
set(BAD_SIGNAL ON CACHE BOOL "")
endif()
if(GDBJIT)
message(STATUS "Build with GDBJIT support")
add_definitions(-DGDBJIT)
endif()
option(LD80BITS "Set to ON if host device have 80bits long double (i.e. i386)" ${LD80BITS})
option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NOALIGN})
option(ARM_DYNAREC "Set to ON to use ARM Dynamic Recompilation" ${ARM_DYNAREC})
@@ -129,68 +142,53 @@ endif()
if(RPI3ARM64)
add_definitions(-DRPI)
add_definitions(-DRPI3ARM64)
add_definitions(-pipe -march=armv8-a+crc -mtune=cortex-a53)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc -mtune=cortex-a53")
set(CFLAGS -pipe -march=armv8-a+crc -mtune=cortex-a53)
elseif(RPI4ARM64)
add_definitions(-DRPI)
add_definitions(-DRPI4ARM64)
add_definitions(-pipe -march=armv8-a+crc -mtune=cortex-a72)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc -mtune=cortex-a72")
set(CFLAGS -pipe -march=armv8-a+crc -mtune=cortex-a72)
elseif(RPI5ARM64)
add_definitions(-DRPI)
add_definitions(-DRPI5ARM64)
add_definitions(-pipe -march=armv8.2-a+crc+crypto+fp16+rcpc+dotprod -mtune=cortex-a76)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.2-a+crc+crypto+fp16+rcpc+dotprod -mtune=cortex-a76")
set(CFLAGS -pipe -march=armv8.2-a+crc+crypto+fp16+rcpc+dotprod -mtune=cortex-a76)
elseif(RK3326)
add_definitions(-DRK3326)
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a35+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a35+crypto")
set(CFLAGS -pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a35+crypto)
elseif(RK3399)
add_definitions(-DRK3399)
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a72.cortex-a53+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a72.cortex-a53+crypto")
set(CFLAGS -pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a72.cortex-a53+crypto)
elseif(RK3588)
add_definitions(-DRK3588)
add_definitions(-pipe -mcpu=cortex-a76.cortex-a55+crypto)
add_definitions(-DBAD_SIGNAL)
set(CMAKE_ASM_FLAGS "-pipe -mcpu=cortex-a76.cortex-a55+crypto")
set(CFLAGS -pipe -mcpu=cortex-a76.cortex-a55+crypto)
elseif(ODROIDN2)
add_definitions(-DODROIDN2)
add_definitions(-march=armv8-a+crc+simd+crypto -mcpu=cortex-a73.cortex-a53+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a73.cortex-a53+crypto")
set(CFLAGS -march=armv8-a+crc+simd+crypto -mcpu=cortex-a73.cortex-a53+crypto)
elseif(TEGRAX1)
add_definitions(-DTEGRAX1)
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a57+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a57+crypto")
set(CFLAGS -pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a57+crypto)
elseif(TEGRA_T194)
add_definitions(-DTEGRA_T194)
add_definitions(-pipe -march=armv8.2-a+fp16+simd+crypto+predres -mcpu=cortex-a76+crypto -mtune=cortex-a76)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.2-a+fp16+simd+crypto+predres -mcpu=cortex-a76+crypto -mtune=cortex-a76")
set(CFLAGS -pipe -march=armv8.2-a+fp16+simd+crypto+predres -mcpu=cortex-a76+crypto -mtune=cortex-a76)
elseif(TEGRA_T234)
add_definitions(-DTEGRA_T234)
add_definitions(-pipe -march=armv8.2-a+fp16+simd+crypto+predres -mcpu=cortex-a78ae+crypto -mtune=cortex-a78ae)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.2-a+fp16+simd+crypto+predres -mcpu=cortex-a78ae+crypto -mtune=cortex-a78ae")
set(CFLAGS -pipe -march=armv8.2-a+fp16+simd+crypto+predres -mcpu=cortex-a78ae+crypto -mtune=cortex-a78ae)
elseif(PHYTIUM)
add_definitions(-DPHYTIUM)
add_definitions(-pipe -march=armv8.1-a+crc+simd+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.1-a+crc+simd+crypto+aes")
set(CFLAGS -pipe -march=armv8.1-a+crc+simd+crypto)
elseif(SD845)
add_definitions(-DSD845)
add_definitions(-pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a75.cortex-a55)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a75.cortex-a55")
set(CFLAGS -pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a75.cortex-a55)
elseif(SD865)
add_definitions(-DSD865)
#note that cortex-a77.cortex-a55 is not supported, so fall back to a76 instead
add_definitions(-pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a76.cortex-a55)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a76.cortex-a55")
set(CFLAGS -pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a76.cortex-a55)
elseif(SD888)
add_definitions(-DSD888)
add_definitions(-pipe -march=armv8.4-a+simd+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.4-a+simd+crypto")
set(CFLAGS -pipe -march=armv8.4-a+simd+crypto)
elseif(SD8G2)
add_definitions(-DSD8G2)
add_definitions(-pipe -march=armv9-a+i8mm+sm4+sha3+rcpc+crypto+nosve+nosve2)
set(CMAKE_ASM_FLAGS "-pipe -march=armv9-a+i8mm+sm4+sha3+rcpc+crypto+nosve+nosve2")
set(CFLAGS -pipe -march=armv9-a+i8mm+sm4+sha3+rcpc+crypto+nosve+nosve2)
elseif(SDORYON1)
add_definitions(-DSDORYON1)
# NOTE
@@ -207,37 +205,38 @@ elseif(SDORYON1)
# * the 3rd positional argument is represented as the "scheduler"
# * the 6th positional argument is represented as the "cost"
# I've chosen the a57 because I don't know if I should choose the a72
add_definitions(-pipe -march=armv8.6-a+crypto+sm4+sha3+fp16 -mtune=cortex-a57)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.6-a+crypto+sm4+sha3+fp16 -mtune=cortex-a57")
set(CFLAGS -pipe -march=armv8.6-a+crypto+sm4+sha3+fp16 -mtune=cortex-a57)
elseif(ADLINK)
add_definitions(-DADLINK)
add_definitions(-pipe -mcpu=neoverse-n1 -fuse-ld=gold -fuse-linker-plugin)
set(CMAKE_ASM_FLAGS "-pipe -mcpu=neoverse-n1")
set(CFLAGS -pipe -mcpu=neoverse-n1 -fuse-ld=gold -fuse-linker-plugin)
elseif(M1)
add_definitions(-DM1)
add_definitions(-pipe -march=armv8.5-a+simd+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.5-a+simd+crypto")
set(CFLAGS -pipe -march=armv8.5-a+simd+crypto)
elseif(LARCH64)
add_definitions(-DLA64)
add_definitions(-pipe -march=loongarch64)
set(CMAKE_ASM_FLAGS "-pipe -march=loongarch64")
set(CFLAGS -pipe -march=loongarch64)
set(ASMFLAGS -pipe -march=loongarch64)
elseif(RV64)
add_definitions(-DRV64)
add_definitions(-pipe -march=rv64gc)
set(CMAKE_ASM_FLAGS "-pipe -march=rv64gc")
set(CFLAGS -pipe -march=rv64gc)
set(ASMFLAGS -pipe -march=rv64gc)
elseif(PPC64LE)
add_definitions(-DPPC64LE)
elseif(LX2160A)
add_definitions(-DLX2160A)
add_definitions(-pipe -march=armv8-a+crypto+crc -mcpu=cortex-a72+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crypto+crc -mcpu=cortex-a72+crypto")
set(CFLAGS -pipe -march=armv8-a+crypto+crc -mcpu=cortex-a72+crypto)
elseif(SW64)
add_definitions(-DSW64)
elseif(ARM64)
#add_definitions(-pipe -march=native)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+simd")
elseif(ARM_DYNAREC)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto")
endif()
if(ARM_DYNAREC)
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "9.0")
set(ASMFLAGS -pipe -march=armv8.2-a+crc+simd+crypto)
else()
#putting a random cpu that have 8.2 architecture so assembly can be build. the use of the feature are conditionnal anyway
set(ASMFLAGS -pipe -mcpu=cortex-a76)
endif()
endif()
if(ANDROID)
add_definitions(-DANDROID)
@@ -245,6 +244,9 @@ endif()
if(TERMUX)
add_definitions(-DTERMUX)
endif()
if(WINLATOR_GLIBC)
add_definitions(-DWINLATOR_GLIBC)
endif()
if(BAD_SIGNAL)
add_definitions(-DBAD_SIGNAL)
endif()
@@ -256,7 +258,7 @@ if(STATICBUILD)
add_definitions(-DSTATICBUILD)
add_definitions(-Wno-deprecated-declarations) #by-design, deprecated function can be used
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")
set(CMAKE_EXE_LINKER_FLAGS -static)
set(HAVE_TRACE OFF)
endif()
if(BOX32)
@@ -345,6 +347,17 @@ set_source_files_properties(
PROPERTIES GENERATED TRUE
HEADER_FILE_ONLY TRUE)
set(OS_LINUX_SRC
"${BOX64_ROOT}/src/os/backtrace.c"
"${BOX64_ROOT}/src/os/emit_signals_linux.c"
"${BOX64_ROOT}/src/os/freq_linux.c"
"${BOX64_ROOT}/src/os/os_linux.c"
"${BOX64_ROOT}/src/os/perfmap.c"
"${BOX64_ROOT}/src/os/symbolfuncs_linux.c"
"${BOX64_ROOT}/src/os/my_cpuid_linux.c"
"${BOX64_ROOT}/src/os/my_cpuid_common.c"
)
set(ELFLOADER_SRC
"${BOX64_ROOT}/src/main.c"
"${BOX64_ROOT}/src/core.c"
@@ -358,8 +371,10 @@ set(ELFLOADER_SRC
"${BOX64_ROOT}/src/elfs/elfhash.c"
"${BOX64_ROOT}/src/elfs/elfload_dump.c"
"${BOX64_ROOT}/src/elfs/elfdwarf_private.c"
"${BOX64_ROOT}/src/emu/entrypoint.c"
"${BOX64_ROOT}/src/emu/x64compstrings.c"
"${BOX64_ROOT}/src/emu/x64emu.c"
"${BOX64_ROOT}/src/emu/x64printer.c"
"${BOX64_ROOT}/src/emu/x64int3.c"
"${BOX64_ROOT}/src/emu/x87emu_private.c"
"${BOX64_ROOT}/src/emu/x64primop.c"
@@ -380,13 +395,16 @@ set(ELFLOADER_SRC
"${BOX64_ROOT}/src/tools/bitutils.c"
"${BOX64_ROOT}/src/tools/box64stack.c"
"${BOX64_ROOT}/src/tools/bridge.c"
"${BOX64_ROOT}/src/tools/alternate.c"
"${BOX64_ROOT}/src/tools/callback.c"
"${BOX64_ROOT}/src/tools/my_cpuid.c"
"${BOX64_ROOT}/src/tools/cleanup.c"
"${BOX64_ROOT}/src/tools/gdbjit.c"
"${BOX64_ROOT}/src/tools/fileutils.c"
"${BOX64_ROOT}/src/tools/pathcoll.c"
"${BOX64_ROOT}/src/tools/rbtree.c"
"${BOX64_ROOT}/src/tools/rcfile.c"
"${BOX64_ROOT}/src/tools/env.c"
"${BOX64_ROOT}/src/tools/wine_tools.c"
"${BOX64_ROOT}/src/tools/pe_tools.c"
"${BOX64_ROOT}/src/wrapped/generated/wrapper.c"
)
if(NOT STATICBUILD)
@@ -411,6 +429,7 @@ if(BOX32)
"${BOX64_ROOT}/src/librarian/globalsymbols32.c"
"${BOX64_ROOT}/src/libtools/myalign32.c"
"${BOX64_ROOT}/src/libtools/myalign64_32.c"
"${BOX64_ROOT}/src/libtools/myalignxcb32.c"
"${BOX64_ROOT}/src/libtools/signal32.c"
"${BOX64_ROOT}/src/libtools/threads32.c"
"${BOX64_ROOT}/src/libtools/libc_net32.c"
@@ -446,6 +465,7 @@ set(INTERPRETER
"${BOX64_ROOT}/src/emu/x64run66dd.c"
"${BOX64_ROOT}/src/emu/x64run66f0.c"
"${BOX64_ROOT}/src/emu/x64run67.c"
"${BOX64_ROOT}/src/emu/x64run6764.c"
"${BOX64_ROOT}/src/emu/x64run67avx.c"
"${BOX64_ROOT}/src/emu/x64run67_32.c"
"${BOX64_ROOT}/src/emu/x64run6764_32.c"
@@ -558,6 +578,9 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedlcms2.c"
"${BOX64_ROOT}/src/wrapped/wrappedldlinux.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibasound.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibavcodec58.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibavformat58.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibavutil56.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibbsd.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibc.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibcmusl.c"
@@ -620,6 +643,7 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedlibxcbrandr.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibxcbrender.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibxcbrenderutil.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibxcbres.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibxcbshape.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibxcbshm.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibxcbsync.c"
@@ -660,6 +684,7 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedpangocairo.c"
"${BOX64_ROOT}/src/wrapped/wrappedpangoft2.c"
"${BOX64_ROOT}/src/wrapped/wrappedpam.c"
"${BOX64_ROOT}/src/wrapped/wrappedpcap.c"
"${BOX64_ROOT}/src/wrapped/wrappedplc4.c"
"${BOX64_ROOT}/src/wrapped/wrappedplds4.c"
"${BOX64_ROOT}/src/wrapped/wrappedpng16.c"
@@ -767,7 +792,7 @@ if(NOT CI)
OUTPUT "${BOX64_ROOT}/src/wrapped/generated/functions_list.txt"
COMMAND "${PYTHON_EXECUTABLE}" "${BOX64_ROOT}/rebuild_wrappers.py"
"${BOX64_ROOT}"
"PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "ANDROID" "TERMUX" "STATICBUILD" "--"
"PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "ANDROID" "TERMUX" "STATICBUILD" "LA64" "--"
${WRAPPEDS_HEAD}
MAIN_DEPENDENCY "${BOX64_ROOT}/rebuild_wrappers.py"
DEPENDS ${WRAPPEDS} ${WRAPPEDS_HEAD}
@@ -816,6 +841,7 @@ if(BOX32)
"${BOX64_ROOT}/src/wrapped32/wrappedfreetype.c"
"${BOX64_ROOT}/src/wrapped32/wrappedfontconfig.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibx11.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibxdamage.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibxext.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibxfixes.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibxrender.c"
@@ -827,10 +853,27 @@ if(BOX32)
"${BOX64_ROOT}/src/wrapped32/wrappedlibxxf86vm.c"
"${BOX64_ROOT}/src/wrapped32/wrappedxinerama.c"
"${BOX64_ROOT}/src/wrapped32/wrappedexpat.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibx11xcb.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibxcb.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibxcbres.c"
"${BOX64_ROOT}/src/wrapped32/wrappedudev0.c"
"${BOX64_ROOT}/src/wrapped32/wrappedudev1.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibuuid.c"
"${BOX64_ROOT}/src/wrapped32/wrappedgnutls.c"
"${BOX64_ROOT}/src/wrapped32/wrappedtcmallocminimal.c"
"${BOX64_ROOT}/src/wrapped32/wrappedcairo.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibdrm.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibvdpau.c"
"${BOX64_ROOT}/src/wrapped32/wrappednsl.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibcups.c"
"${BOX64_ROOT}/src/wrapped32/wrappedgbm.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibegl.c"
"${BOX64_ROOT}/src/wrapped32/wrappedlibglx.c"
"${BOX64_ROOT}/src/wrapped32/wrappedselinux.c"
"${BOX64_ROOT}/src/wrapped32/wrappedblkid.c"
"${BOX64_ROOT}/src/wrapped32/wrappedmount.c"
"${BOX64_ROOT}/src/wrapped32/wrappeddbus.c"
"${BOX64_ROOT}/src/wrapped32/wrappedcurl.c"
)
endif()
string(REPLACE ".c" "_private.h" MODROOT ${BOX64_ROOT})
@@ -841,7 +884,7 @@ if(BOX32)
set(WRAPPEDS32_HEAD ${WRAPPEDS32_HEAD} ${B})
set_source_files_properties(${A} PROPERTIES OBJECT_DEPENDS ${B})
endforeach()
set(WRAPPER32 "${BOX64_ROOT}/src/wrapped32/generated/wrapper32.c" "${BOX64_ROOT}/src/wrapped32/generated/wrapper32.h")
if(NOT CI)
@@ -849,7 +892,7 @@ if(BOX32)
OUTPUT "${BOX64_ROOT}/src/wrapped32/generated/functions_list.txt"
COMMAND "${PYTHON_EXECUTABLE}" "${BOX64_ROOT}/rebuild_wrappers_32.py"
"${BOX64_ROOT}"
"PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "ANDROID" "TERMUX" "STATICBUILD" "--"
"PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "ANDROID" "TERMUX" "WINLATOR_GLIBC" "STATICBUILD" "--"
${WRAPPEDS32_HEAD}
MAIN_DEPENDENCY "${BOX64_ROOT}/rebuild_wrappers_32.py"
DEPENDS ${WRAPPEDS32} ${WRAPPEDS32_HEAD}
@@ -877,10 +920,13 @@ if(ARM_DYNAREC)
${DYNAREC_SRC}
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_functions.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_arch.c"
"${BOX64_ROOT}/src/dynarec/arm64/arm64_immenc.c"
"${BOX64_ROOT}/src/dynarec/arm64/arm64_printer.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_jmpnext.c"
)
set(DYNAREC_ASM
${DYNAREC_ASM}
"${BOX64_ROOT}/src/dynarec/arm64/arm64_prolog.S"
"${BOX64_ROOT}/src/dynarec/arm64/arm64_epilog.S"
"${BOX64_ROOT}/src/dynarec/arm64/arm64_next.S"
@@ -937,10 +983,13 @@ if(RV64_DYNAREC)
${DYNAREC_SRC}
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_functions.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_arch.c"
"${BOX64_ROOT}/src/dynarec/rv64/rv64_printer.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_jmpnext.c"
"${BOX64_ROOT}/src/rv64detect.c"
)
set(DYNAREC_ASM
${DYNAREC_ASM}
"${BOX64_ROOT}/src/dynarec/rv64/rv64_prolog.S"
"${BOX64_ROOT}/src/dynarec/rv64/rv64_epilog.S"
"${BOX64_ROOT}/src/dynarec/rv64/rv64_next.S"
@@ -998,7 +1047,9 @@ if(LARCH64_DYNAREC)
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_functions.c"
"${BOX64_ROOT}/src/dynarec/la64/la64_printer.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_jmpnext.c"
)
set(DYNAREC_ASM
${DYNAREC_ASM}
"${BOX64_ROOT}/src/dynarec/la64/la64_prolog.S"
"${BOX64_ROOT}/src/dynarec/la64/la64_epilog.S"
"${BOX64_ROOT}/src/dynarec/la64/la64_next.S"
@@ -1016,14 +1067,22 @@ if(LARCH64_DYNAREC)
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_64.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_66.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_6664.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_67.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_f30f.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_660f.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_66f0.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_66f20f.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_66f30f.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_67.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_f0.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_f20f.c"
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_f30f.c"
)
endif()
if(GDBJIT)
set(GDBJITREADER "${BOX64_ROOT}/gdbjit/reader.c")
endif()
if(DYNAREC)
set(DYNAREC_PASS
"${BOX64_ROOT}/src/wrapped/generated/wrapper.h"
@@ -1036,18 +1095,22 @@ if(DYNAREC)
)
endif()
add_library(dynarec_native OBJECT ${DYNAREC_SRC})
set_source_files_properties(${DYNAREC_PASS} PROPERTIES COMPILE_OPTIONS "${CFLAGS}")
set_source_files_properties(${DYNAREC_ASM} PROPERTIES COMPILE_OPTIONS "${ASMFLAGS}")
set_source_files_properties(${INTERPRETER} PROPERTIES COMPILE_OPTIONS "${CFLAGS}")
add_library(dynarec_native OBJECT ${DYNAREC_SRC} ${DYNAREC_ASM})
add_library(native_pass0 OBJECT ${DYNAREC_PASS})
set_target_properties(native_pass0 PROPERTIES COMPILE_FLAGS "-DSTEP=0")
set_target_properties(native_pass0 PROPERTIES COMPILE_DEFINITIONS "STEP=0")
add_library(native_pass1 OBJECT ${DYNAREC_PASS})
set_target_properties(native_pass1 PROPERTIES COMPILE_FLAGS "-DSTEP=1")
set_target_properties(native_pass1 PROPERTIES COMPILE_DEFINITIONS "STEP=1")
add_library(native_pass2 OBJECT ${DYNAREC_PASS})
set_target_properties(native_pass2 PROPERTIES COMPILE_FLAGS "-DSTEP=2")
set_target_properties(native_pass2 PROPERTIES COMPILE_DEFINITIONS "STEP=2")
add_library(native_pass3 OBJECT ${DYNAREC_PASS})
set_target_properties(native_pass3 PROPERTIES COMPILE_FLAGS "-DSTEP=3")
set_target_properties(native_pass3 PROPERTIES COMPILE_DEFINITIONS "STEP=3")
add_library(test_interpreter OBJECT ${INTERPRETER})
set_target_properties(test_interpreter PROPERTIES COMPILE_FLAGS "-DTEST_INTERPRETER")
set_target_properties(test_interpreter PROPERTIES COMPILE_DEFINITIONS "TEST_INTERPRETER")
add_dependencies(native_pass0 WRAPPERS)
add_dependencies(native_pass1 WRAPPERS)
add_dependencies(native_pass2 WRAPPERS)
@@ -1067,14 +1130,20 @@ if(DYNAREC)
$<TARGET_OBJECTS:native_pass3>
$<TARGET_OBJECTS:test_interpreter>
)
if(GDBJIT)
add_library(box64gdbjitreader SHARED ${GDBJITREADER})
endif()
endif()
set_source_files_properties(${OS_LINUX_SRC} ${ELFLOADER_SRC} ${INTERPRETER} ${WRAPPEDS} ${WRAPPEDS32} PROPERTIES COMPILE_OPTIONS "${CFLAGS}")
# creates git_head.h
if(DYNAREC)
add_custom_command(
OUTPUT "${BOX64_ROOT}/src/git_head.h"
COMMAND sh -c "echo \\\#define GITREV \\\"$(git rev-parse --short HEAD)\\\">\"${BOX64_ROOT}/src/git_head.h\""
DEPENDS dynarec ${ELFLOADER_SRC} ${INTERPRETER} ${WRAPPEDS} ${WRAPPEDS32}
DEPENDS ${DYNAREC_SRC} ${DYNAREC_ASM} ${DYNAREC_PASS} ${ELFLOADER_SRC} ${INTERPRETER} ${WRAPPEDS} ${WRAPPEDS32}
VERBATIM)
else()
add_custom_command(
@@ -1084,9 +1153,19 @@ else()
VERBATIM)
endif()
add_custom_target(generate_git_head_target
DEPENDS "${BOX64_ROOT}/src/git_head.h"
)
add_custom_target(functions_list DEPENDS "${BOX64_ROOT}/src/wrapped/generated/functions_list.txt" "${BOX64_ROOT}/src/wrapped32/generated/functions_list.txt")
add_dependencies(generate_git_head_target functions_list)
add_library(interpreter OBJECT ${INTERPRETER})
add_executable(${BOX64} ${ELFLOADER_SRC} ${WRAPPEDS} ${WRAPPEDS32} "${BOX64_ROOT}/src/git_head.h")
add_library(mainobj OBJECT ${OS_LINUX_SRC} ${ELFLOADER_SRC} ${WRAPPEDS} ${WRAPPEDS32})
add_dependencies(mainobj generate_git_head_target)
add_executable(${BOX64})
target_link_libraries(${BOX64} mainobj)
set_target_properties(${BOX64} PROPERTIES ENABLE_EXPORTS ON)
add_dependencies(${BOX64} WRAPPERS)
if(BOX32)
@@ -1105,7 +1184,7 @@ else()
target_link_libraries(${BOX64} c m dl)
endif()
else()
set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-Wl,--no-as-needed -lc -lm -ldl -lrt -lpthread -lresolv -lutil -Wl,--as-needed -pthread")
set_property(TARGET ${BOX64} APPEND_STRING PROPERTY LINK_FLAGS "-Wl,--no-as-needed -lc -lm -ldl -lrt -lpthread -lresolv -lutil -Wl,--as-needed -pthread ")
endif()
endif()
if(DYNAREC)
@@ -1116,9 +1195,9 @@ target_link_libraries(${BOX64} interpreter)
if(${CMAKE_VERSION} VERSION_LESS "3.13")
if(NOT NOLOADADDR)
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR WITH_MOLD)
set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-no-pie -Wl,--image-base=${BOX64_ELF_ADDRESS}")
set_property(TARGET ${BOX64} APPEND_STRING PROPERTY LINK_FLAGS "-no-pie -Wl,--image-base=${BOX64_ELF_ADDRESS} ")
else()
set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-Wl,-Ttext-segment,${BOX64_ELF_ADDRESS}")
set_property(TARGET ${BOX64} APPEND_STRING PROPERTY LINK_FLAGS "-Wl,-Ttext-segment,${BOX64_ELF_ADDRESS} ")
endif()
endif()
else()
@@ -1126,7 +1205,7 @@ else()
if(NOT NOLOADADDR)
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR WITH_MOLD)
if(WITH_MOLD) # --image-base requires -no-pie in mold!
set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-no-pie -lm")
set_property(TARGET ${BOX64} APPEND_STRING PROPERTY LINK_FLAGS "-no-pie -lm ")
endif()
target_link_options(${BOX64} PUBLIC LINKER:--image-base=${BOX64_ELF_ADDRESS})
else()
@@ -1156,6 +1235,9 @@ if(NOT _x86 AND NOT _x86_64)
install(PROGRAMS ${CMAKE_SOURCE_DIR}/tests/box64-bash DESTINATION ${TERMUX_PATH}/usr/bin)
endif()
endif()
if (GDBJIT)
install(TARGETS box64gdbjitreader RUNTIME DESTINATION lib)
endif()
if(NOT NO_CONF_INSTALL)
configure_file(system/box64.conf.cmake system/box64.conf)
if(NOT TERMUX)
@@ -1251,6 +1333,27 @@ if(NOT TARGET uninstall)
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
string(REPLACE ";" "," DYNAREC_ASM_STR "${DYNAREC_ASM}")
string(REPLACE ";" "," DYNAREC_PASS_STR "${DYNAREC_PASS}")
string(REPLACE ";" "," INTERPRETER_STR "${INTERPRETER}")
if(WOW64 AND ARM_DYNAREC)
include(ExternalProject)
ExternalProject_Add(
wowbox64
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wow64"
CMAKE_ARGS
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/wow64/toolchain_mingw.cmake
-DDYNAREC_PASS_STR=${DYNAREC_PASS_STR}
-DDYNAREC_ASM_STR=${DYNAREC_ASM_STR}
-DINTERPRETER_STR=${INTERPRETER_STR}
INSTALL_COMMAND ""
TEST_COMMAND ""
BUILD_ALWAYS ON
)
add_dependencies(wowbox64 generate_git_head_target)
endif()
set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "ptitSeb")
set(CPACK_PACKAGE_CONTACT "[email protected]")
@@ -1462,6 +1565,20 @@ add_test(avx_intrinsics ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${B
set_tests_properties(avx_intrinsics PROPERTIES ENVIRONMENT "BOX64_DYNAREC_FASTNAN=0;BOX64_DYNAREC_FASTROUND=0;BOX64_AVX=2")
add_test(fpu_rounding ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test31 -D TEST_OUTPUT=tmpfile31.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref31.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
set_tests_properties(fpu_rounding PROPERTIES ENVIRONMENT "BOX64_DYNAREC_FASTROUND=0")
add_test(x87pc ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test32 -D TEST_OUTPUT=tmpfile32.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref32.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
set_tests_properties(x87pc PROPERTIES ENVIRONMENT "BOX64_DYNAREC_X87DOUBLE=2")
else()
add_test(bootSyscall ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
@@ -1676,14 +1793,11 @@ if(BOX32)
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests32/ref09.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
if(NOT CI)
add_test(NAME cppThreads_32bits COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
add_test(NAME cppThreads_32bits_nocosim COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests32/test10 -D TEST_OUTPUT=tmpfile32_10.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests32/ref10.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
set_tests_properties(cppThreads_32bits PROPERTIES ENVIRONMENT "BOX64_LD_LIBRARY_PATH=${CMAKE_SOURCE_DIR}/x86lib")
endif()
set_tests_properties(cppThreads_32bits_nocosim PROPERTIES ENVIRONMENT "BOX64_LD_LIBRARY_PATH=${CMAKE_SOURCE_DIR}/x86lib")
add_test(NAME tlsData_32bits COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests32/test11 -D TEST_OUTPUT=tmpfile32_11.txt
@@ -1741,8 +1855,8 @@ if(BOX32)
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests32/ref20.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
add_test(NAME multiple_dlopen_32bits COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests32/test21 -D TEST_OUTPUT=tmpfile32_21.txt
add_test(NAME multiple_dlopen_32bits COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests32/test21 -D TEST_OUTPUT=tmpfile32_21.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests32/ref21.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
@@ -1755,13 +1869,13 @@ if(BOX32)
-P ${CMAKE_SOURCE_DIR}/runTest.cmake)
endforeach()
#add_test(NAME sse_optimized_32bits COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
# -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests32/test17_o2 -D TEST_OUTPUT=tmpfile32_17_o2.txt
#add_test(NAME sse_optimized_32bits COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
# -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests32/test17_o2 -D TEST_OUTPUT=tmpfile32_17_o2.txt
# -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests32/ref17_o2.txt
# -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
#set_tests_properties(sse_optimized_32bits PROPERTIES ENVIRONMENT "BOX64_DYNAREC_FASTNAN=0;BOX64_DYNAREC_FASTROUND=0")
#set_tests_properties(sse_optimized_32bits PROPERTIES ENVIRONMENT "BOX64_DYNAREC_FASTNAN=0;BOX64_DYNAREC_FASTROUND=0")
add_test(bswap_32bits ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests32/test23 -D TEST_OUTPUT=tmpfile32_23.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests32/ref23.txt
+2 -1
View File
@@ -34,6 +34,7 @@ Box64 offers environment variables to control its behavior. For details, see [Us
## 🚀 Compiling and Installation
- [Compilation Instructions](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md)
- [Bundle x86 Libraries](https://github.com/ptitSeb/box64/blob/main/docs/BUNDLE-X86-LIBS.md)
- [Wine Installation for Box64](https://github.com/ptitSeb/box64/blob/main/docs/X64WINE.md)
---
@@ -50,7 +51,7 @@ Box64 requires 64-bit libraries on the host system, as it directly translates x8
**Notes**
1. Box32 mode is in the making, which aims to support 32-bit binaries on Box64, you can enable it at build time, but do not expect everything to work. There is actually a few things that works, amny that don't. It's a known issue, no need to create tickets about it for now.
1. Box32 mode is in the making, which aims to support 32-bit binaries on Box64, you can enable it at build time, but do not expect everything to work. There is actually a few things that work, many that don't. It's a known issue, no need to create tickets about it for now.
2. Some installers may default to x86 on 64-bit host OSes, causing compatibility issues. Workaround: Use a fake `uname` that returns "x86_64" for `-m`.
---
+66
View File
@@ -0,0 +1,66 @@
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/bluez-libs-5.72-2.el9.i686.rpm,af1aba8e6fa5ccf33032d58a3acc59368c07d532293396db205fb9a4bc1241ae
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/bluez-libs-5.72-2.el9.x86_64.rpm,49c273813b4616240acdae8dae893192658c7541482f9bbb2c46dfe19b61877d
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/fribidi-1.0.10-6.el9.2.i686.rpm,75f808f0f5f93aceb4e477aa5f302edbed07a605a0644f0ea929d4ea609e36a0
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/fribidi-1.0.10-6.el9.2.x86_64.rpm,b4763ca410f8479b2775efb55ba09e6722948af7526180a56309e3e090c27010
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gmp-6.2.0-13.el9.i686.rpm,fe352f7d197ebdf2c92bbd6e548f9f6b7ac9e69e7a9d6c9861a6274482e79d73
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gmp-6.2.0-13.el9.x86_64.rpm,babe0b1385e723476a216d5f4b72453e031c3d683b19344786c2bddf7203cb04
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gnutls-3.8.3-4.el9_4.i686.rpm,64cf0b0136d3f9b80b07ce2d4b8ce6a4ab86617e8ef9baf560bdfa5edef825ea
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gnutls-3.8.3-4.el9_4.x86_64.rpm,16c48c504fe62f8e19cac7c6442d3e08bba487f610c2f533116dac32357cda86
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/harfbuzz-2.7.4-10.el9.i686.rpm,5157daf2ab0a03b403d37c60b150b8f0f866754714f81e3d96368e06a16339ce
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/harfbuzz-2.7.4-10.el9.x86_64.rpm,1f81073019abe4176d4496723a89b55a349c31f507e96397a0b3efa7cea0ff61
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libblkid-2.37.4-20.el9.i686.rpm,f9e62d2768c31948b53268b7de51bd1c7342cdf39a328a0d89d933b4aa0c5dd1
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libblkid-2.37.4-20.el9.x86_64.rpm,ed02d978a36488b38bad62af21d4045367c1f0b00d00c90ded01e2fc8e190536
https://archive.debian.org/debian/pool/main/c/curl/libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_amd64.deb,d5ae55e3a9838d12358530cd03218cc0d18127a84e9cfc73bdf79dacd40b25e4
https://archive.debian.org/debian/pool/main/c/curl/libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_i386.deb,625e5189304d4d3bfb27cb821e257816c5ce761b1696b5da5ca4fa1035c48463
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libepoxy-1.5.5-4.el9.i686.rpm,fe35e8de9b68c8d7e7b6b525580fc36cf9c86412cdb2b022dc01f95801771981
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libepoxy-1.5.5-4.el9.x86_64.rpm,b6d1e7f1c832882ceb05187cbc2d8fe1f459bcd88c7160487ee6f734e1a5d017
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libffi-devel-3.4.2-8.el9.i686.rpm,0c6f2ecc324680c6424bee4b1dbbdad2863f0f7f3130b196fc6e2b2823f07bc4
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libffi-devel-3.4.2-8.el9.x86_64.rpm,483e4c58cb8af94143a0ff4b3e49b62cb7d6896766c8c0d9fe3659e68945b50e
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgomp-11.5.0-2.el9.alma.1.i686.rpm,686ac26afe2073a3607f26fd1592a8ccd9b78f6eec6e872528634b43c4e04dd7
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgomp-11.5.0-2.el9.alma.1.x86_64.rpm,9a2bdc6807b22ffb6294b30dcc13e20198abe5facaeefcf1bfacec3e1013e3c2
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgpg-error-1.42-5.el9.i686.rpm,23f828674bc30752687452dacf4a25ca8c25ef0d25e3e6953d0714b5b33cef08
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgpg-error-1.42-5.el9.x86_64.rpm,f28fabeb02add41b8156c394427da9dbf99882d8c42055367f872130ee424c97
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libICE-1.0.10-8.el9.i686.rpm,d9c44bb34c990fdcc6987feefacfc9e1e7997ca25f1e0a59c9adc9c16f2266d1
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libICE-1.0.10-8.el9.x86_64.rpm,d0b867203384942985c3c4ad6fc9ec0000fcc9965408451a6cdef8df06a3833c
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libidn2-2.3.0-7.el9.i686.rpm,4458e2d416b5e6714ec664c4f88791eee7d1e707026a5854d948a6159911465b
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libidn2-2.3.0-7.el9.x86_64.rpm,c3ff43237c05258ee0dd77c28540fc8d0d824f1567b115ddfd555b78d2ee0e7a
https://cdn.getsol.us/repo/shannon/libj/libjpeg-turbo/libjpeg-turbo-32bit-3.0.3-21-1-x86_64.eopkg,5624990281f6520026aa2252c711f02d4916099aeac63accc83bd2135b9d3220
https://cdn.getsol.us/repo/shannon/libj/libjpeg-turbo/libjpeg-turbo-3.0.3-21-1-x86_64.eopkg,c92f19d446b4c2450306f13b1a908f2552400da09301996fe349fee243d964d2
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libogg-1.3.4-6.el9.i686.rpm,9e4ff6fa0251c5357ae8f648b3e396d0043d5b3f2fb28d23325f5bd592c67aee
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libogg-1.3.4-6.el9.x86_64.rpm,83b4b333e335654674032d1cda4d7deb328b5a409f95e3952c3dc482b684fd8f
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libpng-1.6.37-12.el9.i686.rpm,66bf967e84f0d8e7a0059f2b7dda33482ff5e4fe088d0e3bc86dc54e6c7c97be
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libpng-1.6.37-12.el9.x86_64.rpm,ebb3e927dfafa0b199e00e2bef4c10c85fc82a70c359faf9aeb599eda70bfa5e
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libbrotli-1.0.9-7.el9_5.i686.rpm,d18c20fccbb9497222059d475161a55c0c6279344f214fe551b8b0f87d3c054a
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libbrotli-1.0.9-7.el9_5.x86_64.rpm,77906ae44bcd42a9f6646d814874768e8befaabf413133d44f71a95ac6c6d68c
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libsigc%2B%2B20-2.10.7-2.el9.i686.rpm,7c33f4c18cbd51dc0a7c9ae0190b1a27d0540ce2fd92ced4776dde66162d1a88
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libsigc%2B%2B20-2.10.7-2.el9.x86_64.rpm,8600132b9e4efadfe23d3125e90287f5a7114165fd9ecb064d9930fcca446ef2
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libSM-1.2.3-10.el9.i686.rpm,ec68b3def828ba442248f3cff495f42c4af3dd58f38c8daad07dfddc109d999a
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libSM-1.2.3-10.el9.x86_64.rpm,d00318843a50138829b470a97b8db1a00723b10bca23c16a8386d9ab670e4c64
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libstdc%2B%2B-11.5.0-5.el9_5.alma.1.i686.rpm,05fd29569c312a661374aa69e28ed5cad20812822070a3138265c92a446e2c80
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libstdc%2B%2B-11.5.0-5.el9_5.alma.1.x86_64.rpm,7efb1ded0ec2763589dd3bc6a9d52fa9f898cc1f3db6e8761e1d223ce4506424
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libtasn1-4.16.0-8.el9_1.i686.rpm,9cbd11277e89bd0d4a80900bee01ca71b0c582c9cb5744f5035135b2ed907c85
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libtasn1-4.16.0-8.el9_1.x86_64.rpm,2dd3a1ad2785df642cb03dfed6dfbeec929ff8b14e52e61272ca7e89f86ba3cd
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libtheora-1.1.1-31.el9.i686.rpm,2155c688b516ab359d0c47be6d73e51d3c65f199ed5591f7bb7ce6d5d9799977
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libtheora-1.1.1-31.el9.x86_64.rpm,25ab4a8ad997b450b4a34a777f5a0678eea72ca1665944a7a461ac63de4b25bf
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libunistring-0.9.10-15.el9.i686.rpm,792600a879fbd94ce4bf249713b0cb3a166c147cfad397e8a15e6b4f01c75997
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libunistring-0.9.10-15.el9.x86_64.rpm,d2f86fbee729a4900a433a6c52a3cb95d9b52b1d79c9e719ee3ef509813eb6d9
https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/34/Everything/x86_64/os/Packages/l/libunwind-1.4.0-5.fc34.i686.rpm,eb518e9d073c36fd29862c7afd00a8a7cb186074a0e162983f18fb6c9dc71d2c
https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/34/Everything/x86_64/os/Packages/l/libunwind-1.4.0-5.fc34.x86_64.rpm,0f44e37e4eb472508e0dba8505ebbb04c2c1390c6a43970a6af80aad886037e3
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libvorbis-1.3.7-5.el9.i686.rpm,e38c5185fea611330ea253db020315dd564507bf95c48a81dbe7db186ce4214b
https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libvorbis-1.3.7-5.el9.x86_64.rpm,3c340337a073975636d198a282503f32a54bf85fb5345522a2c22e530b8d6c9e
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libzstd-1.5.1-2.el9.i686.rpm,e98f253d6f5f9acf2ded628cd98f50a54a031e354bf7bb2efc3fe39f9899fe49
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libzstd-1.5.1-2.el9.x86_64.rpm,2e5215e225cec2db43d92c3b3380812a6f8684e881ed415670299e1e0fe7d1ce
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/lz4-libs-1.9.3-5.el9.i686.rpm,c308ba7380a3b5c5337c919150f0234342b64c1ea696d6207c2b790b82ba4669
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/lz4-libs-1.9.3-5.el9.x86_64.rpm,439e701491af6a957ac4d7dc69cccee1a945333f19d8bfcbd896b5119af01aab
https://repo.almalinux.org/almalinux/8.10/BaseOS/x86_64/os/Packages/nettle-3.4.1-7.el8.i686.rpm,13bc8758355c3ec885f414e0e86efad29a7fe82c0999cdb3754d666949c06cc5
https://repo.almalinux.org/almalinux/8.10/BaseOS/x86_64/os/Packages/nettle-3.4.1-7.el8.x86_64.rpm,fb4aaa22b2e2f2fc0c451b87ac464e8746d240397d64e79f6bfd38f4e9128a5a
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/nettle-3.9.1-1.el9.i686.rpm,e5610fe3b25cfca1616440e1a8a7489fd37b0852f182fdda87ab8e196d981970
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/nettle-3.9.1-1.el9.x86_64.rpm,9786b6610d17aa495fb640ba6d046bf73704915b82d12e6d8339090ff4891de5
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/p11-kit-0.25.3-3.el9_5.i686.rpm,abe4ab924b405c236eaf3fa067fed50ac66d15d0ef42c782a745788c1a9c5b91
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/p11-kit-0.25.3-3.el9_5.x86_64.rpm,0e1bd97e697a9fa3b4e508b945cf352b73b06e4e8218c14ac5fb912b0022c646
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/pam-1.5.1-22.el9_5.i686.rpm,f2ae4441fc667cdcb930e7a2cfe90f7342e7d1c8848d6d18cb350ba68e025862
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/pam-1.5.1-22.el9_5.x86_64.rpm,15bfe177d3c10982c75e81d7b274883a9fb53322011c8d829667c983ee419b18
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/pciutils-libs-3.7.0-5.el9.i686.rpm,2cf468da5ecf307cc325c9a5da0a288aafd25dec0951af2b4d0954a77bdf900d
https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/pciutils-libs-3.7.0-5.el9.x86_64.rpm,308bd897d8f9a36020d70edc79089a3595b22b149200d67c37e2d4e6147a9f75
https://dl.fedoraproject.org/pub/fedora/linux/updates/40/Everything/x86_64/Packages/s/SDL3-3.2.4-1.fc40.i686.rpm,f4776f6f56a8d3e62e95c06fb885832e22116323c0c2e0f57f918cd4b92e16a2
https://dl.fedoraproject.org/pub/fedora/linux/updates/40/Everything/x86_64/Packages/s/SDL3-3.2.4-1.fc40.x86_64.rpm,96f52b7cf293ce335e2bf726c8b6aefd82ed76fbe9d9f0db1fe603780477c2d0
1 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/bluez-libs-5.72-2.el9.i686.rpm af1aba8e6fa5ccf33032d58a3acc59368c07d532293396db205fb9a4bc1241ae
2 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/bluez-libs-5.72-2.el9.x86_64.rpm 49c273813b4616240acdae8dae893192658c7541482f9bbb2c46dfe19b61877d
3 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/fribidi-1.0.10-6.el9.2.i686.rpm 75f808f0f5f93aceb4e477aa5f302edbed07a605a0644f0ea929d4ea609e36a0
4 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/fribidi-1.0.10-6.el9.2.x86_64.rpm b4763ca410f8479b2775efb55ba09e6722948af7526180a56309e3e090c27010
5 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gmp-6.2.0-13.el9.i686.rpm fe352f7d197ebdf2c92bbd6e548f9f6b7ac9e69e7a9d6c9861a6274482e79d73
6 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gmp-6.2.0-13.el9.x86_64.rpm babe0b1385e723476a216d5f4b72453e031c3d683b19344786c2bddf7203cb04
7 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gnutls-3.8.3-4.el9_4.i686.rpm 64cf0b0136d3f9b80b07ce2d4b8ce6a4ab86617e8ef9baf560bdfa5edef825ea
8 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/gnutls-3.8.3-4.el9_4.x86_64.rpm 16c48c504fe62f8e19cac7c6442d3e08bba487f610c2f533116dac32357cda86
9 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/harfbuzz-2.7.4-10.el9.i686.rpm 5157daf2ab0a03b403d37c60b150b8f0f866754714f81e3d96368e06a16339ce
10 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/harfbuzz-2.7.4-10.el9.x86_64.rpm 1f81073019abe4176d4496723a89b55a349c31f507e96397a0b3efa7cea0ff61
11 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libblkid-2.37.4-20.el9.i686.rpm f9e62d2768c31948b53268b7de51bd1c7342cdf39a328a0d89d933b4aa0c5dd1
12 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libblkid-2.37.4-20.el9.x86_64.rpm ed02d978a36488b38bad62af21d4045367c1f0b00d00c90ded01e2fc8e190536
13 https://archive.debian.org/debian/pool/main/c/curl/libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_amd64.deb d5ae55e3a9838d12358530cd03218cc0d18127a84e9cfc73bdf79dacd40b25e4
14 https://archive.debian.org/debian/pool/main/c/curl/libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_i386.deb 625e5189304d4d3bfb27cb821e257816c5ce761b1696b5da5ca4fa1035c48463
15 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libepoxy-1.5.5-4.el9.i686.rpm fe35e8de9b68c8d7e7b6b525580fc36cf9c86412cdb2b022dc01f95801771981
16 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libepoxy-1.5.5-4.el9.x86_64.rpm b6d1e7f1c832882ceb05187cbc2d8fe1f459bcd88c7160487ee6f734e1a5d017
17 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libffi-devel-3.4.2-8.el9.i686.rpm 0c6f2ecc324680c6424bee4b1dbbdad2863f0f7f3130b196fc6e2b2823f07bc4
18 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libffi-devel-3.4.2-8.el9.x86_64.rpm 483e4c58cb8af94143a0ff4b3e49b62cb7d6896766c8c0d9fe3659e68945b50e
19 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgomp-11.5.0-2.el9.alma.1.i686.rpm 686ac26afe2073a3607f26fd1592a8ccd9b78f6eec6e872528634b43c4e04dd7
20 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgomp-11.5.0-2.el9.alma.1.x86_64.rpm 9a2bdc6807b22ffb6294b30dcc13e20198abe5facaeefcf1bfacec3e1013e3c2
21 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgpg-error-1.42-5.el9.i686.rpm 23f828674bc30752687452dacf4a25ca8c25ef0d25e3e6953d0714b5b33cef08
22 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgpg-error-1.42-5.el9.x86_64.rpm f28fabeb02add41b8156c394427da9dbf99882d8c42055367f872130ee424c97
23 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libICE-1.0.10-8.el9.i686.rpm d9c44bb34c990fdcc6987feefacfc9e1e7997ca25f1e0a59c9adc9c16f2266d1
24 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libICE-1.0.10-8.el9.x86_64.rpm d0b867203384942985c3c4ad6fc9ec0000fcc9965408451a6cdef8df06a3833c
25 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libidn2-2.3.0-7.el9.i686.rpm 4458e2d416b5e6714ec664c4f88791eee7d1e707026a5854d948a6159911465b
26 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libidn2-2.3.0-7.el9.x86_64.rpm c3ff43237c05258ee0dd77c28540fc8d0d824f1567b115ddfd555b78d2ee0e7a
27 https://cdn.getsol.us/repo/shannon/libj/libjpeg-turbo/libjpeg-turbo-32bit-3.0.3-21-1-x86_64.eopkg 5624990281f6520026aa2252c711f02d4916099aeac63accc83bd2135b9d3220
28 https://cdn.getsol.us/repo/shannon/libj/libjpeg-turbo/libjpeg-turbo-3.0.3-21-1-x86_64.eopkg c92f19d446b4c2450306f13b1a908f2552400da09301996fe349fee243d964d2
29 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libogg-1.3.4-6.el9.i686.rpm 9e4ff6fa0251c5357ae8f648b3e396d0043d5b3f2fb28d23325f5bd592c67aee
30 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libogg-1.3.4-6.el9.x86_64.rpm 83b4b333e335654674032d1cda4d7deb328b5a409f95e3952c3dc482b684fd8f
31 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libpng-1.6.37-12.el9.i686.rpm 66bf967e84f0d8e7a0059f2b7dda33482ff5e4fe088d0e3bc86dc54e6c7c97be
32 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libpng-1.6.37-12.el9.x86_64.rpm ebb3e927dfafa0b199e00e2bef4c10c85fc82a70c359faf9aeb599eda70bfa5e
33 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libbrotli-1.0.9-7.el9_5.i686.rpm d18c20fccbb9497222059d475161a55c0c6279344f214fe551b8b0f87d3c054a
34 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libbrotli-1.0.9-7.el9_5.x86_64.rpm 77906ae44bcd42a9f6646d814874768e8befaabf413133d44f71a95ac6c6d68c
35 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libsigc%2B%2B20-2.10.7-2.el9.i686.rpm 7c33f4c18cbd51dc0a7c9ae0190b1a27d0540ce2fd92ced4776dde66162d1a88
36 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libsigc%2B%2B20-2.10.7-2.el9.x86_64.rpm 8600132b9e4efadfe23d3125e90287f5a7114165fd9ecb064d9930fcca446ef2
37 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libSM-1.2.3-10.el9.i686.rpm ec68b3def828ba442248f3cff495f42c4af3dd58f38c8daad07dfddc109d999a
38 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libSM-1.2.3-10.el9.x86_64.rpm d00318843a50138829b470a97b8db1a00723b10bca23c16a8386d9ab670e4c64
39 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libstdc%2B%2B-11.5.0-5.el9_5.alma.1.i686.rpm 05fd29569c312a661374aa69e28ed5cad20812822070a3138265c92a446e2c80
40 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libstdc%2B%2B-11.5.0-5.el9_5.alma.1.x86_64.rpm 7efb1ded0ec2763589dd3bc6a9d52fa9f898cc1f3db6e8761e1d223ce4506424
41 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libtasn1-4.16.0-8.el9_1.i686.rpm 9cbd11277e89bd0d4a80900bee01ca71b0c582c9cb5744f5035135b2ed907c85
42 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libtasn1-4.16.0-8.el9_1.x86_64.rpm 2dd3a1ad2785df642cb03dfed6dfbeec929ff8b14e52e61272ca7e89f86ba3cd
43 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libtheora-1.1.1-31.el9.i686.rpm 2155c688b516ab359d0c47be6d73e51d3c65f199ed5591f7bb7ce6d5d9799977
44 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libtheora-1.1.1-31.el9.x86_64.rpm 25ab4a8ad997b450b4a34a777f5a0678eea72ca1665944a7a461ac63de4b25bf
45 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libunistring-0.9.10-15.el9.i686.rpm 792600a879fbd94ce4bf249713b0cb3a166c147cfad397e8a15e6b4f01c75997
46 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libunistring-0.9.10-15.el9.x86_64.rpm d2f86fbee729a4900a433a6c52a3cb95d9b52b1d79c9e719ee3ef509813eb6d9
47 https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/34/Everything/x86_64/os/Packages/l/libunwind-1.4.0-5.fc34.i686.rpm eb518e9d073c36fd29862c7afd00a8a7cb186074a0e162983f18fb6c9dc71d2c
48 https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/34/Everything/x86_64/os/Packages/l/libunwind-1.4.0-5.fc34.x86_64.rpm 0f44e37e4eb472508e0dba8505ebbb04c2c1390c6a43970a6af80aad886037e3
49 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libvorbis-1.3.7-5.el9.i686.rpm e38c5185fea611330ea253db020315dd564507bf95c48a81dbe7db186ce4214b
50 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libvorbis-1.3.7-5.el9.x86_64.rpm 3c340337a073975636d198a282503f32a54bf85fb5345522a2c22e530b8d6c9e
51 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libzstd-1.5.1-2.el9.i686.rpm e98f253d6f5f9acf2ded628cd98f50a54a031e354bf7bb2efc3fe39f9899fe49
52 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libzstd-1.5.1-2.el9.x86_64.rpm 2e5215e225cec2db43d92c3b3380812a6f8684e881ed415670299e1e0fe7d1ce
53 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/lz4-libs-1.9.3-5.el9.i686.rpm c308ba7380a3b5c5337c919150f0234342b64c1ea696d6207c2b790b82ba4669
54 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/lz4-libs-1.9.3-5.el9.x86_64.rpm 439e701491af6a957ac4d7dc69cccee1a945333f19d8bfcbd896b5119af01aab
55 https://repo.almalinux.org/almalinux/8.10/BaseOS/x86_64/os/Packages/nettle-3.4.1-7.el8.i686.rpm 13bc8758355c3ec885f414e0e86efad29a7fe82c0999cdb3754d666949c06cc5
56 https://repo.almalinux.org/almalinux/8.10/BaseOS/x86_64/os/Packages/nettle-3.4.1-7.el8.x86_64.rpm fb4aaa22b2e2f2fc0c451b87ac464e8746d240397d64e79f6bfd38f4e9128a5a
57 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/nettle-3.9.1-1.el9.i686.rpm e5610fe3b25cfca1616440e1a8a7489fd37b0852f182fdda87ab8e196d981970
58 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/nettle-3.9.1-1.el9.x86_64.rpm 9786b6610d17aa495fb640ba6d046bf73704915b82d12e6d8339090ff4891de5
59 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/p11-kit-0.25.3-3.el9_5.i686.rpm abe4ab924b405c236eaf3fa067fed50ac66d15d0ef42c782a745788c1a9c5b91
60 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/p11-kit-0.25.3-3.el9_5.x86_64.rpm 0e1bd97e697a9fa3b4e508b945cf352b73b06e4e8218c14ac5fb912b0022c646
61 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/pam-1.5.1-22.el9_5.i686.rpm f2ae4441fc667cdcb930e7a2cfe90f7342e7d1c8848d6d18cb350ba68e025862
62 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/pam-1.5.1-22.el9_5.x86_64.rpm 15bfe177d3c10982c75e81d7b274883a9fb53322011c8d829667c983ee419b18
63 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/pciutils-libs-3.7.0-5.el9.i686.rpm 2cf468da5ecf307cc325c9a5da0a288aafd25dec0951af2b4d0954a77bdf900d
64 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/pciutils-libs-3.7.0-5.el9.x86_64.rpm 308bd897d8f9a36020d70edc79089a3595b22b149200d67c37e2d4e6147a9f75
65 https://dl.fedoraproject.org/pub/fedora/linux/updates/40/Everything/x86_64/Packages/s/SDL3-3.2.4-1.fc40.i686.rpm f4776f6f56a8d3e62e95c06fb885832e22116323c0c2e0f57f918cd4b92e16a2
66 https://dl.fedoraproject.org/pub/fedora/linux/updates/40/Everything/x86_64/Packages/s/SDL3-3.2.4-1.fc40.x86_64.rpm 96f52b7cf293ce335e2bf726c8b6aefd82ed76fbe9d9f0db1fe603780477c2d0
+96
View File
@@ -0,0 +1,96 @@
#!/bin/bash
set -x
extract_pkg_auto() {
# Example x86_64 package name: libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_amd64.deb
# Example x86 package name: libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_i386.deb
if echo "${1}" | grep -q -P ".deb$"; then
echo "DEB (Debian) package detected."
ar x "$(basename "${1}")"
tar --extract --file data.tar*
# Example x86_64 package name: curl-gnutls-8.1.2-44-1-x86_64.eopkg
# Example x86 package name: curl-gnutls-32bit-8.1.2-44-1-x86_64.eopkg
elif echo "${1}" | grep -q -P ".eopkg$"; then
echo "EOPKG (Solus Linux) package detected."
unzip -o "$(basename "${1}")"
tar --extract --file install.tar.xz
# Example x86_64 package name: bluez-libs-5.63-1.el8.x86_64.rpm
# Example x86 package name: bluez-libs-5.63-1.el8.i686.rpm
elif echo "${1}" | grep -q -P ".rpm$"; then
echo "RPM (Fedora) detected."
rpm2cpio "$(basename "${1}")" | cpio -idmv
# Example x86_64 package name: libjpeg-turbo-3.0.1_1.x86_64.xbps
# Example x86 package name: libjpeg-turbo-32bit-3.0.1_1.x86_64.xbps
elif echo "${1}" | grep -q -P ".xbps$"; then
echo "XBPS (Void Linux) package detected."
tar --extract --file "$(basename "${1}")"
else
echo "Unsupported package type detected."
exit 1
fi
}
box64_dir=$(pwd)
dir_tmp_local="$(mktemp --directory)"
cd "${dir_tmp_local}"
for line in $(cat "${box64_dir}/box64-bundle-x86-libs.csv");
do pkg_url="$(echo "${line}" | cut -d, -f1)"
pkg_checksum_expected="$(echo "${line}" | cut -d, -f2)"
pkg_name="$(basename "${pkg_url}")"
curl --silent --location --remote-name "${pkg_url}"
pkg_checksum_actual="$(sha256sum ${pkg_name} | awk '{print $1}')"
if [[ "${pkg_checksum_expected}" -ne "${pkg_checksum_actual}" ]];
then echo "Invalid checksum for ${pkg_name}"
echo "Expected: ${pkg_checksum_expected}"
echo "Actual: ${pkg_checksum_actual}"
exit 1
fi
extract_pkg_auto "${pkg_name}"
done
# Start preperation of bundles.
mkdir -p \
"${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu" \
"${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu" \
"${dir_tmp_local}/bundle-pkgs" \
# Copy Debian family libraries.
cp --archive "${dir_tmp_local}"/usr/lib/i386-linux-gnu/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu"
cp --archive "${dir_tmp_local}"/usr/lib/x86_64-linux-gnu/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu"
# Copy Fedora family libraries.
cp --archive "${dir_tmp_local}"/usr/lib/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu"
cp --archive "${dir_tmp_local}"/usr/lib64/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu"
## This location is used by a few special packages such as "glibc".
cp --archive "${dir_tmp_local}"/lib/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu"
cp --archive "${dir_tmp_local}"/lib64/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu"
# Copy Solus and Void Linux family libraries.
cp --archive "${dir_tmp_local}"/usr/lib32/*.so* "${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu"
# Create "<LIBRARY_FILE>.so" symlinks.
for dir_lib in \
"${dir_tmp_local}/bundle-libs/usr/lib/box64-i386-linux-gnu" \
"${dir_tmp_local}/bundle-libs/usr/lib/box64-x86_64-linux-gnu"
# If two or more libraries of the same name exist, this will symlink the oldest version.
# Pipe this into a reverse sort `| sort -r` to symlink the newest version.
do for lib in $(ls -1 "${dir_lib}")
# Example output: libbluetooth.so
do lib_base="$(echo "${lib}" | cut -d. -f1,2)"
if ! ls "${dir_lib}/${lib_base}" 2> /dev/null
then ln -s "${lib}" "${dir_lib}/${lib_base}"
fi
done
done
mv "${dir_tmp_local}"/*.deb "${dir_tmp_local}/bundle-pkgs/"
mv "${dir_tmp_local}"/*.eopkg "${dir_tmp_local}/bundle-pkgs/"
mv "${dir_tmp_local}"/*.rpm "${dir_tmp_local}/bundle-pkgs/"
mv "${dir_tmp_local}"/*.xbps "${dir_tmp_local}/bundle-pkgs/"
tar --directory "${dir_tmp_local}/bundle-libs" --create --file "${box64_dir}/box64-bundle-x86-libs.tar.gz" .
tar --directory "${dir_tmp_local}/bundle-pkgs" --create --file "${box64_dir}/box64-bundle-x86-pkgs.tar.gz" .
# Clean up.
cd -
rm -r -f "${dir_tmp_local}"
+22
View File
@@ -1,3 +1,25 @@
box64 (0.3.6) unstable; urgency=low
This version introduces wowbox64.dll for Hangover; the ability to use the Volatile Metadata of Windows executables for x64 wine; and some better x87/SSE/AVX handling
=> WowBox64 can be built directly from Box64 repo, and can be found in the CI artifacts also
=> it also supports a subset of BOX64_XXXX settings, which can be set from command line or via a setting file ".box64rc" in the Wine prefix home
=> Volatile Metadata, when present, allows only applying strong memory ordering when needed, as marked by the compiler, giving overall better performances
=> The precision control bit of x87 is now handled, allowing some older games to run correctly
=> More work has been done in the handling of precise NaN and Round handling in SSE & AVX opcodes
-- Sebastien Chevalier <[email protected]> Thu, 6 Jun 2025 10:30:33 -0100
box64 (0.3.4) unstable; urgency=low
* This version is Faster and more compatible
* => The RV64 backend got faster and more stable, with lots of RVV 1.0 / xThreadVector support to emulate SSE/SSE2+ opcode (no AVX yet)
* => On ARM64, Box64 now support more DRM types than before.
* => BOX32 can run steam now. At least on ARM64 backend, it's still not working on RV64 and LA64 for now.
* Please check CHAGELOG.md for more details
-- Sebastien Chevalier <[email protected]> Thu, 10 Mar 2025 10:30:33 -0100
box64 (0.3.2) unstable; urgency=low
* Introduced Box32 to run 32bits apps on 64bits OS
+2 -1
View File
@@ -21,4 +21,5 @@ override_dh_shlibdeps:
--exclude=libcrypto.so.1.1 \
--exclude=libmbedx509.so.1 \
--exclude=libcrypto.so.1.0.0 \
--exclude=libssl.1.0.0
--exclude=libssl.so.1.0.0 \
--exclude=box64-bash
+73
View File
@@ -0,0 +1,73 @@
# Bundling x86 Libraries
The script `box64-bundle-x86-libs.sh` is provided to download, extract, and re-bundle x86_64 and x86 libraries for use with Box64/Box32 and Box86. These libraries improve Box emulation. This bundle provides a much smaller size compared to using a full root file system of an operating system.
## Usage
### Administrator
Install required dependencies for the bundle script.
- Debian
```
sudo apt-get update
sudo apt-get install coreutils curl binutils rpm2cpio tar zstd
```
- Fedora
```
sudo dnf install coreutils curl binutils tar zstd
```
Run `box64-bundle-x86-libs.sh`. This will create two archives:
- `box64-bundle-x86-libs.tar.gz` = All of the extracted library files in the directory structure of `usr/lib/box64-i386-linux-gnu` and `usr/lib/box64-x86_64-linux-gnu`.
- `box64-bundle-x86-pkgs.tar.gz` = All of the Linux distribution packages used to extract the library files. This is only created for preservation purposes and is otherwise unused.
Extract the library archive. Box will automatically search these paths for library files to emulate.
```
sudo tar --extract --file box64-bundle-x86-libs.tar.gz --directory /
```
### Developer
Add new packages to the `box64-bundle-x86-libs.csv` file in the format of `<PACKAGE_URL>,<SHA256_CHECKSUM>`.
Supported packages:
- DEB (Debian)
- EOPKG (Solus)
- RPM (Fedora)
- XBPS (Void Linux)
Preference of operating system packages that provide a library:
1. RPMs from AlmaLinux 9 provide 10 years of updates.
2. DEBs from Debian 11 provide 5 years of updates.
3. EOPKG from Solus provide old variants of obscure 32-bit libraries.
4. XBPS from Void Linux provide updated variants of obscure 32-bit libraries.
5. Other (whereever a library is packaged)
Some essential library files will never be emulated (only wrapped) and should not be bundled. This includes glibc, OpenGL, Vulkan, and X11/Xorg libraries. The full list can be found [here](https://github.com/ptitSeb/box64/blob/v0.3.2/src/librarian/library.c#L427). Other libraries with lots of dependencies, such as GTK, require all dependencies to be installed for emulation to work. This becomes dependency hell and should be avoided.
For finding package names that contian a specific library file, use the [pkgs.org](https://pkgs.org/) website. Otherwise, use one of these package manager commands on a x86_64 Linux distribution:
- DEB
- `apt-file <LIBRARY_FILE>`
- EOPKG
- Does not support file search. Use pkgs.org instead.
- RPM
- `dnf provides "*/<LIBRARY_FILE>*"`
- XBPS
- `xbps-query --repository --ownedby <LIBRARY_FILE>`
Once the package name is found, find the exact URL for downloading it.
- DEB = Explore "main" and "contrib". Search for packages with the name "deb11" in it. Use the "amd64.deb" and "i386.deb" packages.
- https://archive.debian.org/debian/pool/
- EOPKG = Use the "`<VERSION>-<RELEASE>-x86_64.eopkg`" and "`32bit-<VERSION>-<RELEASE>-x86_64.eopkg`" packages.
- https://cdn.getsol.us/repo/shannon/
- RPM = Navigate to the "`<MAJOR>.<MINOR>`" version directory first. Then explore "AppStream" and "BaseOS". Use the "x86_64.rpm" and "i686.rpm" packages.
- https://repo.almalinux.org/almalinux/
- Enterprise Linux (EL) distributions, such as AlamaLinux, sometimes are missing 32-bit packages. Use the Fedora 34 [update](https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/34/Everything/x86_64/Packages/) and [release](https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/34/Everything/x86_64/os/Packages/) archives for compatible packages with EL 9.
- XBPS = There are too many files in the repository to display on a web browser. Use pkgs.org instead to find the exact URL for downloading it.
- https://repo-default.voidlinux.org/current/
Download the package and then find the checksum with the `sha256sum` command.
Major Linux distributions such as AlmaLinux and Debian provide archives of packages. Rolling distributions such as Solus and Void Linux do not. In those cases, use the [Internet Archive](https://web.archive.org/) to archive any rolling release package used by Box by using the "Save Page Now" feature. If the error "Save Page Now browser crashed" appears, it can be safely ignored. The archive will still have been saved.
+82
View File
@@ -1,3 +1,85 @@
v0.3.6
======
Highlights:
* This version introduces wowbox64.dll for Hangover; the ability to use the Volatile Metadata of Windows executables for x64 wine; and some better x87/SSE/AVX handling
=> WowBox64 can be built directly from Box64 repo, and can be found in the CI artifacts also
=> it also supports a subset of BOX64_XXXX settings, which can be set from command line or via a setting file ".box64rc" in the Wine prefix home
=> Volatile Metadata, when present, allows only applying strong memory ordering when needed, as marked by the compiler, giving overall better performances
=> The precision control bit of x87 is now handled, allowing some older games to run correctly
=> More work has been done in the handling of precise NaN and Round handling in SSE & AVX opcodes
Version summary:
* Added/fixed some Syscalls, helping Go programs
* Wrapper: more functions added, and some fixes too. Vulkan is 1.4 now, among other things
* Wrapper: Added a few more wrapped libs (like some avcodec and friends)
* Improve internal memory allocator (with a dedicated allocator for small memory allocations), and fixed some issues around it
* Improve internal mmaped file tracking
* Box32: Some small refactoring around memory management and internal memory allocations
* Box32: More functions wrapped
* Box32: More libraries wrapped
* ARM64: Added support for Atomic extension in many internal functions (not related to Dynarec).
* ARM64: Added support for CRC2 extension for internal CRC functions
* Interp: A few fixes to some opcodes, and better NAN handling on some selected SSE/AVX opcodes
* Interp: Added a few opcodes with exotic prefixes
* Dynarec: Introcude BOX64_DYNAREC_ROUND=2 to handle x87 precision control bit (ARM64 and RV64, LA64 still doesn't handle x87 yet)
* Dynarec: Some small optimizations on Strongmem emulation, making it more efficient
* Dynarec: Some speed optimizations on code that do SMC and waiting slot
* Dynarec: Added CALLRET=2 to improve call/ret optimization compatibility with SMC code
* Dynarec: ARM64: Various optimizations and fixes on some opcodes, especially AVX ones
* Dynarec: ARM64: Added missing FASTNAN=0 handling on some SSE/AVX opcodes
* Dynarec: ARM64: Added some exotic prefixed opcodes
* Dynarec: ARM64: Avoid purging XMM/YMM register on intra-block loop if possible
* Dynarec: RV64: Many fixes and improvments around x87 emulation
* Dynarec: RV64: Added some more missing opcodes, especially some LOCK prefixed ones and many MMX ones
* Dynarec: RV64: Various fixes on some existing opcodes
* Dynarec: RV64: Improved nativeflags handling, allowing for more cases to use it
* Dynarec: LA64: Added some more opcodes and MMX handling
* Dynarec: LA64: Various fixes to some existing opcodes
* Android: Improved signal handling, structure alignment, and transformation
* WowBox64: Created the dll, with RcFile, Env. Var. handling and log printout (both ARM64 Dynarec and Interpreter available)
* Cosim: Various fixes and improvements to limit false negatives and improve readability of logs
* RcFile: A few fixes for some values that would be ignored
v0.3.4
======
* This version is Faster and more compatible:
=> The RV64 backend got faster and more stable, with lots of RVV 1.0 / xThreadVector support to emulate SSE/SSE2+ opcode (no AVX yet)
=> On ARM64, Box64 now support more DRM types than before.
=> BOX32 can run steam now. At least on ARM64 backend, it's still not working on RV64 and LA64 for now.
* Added support to emulate Windows Syscall (needs Proton and a 48bits address space for now)
* Added BOX64_DYNAREC_DIRTY to have a faster (but less safe) way to handle code that write in it's current page
* Added a few rarely used opcodes
* Added experimental support for GDBJIT, that allow an x86/x86_64 program to be debugged on ARM/RV64/LA64 platform with x86 regs and opcode view (might generate a lot of file tho)
* Added support for Perf tools in a similar way if GDBJIT, to have an x86 fine view of the performances
* Reworked undefined flags for common operations, to be similar to real CPU
* Reworked cpuid handling, adding BOX64_CPUTYPE support to select Intel/AMD emulation (no 3DNow! support on AMD for now)
* Reworked ucontext link to be closer to the real thing (and make it more simple)
* Improved memory traking, file descriptor backed memory map, and detect wine loaded dll
* Introduced settings per library and dll (mostly for Dynarec)
* Wrapper: More functions addes, and some fixes too
* BOX32: Many fixes around pthreads wrapping
* BOX32: More functions wrapped.
* BOX32: More libraies wrapped.
* BOX32: Some reworks on how high memory (higher than 32bits) is masked, and can be used for Dynarec blocks.
* Dynarec: The usual batch of fixes, improvments and opcodes additions on all 3 supported backend
* Dynarec: Some fixes to NativeFlags handling, both on ARM64 and RV64
* Dynarec: Added optimized REP MOVSB (expected for default CPUTYPE=0, according to new cpuid return)
* Dynarec: LA64: more opcoded addes, using hardware extensions like AES
* Dynarec: RV64: More work on using RVV 1.0 and xTheadVector extension to emulate SSE/SSE2+ opcodes
* Dynarec: RV64: Added informations on flags when building blocks, to be used when a signal happens to rebuild a x86 context more accurate
* Dynarec: ARM64: Reworked undefined flags for common operations, to be similar to real CPU
* Dynarec: ARM64: Added informations on flags and xmm/ymm/x87 register when building blocks, to be used when a signal happens to rebuild a x86 context 100% accurate
* TRACE: Reworked how trace for wrapped function call is printed.
* TRACE: Reworked logs to prefix each line with a (optionaly colored) BOX32 or BOX64
* COSIM: Some rework on cosim to limit false negative, especialy when handling x87 operations
* LA64: Added limited support for ABI 1.0
* CI: github CI now also generate MiceWine .rat archive, along with Winlator .wcp archive and regular linux builds.
* RCFile: Added many new games profiles (both for speed improvment or for compatibilty)
v0.3.2
======
* Introduced Box32 to run 32bits apps on 64bits OS
+114 -46
View File
@@ -5,10 +5,12 @@ If you don't want to compile box64 yourself and prefer to use third-party pre-bu
You can also generate your own package using the [instructions below](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md#debian-packaging).
Additional installation steps may be necessary when copying only the box64 executable file without running make install in cross-build environments. See [Cross-compiling](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md#Cross-compiling)
## Per-platform compiling instructions
----
### The general approach
### The general approach is:
```
git clone https://github.com/ptitSeb/box64
cd box64
@@ -20,10 +22,30 @@ If it's the first install, you also need:
```
sudo systemctl restart systemd-binfmt
```
- You can use `make -j1`, `make -j2` to prevent running out of memory
- You can also add `-DBAD_SIGNAL=ON` to the cmake command if you are on Linux Kernel mixed with Android, like on RK3588.
- You can use `make -j1`, `make -j2` with less jobs to prevent running out of memory
- You can also add `-DBAD_SIGNAL=ON` to the cmake command if you are on a Linux Kernel mixed with Android, like on RK3588.
### Note about Box32
If you want to build Box64 with the Box32 option, you will need to add `-DBOX32=ON` to the cmake command. That will enable 32bits process to be run with Box64.
If you also want binfmt integration on 32bits binaries, you also need to add `-DBOX32_BINFMT=ON` to the cmake command.
### Note about WowBox64
A highly experimantal subproject named WowBox64 has been added as a build option, add `-DWOW64=ON` to the cmake command to enable it.
It will build alongside the regular Box64, and produce a `wowbox64.dll` file in `build/wowbox64-prefix/src/wowbox64-build/` directory.
### Note about binfmt_misc on Android
[binfmt_misc](https://en.wikipedia.org/wiki/Binfmt_misc) is a capability of the Linux kernel which allows arbitrary executable file formats to be recognized and passed to certain user space applications such as Box64 usually used with systemd but systems like Android can't run/use systemd so you will need to register Box64 manually, this will also work inside a CHRoot.
```
sudo mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
sudo echo ':box64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/box64:' | sudo tee /proc/sys/fs/binfmt_misc/register
```
#### Example of generic ARM64 build for linux platforms
#### For Instance, if you want to build box64 for Generic ARM64 Linux platforms, it would look like this:
```
git clone https://github.com/ptitSeb/box64
cd box64
@@ -32,25 +54,37 @@ make -j4
sudo make install
sudo systemctl restart systemd-binfmt
```
#### Example of generic ARM64 build for linux platforms with full box32 integration
```
git clone https://github.com/ptitSeb/box64
cd box64
mkdir build; cd build; cmake .. -D ARM_DYNAREC=ON -D CMAKE_BUILD_TYPE=RelWithDebInfo -D BOX32=ON -D BOX32_BINFMT=ON
make -j4
sudo make install
sudo systemctl restart systemd-binfmt
```
----
#### for RK3399
Using a 64bit OS:
On a 64bit OS:
```
-D RK3399=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for RK3588 / RK3588S
Using a 64bit OS:
On a 64bit OS:
```
-D RK3588=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for Raspberry Pi 3
Warning, you need a 64bit OS:
On a 64bit OS:
If building on the Pi, you will also need a large swap (3 GB+)
[optionally reduce GPU memory to a minimum (e.g. 16 MB) using `raspi-config`
@@ -66,7 +100,7 @@ Still, this can be faster if your build is attended.
#### for Raspberry Pi 4
Warning, you need a 64bit OS:
On a 64bit OS:
```
-D RPI4ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -80,7 +114,7 @@ Warning, you need a 64bit OS:
#### for TEGRA X1
Using a 64bit OS:
On a 64bit OS:
```
-D TEGRAX1=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -88,7 +122,7 @@ Using a 64bit OS:
#### for Jetson Xavier/T194
Using a 64bit OS:
On a 64bit OS:
```
-D TEGRA_T194=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -96,16 +130,16 @@ Using a 64bit OS:
#### for Jetson Orin/T234
Using a 64bit OS:
On a 64bit OS:
Caution: please use gcc-11 or higher, older gcc doesn't know cortex-a78ae
Note: use gcc-11 or higher, older gcc doesn't know cortex-a78ae
```
-D TEGRA_T234=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for ODROID N2/N2+
Using a 64bit OS:
On a 64bit OS:
```
-D ODROIDN2=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -113,7 +147,7 @@ Using a 64bit OS:
#### for Snapdragon
Using a 64bit OS:
On a 64bit OS:
```
-D SD845=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -125,18 +159,18 @@ or
-D SD888=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
Depending how recent your Snapdragon is
Depending on how recent your Snapdragon is
#### for Phytium
Using a 64bit OS:
On a 64bit OS:
```
-D PHYTIUM=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for ADLink machines
Using a 64bit OS:
On a 64bit OS:
```
-D ADLINK=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
@@ -151,7 +185,7 @@ Only test on Asahi with Fedora, using the default "16K page" kernel
#### for LoongArch
Using a 64bit OS:
On a 64bit OS:
```
-D LARCH64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -159,7 +193,7 @@ Using a 64bit OS:
#### for RISC-V
Using a 64bit OS:
On a 64bit OS:
```
-D RV64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -167,7 +201,7 @@ Using a 64bit OS:
#### for PowerPC 64 LE
Using a 64bit OS:
On a 64bit OS:
```
-D PPC64LE=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -175,7 +209,7 @@ Using a 64bit OS:
#### for LX2160A
Using a 64bit OS:
On a 64bit OS:
```
-D LX2160A=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -183,7 +217,7 @@ Using a 64bit OS:
#### for Termux
You must have ARM64 Device for build box64.
You must have ARM64 machine to build box64.
##### in CHRoot/PRoot
@@ -193,15 +227,16 @@ You must have ARM64 Device for build box64.
##### in Termux (Native)
NOTE: BUILDING BOX64 IN TERMUX NATIVE IS EXPERIMENTAL AND DOESN'T GONNA RUN LINUX BINARIES IN NATIVE TERMUX BOX64!!!
Note: Box64 in native termux is experimental and won't run linux binaries!
You also needed have `libandroid-sysv-semaphore` and `libandroid-spawn` libraries:
You also need `libandroid-sysv-semaphore` and `libandroid-spawn` libraries.
```
-D TERMUX=1 -DCMAKE_C_COMPILER=clang -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for x86_64 Linux
```
-D LD80BITS=1 -D NOALIGN=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
@@ -215,58 +250,60 @@ Alternatively, you can **use the curses-based ccmake (or any other gui frontend
### Customize your build
#### Use ccache if you have it
#### Use ccache when present
Add `-DUSE_CCACHE=1` if you have ccache (it's better if you plan to touch the sources)
Add `-DUSE_CCACHE=1` option if you have ccache and plan to touch the sources.
#### To have some debug info
#### Include debug information
The `-DCMAKE_BUILD_TYPE=RelWithDebInfo` argument makes a build that is both optimized for speed, and has debug information embedded. That way, if you have a crash or try to analyse performance, you'll have some symbols.
Add `-DCMAKE_BUILD_TYPE=RelWithDebInfo` option for an optimized build with debug information embedded. That way, if you want to debug a crash or analyze performance, you have symbols.
#### To have a Trace Enabled build
#### Build with trace
To have a trace enabled build (***the interpreter will be slightly slower***), add `-DHAVE_TRACE=1`. But you will need to have the [Zydis library](https://github.com/zyantific/zydis) in your `LD_LIBRARY_PATH` or in the system library folders at runtime. Use version v3.2.1, as later version changed the API and will no longer work with box64
To have a trace enabled build (***the interpreter will be slightly slower***), add `-DHAVE_TRACE=1`. You will need the [Zydis library](https://github.com/zyantific/zydis) in your `LD_LIBRARY_PATH` or in the system library folders at runtime to get x86 trace. Use version v3.2.1, as later versions have changed the API and no longer work with box64.
#### To have ARM Dynarec
#### Build DynaRec
Dynarec is only available on ARM (for the meantime), Activate it by using `-DARM_DYNAREC=1`.
Add `-D ARM_DYNAREC=ON` option to enable DynaRec on ARM machines.
Add `-D RV64_DYNAREC=ON` option to enable DynaRec on RV64 machines.
Add `-D LARCH64_DYNAREC=ON` option to enable DynaRec on LARCH64 machines.
#### To have a build using less memory
#### Save memory at run time
You can use `-DSAVE_MEM` to have a build that will try to save some memory. It's, for now, only increasing the jumptable from 4 level to 5 levels. The added granularity avoid wasting space, but the 1 level more to the jumptable means there is on read from memory more when jumping between blocks.
You can use `-DSAVE_MEM` to have a build that will try to save some memory. For now, it only increases the jumptable from 4 levels to 5. The added granularity avoids wasting space, but adds one more read from memory when jumping between blocks.
#### Not building from a git clone
#### Build outside of a git repo
If you are not building from a git clone (for example, downloading a release source code zip from github), you need to use `-DNOGIT=1` from cmake to be able to build (box64 uses git SHA1 to show last commit in version number).
Box64 uses git SHA1 to show last commit in version number, use `-DNOGIT=1` option when building outside of a git repo (for example, downloading a release source code zip from github).
#### Use faster linker
You need to add `-DWITH_MOLD=1` if GNU ld is extremely slow. Then run `mold -run make -j4` to build (make sure [Mold](https://github.com/rui314/mold) is installed).
Add `-DWITH_MOLD=1` option when GNU ld is extremely slow. Then run `mold -run make -j4` to build (make sure [Mold](https://github.com/rui314/mold) is installed).
#### Build a statically linked box64
You can now build box64 statically linked, with `-DSTATICBUILD`. This is to use inside an x86_64 chroot. Note that this version of box64 will have just the minimum of wrapped libs. So only libc, libm and libpthread basically are wrapped. Other libs (like libGL or libvulkan, SDL2, etc...) will not be wrapped and x86_64 version will be used. It's designed to be used in docker image, or in headless server.
Also, the Static Build is highly experimental, but feedback are always welcomed.
You can now build box64 statically linked, with `-DSTATICBUILD` to use inside of a x86_64 chroot. Note that this version of box64 will only have the minimal wrapped libs, such as libc, libm and libpthread. Other libs (like libGL or libvulkan, SDL2, etc...) will use x86_64 versions. A static build is intended to be used in a docker image, or in a headless server. It is highly experimental, but feedback is always welcome.
----
## Testing
----
A few tests are included with box64.
They can be launched using the `ctest` command.
The tests are very basic and only tests some functionality for now.
The tests are very basic and only test some functionality for now.
----
## Debian Packaging
----
Box64 can also be packaged into a .deb file ***using the source code zip from the releases page*** with `DEB_BUILD_OPTIONS=nostrip dpkg-buildpackage -us -uc -nc`. Configure any additional cmake options you might want in `debian/rules`.
## Pre-build packages
----
Box64 can also be packaged into a .deb file ***using the source code zip from the releases page*** with `DEB_BUILD_OPTIONS=nostrip dpkg-buildpackage -us -uc -nc`. Configure any additional cmake options you want in `debian/rules`.
## Pre-built packages
### Debian-based Linux
You can use the [Pi-Apps-Coders apt repository](https://github.com/Pi-Apps-Coders/box64-debs) to install precompiled box64 debs, updated every 24 hours.
```
@@ -296,3 +333,34 @@ Signed-By: /usr/share/keyrings/box64-archive-keyring.gpg" | sudo tee /etc/apt/so
sudo apt update
sudo apt install box64-generic-arm -y
```
## Cross-compiling
----
### Set Up the Cross-Compiler
For example, to compile Box64 for RISC-V on an x86 machine, you can get prebuilt GNU toolchain from the [riscv-gnu-toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain/releases)
### Run CMake with Cross-Compilation Options
Follow the per-platform compilation instructions to configure the CMake options for your target architecture.
In particular, you must specify the cross-compiler. For example:
```
-DCMAKE_C_COMPILER=riscv64-unknown-linux-gnu-gcc # Or whichever cross-compiler you use
```
### Running tests with QEMU (optional)
To do a quick check, run:
```
qemu-riscv64 -L path/to/your/riscv64/sysroot box64 --help
```
You can run `dirname $(find -name libc.so.6)` to determine whether sysroot is provided by the prebuilt GNU toolchain or not.
To run CTest-based tests under QEMU:
```
ctest -j$(nproc)
```
### Installing on the Target Machine
After successfully cross-compiling, copy the box64 executable to your RISC-V device. Note that simply copying the binary does not automatically install Box64’s shared libraries. Because `make install` does not run on the target during cross-compilation, libraries required for emulation may be missing.
To fix this, copy the shared libraries folder from the Box64 repository (`x64lib` or `x86lib`) to your target. Place them into the proper library search paths, for example:
- `/usr/lib/box64-x86_64-linux-gnu/` (for x86_64)
- `/usr/lib/box64-i386-linux-gnu/` (for i386)
+738 -426
View File
File diff suppressed because it is too large. Load diff
+603 -278
View File
File diff suppressed because it is too large. Load diff
+328
View File
@@ -0,0 +1,328 @@
# Usage: python gen.py
import json
import os
import re
from collections import defaultdict
script_dir = os.path.dirname(os.path.abspath(__file__))
usage_file = os.path.join(script_dir, 'usage.json')
with open(usage_file, 'r') as file:
data = json.load(file)
with open(os.path.join(script_dir, '../USAGE.md'), 'w') as md_file:
md_file.write("""<!--- This file is generated by gen.py, do not edit it directly. -->
Usage
----
There are many environment variables to control Box64's behaviour, which will be listed below by category.
There are 2 types of Box64 builds: the Wine WOW64 build (WowBox64) and the regular Linux build. Beware only some of the environment variables are available in WowBox64.
### Configuration files
In addition to environment variables, if you're using the regular Linux build, Box64 also looks for 2 places for rcfile by default: the system-wide `/etc/box64.box64rc` and user-specific `~/.box64rc`.
While in WowBox64, the configuration file is checked at `%USERPROFILE%/.box64rc` only.
Settings priority follows this order (from highest to lowest): `~/.box64rc` > `/etc/box64.box64rc` > environment variables.
Example configuration:
```
[factorio]
BOX64_DYNAREC_SAFEFLAGS=0
BOX64_DYNAREC_BIGBLOCK=2
BOX64_DYNAREC_FORWARD=1024
BOX64_DYNAREC_CALLRET=1
```
This configuration will apply the specified settings application-wide to any executable named `factorio`.
### Advanced usage for Linux build
1. **Wildcard Matching**
Asterisks (`*`) can be used for basic pattern matching in application names. For instance, `[*setup*]` will match any program containing "setup" in its name. Note this implements simple wildcard matching rather than full regex support.
2. **Custom Configuration File**
The `BOX64_RCFILE` environment variable can specify an alternative configuration file instead of the default `/etc/box64.box64rc`.
3. **Per-File Settings**
Sections starting with `/` apply to specific files. For example:
```
[/d3d9.dll]
BOX64_DYNAREC_SAFEFLAGS=0
```
These settings will only affect the `d3d9.dll` file. This syntax also works for **emulated** Linux libraries, e.g., `[/libstdc++.so.6]`.
----
""")
categories = defaultdict(list)
for entry in data:
categories[entry["category"]].append(entry)
for category, entries in categories.items():
md_file.write(f"## {category}\n\n")
for entry in entries:
md_file.write(f"### {entry['name']}\n\n{entry['description']}{' Availble in WowBox64.' if entry['wine'] else ''}\n\n")
for option in entry['options']:
md_file.write(f" * {option['key']}: {option['description']} {'[Default]' if option['default'] else ''}\n")
md_file.write("\n")
with open(os.path.join(script_dir, '../box64.pod'), 'w') as pod_file:
pod_file.write("""=head1 NAME
box64 - Linux Userspace x86_64 Emulator with a twist
=head1 SYNOPSIS
B<box64> [B<--help>] [B<--version>] I<executable>
=head1 DESCRIPTION
B<Box64> lets you run x86_64 Linux programs (such as games) on non-x86_64 Linux
systems, like ARM (host system needs to be 64-bit little-endian). Since B<Box64>
uses the native versions of some "system" libraries, like libc, libm, SDL, and
OpenGL, it's easy to integrate and use with most applications, and performance
can be surprisingly high in many cases. B<Box64> integrates with DynaRec (dynamic
recompiler) for the ARM64 platform, providing a speed boost between 5 to 10
times faster than using only the interpreter.
=head1 OPTIONS
=over 8
=item B<-h,--help>
Print box64 help and quit.
=item B<-v,--version>
Print box64 version and quit.
=back
=head1 BRIEF USAGE
There are many environment variables to control B<Box64>'s behaviour. In
addition to environment variables, B<Box64> also looks for 2 places for rcfile:
F</etc/box64.box64rc> and F<~/.box64rc>, in the format of .ini files.
Settings priority: F<~/.box64rc> > F</etc/box64.box64rc> > environment variables.
Example:
[factorio]
BOX64_DYNAREC_SAFEFLAGS=0
BOX64_DYNAREC_BIGBLOCK=2
BOX64_DYNAREC_FORWARD=1024
BOX64_DYNAREC_CALLRET=1
=head1 ENVIRONMENT VARIABLES
=over 8
""")
for entry in data:
pod_file.write(f"\n=item B<{entry['name']}> =I<{ '|'.join(option['key'] for option in entry['options']) }>\n\n{entry['description']}{' Availble in WowBox64.' if entry['wine'] else ''}\n\n")
for option in entry['options']:
pod_file.write(f" * {option['key']} : {option['description']} {'[Default]' if option['default'] else ''}\n")
pod_file.write("\n")
pod_file.write("""
=back
=cut
""")
####################
# Validation
####################
PADDING = 30
INCLUDE_BLANK = False
def get_usage_entry(usage, define):
entry = list(e for e in usage if e["name"] == define)
if len(entry) == 0:
print(f"{define:<{PADDING}}: missing usage.json entry")
elif len(entry) > 1:
print(f"{define:<{PADDING}}: multiple usage entries found", len(entry))
else:
return entry[0]
return None
# check `default` uniqueness
for entry in data:
i = list(d["default"] for d in entry["options"]).count(True)
if i > 1:
print(f"{entry['name']:<{PADDING}}: multiple default values usage.json")
# regex to match env.h C code
regex = {
"INTEGER": re.compile(
r"^\s*INTEGER\((?P<define>\w+), (?P<name>\w+), (?P<default>\w+), (?P<min>\w+), (?P<max>\w+), (?P<wine>\w+)\)"
),
"INTEGER64": re.compile(
r"^\s*INTEGER64\((?P<define>\w+), (?P<name>\w+), (?P<default>\w+), (?P<wine>\w+)\)"
),
"BOOLEAN": re.compile(
r"^\s*BOOLEAN\((?P<define>\w+), (?P<name>\w+), (?P<default>\w+), (?P<wine>\w+)\)"
),
"ADDRESS": re.compile(r"^\s*ADDRESS\((?P<define>\w+), (?P<name>\w+), (?P<wine>\w+)\)"),
"STRING": re.compile(r"^\s*STRING\((?P<define>\w+), (?P<name>\w+), (?P<wine>\w+)\)"),
}
env_file = os.path.join(script_dir, "../../src/include/env.h")
with open(env_file, "r") as file:
matches = {}
for line in file.readlines():
for t, r in regex.items():
m = r.search(line)
if m:
# filter out comments and other non useful code
if m.group("define") == "NAME":
continue
if t not in matches:
matches[t] = {}
if (m.group("define") in matches[t]):
# multiple definitions, no default
matches[t][m.group("define")]['no_default'] = True
break
matches[t][m.group("define")] = m.groupdict()
matches[t][m.group("define")]['no_default'] = False
for define, m in matches["INTEGER"].items():
name = m["name"]
default = None if m["no_default"] or not m["default"].isdigit() else int(m["default"])
min = int(m["min"])
max = int(m["max"])
# Check default in valid range
if default and (default < min or default > max):
print(f"{define:<{PADDING}}: default lays outside of min/max range")
# Check consistency with usage.json
if e := get_usage_entry(data, define):
# guess min/max values if possible
min2 = max2 = None
# blank means that the entry has an 'XXXX' entry which usually indicated that arbitrary values are valid
blank = False
default2 = None
if int(m["wine"]) != int(e["wine"]):
print(f"{define:<{PADDING}}: wine mismatch: env.h={int(m['wine'])}, usage.json={int(e['wine'])}")
for o in e["options"]:
if o["key"] == "XXXX":
blank = True
continue
val = int(o["key"]) # not supposed to fail
min2 = min2 if min2 is not None and min2 < val else val
max2 = max2 if max2 is not None and max2 > val else val
if o["default"]:
default2 = val
if min2 and min2 != min:
if not blank or (blank and INCLUDE_BLANK):
print(
f"{define:<{PADDING}}: min value mismatch: env.h={min}, usage.json={min2}{(' (possible false positive)' if blank else '')}"
)
if max2 and max2 != max:
if not blank or (blank and INCLUDE_BLANK):
print(
f"{define:<{PADDING}}: max value mismatch: env.h={max}, usage.json={max2}{(' (possible false positive)' if blank else '')}"
)
if default2 != default:
print(
f"{define:<{PADDING}}: default value mismatch: env.h={default}, usage.json={default2}"
)
for define, m in matches['INTEGER64'].items():
# similar to INTEGER but without min/max
name = m["name"]
default = None if m["no_default"] or not m["default"].isdigit() else int(m["default"])
# Check consistency with usage.json
if e := get_usage_entry(data, define):
default2 = None
if int(m["wine"]) != int(e["wine"]):
print(f"{define:<{PADDING}}: wine mismatch: env.h={int(m['wine'])}, usage.json={int(e['wine'])}")
for o in e["options"]:
if o["key"] == "XXXX":
continue
val = int(o["key"])
if o["default"]:
default2 = val
if default2 != default:
print(
f"{define:<{PADDING}}: default value mismatch: env.h={default}, usage.json={default2}"
)
for define, m in matches["BOOLEAN"].items():
name = m["name"]
default = None if m["no_default"] or m["default"] not in ["0", "1"] else bool(m["default"])
# Check consistency with usage.json
if e := get_usage_entry(data, define):
default2 = None
if int(m["wine"]) != int(e["wine"]):
print(f"{define:<{PADDING}}: wine mismatch: env.h={int(m['wine'])}, usage.json={int(e['wine'])}")
for o in e["options"]:
try:
val = bool(o["key"])
except ValueError:
print(f"{define:<{PADDING}}: failed to parse boolean {o['key']}")
if o["default"]:
default2 = val
if default2 != default:
print(
f"{define:<{PADDING}}: default value mismatch: env.h={default}, usage.json={default2}"
)
# ADDRESS and STRING are not that interesting
for define, m in matches["ADDRESS"].items():
if e := get_usage_entry(data, define):
if int(m["wine"]) != int(e["wine"]):
print(f"{define:<{PADDING}}: wine mismatch: env.h={int(m['wine'])}, usage.json={int(e['wine'])}")
for define, m in matches["STRING"].items():
# skip BOX64_ENV[1-5] entries, they mismatch but this is fine
if define.startswith("BOX64_ENV"):
continue
if e := get_usage_entry(data, define):
if int(m["wine"]) != int(e["wine"]):
print(f"{define:<{PADDING}}: wine mismatch: env.h={int(m['wine'])}, usage.json={int(e['wine'])}")
# check that everything from usage.json is in env.h
for e in data:
define = e["name"]
# skip BOX64_ENV[1-5] entries, they mismatch but this is fine
if define.startswith("BOX64_ENV"):
continue
found = False
for t in matches:
for d in matches[t]:
if d == define:
found = True
if not found:
print(f"{define:<{PADDING}}: missing env.h entry")
+1809
View File
File diff suppressed because it is too large. Load diff
+71
View File
@@ -0,0 +1,71 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __cos( x, y )
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
*
* Algorithm
* 1. Since cos(-x) = cos(x), we need only to consider positive x.
* 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
* 3. cos(x) is approximated by a polynomial of degree 14 on
* [0,pi/4]
* 4 14
* cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
* where the remez error is
*
* | 2 4 6 8 10 12 14 | -58
* |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
* | |
*
* 4 6 8 10 12 14
* 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
* cos(x) ~ 1 - x*x/2 + r
* since cos(x+y) ~ cos(x) - sin(x)*y
* ~ cos(x) - x*y,
* a correction term is necessary in cos(x) and hence
* cos(x+y) = 1 - (x*x/2 - (r - x*y))
* For better accuracy, rearrange to
* cos(x+y) ~ w + (tmp + (r-x*y))
* where w = 1 - x*x/2 and tmp is a tiny correction term
* (1 - x*x/2 == w + tmp exactly in infinite precision).
* The exactness of w + tmp in infinite precision depends on w
* and tmp having the same precision as x. If they have extra
* precision due to compiler bugs, then the extra precision is
* only good provided it is retained in all terms of the final
* expression for cos(). Retention happens in all cases tested
* under FreeBSD, so don't pessimize things by forcibly clipping
* any extra precision in w.
*/
#include "libm.h"
static const double
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
double __cos(double x, double y)
{
double_t hz,z,r,w;
z = x*x;
w = z*z;
r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));
hz = 0.5*z;
w = 1.0-hz;
return w + (((1.0-w)-hz) + (z*r-x*y));
}
+6
View File
@@ -0,0 +1,6 @@
#include "libm.h"
double __math_divzero(uint32_t sign)
{
return fp_barrier(sign ? -1.0 : 1.0) / 0.0;
}
+6
View File
@@ -0,0 +1,6 @@
#include "libm.h"
double __math_invalid(double x)
{
return (x - x) / (x - x);
}
+190
View File
@@ -0,0 +1,190 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
* Optimized by Bruce D. Evans.
*/
/* __rem_pio2(x,y)
*
* return the remainder of x rem pi/2 in y[0]+y[1]
* use __rem_pio2_large() for large x
*/
#include "libm.h"
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD==2
#define EPS LDBL_EPSILON
#endif
/*
* invpio2: 53 bits of 2/pi
* pio2_1: first 33 bit of pi/2
* pio2_1t: pi/2 - pio2_1
* pio2_2: second 33 bit of pi/2
* pio2_2t: pi/2 - (pio2_1+pio2_2)
* pio2_3: third 33 bit of pi/2
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const double
toint = 1.5/EPS,
pio4 = 0x1.921fb54442d18p-1,
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
int __rem_pio2(double x, double *y)
{
union {double f; uint64_t i;} u = {x};
double_t z,w,t,r,fn;
double tx[3],ty[2];
uint32_t ix;
int sign, n, ex, ey, i;
sign = u.i>>63;
ix = u.i>>32 & 0x7fffffff;
if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */
if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */
goto medium; /* cancellation -- use medium case */
if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */
if (!sign) {
z = x - pio2_1; /* one round good to 85 bits */
y[0] = z - pio2_1t;
y[1] = (z-y[0]) - pio2_1t;
return 1;
} else {
z = x + pio2_1;
y[0] = z + pio2_1t;
y[1] = (z-y[0]) + pio2_1t;
return -1;
}
} else {
if (!sign) {
z = x - 2*pio2_1;
y[0] = z - 2*pio2_1t;
y[1] = (z-y[0]) - 2*pio2_1t;
return 2;
} else {
z = x + 2*pio2_1;
y[0] = z + 2*pio2_1t;
y[1] = (z-y[0]) + 2*pio2_1t;
return -2;
}
}
}
if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */
if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */
if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */
goto medium;
if (!sign) {
z = x - 3*pio2_1;
y[0] = z - 3*pio2_1t;
y[1] = (z-y[0]) - 3*pio2_1t;
return 3;
} else {
z = x + 3*pio2_1;
y[0] = z + 3*pio2_1t;
y[1] = (z-y[0]) + 3*pio2_1t;
return -3;
}
} else {
if (ix == 0x401921fb) /* |x| ~= 4pi/2 */
goto medium;
if (!sign) {
z = x - 4*pio2_1;
y[0] = z - 4*pio2_1t;
y[1] = (z-y[0]) - 4*pio2_1t;
return 4;
} else {
z = x + 4*pio2_1;
y[0] = z + 4*pio2_1t;
y[1] = (z-y[0]) + 4*pio2_1t;
return -4;
}
}
}
if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */
medium:
/* rint(x/(pi/2)) */
fn = rint(x * invpio2);
n = (int32_t)fn;
r = x - fn*pio2_1;
w = fn*pio2_1t; /* 1st round, good to 85 bits */
/* Matters with directed rounding. */
if (predict_false(r - w < -pio4)) {
n--;
fn--;
r = x - fn*pio2_1;
w = fn*pio2_1t;
} else if (predict_false(r - w > pio4)) {
n++;
fn++;
r = x - fn*pio2_1;
w = fn*pio2_1t;
}
y[0] = r - w;
u.f = y[0];
ey = u.i>>52 & 0x7ff;
ex = ix>>20;
if (ex - ey > 16) { /* 2nd round, good to 118 bits */
t = r;
w = fn*pio2_2;
r = t - w;
w = fn*pio2_2t - ((t-r)-w);
y[0] = r - w;
u.f = y[0];
ey = u.i>>52 & 0x7ff;
if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */
t = r;
w = fn*pio2_3;
r = t - w;
w = fn*pio2_3t - ((t-r)-w);
y[0] = r - w;
}
}
y[1] = (r - y[0]) - w;
return n;
}
/*
* all other (large) arguments
*/
if (ix >= 0x7ff00000) { /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
/* set z = scalbn(|x|,-ilogb(x)+23) */
u.f = x;
u.i &= (uint64_t)-1>>12;
u.i |= (uint64_t)(0x3ff + 23)<<52;
z = u.f;
for (i=0; i < 2; i++) {
tx[i] = (double)(int32_t)z;
z = (z-tx[i])*0x1p24;
}
tx[i] = z;
/* skip zero terms, first term is non-zero */
while (tx[i] == 0.0)
i--;
n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);
if (sign) {
y[0] = -ty[0];
y[1] = -ty[1];
return -n;
}
y[0] = ty[0];
y[1] = ty[1];
return n;
}
+442
View File
@@ -0,0 +1,442 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __rem_pio2_large(x,y,e0,nx,prec)
* double x[],y[]; int e0,nx,prec;
*
* __rem_pio2_large return the last three digits of N with
* y = x - N*pi/2
* so that |y| < pi/2.
*
* The method is to compute the integer (mod 8) and fraction parts of
* (2/pi)*x without doing the full multiplication. In general we
* skip the part of the product that are known to be a huge integer (
* more accurately, = 0 mod 8 ). Thus the number of operations are
* independent of the exponent of the input.
*
* (2/pi) is represented by an array of 24-bit integers in ipio2[].
*
* Input parameters:
* x[] The input value (must be positive) is broken into nx
* pieces of 24-bit integers in double precision format.
* x[i] will be the i-th 24 bit of x. The scaled exponent
* of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
* match x's up to 24 bits.
*
* Example of breaking a double positive z into x[0]+x[1]+x[2]:
* e0 = ilogb(z)-23
* z = scalbn(z,-e0)
* for i = 0,1,2
* x[i] = floor(z)
* z = (z-x[i])*2**24
*
*
* y[] ouput result in an array of double precision numbers.
* The dimension of y[] is:
* 24-bit precision 1
* 53-bit precision 2
* 64-bit precision 2
* 113-bit precision 3
* The actual value is the sum of them. Thus for 113-bit
* precison, one may have to do something like:
*
* long double t,w,r_head, r_tail;
* t = (long double)y[2] + (long double)y[1];
* w = (long double)y[0];
* r_head = t+w;
* r_tail = w - (r_head - t);
*
* e0 The exponent of x[0]. Must be <= 16360 or you need to
* expand the ipio2 table.
*
* nx dimension of x[]
*
* prec an integer indicating the precision:
* 0 24 bits (single)
* 1 53 bits (double)
* 2 64 bits (extended)
* 3 113 bits (quad)
*
* External function:
* double scalbn(), floor();
*
*
* Here is the description of some local variables:
*
* jk jk+1 is the initial number of terms of ipio2[] needed
* in the computation. The minimum and recommended value
* for jk is 3,4,4,6 for single, double, extended, and quad.
* jk+1 must be 2 larger than you might expect so that our
* recomputation test works. (Up to 24 bits in the integer
* part (the 24 bits of it that we compute) and 23 bits in
* the fraction part may be lost to cancelation before we
* recompute.)
*
* jz local integer variable indicating the number of
* terms of ipio2[] used.
*
* jx nx - 1
*
* jv index for pointing to the suitable ipio2[] for the
* computation. In general, we want
* ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
* is an integer. Thus
* e0-3-24*jv >= 0 or (e0-3)/24 >= jv
* Hence jv = max(0,(e0-3)/24).
*
* jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
*
* q[] double array with integral value, representing the
* 24-bits chunk of the product of x and 2/pi.
*
* q0 the corresponding exponent of q[0]. Note that the
* exponent for q[i] would be q0-24*i.
*
* PIo2[] double precision array, obtained by cutting pi/2
* into 24 bits chunks.
*
* f[] ipio2[] in floating point
*
* iq[] integer array by breaking up q[] in 24-bits chunk.
*
* fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
*
* ih integer. If >0 it indicates q[] is >= 0.5, hence
* it also indicates the *sign* of the result.
*
*/
/*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "libm.h"
static const int init_jk[] = {3,4,4,6}; /* initial value for jk */
/*
* Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
*
* integer array, contains the (24*i)-th to (24*i+23)-th
* bit of 2/pi after binary point. The corresponding
* floating value is
*
* ipio2[i] * 2^(-24(i+1)).
*
* NB: This table must have at least (e0-3)/24 + jk terms.
* For quad precision (e0 <= 16360, jk = 6), this is 686.
*/
static const int32_t ipio2[] = {
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
#if LDBL_MAX_EXP > 1024
0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6,
0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2,
0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35,
0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30,
0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C,
0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4,
0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770,
0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7,
0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19,
0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522,
0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16,
0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6,
0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E,
0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48,
0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3,
0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF,
0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55,
0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612,
0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929,
0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC,
0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B,
0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C,
0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4,
0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB,
0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC,
0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C,
0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F,
0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5,
0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437,
0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B,
0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA,
0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD,
0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3,
0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3,
0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717,
0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F,
0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61,
0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB,
0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51,
0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0,
0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C,
0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6,
0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC,
0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED,
0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328,
0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D,
0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0,
0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B,
0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4,
0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3,
0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F,
0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD,
0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B,
0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4,
0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761,
0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31,
0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30,
0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262,
0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E,
0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1,
0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C,
0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4,
0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08,
0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196,
0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9,
0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4,
0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC,
0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C,
0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0,
0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C,
0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0,
0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC,
0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22,
0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893,
0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7,
0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5,
0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F,
0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4,
0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF,
0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B,
0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2,
0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138,
0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E,
0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569,
0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34,
0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9,
0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D,
0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F,
0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855,
0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569,
0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B,
0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE,
0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41,
0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49,
0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F,
0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110,
0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8,
0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365,
0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A,
0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270,
0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5,
0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616,
0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B,
0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0,
#endif
};
static const double PIo2[] = {
1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
};
int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec)
{
int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
double z,fw,f[20],fq[20],q[20];
/* initialize jk*/
jk = init_jk[prec];
jp = jk;
/* determine jx,jv,q0, note that 3>q0 */
jx = nx-1;
jv = (e0-3)/24; if(jv<0) jv=0;
q0 = e0-24*(jv+1);
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
j = jv-jx; m = jx+jk;
for (i=0; i<=m; i++,j++)
f[i] = j<0 ? 0.0 : (double)ipio2[j];
/* compute q[0],q[1],...q[jk] */
for (i=0; i<=jk; i++) {
for (j=0,fw=0.0; j<=jx; j++)
fw += x[j]*f[jx+i-j];
q[i] = fw;
}
jz = jk;
recompute:
/* distill q[] into iq[] reversingly */
for (i=0,j=jz,z=q[jz]; j>0; i++,j--) {
fw = (double)(int32_t)(0x1p-24*z);
iq[i] = (int32_t)(z - 0x1p24*fw);
z = q[j-1]+fw;
}
/* compute n */
z = scalbn(z,q0); /* actual value of z */
z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
n = (int32_t)z;
z -= (double)n;
ih = 0;
if (q0 > 0) { /* need iq[jz-1] to determine n */
i = iq[jz-1]>>(24-q0); n += i;
iq[jz-1] -= i<<(24-q0);
ih = iq[jz-1]>>(23-q0);
}
else if (q0 == 0) ih = iq[jz-1]>>23;
else if (z >= 0.5) ih = 2;
if (ih > 0) { /* q > 0.5 */
n += 1; carry = 0;
for (i=0; i<jz; i++) { /* compute 1-q */
j = iq[i];
if (carry == 0) {
if (j != 0) {
carry = 1;
iq[i] = 0x1000000 - j;
}
} else
iq[i] = 0xffffff - j;
}
if (q0 > 0) { /* rare case: chance is 1 in 12 */
switch(q0) {
case 1:
iq[jz-1] &= 0x7fffff; break;
case 2:
iq[jz-1] &= 0x3fffff; break;
}
}
if (ih == 2) {
z = 1.0 - z;
if (carry != 0)
z -= scalbn(1.0,q0);
}
}
/* check if recomputation is needed */
if (z == 0.0) {
j = 0;
for (i=jz-1; i>=jk; i--) j |= iq[i];
if (j == 0) { /* need recomputation */
for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
f[jx+i] = (double)ipio2[jv+i];
for (j=0,fw=0.0; j<=jx; j++)
fw += x[j]*f[jx+i-j];
q[i] = fw;
}
jz += k;
goto recompute;
}
}
/* chop off zero terms */
if (z == 0.0) {
jz -= 1;
q0 -= 24;
while (iq[jz] == 0) {
jz--;
q0 -= 24;
}
} else { /* break z into 24-bit if necessary */
z = scalbn(z,-q0);
if (z >= 0x1p24) {
fw = (double)(int32_t)(0x1p-24*z);
iq[jz] = (int32_t)(z - 0x1p24*fw);
jz += 1;
q0 += 24;
iq[jz] = (int32_t)fw;
} else
iq[jz] = (int32_t)z;
}
/* convert integer "bit" chunk to floating-point value */
fw = scalbn(1.0,q0);
for (i=jz; i>=0; i--) {
q[i] = fw*(double)iq[i];
fw *= 0x1p-24;
}
/* compute PIo2[0,...,jp]*q[jz,...,0] */
for(i=jz; i>=0; i--) {
for (fw=0.0,k=0; k<=jp && k<=jz-i; k++)
fw += PIo2[k]*q[i+k];
fq[jz-i] = fw;
}
/* compress fq[] into y[] */
switch(prec) {
case 0:
fw = 0.0;
for (i=jz; i>=0; i--)
fw += fq[i];
y[0] = ih==0 ? fw : -fw;
break;
case 1:
case 2:
fw = 0.0;
for (i=jz; i>=0; i--)
fw += fq[i];
// TODO: drop excess precision here once double_t is used
fw = (double)fw;
y[0] = ih==0 ? fw : -fw;
fw = fq[0]-fw;
for (i=1; i<=jz; i++)
fw += fq[i];
y[1] = ih==0 ? fw : -fw;
break;
case 3: /* painful */
for (i=jz; i>0; i--) {
fw = fq[i-1]+fq[i];
fq[i] += fq[i-1]-fw;
fq[i-1] = fw;
}
for (i=jz; i>1; i--) {
fw = fq[i-1]+fq[i];
fq[i] += fq[i-1]-fw;
fq[i-1] = fw;
}
for (fw=0.0,i=jz; i>=2; i--)
fw += fq[i];
if (ih==0) {
y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
} else {
y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
}
}
return n&7;
}
+64
View File
@@ -0,0 +1,64 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __sin( x, y, iy)
* kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
* Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
*
* Algorithm
* 1. Since sin(-x) = -sin(x), we need only to consider positive x.
* 2. Callers must return sin(-0) = -0 without calling here since our
* odd polynomial is not evaluated in a way that preserves -0.
* Callers may do the optimization sin(x) ~ x for tiny x.
* 3. sin(x) is approximated by a polynomial of degree 13 on
* [0,pi/4]
* 3 13
* sin(x) ~ x + S1*x + ... + S6*x
* where
*
* |sin(x) 2 4 6 8 10 12 | -58
* |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
* | x |
*
* 4. sin(x+y) = sin(x) + sin'(x')*y
* ~ sin(x) + (1-x*x/2)*y
* For better accuracy, let
* 3 2 2 2 2
* r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
* then 3 2
* sin(x) = x + (S1*x + (x *(r-y/2)+y))
*/
#include "libm.h"
static const double
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
double __sin(double x, double y, int iy)
{
double_t z,r,v,w;
z = x*x;
w = z*z;
r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6);
v = z*x;
if (iy == 0)
return x + v*(S1 + z*r);
else
return x - ((z*(0.5*y - v*r) - y) - v*S1);
}
+79
View File
@@ -0,0 +1,79 @@
/* origin: FreeBSD /usr/src/lib/msun/src/s_cos.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* cos(x)
* Return cosine function of x.
*
* kernel function:
* __sin ... sine function on [-pi/4,pi/4]
* __cos ... cosine function on [-pi/4,pi/4]
* __rem_pio2 ... argument reduction routine
*
* Method.
* Let S,C and T denote the sin, cos and tan respectively on
* [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
* in [-pi/4 , +pi/4], and let n = k mod 4.
* We have
*
* n sin(x) cos(x) tan(x)
* ----------------------------------------------------------
* 0 S C T
* 1 C -S -1/T
* 2 -S -C T
* 3 -C S -1/T
* ----------------------------------------------------------
*
* Special cases:
* Let trig be any of sin, cos, or tan.
* trig(+-INF) is NaN, with signals;
* trig(NaN) is that NaN;
*
* Accuracy:
* TRIG(x) returns trig(x) nearly rounded
*/
#include "libm.h"
double __cdecl cos(double x)
{
double y[2];
uint32_t ix;
unsigned n;
GET_HIGH_WORD(ix, x);
ix &= 0x7fffffff;
/* |x| ~< pi/4 */
if (ix <= 0x3fe921fb) {
if (ix < 0x3e46a09e) { /* |x| < 2**-27 * sqrt(2) */
/* raise inexact if x!=0 */
FORCE_EVAL(x + 0x1p120f);
return 1.0;
}
return __cos(x, 0);
}
/* cos(Inf or NaN) is NaN */
if (isinf(x))
return math_error(_DOMAIN, "cos", x, 0, x - x);
if (ix >= 0x7ff00000)
return x-x;
/* argument reduction */
n = __rem_pio2(x, y);
switch (n&3) {
case 0: return __cos(y[0], y[1]);
case 1: return -__sin(y[0], y[1], 1);
case 2: return -__cos(y[0], y[1]);
default:
return __sin(y[0], y[1], 1);
}
}
+130
View File
@@ -0,0 +1,130 @@
/*
* Double-precision 2^x function.
*
* Copyright (c) 2018, Arm Limited.
* SPDX-License-Identifier: MIT
*/
#include <math.h>
#include <stdint.h>
#include "libm.h"
#include "exp_data.h"
#define N (1 << EXP_TABLE_BITS)
#define Shift __exp_data.exp2_shift
#define T __exp_data.tab
#define C1 __exp_data.exp2_poly[0]
#define C2 __exp_data.exp2_poly[1]
#define C3 __exp_data.exp2_poly[2]
#define C4 __exp_data.exp2_poly[3]
#define C5 __exp_data.exp2_poly[4]
/* Handle cases that may overflow or underflow when computing the result that
is scale*(1+TMP) without intermediate rounding. The bit representation of
scale is in SBITS, however it has a computed exponent that may have
overflown into the sign bit so that needs to be adjusted before using it as
a double. (int32_t)KI is the k used in the argument reduction and exponent
adjustment of scale, positive k here means the result may overflow and
negative k means the result may underflow. */
static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
{
double_t scale, y;
if ((ki & 0x80000000) == 0) {
/* k > 0, the exponent of scale might have overflowed by 1. */
sbits -= 1ull << 52;
scale = asdouble(sbits);
y = 2 * (scale + scale * tmp);
return eval_as_double(y);
}
/* k < 0, need special care in the subnormal range. */
sbits += 1022ull << 52;
scale = asdouble(sbits);
y = scale + scale * tmp;
if (y < 1.0) {
/* Round y to the right precision before scaling it into the subnormal
range to avoid double rounding that can cause 0.5+E/2 ulp error where
E is the worst-case ulp error outside the subnormal range. So this
is only useful if the goal is better than 1 ulp worst-case error. */
double_t hi, lo;
lo = scale - y + scale * tmp;
hi = 1.0 + y;
lo = 1.0 - hi + y + lo;
y = eval_as_double(hi + lo) - 1.0;
/* Avoid -0.0 with downward rounding. */
if (WANT_ROUNDING && y == 0.0)
y = 0.0;
/* The underflow exception needs to be signaled explicitly. */
fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022);
}
y = 0x1p-1022 * y;
return eval_as_double(y);
}
/* Top 12 bits of a double (sign and exponent bits). */
static inline uint32_t top12(double x)
{
return asuint64(x) >> 52;
}
double __cdecl exp2(double x)
{
uint32_t abstop;
uint64_t ki, idx, top, sbits;
double_t kd, r, r2, scale, tail, tmp;
abstop = top12(x) & 0x7ff;
if (predict_false(abstop - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54))) {
if (abstop - top12(0x1p-54) >= 0x80000000)
/* Avoid spurious underflow for tiny x. */
/* Note: 0 is common input. */
return WANT_ROUNDING ? 1.0 + x : 1.0;
if (abstop >= top12(1024.0)) {
if (asuint64(x) == asuint64(-INFINITY))
return 0.0;
if (abstop >= top12(INFINITY))
return 1.0 + x;
if (!(asuint64(x) >> 63)) {
errno = ERANGE;
return fp_barrier(DBL_MAX) * DBL_MAX;
}
else if (x <= -2147483648.0) {
fp_barrier(x + 0x1p120f);
return 0;
}
else if (asuint64(x) >= asuint64(-1075.0)) {
errno = ERANGE;
fp_barrier(x + 0x1p120f);
return 0;
}
}
if (2 * asuint64(x) > 2 * asuint64(928.0))
/* Large x is special cased below. */
abstop = 0;
}
/* exp2(x) = 2^(k/N) * 2^r, with 2^r in [2^(-1/2N),2^(1/2N)]. */
/* x = k/N + r, with int k and r in [-1/2N, 1/2N]. */
kd = eval_as_double(x + Shift);
ki = asuint64(kd); /* k. */
kd -= Shift; /* k/N for int k. */
r = x - kd;
/* 2^(k/N) ~= scale * (1 + tail). */
idx = 2 * (ki % N);
top = ki << (52 - EXP_TABLE_BITS);
tail = asdouble(T[idx]);
/* This is only a valid scale when -1023*N < k < 1024*N. */
sbits = T[idx + 1] + top;
/* exp2(x) = 2^(k/N) * 2^r ~= scale + scale * (tail + 2^r - 1). */
/* Evaluation is optimized assuming superscalar pipelined execution. */
r2 = r * r;
/* Without fma the worst case error is 0.5/N ulp larger. */
/* Worst case error is less than 0.5+0.86/N+(abs poly error * 2^53) ulp. */
tmp = tail + r * C1 + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);
if (predict_false(abstop == 0))
return specialcase(tmp, sbits, ki);
scale = asdouble(sbits);
/* Note: tmp == 0 or |tmp| > 2^-65 and scale > 2^-928, so there
is no spurious underflow here even without fma. */
return eval_as_double(scale + scale * tmp);
}
+182
View File
@@ -0,0 +1,182 @@
/*
* Shared data between exp, exp2 and pow.
*
* Copyright (c) 2018, Arm Limited.
* SPDX-License-Identifier: MIT
*/
#include "exp_data.h"
#define N (1 << EXP_TABLE_BITS)
const struct exp_data __exp_data = {
// N/ln2
.invln2N = 0x1.71547652b82fep0 * N,
// -ln2/N
.negln2hiN = -0x1.62e42fefa0000p-8,
.negln2loN = -0x1.cf79abc9e3b3ap-47,
// Used for rounding when !TOINT_INTRINSICS
#if EXP_USE_TOINT_NARROW
.shift = 0x1800000000.8p0,
#else
.shift = 0x1.8p52,
#endif
// exp polynomial coefficients.
.poly = {
// abs error: 1.555*2^-66
// ulp error: 0.509 (0.511 without fma)
// if |x| < ln2/256+eps
// abs error if |x| < ln2/256+0x1p-15: 1.09*2^-65
// abs error if |x| < ln2/128: 1.7145*2^-56
0x1.ffffffffffdbdp-2,
0x1.555555555543cp-3,
0x1.55555cf172b91p-5,
0x1.1111167a4d017p-7,
},
.exp2_shift = 0x1.8p52 / N,
// exp2 polynomial coefficients.
.exp2_poly = {
// abs error: 1.2195*2^-65
// ulp error: 0.507 (0.511 without fma)
// if |x| < 1/256
// abs error if |x| < 1/128: 1.9941*2^-56
0x1.62e42fefa39efp-1,
0x1.ebfbdff82c424p-3,
0x1.c6b08d70cf4b5p-5,
0x1.3b2abd24650ccp-7,
0x1.5d7e09b4e3a84p-10,
},
// 2^(k/N) ~= H[k]*(1 + T[k]) for int k in [0,N)
// tab[2*k] = asuint64(T[k])
// tab[2*k+1] = asuint64(H[k]) - (k << 52)/N
.tab = {
0x0, 0x3ff0000000000000,
0x3c9b3b4f1a88bf6e, 0x3feff63da9fb3335,
0xbc7160139cd8dc5d, 0x3fefec9a3e778061,
0xbc905e7a108766d1, 0x3fefe315e86e7f85,
0x3c8cd2523567f613, 0x3fefd9b0d3158574,
0xbc8bce8023f98efa, 0x3fefd06b29ddf6de,
0x3c60f74e61e6c861, 0x3fefc74518759bc8,
0x3c90a3e45b33d399, 0x3fefbe3ecac6f383,
0x3c979aa65d837b6d, 0x3fefb5586cf9890f,
0x3c8eb51a92fdeffc, 0x3fefac922b7247f7,
0x3c3ebe3d702f9cd1, 0x3fefa3ec32d3d1a2,
0xbc6a033489906e0b, 0x3fef9b66affed31b,
0xbc9556522a2fbd0e, 0x3fef9301d0125b51,
0xbc5080ef8c4eea55, 0x3fef8abdc06c31cc,
0xbc91c923b9d5f416, 0x3fef829aaea92de0,
0x3c80d3e3e95c55af, 0x3fef7a98c8a58e51,
0xbc801b15eaa59348, 0x3fef72b83c7d517b,
0xbc8f1ff055de323d, 0x3fef6af9388c8dea,
0x3c8b898c3f1353bf, 0x3fef635beb6fcb75,
0xbc96d99c7611eb26, 0x3fef5be084045cd4,
0x3c9aecf73e3a2f60, 0x3fef54873168b9aa,
0xbc8fe782cb86389d, 0x3fef4d5022fcd91d,
0x3c8a6f4144a6c38d, 0x3fef463b88628cd6,
0x3c807a05b0e4047d, 0x3fef3f49917ddc96,
0x3c968efde3a8a894, 0x3fef387a6e756238,
0x3c875e18f274487d, 0x3fef31ce4fb2a63f,
0x3c80472b981fe7f2, 0x3fef2b4565e27cdd,
0xbc96b87b3f71085e, 0x3fef24dfe1f56381,
0x3c82f7e16d09ab31, 0x3fef1e9df51fdee1,
0xbc3d219b1a6fbffa, 0x3fef187fd0dad990,
0x3c8b3782720c0ab4, 0x3fef1285a6e4030b,
0x3c6e149289cecb8f, 0x3fef0cafa93e2f56,
0x3c834d754db0abb6, 0x3fef06fe0a31b715,
0x3c864201e2ac744c, 0x3fef0170fc4cd831,
0x3c8fdd395dd3f84a, 0x3feefc08b26416ff,
0xbc86a3803b8e5b04, 0x3feef6c55f929ff1,
0xbc924aedcc4b5068, 0x3feef1a7373aa9cb,
0xbc9907f81b512d8e, 0x3feeecae6d05d866,
0xbc71d1e83e9436d2, 0x3feee7db34e59ff7,
0xbc991919b3ce1b15, 0x3feee32dc313a8e5,
0x3c859f48a72a4c6d, 0x3feedea64c123422,
0xbc9312607a28698a, 0x3feeda4504ac801c,
0xbc58a78f4817895b, 0x3feed60a21f72e2a,
0xbc7c2c9b67499a1b, 0x3feed1f5d950a897,
0x3c4363ed60c2ac11, 0x3feece086061892d,
0x3c9666093b0664ef, 0x3feeca41ed1d0057,
0x3c6ecce1daa10379, 0x3feec6a2b5c13cd0,
0x3c93ff8e3f0f1230, 0x3feec32af0d7d3de,
0x3c7690cebb7aafb0, 0x3feebfdad5362a27,
0x3c931dbdeb54e077, 0x3feebcb299fddd0d,
0xbc8f94340071a38e, 0x3feeb9b2769d2ca7,
0xbc87deccdc93a349, 0x3feeb6daa2cf6642,
0xbc78dec6bd0f385f, 0x3feeb42b569d4f82,
0xbc861246ec7b5cf6, 0x3feeb1a4ca5d920f,
0x3c93350518fdd78e, 0x3feeaf4736b527da,
0x3c7b98b72f8a9b05, 0x3feead12d497c7fd,
0x3c9063e1e21c5409, 0x3feeab07dd485429,
0x3c34c7855019c6ea, 0x3feea9268a5946b7,
0x3c9432e62b64c035, 0x3feea76f15ad2148,
0xbc8ce44a6199769f, 0x3feea5e1b976dc09,
0xbc8c33c53bef4da8, 0x3feea47eb03a5585,
0xbc845378892be9ae, 0x3feea34634ccc320,
0xbc93cedd78565858, 0x3feea23882552225,
0x3c5710aa807e1964, 0x3feea155d44ca973,
0xbc93b3efbf5e2228, 0x3feea09e667f3bcd,
0xbc6a12ad8734b982, 0x3feea012750bdabf,
0xbc6367efb86da9ee, 0x3fee9fb23c651a2f,
0xbc80dc3d54e08851, 0x3fee9f7df9519484,
0xbc781f647e5a3ecf, 0x3fee9f75e8ec5f74,
0xbc86ee4ac08b7db0, 0x3fee9f9a48a58174,
0xbc8619321e55e68a, 0x3fee9feb564267c9,
0x3c909ccb5e09d4d3, 0x3feea0694fde5d3f,
0xbc7b32dcb94da51d, 0x3feea11473eb0187,
0x3c94ecfd5467c06b, 0x3feea1ed0130c132,
0x3c65ebe1abd66c55, 0x3feea2f336cf4e62,
0xbc88a1c52fb3cf42, 0x3feea427543e1a12,
0xbc9369b6f13b3734, 0x3feea589994cce13,
0xbc805e843a19ff1e, 0x3feea71a4623c7ad,
0xbc94d450d872576e, 0x3feea8d99b4492ed,
0x3c90ad675b0e8a00, 0x3feeaac7d98a6699,
0x3c8db72fc1f0eab4, 0x3feeace5422aa0db,
0xbc65b6609cc5e7ff, 0x3feeaf3216b5448c,
0x3c7bf68359f35f44, 0x3feeb1ae99157736,
0xbc93091fa71e3d83, 0x3feeb45b0b91ffc6,
0xbc5da9b88b6c1e29, 0x3feeb737b0cdc5e5,
0xbc6c23f97c90b959, 0x3feeba44cbc8520f,
0xbc92434322f4f9aa, 0x3feebd829fde4e50,
0xbc85ca6cd7668e4b, 0x3feec0f170ca07ba,
0x3c71affc2b91ce27, 0x3feec49182a3f090,
0x3c6dd235e10a73bb, 0x3feec86319e32323,
0xbc87c50422622263, 0x3feecc667b5de565,
0x3c8b1c86e3e231d5, 0x3feed09bec4a2d33,
0xbc91bbd1d3bcbb15, 0x3feed503b23e255d,
0x3c90cc319cee31d2, 0x3feed99e1330b358,
0x3c8469846e735ab3, 0x3feede6b5579fdbf,
0xbc82dfcd978e9db4, 0x3feee36bbfd3f37a,
0x3c8c1a7792cb3387, 0x3feee89f995ad3ad,
0xbc907b8f4ad1d9fa, 0x3feeee07298db666,
0xbc55c3d956dcaeba, 0x3feef3a2b84f15fb,
0xbc90a40e3da6f640, 0x3feef9728de5593a,
0xbc68d6f438ad9334, 0x3feeff76f2fb5e47,
0xbc91eee26b588a35, 0x3fef05b030a1064a,
0x3c74ffd70a5fddcd, 0x3fef0c1e904bc1d2,
0xbc91bdfbfa9298ac, 0x3fef12c25bd71e09,
0x3c736eae30af0cb3, 0x3fef199bdd85529c,
0x3c8ee3325c9ffd94, 0x3fef20ab5fffd07a,
0x3c84e08fd10959ac, 0x3fef27f12e57d14b,
0x3c63cdaf384e1a67, 0x3fef2f6d9406e7b5,
0x3c676b2c6c921968, 0x3fef3720dcef9069,
0xbc808a1883ccb5d2, 0x3fef3f0b555dc3fa,
0xbc8fad5d3ffffa6f, 0x3fef472d4a07897c,
0xbc900dae3875a949, 0x3fef4f87080d89f2,
0x3c74a385a63d07a7, 0x3fef5818dcfba487,
0xbc82919e2040220f, 0x3fef60e316c98398,
0x3c8e5a50d5c192ac, 0x3fef69e603db3285,
0x3c843a59ac016b4b, 0x3fef7321f301b460,
0xbc82d52107b43e1f, 0x3fef7c97337b9b5f,
0xbc892ab93b470dc9, 0x3fef864614f5a129,
0x3c74b604603a88d3, 0x3fef902ee78b3ff6,
0x3c83c5ec519d7271, 0x3fef9a51fbc74c83,
0xbc8ff7128fd391f0, 0x3fefa4afa2a490da,
0xbc8dae98e223747d, 0x3fefaf482d8e67f1,
0x3c8ec3bc41aa2008, 0x3fefba1bee615a27,
0x3c842b94c3a9eb32, 0x3fefc52b376bba97,
0x3c8a64a931d185ee, 0x3fefd0765b6e4540,
0xbc8e37bae43be3ed, 0x3fefdbfdad9cbe14,
0x3c77893b4d91cd9d, 0x3fefe7c1819e90d8,
0x3c5305c14160cc89, 0x3feff3c22b8f71f1,
},
};
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2018, Arm Limited.
* SPDX-License-Identifier: MIT
*/
#ifndef _EXP_DATA_H
#define _EXP_DATA_H
#include <features.h>
#include <stdint.h>
#define EXP_TABLE_BITS 7
#define EXP_POLY_ORDER 5
#define EXP_USE_TOINT_NARROW 0
#define EXP2_POLY_ORDER 5
extern hidden const struct exp_data {
double invln2N;
double shift;
double negln2hiN;
double negln2loN;
double poly[4]; /* Last four coefficients. */
double exp2_shift;
double exp2_poly[EXP2_POLY_ORDER];
uint64_t tab[2*(1 << EXP_TABLE_BITS)];
} __exp_data;
#endif
+202
View File
@@ -0,0 +1,202 @@
/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* expm1(x)
* Returns exp(x)-1, the exponential of x minus 1.
*
* Method
* 1. Argument reduction:
* Given x, find r and integer k such that
*
* x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
*
* Here a correction term c will be computed to compensate
* the error in r when rounded to a floating-point number.
*
* 2. Approximating expm1(r) by a special rational function on
* the interval [0,0.34658]:
* Since
* r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
* we define R1(r*r) by
* r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
* That is,
* R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
* = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
* = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
* We use a special Remez algorithm on [0,0.347] to generate
* a polynomial of degree 5 in r*r to approximate R1. The
* maximum error of this polynomial approximation is bounded
* by 2**-61. In other words,
* R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
* where Q1 = -1.6666666666666567384E-2,
* Q2 = 3.9682539681370365873E-4,
* Q3 = -9.9206344733435987357E-6,
* Q4 = 2.5051361420808517002E-7,
* Q5 = -6.2843505682382617102E-9;
* z = r*r,
* with error bounded by
* | 5 | -61
* | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
* | |
*
* expm1(r) = exp(r)-1 is then computed by the following
* specific way which minimize the accumulation rounding error:
* 2 3
* r r [ 3 - (R1 + R1*r/2) ]
* expm1(r) = r + --- + --- * [--------------------]
* 2 2 [ 6 - r*(3 - R1*r/2) ]
*
* To compensate the error in the argument reduction, we use
* expm1(r+c) = expm1(r) + c + expm1(r)*c
* ~ expm1(r) + c + r*c
* Thus c+r*c will be added in as the correction terms for
* expm1(r+c). Now rearrange the term to avoid optimization
* screw up:
* ( 2 2 )
* ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
* expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
* ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
* ( )
*
* = r - E
* 3. Scale back to obtain expm1(x):
* From step 1, we have
* expm1(x) = either 2^k*[expm1(r)+1] - 1
* = or 2^k*[expm1(r) + (1-2^-k)]
* 4. Implementation notes:
* (A). To save one multiplication, we scale the coefficient Qi
* to Qi*2^i, and replace z by (x^2)/2.
* (B). To achieve maximum accuracy, we compute expm1(x) by
* (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
* (ii) if k=0, return r-E
* (iii) if k=-1, return 0.5*(r-E)-0.5
* (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
* else return 1.0+2.0*(r-E);
* (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
* (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
* (vii) return 2^k(1-((E+2^-k)-r))
*
* Special cases:
* expm1(INF) is INF, expm1(NaN) is NaN;
* expm1(-INF) is -1, and
* for finite argument, only expm1(0)=0 is exact.
*
* Accuracy:
* according to an error analysis, the error is always less than
* 1 ulp (unit in the last place).
*
* Misc. info.
* For IEEE double
* if x > 7.09782712893383973096e+02 then expm1(x) overflow
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "libm.h"
static const double
o_threshold = 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
ln2_hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
ln2_lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
/* Scaled Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */
Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
double __cdecl expm1(double x)
{
double_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
union {double f; uint64_t i;} u = {x};
uint32_t hx = u.i>>32 & 0x7fffffff;
int k, sign = u.i>>63;
/* filter out huge and non-finite argument */
if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */
if (isnan(x))
return x;
if (isinf(x))
return sign ? -1 : x;
if (sign)
return math_error(_UNDERFLOW, "exp", x, 0, -1);
if (x > o_threshold) {
return math_error(_OVERFLOW, "exp", x, 0, x * 0x1p1023);
}
}
/* argument reduction */
if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
if (!sign) {
hi = x - ln2_hi;
lo = ln2_lo;
k = 1;
} else {
hi = x + ln2_hi;
lo = -ln2_lo;
k = -1;
}
} else {
k = invln2*x + (sign ? -0.5 : 0.5);
t = k;
hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
lo = t*ln2_lo;
}
x = hi-lo;
c = (hi-x)-lo;
} else if (hx < 0x3c900000) { /* |x| < 2**-54, return x */
if (hx < 0x00100000)
FORCE_EVAL((float)x);
return x;
} else
k = 0;
/* x is now in primary range */
hfx = 0.5*x;
hxs = x*hfx;
r1 = 1.0+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
t = 3.0-r1*hfx;
e = hxs*((r1-t)/(6.0 - x*t));
if (k == 0) /* c is 0 */
return x - (x*e-hxs);
e = x*(e-c) - c;
e -= hxs;
/* exp(x) ~ 2^k (x_reduced - e + 1) */
if (k == -1)
return 0.5*(x-e) - 0.5;
if (k == 1) {
if (x < -0.25)
return -2.0*(e-(x+0.5));
return 1.0+2.0*(x-e);
}
u.i = (uint64_t)(0x3ff + k)<<52; /* 2^k */
twopk = u.f;
if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */
y = x - e + 1.0;
if (k == 1024)
y = y*2.0*0x1p1023;
else
y = y*twopk;
return y - 1.0;
}
u.i = (uint64_t)(0x3ff - k)<<52; /* 2^-k */
if (k < 20)
y = (x-e+(1-u.f))*twopk;
else
y = (x-(e+u.f)+1)*twopk;
return y;
}
+23
View File
@@ -0,0 +1,23 @@
#include <math.h>
#include <stdint.h>
double __cdecl frexp(double x, int *e)
{
union { double d; uint64_t i; } y = { x };
int ee = y.i>>52 & 0x7ff;
if (!ee) {
if (x) {
x = frexp(x*0x1p64, e);
*e -= 64;
} else *e = 0;
return x;
} else if (ee == 0x7ff) {
return x;
}
*e = ee - 0x3fe;
y.i &= 0x800fffffffffffffull;
y.i |= 0x3fe0000000000000ull;
return y.d;
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef FEATURES_H
#define FEATURES_H
#define weak
#define hidden
#define weak_alias(old, new)
#endif
+282
View File
@@ -0,0 +1,282 @@
#ifndef _LIBM_H
#define _LIBM_H
#include <stdint.h>
#include <float.h>
#include <math.h>
#include <errno.h>
#include <features.h>
typedef float float_t;
typedef double double_t;
hidden double math_error(int type, const char *name, double arg1, double arg2, double retval);
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape {
long double f;
struct {
uint64_t m;
uint16_t se;
} i;
};
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
/* This is the m68k variant of 80-bit long double, and this definition only works
* on archs where the alignment requirement of uint64_t is <= 4. */
union ldshape {
long double f;
struct {
uint16_t se;
uint16_t pad;
uint64_t m;
} i;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape {
long double f;
struct {
uint64_t lo;
uint32_t mid;
uint16_t top;
uint16_t se;
} i;
struct {
uint64_t lo;
uint64_t hi;
} i2;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
union ldshape {
long double f;
struct {
uint16_t se;
uint16_t top;
uint32_t mid;
uint64_t lo;
} i;
struct {
uint64_t hi;
uint64_t lo;
} i2;
};
#else
#error Unsupported long double representation
#endif
/* Support non-nearest rounding mode. */
#define WANT_ROUNDING 1
/* Support signaling NaNs. */
#define WANT_SNAN 0
#if WANT_SNAN
#error SNaN is unsupported
#else
#define issignalingf_inline(x) 0
#define issignaling_inline(x) 0
#endif
#ifndef TOINT_INTRINSICS
#define TOINT_INTRINSICS 0
#endif
#if TOINT_INTRINSICS
/* Round x to nearest int in all rounding modes, ties have to be rounded
consistently with converttoint so the results match. If the result
would be outside of [-2^31, 2^31-1] then the semantics is unspecified. */
static double_t roundtoint(double_t);
/* Convert x to nearest int in all rounding modes, ties have to be rounded
consistently with roundtoint. If the result is not representible in an
int32_t then the semantics is unspecified. */
static int32_t converttoint(double_t);
#endif
/* Helps static branch prediction so hot path can be better optimized. */
#ifdef __GNUC__
#define predict_true(x) __builtin_expect(!!(x), 1)
#define predict_false(x) __builtin_expect(x, 0)
#else
#define predict_true(x) (x)
#define predict_false(x) (x)
#endif
/* Evaluate an expression as the specified type. With standard excess
precision handling a type cast or assignment is enough (with
-ffloat-store an assignment is required, in old compilers argument
passing and return statement may not drop excess precision).
If compiled without -ffloat-store or -fexcess-precision=standard,
an extra volatile qualifier here will force limiting the precision. */
static inline float eval_as_float(float x)
{
volatile float y = x;
return y;
}
static inline double eval_as_double(double x)
{
volatile double y = x;
return y;
}
/* fp_barrier returns its input, but limits code transformations
as if it had a side-effect (e.g. observable io) and returned
an arbitrary value. */
#ifndef fp_barrierf
#define fp_barrierf fp_barrierf
static inline float fp_barrierf(float x)
{
volatile float y = x;
return y;
}
#endif
#ifndef fp_barrier
#define fp_barrier fp_barrier
static inline double fp_barrier(double x)
{
volatile double y = x;
return y;
}
#endif
#ifndef fp_barrierl
#define fp_barrierl fp_barrierl
static inline long double fp_barrierl(long double x)
{
volatile long double y = x;
return y;
}
#endif
/* fp_force_eval ensures that the input value is computed when that's
otherwise unused. To prevent the constant folding of the input
expression, an additional fp_barrier may be needed or a compilation
mode that does so (e.g. -frounding-math in gcc). Then it can be
used to evaluate an expression for its fenv side-effects only. */
#ifndef fp_force_evalf
#define fp_force_evalf fp_force_evalf
static inline void fp_force_evalf(float x)
{
volatile float y;
y = x;
}
#endif
#ifndef fp_force_eval
#define fp_force_eval fp_force_eval
static inline void fp_force_eval(double x)
{
volatile double y;
y = x;
}
#endif
#ifndef fp_force_evall
#define fp_force_evall fp_force_evall
static inline void fp_force_evall(long double x)
{
volatile long double y;
y = x;
}
#endif
#define FORCE_EVAL(x) do { \
if (sizeof(x) == sizeof(float)) { \
fp_force_evalf(x); \
} else if (sizeof(x) == sizeof(double)) { \
fp_force_eval(x); \
} else { \
fp_force_evall(x); \
} \
} while(0)
#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i
#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f
#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i
#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f
#define EXTRACT_WORDS(hi,lo,d) \
do { \
uint64_t __u = asuint64(d); \
(hi) = __u >> 32; \
(lo) = (uint32_t)__u; \
} while (0)
#define GET_HIGH_WORD(hi,d) \
do { \
(hi) = asuint64(d) >> 32; \
} while (0)
#define GET_LOW_WORD(lo,d) \
do { \
(lo) = (uint32_t)asuint64(d); \
} while (0)
#define INSERT_WORDS(d,hi,lo) \
do { \
(d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \
} while (0)
#define SET_HIGH_WORD(d,hi) \
INSERT_WORDS(d, hi, (uint32_t)asuint64(d))
#define SET_LOW_WORD(d,lo) \
INSERT_WORDS(d, asuint64(d)>>32, lo)
#define GET_FLOAT_WORD(w,d) \
do { \
(w) = asuint(d); \
} while (0)
#define SET_FLOAT_WORD(d,w) \
do { \
(d) = asfloat(w); \
} while (0)
hidden int __rem_pio2_large(double*,double*,int,int,int);
hidden int __rem_pio2(double,double*);
hidden double __sin(double,double,int);
hidden double __cos(double,double);
hidden double __tan(double,double,int);
hidden double __expo2(double,double);
hidden int __rem_pio2f(float,double*);
hidden float __sindf(double);
hidden float __cosdf(double);
hidden float __tandf(double,int);
hidden float __expo2f(float,float);
hidden int __rem_pio2l(long double, long double *);
hidden long double __sinl(long double, long double, int);
hidden long double __cosl(long double, long double);
hidden long double __tanl(long double, long double, int);
hidden long double __polevll(long double, const long double *, int);
hidden long double __p1evll(long double, const long double *, int);
extern int __signgam;
hidden double __lgamma_r(double, int *);
hidden float __lgammaf_r(float, int *);
/* error handling functions */
hidden float __math_xflowf(uint32_t, float);
hidden float __math_uflowf(uint32_t);
hidden float __math_oflowf(uint32_t);
hidden float __math_divzerof(uint32_t);
hidden float __math_invalidf(float);
hidden double __math_xflow(uint32_t, double);
hidden double __math_uflow(uint32_t);
hidden double __math_oflow(uint32_t);
hidden double __math_divzero(uint32_t);
hidden double __math_invalid(double);
#if LDBL_MANT_DIG != DBL_MANT_DIG
hidden long double __math_invalidl(long double);
#endif
#endif
+6
View File
@@ -0,0 +1,6 @@
#include <math.h>
double __cdecl ldexp(double x, int n)
{
return scalbn(x, n);
}
+126
View File
@@ -0,0 +1,126 @@
/* origin: FreeBSD /usr/src/lib/msun/src/s_log1p.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* double log1p(double x)
* Return the natural logarithm of 1+x.
*
* Method :
* 1. Argument Reduction: find k and f such that
* 1+x = 2^k * (1+f),
* where sqrt(2)/2 < 1+f < sqrt(2) .
*
* Note. If k=0, then f=x is exact. However, if k!=0, then f
* may not be representable exactly. In that case, a correction
* term is need. Let u=1+x rounded. Let c = (1+x)-u, then
* log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
* and add back the correction term c/u.
* (Note: when x > 2**53, one can simply return log(x))
*
* 2. Approximation of log(1+f): See log.c
*
* 3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c
*
* Special cases:
* log1p(x) is NaN with signal if x < -1 (including -INF) ;
* log1p(+INF) is +INF; log1p(-1) is -INF with signal;
* log1p(NaN) is that NaN with no signal.
*
* Accuracy:
* according to an error analysis, the error is always less than
* 1 ulp (unit in the last place).
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*
* Note: Assuming log() return accurate answer, the following
* algorithm can be used to compute log1p(x) to within a few ULP:
*
* u = 1+x;
* if(u==1.0) return x ; else
* return log(u)*(x/(u-1.0));
*
* See HP-15C Advanced Functions Handbook, p.193.
*/
#include "libm.h"
static const double
ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
double __cdecl log1p(double x)
{
union {double f; uint64_t i;} u = {x};
double_t hfsq,f,c,s,z,R,w,t1,t2,dk;
uint32_t hx,hu;
int k;
hx = u.i>>32;
k = 1;
if (hx < 0x3fda827a || hx>>31) { /* 1+x < sqrt(2)+ */
if (hx >= 0xbff00000) { /* x <= -1.0 */
if (x == -1) {
errno = ERANGE;
return x/0.0; /* log1p(-1) = -inf */
}
errno = EDOM;
return (x-x)/0.0; /* log1p(x<-1) = NaN */
}
if (hx<<1 < 0x3ca00000<<1) { /* |x| < 2**-53 */
fp_barrier(x + 0x1p120f);
/* underflow if subnormal */
if ((hx&0x7ff00000) == 0)
FORCE_EVAL((float)x);
return x;
}
if (hx <= 0xbfd2bec4) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */
k = 0;
c = 0;
f = x;
}
} else if (hx >= 0x7ff00000)
return x;
if (k) {
u.f = 1 + x;
hu = u.i>>32;
hu += 0x3ff00000 - 0x3fe6a09e;
k = (int)(hu>>20) - 0x3ff;
/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */
if (k < 54) {
c = k >= 2 ? 1-(u.f-x) : x-(u.f-1);
c /= u.f;
} else
c = 0;
/* reduce u into [sqrt(2)/2, sqrt(2)] */
hu = (hu&0x000fffff) + 0x3fe6a09e;
u.i = (uint64_t)hu<<32 | (u.i&0xffffffff);
f = u.f - 1;
}
hfsq = 0.5*f*f;
s = f/(2.0+f);
z = s*s;
w = z*z;
t1 = w*(Lg2+w*(Lg4+w*Lg6));
t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
R = t2 + t1;
dk = k;
return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;
}
+128
View File
@@ -0,0 +1,128 @@
/*
* Double-precision log2(x) function.
*
* Copyright (c) 2018, Arm Limited.
* SPDX-License-Identifier: MIT
*/
#include <math.h>
#include <stdint.h>
#include "libm.h"
#include "log2_data.h"
#define T __log2_data.tab
#define T2 __log2_data.tab2
#define B __log2_data.poly1
#define A __log2_data.poly
#define InvLn2hi __log2_data.invln2hi
#define InvLn2lo __log2_data.invln2lo
#define N (1 << LOG2_TABLE_BITS)
#define OFF 0x3fe6000000000000
/* Top 16 bits of a double. */
static inline uint32_t top16(double x)
{
return asuint64(x) >> 48;
}
double __cdecl log2(double x)
{
double_t z, r, r2, r4, y, invc, logc, kd, hi, lo, t1, t2, t3, p;
uint64_t ix, iz, tmp;
uint32_t top;
int k, i;
ix = asuint64(x);
top = top16(x);
#define LO asuint64(1.0 - 0x1.5b51p-5)
#define HI asuint64(1.0 + 0x1.6ab2p-5)
if (predict_false(ix - LO < HI - LO)) {
/* Handle close to 1.0 inputs separately. */
/* Fix sign of zero with downward rounding when x==1. */
if (WANT_ROUNDING && predict_false(ix == asuint64(1.0)))
return 0;
r = x - 1.0;
#if __FP_FAST_FMA
hi = r * InvLn2hi;
lo = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -hi);
#else
double_t rhi, rlo;
rhi = asdouble(asuint64(r) & -1ULL << 32);
rlo = r - rhi;
hi = rhi * InvLn2hi;
lo = rlo * InvLn2hi + r * InvLn2lo;
#endif
r2 = r * r; /* rounding error: 0x1p-62. */
r4 = r2 * r2;
/* Worst-case error is less than 0.54 ULP (0.55 ULP without fma). */
p = r2 * (B[0] + r * B[1]);
y = hi + p;
lo += hi - y + p;
lo += r4 * (B[2] + r * B[3] + r2 * (B[4] + r * B[5]) +
r4 * (B[6] + r * B[7] + r2 * (B[8] + r * B[9])));
y += lo;
return eval_as_double(y);
}
if (predict_false(top - 0x0010 >= 0x7ff0 - 0x0010)) {
/* x < 0x1p-1022 or inf or nan. */
if (ix * 2 == 0) {
errno = ERANGE;
return __math_divzero(1);
}
if (ix == asuint64(INFINITY)) /* log(inf) == inf. */
return x;
if ((top & 0x7ff0) == 0x7ff0 && (ix & 0xfffffffffffffULL))
return x;
if (top & 0x8000) {
errno = EDOM;
return __math_invalid(x);
}
/* x is subnormal, normalize it. */
ix = asuint64(x * 0x1p52);
ix -= 52ULL << 52;
}
/* x = 2^k z; where z is in range [OFF,2*OFF) and exact.
The range is split into N subintervals.
The ith subinterval contains z and c is near its center. */
tmp = ix - OFF;
i = (tmp >> (52 - LOG2_TABLE_BITS)) % N;
k = (int64_t)tmp >> 52; /* arithmetic shift */
iz = ix - (tmp & 0xfffULL << 52);
invc = T[i].invc;
logc = T[i].logc;
z = asdouble(iz);
kd = (double_t)k;
/* log2(x) = log2(z/c) + log2(c) + k. */
/* r ~= z/c - 1, |r| < 1/(2*N). */
#if __FP_FAST_FMA
/* rounding error: 0x1p-55/N. */
r = __builtin_fma(z, invc, -1.0);
t1 = r * InvLn2hi;
t2 = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -t1);
#else
double_t rhi, rlo;
/* rounding error: 0x1p-55/N + 0x1p-65. */
r = (z - T2[i].chi - T2[i].clo) * invc;
rhi = asdouble(asuint64(r) & -1ULL << 32);
rlo = r - rhi;
t1 = rhi * InvLn2hi;
t2 = rlo * InvLn2hi + r * InvLn2lo;
#endif
/* hi + lo = r/ln2 + log2(c) + k. */
t3 = kd + logc;
hi = t3 + t1;
lo = t3 - hi + t1 + t2;
/* log2(r+1) = r/ln2 + r^2*poly(r). */
/* Evaluation is optimized assuming superscalar pipelined execution. */
r2 = r * r; /* rounding error: 0x1p-54/N^2. */
r4 = r2 * r2;
/* Worst-case error if |y| > 0x1p-4: 0.547 ULP (0.550 ULP without fma).
~ 0.5 + 2/N/ln2 + abs-poly-error*0x1p56 ULP (+ 0.003 ULP without fma). */
p = A[0] + r * A[1] + r2 * (A[2] + r * A[3]) + r4 * (A[4] + r * A[5]);
y = lo + r2 * p + hi;
return eval_as_double(y);
}
+201
View File
@@ -0,0 +1,201 @@
/*
* Data for log2.
*
* Copyright (c) 2018, Arm Limited.
* SPDX-License-Identifier: MIT
*/
#include "log2_data.h"
#define N (1 << LOG2_TABLE_BITS)
const struct log2_data __log2_data = {
// First coefficient: 0x1.71547652b82fe1777d0ffda0d24p0
.invln2hi = 0x1.7154765200000p+0,
.invln2lo = 0x1.705fc2eefa200p-33,
.poly1 = {
// relative error: 0x1.2fad8188p-63
// in -0x1.5b51p-5 0x1.6ab2p-5
-0x1.71547652b82fep-1,
0x1.ec709dc3a03f7p-2,
-0x1.71547652b7c3fp-2,
0x1.2776c50f05be4p-2,
-0x1.ec709dd768fe5p-3,
0x1.a61761ec4e736p-3,
-0x1.7153fbc64a79bp-3,
0x1.484d154f01b4ap-3,
-0x1.289e4a72c383cp-3,
0x1.0b32f285aee66p-3,
},
.poly = {
// relative error: 0x1.a72c2bf8p-58
// abs error: 0x1.67a552c8p-66
// in -0x1.f45p-8 0x1.f45p-8
-0x1.71547652b8339p-1,
0x1.ec709dc3a04bep-2,
-0x1.7154764702ffbp-2,
0x1.2776c50034c48p-2,
-0x1.ec7b328ea92bcp-3,
0x1.a6225e117f92ep-3,
},
/* Algorithm:
x = 2^k z
log2(x) = k + log2(c) + log2(z/c)
log2(z/c) = poly(z/c - 1)
where z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls
into the ith one, then table entries are computed as
tab[i].invc = 1/c
tab[i].logc = (double)log2(c)
tab2[i].chi = (double)c
tab2[i].clo = (double)(c - (double)c)
where c is near the center of the subinterval and is chosen by trying +-2^29
floating point invc candidates around 1/center and selecting one for which
1) the rounding error in 0x1.8p10 + logc is 0,
2) the rounding error in z - chi - clo is < 0x1p-64 and
3) the rounding error in (double)log2(c) is minimized (< 0x1p-68).
Note: 1) ensures that k + logc can be computed without rounding error, 2)
ensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to a
single rounding error when there is no fast fma for z*invc - 1, 3) ensures
that logc + poly(z/c - 1) has small error, however near x == 1 when
|log2(x)| < 0x1p-4, this is not enough so that is special cased. */
.tab = {
{0x1.724286bb1acf8p+0, -0x1.1095feecdb000p-1},
{0x1.6e1f766d2cca1p+0, -0x1.08494bd76d000p-1},
{0x1.6a13d0e30d48ap+0, -0x1.00143aee8f800p-1},
{0x1.661ec32d06c85p+0, -0x1.efec5360b4000p-2},
{0x1.623fa951198f8p+0, -0x1.dfdd91ab7e000p-2},
{0x1.5e75ba4cf026cp+0, -0x1.cffae0cc79000p-2},
{0x1.5ac055a214fb8p+0, -0x1.c043811fda000p-2},
{0x1.571ed0f166e1ep+0, -0x1.b0b67323ae000p-2},
{0x1.53909590bf835p+0, -0x1.a152f5a2db000p-2},
{0x1.5014fed61adddp+0, -0x1.9217f5af86000p-2},
{0x1.4cab88e487bd0p+0, -0x1.8304db0719000p-2},
{0x1.49539b4334feep+0, -0x1.74189f9a9e000p-2},
{0x1.460cbdfafd569p+0, -0x1.6552bb5199000p-2},
{0x1.42d664ee4b953p+0, -0x1.56b23a29b1000p-2},
{0x1.3fb01111dd8a6p+0, -0x1.483650f5fa000p-2},
{0x1.3c995b70c5836p+0, -0x1.39de937f6a000p-2},
{0x1.3991c4ab6fd4ap+0, -0x1.2baa1538d6000p-2},
{0x1.3698e0ce099b5p+0, -0x1.1d98340ca4000p-2},
{0x1.33ae48213e7b2p+0, -0x1.0fa853a40e000p-2},
{0x1.30d191985bdb1p+0, -0x1.01d9c32e73000p-2},
{0x1.2e025cab271d7p+0, -0x1.e857da2fa6000p-3},
{0x1.2b404cf13cd82p+0, -0x1.cd3c8633d8000p-3},
{0x1.288b02c7ccb50p+0, -0x1.b26034c14a000p-3},
{0x1.25e2263944de5p+0, -0x1.97c1c2f4fe000p-3},
{0x1.234563d8615b1p+0, -0x1.7d6023f800000p-3},
{0x1.20b46e33eaf38p+0, -0x1.633a71a05e000p-3},
{0x1.1e2eefdcda3ddp+0, -0x1.494f5e9570000p-3},
{0x1.1bb4a580b3930p+0, -0x1.2f9e424e0a000p-3},
{0x1.19453847f2200p+0, -0x1.162595afdc000p-3},
{0x1.16e06c0d5d73cp+0, -0x1.f9c9a75bd8000p-4},
{0x1.1485f47b7e4c2p+0, -0x1.c7b575bf9c000p-4},
{0x1.12358ad0085d1p+0, -0x1.960c60ff48000p-4},
{0x1.0fef00f532227p+0, -0x1.64ce247b60000p-4},
{0x1.0db2077d03a8fp+0, -0x1.33f78b2014000p-4},
{0x1.0b7e6d65980d9p+0, -0x1.0387d1a42c000p-4},
{0x1.0953efe7b408dp+0, -0x1.a6f9208b50000p-5},
{0x1.07325cac53b83p+0, -0x1.47a954f770000p-5},
{0x1.05197e40d1b5cp+0, -0x1.d23a8c50c0000p-6},
{0x1.03091c1208ea2p+0, -0x1.16a2629780000p-6},
{0x1.0101025b37e21p+0, -0x1.720f8d8e80000p-8},
{0x1.fc07ef9caa76bp-1, 0x1.6fe53b1500000p-7},
{0x1.f4465d3f6f184p-1, 0x1.11ccce10f8000p-5},
{0x1.ecc079f84107fp-1, 0x1.c4dfc8c8b8000p-5},
{0x1.e573a99975ae8p-1, 0x1.3aa321e574000p-4},
{0x1.de5d6f0bd3de6p-1, 0x1.918a0d08b8000p-4},
{0x1.d77b681ff38b3p-1, 0x1.e72e9da044000p-4},
{0x1.d0cb5724de943p-1, 0x1.1dcd2507f6000p-3},
{0x1.ca4b2dc0e7563p-1, 0x1.476ab03dea000p-3},
{0x1.c3f8ee8d6cb51p-1, 0x1.7074377e22000p-3},
{0x1.bdd2b4f020c4cp-1, 0x1.98ede8ba94000p-3},
{0x1.b7d6c006015cap-1, 0x1.c0db86ad2e000p-3},
{0x1.b20366e2e338fp-1, 0x1.e840aafcee000p-3},
{0x1.ac57026295039p-1, 0x1.0790ab4678000p-2},
{0x1.a6d01bc2731ddp-1, 0x1.1ac056801c000p-2},
{0x1.a16d3bc3ff18bp-1, 0x1.2db11d4fee000p-2},
{0x1.9c2d14967feadp-1, 0x1.406464ec58000p-2},
{0x1.970e4f47c9902p-1, 0x1.52dbe093af000p-2},
{0x1.920fb3982bcf2p-1, 0x1.651902050d000p-2},
{0x1.8d30187f759f1p-1, 0x1.771d2cdeaf000p-2},
{0x1.886e5ebb9f66dp-1, 0x1.88e9c857d9000p-2},
{0x1.83c97b658b994p-1, 0x1.9a80155e16000p-2},
{0x1.7f405ffc61022p-1, 0x1.abe186ed3d000p-2},
{0x1.7ad22181415cap-1, 0x1.bd0f2aea0e000p-2},
{0x1.767dcf99eff8cp-1, 0x1.ce0a43dbf4000p-2},
},
#if !__FP_FAST_FMA
.tab2 = {
{0x1.6200012b90a8ep-1, 0x1.904ab0644b605p-55},
{0x1.66000045734a6p-1, 0x1.1ff9bea62f7a9p-57},
{0x1.69fffc325f2c5p-1, 0x1.27ecfcb3c90bap-55},
{0x1.6e00038b95a04p-1, 0x1.8ff8856739326p-55},
{0x1.71fffe09994e3p-1, 0x1.afd40275f82b1p-55},
{0x1.7600015590e1p-1, -0x1.2fd75b4238341p-56},
{0x1.7a00012655bd5p-1, 0x1.808e67c242b76p-56},
{0x1.7e0003259e9a6p-1, -0x1.208e426f622b7p-57},
{0x1.81fffedb4b2d2p-1, -0x1.402461ea5c92fp-55},
{0x1.860002dfafcc3p-1, 0x1.df7f4a2f29a1fp-57},
{0x1.89ffff78c6b5p-1, -0x1.e0453094995fdp-55},
{0x1.8e00039671566p-1, -0x1.a04f3bec77b45p-55},
{0x1.91fffe2bf1745p-1, -0x1.7fa34400e203cp-56},
{0x1.95fffcc5c9fd1p-1, -0x1.6ff8005a0695dp-56},
{0x1.9a0003bba4767p-1, 0x1.0f8c4c4ec7e03p-56},
{0x1.9dfffe7b92da5p-1, 0x1.e7fd9478c4602p-55},
{0x1.a1fffd72efdafp-1, -0x1.a0c554dcdae7ep-57},
{0x1.a5fffde04ff95p-1, 0x1.67da98ce9b26bp-55},
{0x1.a9fffca5e8d2bp-1, -0x1.284c9b54c13dep-55},
{0x1.adfffddad03eap-1, 0x1.812c8ea602e3cp-58},
{0x1.b1ffff10d3d4dp-1, -0x1.efaddad27789cp-55},
{0x1.b5fffce21165ap-1, 0x1.3cb1719c61237p-58},
{0x1.b9fffd950e674p-1, 0x1.3f7d94194cep-56},
{0x1.be000139ca8afp-1, 0x1.50ac4215d9bcp-56},
{0x1.c20005b46df99p-1, 0x1.beea653e9c1c9p-57},
{0x1.c600040b9f7aep-1, -0x1.c079f274a70d6p-56},
{0x1.ca0006255fd8ap-1, -0x1.a0b4076e84c1fp-56},
{0x1.cdfffd94c095dp-1, 0x1.8f933f99ab5d7p-55},
{0x1.d1ffff975d6cfp-1, -0x1.82c08665fe1bep-58},
{0x1.d5fffa2561c93p-1, -0x1.b04289bd295f3p-56},
{0x1.d9fff9d228b0cp-1, 0x1.70251340fa236p-55},
{0x1.de00065bc7e16p-1, -0x1.5011e16a4d80cp-56},
{0x1.e200002f64791p-1, 0x1.9802f09ef62ep-55},
{0x1.e600057d7a6d8p-1, -0x1.e0b75580cf7fap-56},
{0x1.ea00027edc00cp-1, -0x1.c848309459811p-55},
{0x1.ee0006cf5cb7cp-1, -0x1.f8027951576f4p-55},
{0x1.f2000782b7dccp-1, -0x1.f81d97274538fp-55},
{0x1.f6000260c450ap-1, -0x1.071002727ffdcp-59},
{0x1.f9fffe88cd533p-1, -0x1.81bdce1fda8bp-58},
{0x1.fdfffd50f8689p-1, 0x1.7f91acb918e6ep-55},
{0x1.0200004292367p+0, 0x1.b7ff365324681p-54},
{0x1.05fffe3e3d668p+0, 0x1.6fa08ddae957bp-55},
{0x1.0a0000a85a757p+0, -0x1.7e2de80d3fb91p-58},
{0x1.0e0001a5f3fccp+0, -0x1.1823305c5f014p-54},
{0x1.11ffff8afbaf5p+0, -0x1.bfabb6680bac2p-55},
{0x1.15fffe54d91adp+0, -0x1.d7f121737e7efp-54},
{0x1.1a00011ac36e1p+0, 0x1.c000a0516f5ffp-54},
{0x1.1e00019c84248p+0, -0x1.082fbe4da5dap-54},
{0x1.220000ffe5e6ep+0, -0x1.8fdd04c9cfb43p-55},
{0x1.26000269fd891p+0, 0x1.cfe2a7994d182p-55},
{0x1.2a00029a6e6dap+0, -0x1.00273715e8bc5p-56},
{0x1.2dfffe0293e39p+0, 0x1.b7c39dab2a6f9p-54},
{0x1.31ffff7dcf082p+0, 0x1.df1336edc5254p-56},
{0x1.35ffff05a8b6p+0, -0x1.e03564ccd31ebp-54},
{0x1.3a0002e0eaeccp+0, 0x1.5f0e74bd3a477p-56},
{0x1.3e000043bb236p+0, 0x1.c7dcb149d8833p-54},
{0x1.4200002d187ffp+0, 0x1.e08afcf2d3d28p-56},
{0x1.460000d387cb1p+0, 0x1.20837856599a6p-55},
{0x1.4a00004569f89p+0, -0x1.9fa5c904fbcd2p-55},
{0x1.4e000043543f3p+0, -0x1.81125ed175329p-56},
{0x1.51fffcc027f0fp+0, 0x1.883d8847754dcp-54},
{0x1.55ffffd87b36fp+0, -0x1.709e731d02807p-55},
{0x1.59ffff21df7bap+0, 0x1.7f79f68727b02p-55},
{0x1.5dfffebfc3481p+0, -0x1.180902e30e93ep-54},
},
#endif
};
+28
View File
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2018, Arm Limited.
* SPDX-License-Identifier: MIT
*/
#ifndef _LOG2_DATA_H
#define _LOG2_DATA_H
#include <features.h>
#define LOG2_TABLE_BITS 6
#define LOG2_POLY_ORDER 7
#define LOG2_POLY1_ORDER 11
extern hidden const struct log2_data {
double invln2hi;
double invln2lo;
double poly[LOG2_POLY_ORDER - 1];
double poly1[LOG2_POLY1_ORDER - 1];
struct {
double invc, logc;
} tab[1 << LOG2_TABLE_BITS];
#if !__FP_FAST_FMA
struct {
double chi, clo;
} tab2[1 << LOG2_TABLE_BITS];
#endif
} __log2_data;
#endif
+34
View File
@@ -0,0 +1,34 @@
#include <math.h>
#include <stdint.h>
#include "libm.h"
double __cdecl scalbn(double x, int n)
{
union {double f; uint64_t i;} u;
double_t y = x;
if (n > 1023) {
y *= 0x1p1023;
n -= 1023;
if (n > 1023) {
y *= 0x1p1023;
n -= 1023;
if (n > 1023)
n = 1023;
}
} else if (n < -1022) {
/* make sure final n < -53 to avoid double
rounding in the subnormal range */
y *= 0x1p-1022 * 0x1p53;
n += 1022 - 53;
if (n < -1022) {
y *= 0x1p-1022 * 0x1p53;
n += 1022 - 53;
if (n < -1022)
n = -1022;
}
}
u.i = (uint64_t)(0x3ff+n)<<52;
x = y * u.f;
return x;
}
+80
View File
@@ -0,0 +1,80 @@
/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* sin(x)
* Return sine function of x.
*
* kernel function:
* __sin ... sine function on [-pi/4,pi/4]
* __cos ... cose function on [-pi/4,pi/4]
* __rem_pio2 ... argument reduction routine
*
* Method.
* Let S,C and T denote the sin, cos and tan respectively on
* [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
* in [-pi/4 , +pi/4], and let n = k mod 4.
* We have
*
* n sin(x) cos(x) tan(x)
* ----------------------------------------------------------
* 0 S C T
* 1 C -S -1/T
* 2 -S -C T
* 3 -C S -1/T
* ----------------------------------------------------------
*
* Special cases:
* Let trig be any of sin, cos, or tan.
* trig(+-INF) is NaN, with signals;
* trig(NaN) is that NaN;
*
* Accuracy:
* TRIG(x) returns trig(x) nearly rounded
*/
#include "libm.h"
double __cdecl sin(double x)
{
double y[2];
uint32_t ix;
unsigned n;
/* High word of x. */
GET_HIGH_WORD(ix, x);
ix &= 0x7fffffff;
/* |x| ~< pi/4 */
if (ix <= 0x3fe921fb) {
if (ix < 0x3e500000) { /* |x| < 2**-26 */
/* raise inexact if x != 0 and underflow if subnormal*/
FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
return x;
}
return __sin(x, 0.0, 0);
}
/* sin(Inf or NaN) is NaN */
if (isinf(x))
return math_error(_DOMAIN, "sin", x, 0, x - x);
if (ix >= 0x7ff00000)
return x - x;
/* argument reduction needed */
n = __rem_pio2(x, y);
switch (n&3) {
case 0: return __sin(y[0], y[1], 1);
case 1: return __cos(y[0], y[1]);
case 2: return -__sin(y[0], y[1], 1);
default:
return -__cos(y[0], y[1]);
}
}
+69
View File
@@ -0,0 +1,69 @@
/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#define _GNU_SOURCE
#include "libm.h"
void __cdecl sincos(double x, double *sin, double *cos)
{
double y[2], s, c;
uint32_t ix;
unsigned n;
GET_HIGH_WORD(ix, x);
ix &= 0x7fffffff;
/* |x| ~< pi/4 */
if (ix <= 0x3fe921fb) {
/* if |x| < 2**-27 * sqrt(2) */
if (ix < 0x3e46a09e) {
/* raise inexact if x!=0 and underflow if subnormal */
FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
*sin = x;
*cos = 1.0;
return;
}
*sin = __sin(x, 0.0, 0);
*cos = __cos(x, 0.0);
return;
}
/* sincos(Inf or NaN) is NaN */
if (ix >= 0x7ff00000) {
*sin = *cos = x - x;
return;
}
/* argument reduction needed */
n = __rem_pio2(x, y);
s = __sin(y[0], y[1], 1);
c = __cos(y[0], y[1]);
switch (n&3) {
case 0:
*sin = s;
*cos = c;
break;
case 1:
*sin = c;
*cos = -s;
break;
case 2:
*sin = -s;
*cos = -c;
break;
case 3:
default:
*sin = -c;
*cos = s;
break;
}
}
+158
View File
@@ -0,0 +1,158 @@
#include <stdint.h>
#include <math.h>
#include "libm.h"
#include "sqrt_data.h"
#define FENV_SUPPORT 1
/* returns a*b*2^-32 - e, with error 0 <= e < 1. */
static inline uint32_t mul32(uint32_t a, uint32_t b)
{
return (uint64_t)a*b >> 32;
}
/* returns a*b*2^-64 - e, with error 0 <= e < 3. */
static inline uint64_t mul64(uint64_t a, uint64_t b)
{
uint64_t ahi = a>>32;
uint64_t alo = a&0xffffffff;
uint64_t bhi = b>>32;
uint64_t blo = b&0xffffffff;
return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32);
}
double __cdecl sqrt(double x)
{
uint64_t ix, top, m;
/* special case handling. */
ix = asuint64(x);
top = ix >> 52;
if (predict_false(top - 0x001 >= 0x7ff - 0x001)) {
/* x < 0x1p-1022 or inf or nan. */
if (ix * 2 == 0)
return x;
if (ix == 0x7ff0000000000000)
return x;
if (ix > 0x7ff0000000000000)
return math_error(_DOMAIN, "sqrt", x, 0, (x - x) / (x - x));
/* x is subnormal, normalize it. */
ix = asuint64(x * 0x1p52);
top = ix >> 52;
top -= 52;
}
/* argument reduction:
x = 4^e m; with integer e, and m in [1, 4)
m: fixed point representation [2.62]
2^e is the exponent part of the result. */
int even = top & 1;
m = (ix << 11) | 0x8000000000000000;
if (even) m >>= 1;
top = (top + 0x3ff) >> 1;
/* approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4)
initial estimate:
7bit table lookup (1bit exponent and 6bit significand).
iterative approximation:
using 2 goldschmidt iterations with 32bit int arithmetics
and a final iteration with 64bit int arithmetics.
details:
the relative error (e = r0 sqrt(m)-1) of a linear estimate
(r0 = a m + b) is |e| < 0.085955 ~ 0x1.6p-4 at best,
a table lookup is faster and needs one less iteration
6 bit lookup table (128b) gives |e| < 0x1.f9p-8
7 bit lookup table (256b) gives |e| < 0x1.fdp-9
for single and double prec 6bit is enough but for quad
prec 7bit is needed (or modified iterations). to avoid
one more iteration >=13bit table would be needed (16k).
a newton-raphson iteration for r is
w = r*r
u = 3 - m*w
r = r*u/2
can use a goldschmidt iteration for s at the end or
s = m*r
first goldschmidt iteration is
s = m*r
u = 3 - s*r
r = r*u/2
s = s*u/2
next goldschmidt iteration is
u = 3 - s*r
r = r*u/2
s = s*u/2
and at the end r is not computed only s.
they use the same amount of operations and converge at the
same quadratic rate, i.e. if
r1 sqrt(m) - 1 = e, then
r2 sqrt(m) - 1 = -3/2 e^2 - 1/2 e^3
the advantage of goldschmidt is that the mul for s and r
are independent (computed in parallel), however it is not
"self synchronizing": it only uses the input m in the
first iteration so rounding errors accumulate. at the end
or when switching to larger precision arithmetics rounding
errors dominate so the first iteration should be used.
the fixed point representations are
m: 2.30 r: 0.32, s: 2.30, d: 2.30, u: 2.30, three: 2.30
and after switching to 64 bit
m: 2.62 r: 0.64, s: 2.62, d: 2.62, u: 2.62, three: 2.62 */
static const uint64_t three = 0xc0000000;
uint64_t r, s, d, u, i;
i = (ix >> 46) % 128;
r = (uint32_t)__rsqrt_tab[i] << 16;
/* |r sqrt(m) - 1| < 0x1.fdp-9 */
s = mul32(m>>32, r);
/* |s/sqrt(m) - 1| < 0x1.fdp-9 */
d = mul32(s, r);
u = three - d;
r = mul32(r, u) << 1;
/* |r sqrt(m) - 1| < 0x1.7bp-16 */
s = mul32(s, u) << 1;
/* |s/sqrt(m) - 1| < 0x1.7bp-16 */
d = mul32(s, r);
u = three - d;
r = mul32(r, u) << 1;
/* |r sqrt(m) - 1| < 0x1.3704p-29 (measured worst-case) */
r = r << 32;
s = mul64(m, r);
d = mul64(s, r);
u = (three<<32) - d;
s = mul64(s, u); /* repr: 3.61 */
/* -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 */
s = (s - 2) >> 9; /* repr: 12.52 */
/* -0x1.09p-52 < s - sqrt(m) < -0x1.fffcp-63 */
/* s < sqrt(m) < s + 0x1.09p-52,
compute nearest rounded result:
the nearest result to 52 bits is either s or s+0x1p-52,
we can decide by comparing (2^52 s + 0.5)^2 to 2^104 m. */
uint64_t d0, d1, d2;
double y, t;
d0 = (m << 42) - s*s;
d1 = s - d0;
d2 = d1 + s + 1;
s += d1 >> 63;
s &= 0x000fffffffffffff;
s |= top << 52;
y = asdouble(s);
if (FENV_SUPPORT) {
/* handle rounding modes and inexact exception:
only (s+1)^2 == 2^42 m case is exact otherwise
add a tiny value to cause the fenv effects. */
uint64_t tiny = predict_false(d2==0) ? 0 : 0x0010000000000000;
tiny |= (d1^d2) & 0x8000000000000000;
t = asdouble(tiny);
y = eval_as_double(y + t);
}
return y;
}
+19
View File
@@ -0,0 +1,19 @@
#include "sqrt_data.h"
const uint16_t __rsqrt_tab[128] = {
0xb451,0xb2f0,0xb196,0xb044,0xaef9,0xadb6,0xac79,0xab43,
0xaa14,0xa8eb,0xa7c8,0xa6aa,0xa592,0xa480,0xa373,0xa26b,
0xa168,0xa06a,0x9f70,0x9e7b,0x9d8a,0x9c9d,0x9bb5,0x9ad1,
0x99f0,0x9913,0x983a,0x9765,0x9693,0x95c4,0x94f8,0x9430,
0x936b,0x92a9,0x91ea,0x912e,0x9075,0x8fbe,0x8f0a,0x8e59,
0x8daa,0x8cfe,0x8c54,0x8bac,0x8b07,0x8a64,0x89c4,0x8925,
0x8889,0x87ee,0x8756,0x86c0,0x862b,0x8599,0x8508,0x8479,
0x83ec,0x8361,0x82d8,0x8250,0x81c9,0x8145,0x80c2,0x8040,
0xff02,0xfd0e,0xfb25,0xf947,0xf773,0xf5aa,0xf3ea,0xf234,
0xf087,0xeee3,0xed47,0xebb3,0xea27,0xe8a3,0xe727,0xe5b2,
0xe443,0xe2dc,0xe17a,0xe020,0xdecb,0xdd7d,0xdc34,0xdaf1,
0xd9b3,0xd87b,0xd748,0xd61a,0xd4f1,0xd3cd,0xd2ad,0xd192,
0xd07b,0xcf69,0xce5b,0xcd51,0xcc4a,0xcb48,0xca4a,0xc94f,
0xc858,0xc764,0xc674,0xc587,0xc49d,0xc3b7,0xc2d4,0xc1f4,
0xc116,0xc03c,0xbf65,0xbe90,0xbdbe,0xbcef,0xbc23,0xbb59,
0xba91,0xb9cc,0xb90a,0xb84a,0xb78c,0xb6d0,0xb617,0xb560,
};
+13
View File
@@ -0,0 +1,13 @@
#ifndef _SQRT_DATA_H
#define _SQRT_DATA_H
#include <features.h>
#include <stdint.h>
/* if x in [1,2): i = (int)(64*x);
if x in [2,4): i = (int)(32*x-64);
__rsqrt_tab[i]*2^-16 is estimating 1/sqrt(x) with small relative error:
|__rsqrt_tab[i]*0x1p-16*sqrt(x) - 1| < -0x1.fdp-9 < 2^-8 */
extern hidden const uint16_t __rsqrt_tab[128];
#endif
+83
View File
@@ -0,0 +1,83 @@
#include <stdint.h>
#include <math.h>
#include "libm.h"
#include "sqrt_data.h"
#define FENV_SUPPORT 1
static inline uint32_t mul32(uint32_t a, uint32_t b)
{
return (uint64_t)a*b >> 32;
}
/* see sqrt.c for more detailed comments. */
float __cdecl sqrtf(float x)
{
uint32_t ix, m, m1, m0, even, ey;
ix = asuint(x);
if (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {
/* x < 0x1p-126 or inf or nan. */
if (ix * 2 == 0)
return x;
if (ix == 0x7f800000)
return x;
if (ix > 0x7f800000)
return math_error(_DOMAIN, "sqrtf", x, 0, (x - x) / (x - x));
/* x is subnormal, normalize it. */
ix = asuint(x * 0x1p23f);
ix -= 23 << 23;
}
/* x = 4^e m; with int e and m in [1, 4). */
even = ix & 0x00800000;
m1 = (ix << 8) | 0x80000000;
m0 = (ix << 7) & 0x7fffffff;
m = even ? m0 : m1;
/* 2^e is the exponent part of the return value. */
ey = ix >> 1;
ey += 0x3f800000 >> 1;
ey &= 0x7f800000;
/* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations. */
static const uint32_t three = 0xc0000000;
uint32_t r, s, d, u, i;
i = (ix >> 17) % 128;
r = (uint32_t)__rsqrt_tab[i] << 16;
/* |r*sqrt(m) - 1| < 0x1p-8 */
s = mul32(m, r);
/* |s/sqrt(m) - 1| < 0x1p-8 */
d = mul32(s, r);
u = three - d;
r = mul32(r, u) << 1;
/* |r*sqrt(m) - 1| < 0x1.7bp-16 */
s = mul32(s, u) << 1;
/* |s/sqrt(m) - 1| < 0x1.7bp-16 */
d = mul32(s, r);
u = three - d;
s = mul32(s, u);
/* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */
s = (s - 1)>>6;
/* s < sqrt(m) < s + 0x1.08p-23 */
/* compute nearest rounded result. */
uint32_t d0, d1, d2;
float y, t;
d0 = (m << 16) - s*s;
d1 = s - d0;
d2 = d1 + s + 1;
s += d1 >> 31;
s &= 0x007fffff;
s |= ey;
y = asfloat(s);
if (FENV_SUPPORT) {
/* handle rounding and inexact exception. */
uint32_t tiny = predict_false(d2==0) ? 0 : 0x01000000;
tiny |= (d1^d2) & 0x80000000;
t = asfloat(tiny);
y = eval_as_float(y + t);
}
return y;
}
+45
View File
@@ -0,0 +1,45 @@
#include "gdbjit.h"
#include <stdio.h>
static char block_name_buffer[16];
static enum gdb_status read_debug_info(struct gdb_reader_funcs* self, struct gdb_symbol_callbacks* cbs, void* memory, long memory_sz)
{
gdbjit_block_t* block = (gdbjit_block_t*)memory;
struct gdb_object* object = cbs->object_open(cbs);
struct gdb_symtab* symtab = cbs->symtab_open(cbs, object, block->filename);
sprintf(block_name_buffer, "%x", block->x64start);
cbs->block_open(cbs, symtab, NULL, block->start, block->end, block_name_buffer);
cbs->line_mapping_add(cbs, symtab, block->nlines, block->lines);
cbs->symtab_close(cbs, symtab);
cbs->object_close(cbs, object);
return GDB_SUCCESS;
}
enum gdb_status unwind_frame(struct gdb_reader_funcs* self, struct gdb_unwind_callbacks* cbs)
{
return GDB_SUCCESS;
}
struct gdb_frame_id get_frame_id(struct gdb_reader_funcs* self, struct gdb_unwind_callbacks* cbs)
{
struct gdb_frame_id frame = {0xdeadbeef, 0};
return frame;
}
void destroy_reader(struct gdb_reader_funcs* self) {}
__attribute__((visibility("default"))) struct gdb_reader_funcs* gdb_init_reader(void)
{
static struct gdb_reader_funcs funcs = {GDB_READER_INTERFACE_VERSION, NULL, read_debug_info, unwind_frame, get_frame_id, destroy_reader};
return &funcs;
}
__attribute__((visibility("default"))) int plugin_is_GPL_compatible (void)
{
return 0;
}
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
# create necessary directories
mkdir -p ~/steam
mkdir -p ~/steam/tmp
cd ~/steam/tmp
# download latest deb and unpack
wget https://cdn.cloudflare.steamstatic.com/client/installer/steam.deb
ar x steam.deb
tar xf data.tar.xz
# remove deb archives, not needed anymore
rm ./*.tar.xz ./steam.deb
# move deb contents to steam folder
mv ./usr/* ../
cd ../ && rm -rf ./tmp/
# create run script
echo '#!/bin/bash
export STEAMOS=1
export STEAM_RUNTIME=1
export DBUS_FATAL_WARNINGS=0
~/steam/bin/steam $@' > steam
# make script executable and move
chmod +x steam
sudo mv steam /usr/local/bin/
echo "Script complete."
+63 -6
View File
@@ -363,7 +363,7 @@ def readFiles(files: Iterable[Filename]) -> Tuple[JumbledGlobals, JumbledRedirec
gbl : JumbledGlobals = {}
redirects: JumbledRedirects = {}
filespec : JumbledFilesSpecific = {}
functions: Dict[str, Filename] = {}
halt_required = False # Is there a GO(*, .FE*) or similar in-batch error(s)?
# First read the files inside the headers
@@ -842,24 +842,25 @@ def main(root: str, files: Iterable[Filename], ver: str):
# H could be allowed maybe?
allowed_simply: Dict[str, str] = {"ARM64": "v", "RV64": "v"}
allowed_regs : Dict[str, str] = {"ARM64": "cCwWiuIUlLp", "RV64": "CWuIUlLp"}
allowed_regs : Dict[str, str] = {"ARM64": "cCwWiuIUlLp", "RV64": "CWIUlLp"}
allowed_fpr : Dict[str, str] = {"ARM64": "fd", "RV64": "fd"}
allowed_sextw : Dict[str, str] = {"ARM64": "", "RV64": "cwiu"}
# Detect functions which return in an x87 register
retx87_wraps: Dict[ClausesStr, List[FunctionType]] = {}
return_x87: str = "D"
# Sanity checks
forbidden_simple: Dict[str, str] = {"ARM64": "EDVOSNHPAxXYb", "RV64": "EcwiDVOSNHPAxXYb"}
forbidden_simple: Dict[str, str] = {"ARM64": "EDVOSNHPAxXYb", "RV64": "EDVOSNHPAxXYb"}
assert(all(k in allowed_simply for k in forbidden_simple))
assert(all(k in allowed_regs for k in forbidden_simple))
assert(all(k in allowed_fpr for k in forbidden_simple))
for k1 in forbidden_simple:
assert(len(allowed_simply[k1]) + len(allowed_regs[k1]) + len(allowed_fpr[k1]) + len(forbidden_simple[k1]) == len(allowed_conv.values))
assert(len(allowed_simply[k1]) + len(allowed_regs[k1]) + len(allowed_fpr[k1]) + len(allowed_sextw[k1]) + len(forbidden_simple[k1]) == len(allowed_conv.values))
assert(all(c not in allowed_regs[k1] for c in allowed_simply[k1]))
assert(all(c not in allowed_simply[k1] + allowed_regs[k1] for c in allowed_fpr[k1]))
assert(all(c not in allowed_simply[k1] + allowed_regs[k1] + allowed_fpr[k1] for c in forbidden_simple[k1]))
assert(all(c in allowed_simply[k1] + allowed_regs[k1] + allowed_fpr[k1] + forbidden_simple[k1] for c in allowed_conv.values))
assert(all(c in allowed_simply[k1] + allowed_regs[k1] + allowed_fpr[k1] + allowed_sextw[k1] + forbidden_simple[k1] for c in allowed_conv.values))
assert(all(c in allowed_conv.values for c in return_x87))
assert(all(c in forbidden_simple[k] for c in depends_on_ld for k in forbidden_simple))
@@ -872,6 +873,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
for k in forbidden_simple:
regs_count: int = 0
fpr_count : int = 0
sextw_mask: int = 0
if v.get_convention() is not allowed_conv:
continue
@@ -884,6 +886,9 @@ def main(root: str, files: Iterable[Filename], ver: str):
fpr_count = fpr_count + 1
elif c in allowed_simply[k]:
continue
elif c in allowed_sextw[k]:
sextw_mask |= 1 << regs_count
regs_count += 1
else:
break
else:
@@ -891,6 +896,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
if (regs_count <= 6) and (fpr_count <= 8):
# All checks passed!
ret_val = 1 + fpr_count
ret_val |= sextw_mask << 4
if v[0] in allowed_fpr[k]:
ret_val = -ret_val
ret[k] = ret_val
@@ -1027,6 +1033,26 @@ def main(root: str, files: Iterable[Filename], ver: str):
#ifndef __{filename}UNDEFS_H_
#define __{filename}UNDEFS_H_
""",
"x64printer.c": """
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "x64emu.h"
#include "x64emu_private.h"
#include "wrapper.h"
#define PRIp "p"
#define PRIf "f"
#define PRILf "Lf"
#define PRIs "s"
void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int tid, wrapper_t w)
{lbr}
#ifdef HAVE_TRACE
if (0) {lbr}
"""
}
files_guard = {
@@ -1049,6 +1075,14 @@ def main(root: str, files: Iterable[Filename], ver: str):
"fnundefs.h": """
#endif // __{filename}UNDEFS_H_
""",
"x64printer.c": """
else
#endif // HAVE_TRACE
{lbr}
snprintf(buff, buffsz, "%04d|%p: Calling %s(0x%lX, 0x%lX, 0x%lX, ...)", tid, *(void**)(R_RSP), func, R_RDI, R_RSI, R_RDX);
{rbr}
{rbr}
"""
}
@@ -1724,7 +1758,30 @@ def main(root: str, files: Iterable[Filename], ver: str):
if k != str(Clauses()):
file.write("#endif\n")
file.write(files_guard["wrapper.h"].format(lbr="{", rbr="}", version=ver))
# E v c w i I C W u U f d D l L p V O S N H P A x X Y b
formats_map = ["(error)", "(error)", "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "f", "f", "Lf", "i64", "u64", "p", "p", "(error)", "(error)", "(error)", "u64", "p", "p", "(error)", "(error)", "(error)", "(error)"]
# Rewrite the x64printer.c file:
with open(os.path.join(root, "src", "emu", "x64printer.c"), 'w') as file:
file.write(files_header["x64printer.c"].format(lbr="{", rbr="}", version=ver))
for k in gbls:
if k != str(Clauses()):
file.write("#if {k}\n".format(k=k))
for signature in gbls[k]:
sig = signature if signature[2] != "E" else (signature[:2]+signature[3:])
if any(letter in sig[2:] for letter in "OSNHxXYb") or signature.endswith('FE') or signature[1] == 'W':
continue
formats = sig[2:].replace("G", "UU")
params = '' if formats == "v" else ", " + function_args_systemV(FunctionType(formats))[:-2]
formats = '' if formats == "v" else ', '.join("%\" PRI{x} \"".format(x=formats_map[FunctionType(sig).get_convention().values.index(t)]) for t in formats)
file.write(" {rbr} else if (w == {signature}) {lbr}\n".format(signature=signature, lbr="{", rbr="}"))
file.write(" snprintf(buff, buffsz, \"%04d|%p: Calling %s({formats})\", tid, *(void**)(R_RSP), func{params});\n".format(formats=formats, params=params))
if k != str(Clauses()):
file.write("#endif\n")
file.write(" }\n")
file.write(files_guard["x64printer.c"].format(lbr="{", rbr="}", version=ver))
# Rewrite the *types.h files:
for k in conventions:
td_types[k][conventions[k].values.index('A')] = "va_list"
+17 -7
View File
@@ -583,8 +583,8 @@ class FileSpec:
# CONSTANT- rvalues: valid replacement values (outside of structures)
# CONSTANT- validrepl: valid replacement values (for structures)
# structs: structure ids and additional data
values: Sequence[str] = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'h', 'H', 'a', 'A', 'V', 'O', 'S', '2', 'P', 'N', 'M', 's', 'r', 'b', 'B', '_', 't', 'X']
rvalues: Sequence[str] = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'h', 'H', 'a', 'A', 'V', 'O', 'S', '2', 'P', 'N', 'M', 's', 'r', 'b', 'B', '_', 't', 'X']
values: Sequence[str] = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'h', 'H', 'a', 'A', 'V', 'O', 'S', '2', 'P', 'N', 'M', 's', 'r', 'b', 'B', '_', 't', 'X', 'n']
rvalues: Sequence[str] = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'h', 'H', 'a', 'A', 'V', 'O', 'S', '2', 'P', 'N', 'M', 's', 'r', 'b', 'B', '_', 't', 'X', 'n']
validrepl: Sequence[str] = ['c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'h', 'H', 'a', 'A', 'V', 'O', 'S', '2', 'P', 'N', 'M', 's', 'r', 'b', 'B', '_']
def __init__(self) -> None:
@@ -874,6 +874,8 @@ def readFiles(files: Iterable[str]) -> Tuple[JumbledFunctions, JumbledFunctions,
or match("gstinterfaces010","gstaudio")\
or match("gstreamer010","gstreamer") \
or match("appindicator","appindicator3")\
or match("libgl", "libegl") \
or match("libgl", "libglx") \
\
or match("libc", "tcmallocminimal") \
or match("libc", "ldlinux") \
@@ -1150,7 +1152,8 @@ def generate_files(root: str, files: Iterable[str], ver: str, gbls: SortedGlobal
"\n#error Invalid return type: wo structure declaration\n", # B
"\n#error Invalid return type: end of structure declaration\n", # _
"R_EAX = to_cstring(fn({0}));", # t
"R_EAX = to_ptrv(addDisplay(fn({0})));", # X
"R_EAX = to_ptrv(addDisplay(fn({0})));", # X
"\n#error Invalid return type: xcb_connection_t*\n", # n
]
asargs = [
"emu, ", # E
@@ -1188,6 +1191,7 @@ def generate_files(root: str, files: Iterable[str], ver: str, gbls: SortedGlobal
"\n#error Invalid argument type: end of structure declaration\n", # _
"\n#error Invalid argument type: maybe-high string\n",# t
"getDisplay(from_ptriv(R_ESP + {p})), ", # X
"aligned_xcb, ", # n
]
if len(FileSpec.values) != len(asreturns):
raise NotImplementedError("len(values) = {lenval} != len(asreturns) = {lenvals}".format(lenval=len(FileSpec.values), lenvals=len(asreturns)))
@@ -1201,6 +1205,9 @@ def generate_files(root: str, files: Iterable[str], ver: str, gbls: SortedGlobal
CType[(value, CType.ReadWrite.none)].aspre = ""
CType[(value, CType.ReadWrite.none)].asarg = asarg
CType[(value, CType.ReadWrite.none)].aspost = ""
if value == 'n':
CType[(value, CType.ReadWrite.none)].aspre = f"void *aligned_xcb = align_xcb_connection32(from_ptriv(R_ESP + {{p}})); "
CType[(value, CType.ReadWrite.none)].aspost = f" unalign_xcb_connection32(aligned_xcb, from_ptriv(R_ESP + {{p}}));"
for ctn in CType.getSingletons():
CType[ctn].generate_converters()
@@ -1300,6 +1307,9 @@ def generate_files(root: str, files: Iterable[str], ver: str, gbls: SortedGlobal
void* getDisplay(void*);
void* addDisplay(void*);
void* align_xcb_connection32(void* src);
void unalign_xcb_connection32(void* src, void* dst);
""",
"wrapper32.h": """
#ifndef __WRAPPER32_H_
@@ -1405,8 +1415,8 @@ def generate_files(root: str, files: Iterable[str], ver: str, gbls: SortedGlobal
files_guard[fhdr] = trim(files_guard[fhdr])
# Typedefs
# E v c w i I C W u U f d D K l L p h H a A V O S 2 P N M s r b B _ t X
tdtypes = ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "uintptr_t", "uintptr_t", "void*", "void*", "void*", "int32_t", "void*", "_2uint_struct_t", "void*", "...", "...", "void*", "\n#error _\n", "\n#error _\n", "\n#error _\n", "\n#error _\n", "char*", "void*"]
# E v c w i I C W u U f d D K l L p h H a A V O S 2 P N M s r b B _ t X n
tdtypes = ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "uintptr_t", "uintptr_t", "void*", "void*", "void*", "int32_t", "void*", "_2uint_struct_t", "void*", "...", "...", "void*", "\n#error _\n", "\n#error _\n", "\n#error _\n", "\n#error _\n", "char*", "void*", "void*"]
if len(FileSpec.values) != len(tdtypes):
raise NotImplementedError("len(values) = {lenval} != len(tdtypes) = {lentypes}".format(lenval=len(FileSpec.values), lentypes=len(tdtypes)))
def generate_typedefs(funs: Iterable[FunctionType], file):
@@ -1431,8 +1441,8 @@ def generate_files(root: str, files: Iterable[str], ver: str, gbls: SortedGlobal
for i in range(2, len(funtype.orig.replaced))) + ");\n")
# Wrappers
# E v c w i I C W u U f d D K l L p h H a A V O S 2 P N M s r b B _ t X
deltas = [0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 8, 4, 0, 0, 0, 1, 1, 4, 1, 4, 4]
# E v c w i I C W u U f d D K l L p h H a A V O S 2 P N M s r b B _ t X n
deltas = [0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 8, 4, 0, 0, 0, 1, 1, 4, 1, 4, 4, 4]
# Asserts
if len(FileSpec.values) != len(deltas):
raise NotImplementedError("len(values) = {lenval} != len(deltas) = {lendeltas}".format(lenval=len(FileSpec.values), lendeltas=len(deltas)))
-7
View File
@@ -17,13 +17,6 @@ endif()
set(ENV{BOX64_LOG} 0)
set(ENV{BOX64_NOBANNER} 1)
if( EXISTS ${CMAKE_SOURCE_DIR}/x64lib )
# we are inside box64 folder
set(ENV{BOX64_LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/x64lib)
else()
# we are inside build folder
set(ENV{BOX64_LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/../x64lib)
endif( EXISTS ${CMAKE_SOURCE_DIR}/x64lib )
# run the test program, capture the stdout/stderr and the result var
execute_process(
+7 -7
View File
@@ -147,11 +147,11 @@ ulong_t to_hash_d(uintptr_t p) {
}
typedef struct struct_locale_s {
void* p0[13];
void* p0[13]; // struct __locale_data *
void* p1; //const unsigned short int *__ctype_b;
void* p2; //const int *__ctype_tolower;
void* p3; //const int *__ctype_toupper;
void* p4[13];
void* p4[13]; //const char*
} struct_locale_t;
// not a real structure
#define LOCALE_SIGN 0x54abcd845412LL
@@ -180,7 +180,7 @@ void to_struct_locale(ptr_t d, const struct_locale_t *src) {
dest->p0[i] = to_hashv(src->p0[i]);
}
for(int i=0; i<13; ++i) {
dest->p4[i] = to_hashv(src->p4[i]);
dest->p4[i] = to_cstring(src->p4[i]);
}
// copy the 3 ctype int (1st is short int, but int will do)
memcpy(dest->type_b, src->p1-128*sizeof(short), 384*sizeof(short));
@@ -194,9 +194,9 @@ void free_struct_locale(const struct_locale_t *src) {
for(int i=0; i<13; ++i) {
to_hash_d((uintptr_t)src->p0[i]);
}
for(int i=0; i<13; ++i) {
/*for(int i=0; i<13; ++i) {
to_hash_d((uintptr_t)src->p4[i]);
}
}*/
}
// Convert from locale key to original 64bits value
@@ -314,7 +314,7 @@ ptr_t to_cstring(char* p) {
// create a new key, but need write lock!
pthread_rwlock_unlock(&hash_lock);
pthread_rwlock_wrlock(&hash_lock);
ret = to_ptrv(box_strdup(p));
ret = to_ptrv(box32_strdup(p));
int r;
k = kh_put(strings, const_strings, (char*)from_ptrv(ret), &r);
kh_value(const_strings, k) = ret;
@@ -335,7 +335,7 @@ ptr_t to_cstring_d(char* p) {
} else {
ret = kh_value(const_strings, k);
kh_del(strings, const_strings, k);
free(from_ptrv(ret));
box32_free(from_ptrv(ret));
}
pthread_rwlock_unlock(&hash_lock);
return ret;
+12 -45
View File
@@ -7,6 +7,7 @@
#include <sys/mman.h>
#include <pthread.h>
#include "os.h"
#include "box64context.h"
#include "debug.h"
#include "elfloader.h"
@@ -14,15 +15,15 @@
#include "threads.h"
#include "x64trace.h"
#include "bridge.h"
#include "alternate.h"
#include "librarian.h"
#include "library.h"
#include "wrapper.h"
#include "x64emu.h"
#include "signals.h"
#include "rcfile.h"
#include "gltools.h"
#include "rbtree.h"
#include "dynarec.h"
#include "box64cpu.h"
#ifdef BOX32
#include "box32.h"
#endif
@@ -49,7 +50,6 @@ void finiAllHelpers(box64context_t* context)
static int finied = 0;
if(finied)
return;
DeleteParams();
fini_pthread_helper(context);
fini_signal_helper();
fini_bridge_helper();
@@ -77,8 +77,8 @@ void free_tlsdatasize(void* p)
if(!p)
return;
tlsdatasize_t *data = (tlsdatasize_t*)p;
box_free(data->ptr);
box_free(p);
actual_free(data->ptr);
actual_free(p);
if(my_context)
pthread_setspecific(my_context->tlskey, NULL);
}
@@ -86,39 +86,6 @@ void free_tlsdatasize(void* p)
void x64Syscall(x64emu_t *emu);
void x86Syscall(x64emu_t *emu);
int unlockMutex()
{
int ret = unlockCustommemMutex();
int i;
#ifdef USE_CUSTOM_MUTEX
uint32_t tid = (uint32_t)GetTID();
#define GO(A, B) \
i = (native_lock_storeifref2_d(&A, 0, tid)==tid); \
if(i) { \
ret|=(1<<B); \
}
#else
#define GO(A, B) \
i = checkUnlockMutex(&A); \
if(i) { \
ret|=(1<<B); \
}
#endif
GO(my_context->mutex_trace, 7)
#ifdef DYNAREC
GO(my_context->mutex_dyndump, 8)
#else
GO(my_context->mutex_lock, 8)
#endif
GO(my_context->mutex_tls, 9)
GO(my_context->mutex_thread, 10)
GO(my_context->mutex_bridge, 11)
#undef GO
return ret;
}
void relockMutex(int locks)
{
relockCustommemMutex(locks);
@@ -181,8 +148,8 @@ static void atfork_child_box64context(void)
void freeCycleLog(box64context_t* ctx)
{
if(cycle_log) {
for(int i=0; i<cycle_log; ++i) {
if(BOX64ENV(rolling_log)) {
for(int i=0; i<BOX64ENV(rolling_log); ++i) {
box_free(ctx->log_call[i]);
box_free(ctx->log_ret[i]);
}
@@ -194,10 +161,10 @@ void freeCycleLog(box64context_t* ctx)
}
void initCycleLog(box64context_t* context)
{
if(cycle_log) {
context->log_call = (char**)box_calloc(cycle_log, sizeof(char*));
context->log_ret = (char**)box_calloc(cycle_log, sizeof(char*));
for(int i=0; i<cycle_log; ++i) {
if(context && BOX64ENV(rolling_log)) {
context->log_call = (char**)box_calloc(BOX64ENV(rolling_log), sizeof(char*));
context->log_ret = (char**)box_calloc(BOX64ENV(rolling_log), sizeof(char*));
for(int i=0; i<BOX64ENV(rolling_log); ++i) {
context->log_call[i] = (char*)box_calloc(256, 1);
context->log_ret[i] = (char*)box_calloc(128, 1);
}
@@ -303,7 +270,7 @@ void FreeBox64Context(box64context_t** context)
if(--(*context)->forked >= 0)
return;
box64context_t* ctx = *context; // local copy to do the cleanning
box64context_t* ctx = *context; // local copy to do the cleaning
//clean_current_emuthread(); // cleaning main thread seems a bad idea
if(ctx->local_maplib)
+1 -1
View File
@@ -3,6 +3,6 @@
#define BOX64_MAJOR 0
#define BOX64_MINOR 3
#define BOX64_REVISION 2
#define BOX64_REVISION 6
#endif //__BOX64_VERSION_H_
+15 -17
View File
@@ -1,27 +1,25 @@
#include <stdio.h>
#include "debug.h"
#include "box64version.h"
#ifdef NOGIT
#define GITREV "nogit"
#include "build_info.h"
#if defined(DYNAREC)
#define WITH_DYNAREC_STR " with Dynarec"
#else
#include "git_head.h"
#define WITH_DYNAREC_STR ""
#endif
void PrintBox64Version()
#ifdef HAVE_TRACE
#define WITH_TRACE_STR " with trace"
#else
#define WITH_TRACE_STR ""
#endif
void PrintBox64Version(int prefix)
{
printf_log(LOG_NONE, "Box64%s%s v%d.%d.%d %s built on %s %s\n",
#ifdef HAVE_TRACE
" with trace",
#else
"",
#endif
#ifdef DYNAREC
" with Dynarec",
#else
"",
#endif
BOX64_MAJOR, BOX64_MINOR, BOX64_REVISION,
GITREV,
PrintfFtrace(prefix, BOX64_BUILD_INFO_STRING WITH_DYNAREC_STR WITH_TRACE_STR " built on %s %s\n",
__DATE__, __TIME__);
}
#undef WITH_TRACE
#undef WITH_DYNAREC
+35 -2
View File
@@ -1,6 +1,39 @@
#include "box64version.h"
#ifdef NOGIT
#define GITREV "nogit"
#else
#include "git_head.h"
#endif
#ifndef __BUILD_INFO_H__
#define __BUILD_INFO_H__
void PrintBox64Version(void);
#endif //__BUILD_INFO_H__
#if defined(DYNAREC) && (defined(ARM64) || defined(RV64) || defined(LA64))
#if defined(ARM64)
#define ARCH_STR " arm64"
#elif defined(RV64)
#define ARCH_STR " riscv64"
#elif defined(LA64)
#define ARCH_STR " loongarch64"
#endif
#else
#define ARCH_STR ""
#endif
void PrintBox64Version(int prefix);
#define BOX64_BUILD_INFO_STR_HELPER(x) #x
#define BOX64_BUILD_INFO_STR(x) BOX64_BUILD_INFO_STR_HELPER(x)
#ifdef _WIN32
#define BOX64_STR "WowBox64"
#else
#define BOX64_STR "Box64"
#endif
#define BOX64_BUILD_INFO_STRING \
BOX64_STR ARCH_STR \
" v" BOX64_BUILD_INFO_STR(BOX64_MAJOR) "." BOX64_BUILD_INFO_STR(BOX64_MINOR) "." BOX64_BUILD_INFO_STR(BOX64_REVISION) " " GITREV
#endif //__BUILD_INFO_H__
+387 -1343
View File
File diff suppressed because it is too large. Load diff
+610 -316
View File
File diff suppressed because it is too large. Load diff
+10 -7
View File
@@ -2,6 +2,8 @@
#include <unistd.h>
#include <stdint.h>
#include "env.h"
#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif
@@ -22,21 +24,22 @@ extern void* mapallmem;
extern int box64_is32bits;
void setProtection(uintptr_t addr, size_t size, uint32_t prot);
void freeProtection(uintptr_t addr, size_t size);
void* internal_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset);
int internal_munmap(void* addr, unsigned long length);
void* InternalMmap(void* addr, unsigned long length, int prot, int flags, int fd, ssize_t offset);
int InternalMunmap(void* addr, unsigned long length);
void* box_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset);
void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset);
extern int running32bits;
extern int box64_mmap32;
extern box64env_t box64env;
EXPORT void* mmap64(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset)
{
void* ret;
if(!addr && ((running32bits && box64_mmap32) || (flags&MAP_32BIT) || box64_is32bits))
ret = my_mmap64(NULL, addr, length, prot, flags | MAP_32BIT, fd, offset);
if(!addr && ((running32bits && BOX64ENV(mmap32)) || (flags&MAP_32BIT) || box64_is32bits))
ret = box_mmap(addr, length, prot, flags | MAP_32BIT, fd, offset);
else
ret = internal_mmap(addr, length, prot, flags, fd, offset);
ret = InternalMmap(addr, length, prot, flags, fd, offset);
if(ret!=MAP_FAILED && mapallmem)
setProtection((uintptr_t)ret, length, prot);
return ret;
@@ -45,7 +48,7 @@ EXPORT void* mmap(void *addr, unsigned long length, int prot, int flags, int fd,
EXPORT int munmap(void* addr, unsigned long length)
{
int ret = internal_munmap(addr, length);
int ret = InternalMunmap(addr, length);
if(!ret && mapallmem) {
freeProtection((uintptr_t)addr, length);
}
+58 -7
View File
@@ -89,7 +89,8 @@ p0-p3 are used to pass scalable predicate arguments to a subroutine and to retur
#define x4 4
#define x5 5
#define x6 6
#define x7 7
#define x87pc 7
// x87 can be a scratch, but check if it's used as x87 PC and restore if needed in that case
// 32bits version of scratch
#define w1 x1
#define w2 x2
@@ -97,7 +98,7 @@ p0-p3 are used to pass scalable predicate arguments to a subroutine and to retur
#define w4 x4
#define w5 x5
#define w6 x6
#define w7 x7
#define w87pc x87pc
// emu is r0
#define xEmu 0
// ARM64 LR
@@ -144,6 +145,9 @@ p0-p3 are used to pass scalable predicate arguments to a subroutine and to retur
// always
#define c__ 0b1110
//FCMP type of opcode produce:
// if any NAN: CV / v1 == v2: ZC / v1 < v2: N / v1 > v2: C
int convert_bitmask(uint64_t bitmask);
#define convert_bitmask_w(A) convert_bitmask(((uint64_t)(A) << 32) + (uint32_t)(A))
#define convert_bitmask_x(A) convert_bitmask((uint64_t)A)
@@ -205,17 +209,26 @@ int convert_bitmask(uint64_t bitmask);
#define SUBx_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(1, 1, 0, 0b00, Rm, 0, Rn, Rd))
#define SUBSx_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(1, 1, 1, 0b00, Rm, 0, Rn, Rd))
#define SUBSx_REG_ASR(Rd, Rn, Rm, asr) FEMIT(ADDSUB_REG_gen(1, 1, 1, 0b10, Rm, asr, Rn, Rd))
#define SUBx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(1, 1, 0, 0b00, Rm, lsl, Rn, Rd))
#define SUBw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(0, 1, 0, 0b00, Rm, 0, Rn, Rd))
#define SUBw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(0, 1, 0, 0b00, Rm, lsl, Rn, Rd))
#define SUBw_REG_ASR(Rd, Rn, Rm, asr) EMIT(ADDSUB_REG_gen(0, 1, 0, 0b10, Rm, asr, Rn, Rd))
#define SUBSw_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(0, 1, 1, 0b00, Rm, 0, Rn, Rd))
#define SUBSw_REG_LSL(Rd, Rn, Rm, lsl) FEMIT(ADDSUB_REG_gen(0, 1, 1, 0b00, Rm, lsl, Rn, Rd))
#define SUBSw_REG_LSR(Rd, Rn, Rm, lsr) FEMIT(ADDSUB_REG_gen(0, 1, 1, 0b01, Rm, lsr, Rn, Rd))
#define SUBSw_REG_ASR(Rd, Rn, Rm, asr) FEMIT(ADDSUB_REG_gen(0, 1, 1, 0b10, Rm, asr, Rn, Rd))
#define SUBxw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(rex.w, 1, 0, 0b00, Rm, 0, Rn, Rd))
#define SUBz_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(rex.is32bits?0:1, 1, 0, 0b00, Rm, 0, Rn, Rd))
#define SUBSxw_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(rex.w, 1, 1, 0b00, Rm, 0, Rn, Rd))
#define SUBSxw_REG_ASR(Rd, Rn, Rm, asr) FEMIT(ADDSUB_REG_gen(rex.w, 1, 1, 0b10, Rm, asr, Rn, Rd))
#define CMPSx_REG(Rn, Rm) SUBSx_REG(xZR, Rn, Rm)
#define CMPSx_REG_ASR(Rn, Rm, asr) SUBSx_REG_ASR(xZR, Rn, Rm, asr)
#define CMPSw_REG(Rn, Rm) SUBSw_REG(wZR, Rn, Rm)
#define CMPSw_REG_LSR(Rn, Rm, lsr) SUBSw_REG_LSR(wZR, Rn, Rm, lsr)
#define CMPSw_REG_ASR(Rn, Rm, asr) SUBSw_REG_ASR(wZR, Rn, Rm, asr)
#define CMPSxw_REG(Rn, Rm) SUBSxw_REG(xZR, Rn, Rm)
#define CMPSxw_REG_ASR(Rn, Rm, asr) SUBSxw_REG_ASR(xZR, Rn, Rm, asr)
#define NEGx_REG(Rd, Rm) SUBx_REG(Rd, xZR, Rm);
#define NEGw_REG(Rd, Rm) SUBw_REG(Rd, wZR, Rm);
#define NEGxw_REG(Rd, Rm) SUBxw_REG(Rd, xZR, Rm);
@@ -248,6 +261,10 @@ int convert_bitmask(uint64_t bitmask);
#define SBCSw_REG(Rd, Rn, Rm) FEMIT(ADDSUBC_gen(0, 1, 1, Rm, Rn, Rd))
#define SBCSxw_REG(Rd, Rn, Rm) FEMIT(ADDSUBC_gen(rex.w, 1, 1, Rm, Rn, Rd))
#define SUB_ext(sf, op, S, Rm, option, imm3, Rn, Rd) ((sf)<<31 | (op)<<30 | (S)<<29 | 0b01011<<24 | 1<<21 | (Rm)<<16 | (option)<<13 | (imm3)<<10 | (Rn)<<5 | (Rd))
#define SUBxw_UXTB(Rd, Rn, Rm) EMIT(SUB_ext(rex.w, 1, 0, Rm, 0b000, 0, Rn, Rd))
#define SUBw_UXTB(Rd, Rn, Rm) EMIT(SUB_ext(0, 1, 0, Rm, 0b000, 0, Rn, Rd))
// CCMP compare if cond is true, set nzcv if false
#define CCMP_reg(sf, Rm, cond, Rn, nzcv) ((sf)<<31 | 1<<30 | 1<<29 | 0b11010010<<21 | (Rm)<<16 | (cond)<<12 | (Rn)<<5 | (nzcv))
#define CCMPw(Wn, Wm, nzcv, cond) FEMIT(CCMP_reg(0, Wm, cond, Wn, nzcv))
@@ -290,18 +307,24 @@ int convert_bitmask(uint64_t bitmask);
#define LDRx_REG_LSL3(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b11, Rm, 0b011, 1, Rn, Rt))
#define LDRx_REG_UXTW3(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b11, Rm, 0b010, 1, Rn, Rt))
#define LDRx_REG_SXTW(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b11, Rm, 0b110, 0, Rn, Rt))
#define LDRx_REGz(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b11, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define LDRw_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10, Rm, 0b011, 0, Rn, Rt))
#define LDRw_REG_LSL2(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10, Rm, 0b011, 1, Rn, Rt))
#define LDRw_REG_SXTW(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10, Rm, 0b110, 0, Rn, Rt))
#define LDRw_REGz(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define LDRxw_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10+rex.w, Rm, 0b011, 0, Rn, Rt))
#define LDRz_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b011, 0, Rn, Rt))
#define LDRxw_REG_SXTW(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10+rex.w, Rm, 0b110, 0, Rn, Rt))
#define LDRxw_REGz(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10+rex.w, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define LDRz_REG_SXTW(Rt, Rn, Rm) EMIT(LDR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b110, 0, Rn, Rt))
#define LDRz_REGz(Rt, Rn, Rm) EMIT(LDR_REG_gen(rex.is32bits?0b10:0b11, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define LDRB_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b00, Rm, 0b011, 0, Rn, Rt))
#define LDRB_REG_UXTW(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b00, Rm, 0b010, 0, Rn, Rt))
#define LDRB_REG_SXTW(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b00, Rm, 0b110, 0, Rn, Rt))
#define LDRB_REGz(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b00, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define LDRH_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b01, Rm, 0b011, 0, Rn, Rt))
#define LDRH_REG_SXTW(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b01, Rm, 0b110, 0, Rn, Rt))
#define LDRH_REGz(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b01, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define LDRS_U12_gen(size, op1, opc, imm12, Rn, Rt) ((size)<<30 | 0b111<<27 | (op1)<<24 | (opc)<<22 | (imm12)<<10 | (Rn)<<5 | (Rt))
#define LDRSHx_U12(Rt, Rn, imm12) EMIT(LDRS_U12_gen(0b01, 0b01, 0b10, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
@@ -314,9 +337,10 @@ int convert_bitmask(uint64_t bitmask);
#define LDRS_REG_gen(size, Rm, option, S, Rn, Rt) ((size)<<30 | 0b111<<27 | 0b10<<22 | 1<<21 | (Rm)<<16 | (option)<<13 | (S)<<12 | (0b10)<<10 | (Rn)<<5 | (Rt))
#define LDRSW_REG(Rt, Rn, Rm) EMIT(LDRS_REG_gen(0b10, Rm, 0b011, 0, Rn, Rt))
#define LDRSW_REG_SXTW(Rt, Rn, Rm) EMIT(LDRS_REG_gen(0b10, Rm, 0b110, 0, Rn, Rt))
#define LDRSW_REGz(Rt, Rn, Rm) EMIT(LDRS_REG_gen(0b10, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define LDR_PC_gen(opc, imm19, Rt) ((opc)<<30 | 0b011<<27 | (imm19)<<5 | (Rt))
#define LDRx_literal(Rt, imm19) EMIT(LDR_PC_gen(0b01, ((imm19)>>2)&0x7FFFF, Rt))
#define LDRx_literal(Rt, imm21) EMIT(LDR_PC_gen(0b01, (((int64_t)(imm21))>>2)&0x7FFFF, Rt))
#define LDU_gen(size, opc, imm9, Rn, Rt) ((size)<<30 | 0b111<<27 | (opc)<<22 | ((imm9)&0x1ff)<<12 | (Rn)<<5 | (Rt))
#define LDURx_I9(Rt, Rn, imm9) EMIT(LDU_gen(0b11, 0b01, imm9, Rn, Rt))
@@ -390,12 +414,15 @@ int convert_bitmask(uint64_t bitmask);
#define STRw_REG_SXTW(Rt, Rn, Rm) EMIT(STR_REG_gen(0b10, Rm, 0b110, 0, Rn, Rt))
#define STRB_REG(Rt, Rn, Rm) EMIT(STR_REG_gen(0b00, Rm, 0b011, 0, Rn, Rt))
#define STRB_REG_SXTW(Rt, Rn, Rm) EMIT(STR_REG_gen(0b00, Rm, 0b110, 0, Rn, Rt))
#define STRB_REGz(Rt, Rn, Rm) EMIT(STR_REG_gen(0b00, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define STRH_REG(Rt, Rn, Rm) EMIT(STR_REG_gen(0b01, Rm, 0b011, 0, Rn, Rt))
#define STRH_REG_SXTW(Rt, Rn, Rm) EMIT(STR_REG_gen(0b01, Rm, 0b110, 0, Rn, Rt))
#define STRxw_REG(Rt, Rn, Rm) EMIT(STR_REG_gen(rex.w?0b11:0b10, Rm, 0b011, 0, Rn, Rt))
#define STRxw_REG_SXTW(Rt, Rn, Rm) EMIT(STR_REG_gen(rex.w?0b11:0b10, Rm, 0b110, 0, Rn, Rt))
#define STRxw_REGz(Rt, Rn, Rm) EMIT(STR_REG_gen(rex.w?0b11:0b10, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
#define STRz_REG(Rt, Rn, Rm) EMIT(STR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b011, 0, Rn, Rt))
#define STRz_REG_SXTW(Rt, Rn, Rm) EMIT(STR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b110, 0, Rn, Rt))
#define STRz_REGz(Rt, Rn, Rm) EMIT(STR_REG_gen(rex.is32bits?0b10:0b11, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
// LOAD/STORE PAIR
#define MEMPAIR_gen(size, L, op2, imm7, Rt2, Rn, Rt) ((size)<<31 | 0b101<<27 | (op2)<<23 | (L)<<22 | (imm7)<<15 | (Rt2)<<10 | (Rn)<<5 | (Rt))
@@ -560,7 +587,7 @@ int convert_bitmask(uint64_t bitmask);
#define CSINV_gen(sf, Rm, cond, Rn, Rd) ((sf)<<31 | 1<<30 | 0b11010100<<21 | (Rm)<<16 | (cond)<<12 | (Rn)<<5 | (Rd))
#define CSINVx(Rd, Rn, Rm, cond) EMIT(CSINV_gen(1, Rm, cond, Rn, Rd))
#define CSINVw(Rd, Rn, Rm, cond) EMIT(CSINV_gen(0, Rm, cond, Rn, Rd))
#define CSINVxw(Rd, Rn, Rm, cond) EMIT(CSINV_gen(rex.w?, Rm, cond, Rn, Rd))
#define CSINVxw(Rd, Rn, Rm, cond) EMIT(CSINV_gen(rex.w, Rm, cond, Rn, Rd))
#define CINVx(Rd, Rn, cond) CSINVx(Rd, Rn, Rn, invertCond(cond))
#define CINVw(Rd, Rn, cond) CSINVw(Rd, Rn, Rn, invertCond(cond))
#define CINVxw(Rd, Rn, cond) CSINVxw(Rd, Rn, Rn, invertCond(cond))
@@ -694,6 +721,7 @@ int convert_bitmask(uint64_t bitmask);
#define BFCx(Rd, lsb, width) BFMx(Rd, xZR, ((-(lsb))%64)&0x3f, (width)-1)
#define BFCw(Rd, lsb, width) BFMw(Rd, xZR, ((-(lsb))%32)&0x1f, (width)-1)
#define BFCxw(Rd, lsb, width) BFMxw(Rd, xZR, rex.w?(((-(lsb))%64)&0x3f):(((-(lsb))%32)&0x1f), (width)-1)
#define BFCz(Rd, lsb, width) if(rex.is32bits) {BFCw(Rd, lsb, width);} else {BFCx(Rd, lsb, width);}
// Insert lsb:width part of Rn into low part of Rd (leaving rest of Rd untouched)
#define BFXILx(Rd, Rn, lsb, width) EMIT(BFM_gen(1, 0b01, 1, (lsb), (lsb)+(width)-1, Rn, Rd))
// Insert lsb:width part of Rn into low part of Rd (leaving rest of Rd untouched)
@@ -881,7 +909,7 @@ int convert_bitmask(uint64_t bitmask);
#define FCSELS(Sd, Sn, Sm, cond) EMIT(FCSEL_scalar(0b00, Sm, cond, Sn, Sd))
#define FCSELD(Dd, Dn, Dm, cond) EMIT(FCSEL_scalar(0b01, Dm, cond, Dn, Dd))
// VLDR
// VLDR/VSTR
#define VMEM_gen(size, opc, imm12, Rn, Rt) ((size)<<30 | 0b111<<27 | 1<<26 | 0b01<<24 | (opc)<<22 | (imm12)<<10 | (Rn)<<5 | (Rt))
// imm13 must be 1-aligned
#define VLDR16_U12(Ht, Rn, imm13) EMIT(VMEM_gen(0b01, 0b01, ((uint32_t)((imm13)>>1))&0xfff, Rn, Ht))
@@ -900,6 +928,15 @@ int convert_bitmask(uint64_t bitmask);
// (imm13) must be 1-aligned
#define VSTR16_U12(Ht, Rn, imm13) EMIT(VMEM_gen(0b01, 0b00, ((uint32_t)((imm13)>>1))&0xfff, Rn, Ht))
//VLDP/VSTP
#define VMEMP_vector(opc, L, imm7, Rt2, Rn, Rt) ((opc)<<30 | 0b101<<27 | 1<<26 | 0b010<<23 | (L)<<22 | (imm7)<<15 | (Rt2)<<10 | (Rn)<<5 | (Rt))
#define VLDP32_I7(Rt1, Rt2, Rn, imm9) EMIT(VMEMP_vector(0b00, 1, (((int64_t)(imm9))>>2)&0x7f, Rt2, Rn, Rt1))
#define VLDP64_I7(Rt1, Rt2, Rn, imm10) EMIT(VMEMP_vector(0b01, 1, (((int64_t)(imm10))>>3)&0x7f, Rt2, Rn, Rt1))
#define VLDP128_I7(Rt1, Rt2, Rn, imm11) EMIT(VMEMP_vector(0b10, 1, (((int64_t)(imm11))>>4)&0x7f, Rt2, Rn, Rt1))
#define VSTP32_I7(Rt1, Rt2, Rn, imm9) EMIT(VMEMP_vector(0b00, 0, (((int64_t)(imm9))>>2)&0x7f, Rt2, Rn, Rt1))
#define VSTP64_I7(Rt1, Rt2, Rn, imm10) EMIT(VMEMP_vector(0b01, 0, (((int64_t)(imm10))>>3)&0x7f, Rt2, Rn, Rt1))
#define VSTP128_I7(Rt1, Rt2, Rn, imm11) EMIT(VMEMP_vector(0b10, 0, (((int64_t)(imm11))>>4)&0x7f, Rt2, Rn, Rt1))
#define VMEMUR_vector(size, opc, imm9, Rn, Rt) ((size)<<30 | 0b111<<27 | 1<<26 | (opc)<<22 | (imm9)<<12 | (Rn)<<5 | (Rt))
// signed offset, no alignement!
#define VLDR8_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b00, 0b01, (imm9)&0b111111111, Rn, Vt))
@@ -918,10 +955,12 @@ int convert_bitmask(uint64_t bitmask);
#define VLD64(A, B, C) if(unscaled) {VLDR64_I9(A, B, C);} else {VLDR64_U12(A, B, C);}
#define VLD32(A, B, C) if(unscaled) {VLDR32_I9(A, B, C);} else {VLDR32_U12(A, B, C);}
#define VLD16(A, B, C) if(unscaled) {VLDR16_I9(A, B, C);} else {VLDR16_U12(A, B, C);}
#define VLD8(A, B, C) if(unscaled) {VLDR8_I9(A, B, C);} else {VLDR8_U12(A, B, C);}
#define VST128(A, B, C) if(unscaled) {VSTR128_I9(A, B, C);} else {VSTR128_U12(A, B, C);}
#define VST64(A, B, C) if(unscaled) {VSTR64_I9(A, B, C);} else {VSTR64_U12(A, B, C);}
#define VST32(A, B, C) if(unscaled) {VSTR32_I9(A, B, C);} else {VSTR32_U12(A, B, C);}
#define VST16(A, B, C) if(unscaled) {VSTR16_I9(A, B, C);} else {VSTR16_U12(A, B, C);}
#define VST8(A, B, C) if(unscaled) {VSTR8_I9(A, B, C);} else {VSTR8_U12(A, B, C);}
#define VMEMW_gen(size, opc, imm9, op2, Rn, Rt) ((size)<<30 | 0b111<<27 | 1<<26 | (opc)<<22 | (imm9)<<12 | (op2)<<10 | 0b01<<10 | (Rn)<<5 | (Rt))
#define VLDR64_S9_postindex(Rt, Rn, imm9) EMIT(VMEMW_gen(0b11, 0b01, (imm9)&0x1ff, 0b01, Rn, Rt))
@@ -1141,7 +1180,9 @@ int convert_bitmask(uint64_t bitmask);
#define VFMOVDQ_8(Vd, u8) EMIT(FMOV_vector_imm(1, 1, ((u8)>>5)&0b111, (u8)&0b11111, Vd))
#define FMOV_scalar_imm(type, imm8, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | (imm8)<<13 | 0b100<<10 | (Rd))
// FMOV to Sd, imm=7 :~6:6:6:6:6:6:5:4 :3:2:1:0....
#define FMOVS_8(Sd, u8) EMIT(FMOV_scalar_imm(0b00, u8, Sd))
// FMOV to Dd, imm=7 :~6:6:6:6:6:6:6:6:6:5:4 :3:2:1:0....
#define FMOVD_8(Dd, u8) EMIT(FMOV_scalar_imm(0b01, u8, Dd))
// VMOV
@@ -1297,7 +1338,7 @@ int convert_bitmask(uint64_t bitmask);
#define VFRSQRTSQS(Vd, Vn, Vm) EMIT(FRSQRTS_vector(1, 0, Vm, Vn, Vd))
#define VFRSQRTSQD(Vd, Vn, Vm) EMIT(FRSQRTS_vector(1, 0, Vm, Vn, Vd))
// CMP
// CMP . NZCV: unordere=0011, eq=0110, inf=1000, sup=0010
#define FCMP_scalar(type, Rn, Rm, opc) (0b11110<<24 | (type)<<22 | 1<<21 | (Rm)<<16 | 0b1000<<10 | (Rn)<<5 | (opc)<<3)
#define FCMPS(Sn, Sm) FEMIT(FCMP_scalar(0b00, Sn, Sm, 0b00))
#define FCMPD(Dn, Dm) FEMIT(FCMP_scalar(0b01, Dn, Dm, 0b00))
@@ -1538,6 +1579,12 @@ int convert_bitmask(uint64_t bitmask);
#define VFMAXQS(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 0, 0, 0, Vm, Vn, Vd))
#define VFMINQD(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 0, 1, 1, Vm, Vn, Vd))
#define VFMAXQD(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 0, 0, 1, Vm, Vn, Vd))
#define VFMINPS(Vd, Vn, Vm) EMIT(FMINMAX_vector(0, 1, 1, 0, Vm, Vn, Vd))
#define VFMAXPS(Vd, Vn, Vm) EMIT(FMINMAX_vector(0, 1, 0, 0, Vm, Vn, Vd))
#define VFMINPQS(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 1, 1, 0, Vm, Vn, Vd))
#define VFMAXPQS(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 1, 0, 0, Vm, Vn, Vd))
#define VFMINPQD(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 1, 1, 1, Vm, Vn, Vd))
#define VFMAXPQD(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 1, 0, 1, Vm, Vn, Vd))
#define FMINMAX_scalar(type, Rm, op, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | (Rm)<<16 | 0b01<<14 | (op)<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
#define FMINS(Sd, Sn, Sm) EMIT(FMINMAX_scalar(0b00, Sm, 0b01, Sn, Sd))
@@ -1826,7 +1873,7 @@ int convert_bitmask(uint64_t bitmask);
#define FCMLTS_0(Rd, Rn) EMIT(FCMP_0_scalar(0, 0, 0b10, (Rn), (Rd)))
#define FCMLTD_0(Rd, Rn) EMIT(FCMP_0_scalar(0, 1, 0b10, (Rn), (Rd)))
// Scalar Float CMP
// Scalar Float CMEQ
#define FCMP_op_scalar(U, E, sz, Rm, ac, Rn, Rd) (0b01<<30 | (U)<<29 | 0b11110<<24 | (E)<<23 | (sz)<<22 | 1<<21 | (Rm)<<16 | 0b1110<<12 | (ac)<<11 | 1<<10 | (Rn)<<5 | (Rd))
#define FCMEQS(Rd, Rn, Rm) EMIT(FCMP_op_scalar(0, 0, 0, (Rm), 0, (Rn), (Rd)))
#define FCMEQD(Rd, Rn, Rm) EMIT(FCMP_op_scalar(0, 0, 1, (Rm), 0, (Rn), (Rd)))
@@ -2119,6 +2166,10 @@ int convert_bitmask(uint64_t bitmask);
#define URHADDQ_16(Vd, Vn, Vm) EMIT(RHADD_vector(1, 1, 0b01, Vm, Vn, Vd))
#define URHADDQ_32(Vd, Vn, Vm) EMIT(RHADD_vector(1, 1, 0b10, Vm, Vn, Vd))
//SRSHR/URSHR
#define RSHR(Q, U, immh, immb, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b011110<<23 | (immh)<<19 | (immb)<<16 | 1<<13 | 0<<12 | 1<<10 | (Rn)<<5 | (Rd))
#define SRSHRQ_32(Vd, Vn, shift) EMIT(RSHR(1, 0, 0b0100 | (((32-(shift))>>3)&0b11), (32-(shift))&0b111, Vn, Vd))
// QRDMULH Signed saturating (Rounding) Doubling Multiply returning High half
#define QDMULH_vector(Q, U, size, Rm, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b10110<<11 | 1<<10 | (Rn)<<5 | (Rd))
#define SQRDMULH_8(Vd, Vn, Vm) EMIT(QDMULH_vector(0, 1, 0b00, Vm, Vn, Vd))
+3
View File
@@ -19,6 +19,9 @@ arm64_epilog:
stp x24, x25, [x0, (8 * 14)]
stp x26, x27, [x0, (8 * 16)] // put back reg value in emu, including EIP (so x27 must be EIP now)
//restore all used register
#ifdef _WIN32
ldr x18, [x0, 3120]
#endif
add sp, x28, 0
//vpop {d8-d15}
ldp x19, x20, [sp, (8 * 0)]
+142
View File
@@ -5,6 +5,7 @@
.text
.align 4
.extern arm64_atomics
.global arm64_lock_read_b
.global arm64_lock_write_b
.global arm64_lock_read_h
@@ -33,6 +34,7 @@
.global arm64_lock_get_b
.global arm64_lock_get_d
.global arm64_lock_get_dd
.global arm64_crc
arm64_lock_read_b:
dmb ish
@@ -104,6 +106,10 @@ arm64_lock_write_dq:
arm64_lock_xchg_dd:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_xchg_dd
dmb ish
arm64_lock_xchg_dd_0:
// address is x0, value is x1, return old value in x0
@@ -113,7 +119,17 @@ arm64_lock_xchg_dd_0:
mov x0, x2
ret
arm64_atomic_xchg_dd:
dmb ish
// address is x0, value is x1, return old value in x0
swpal x1, x0, [x0]
ret
arm64_lock_xchg_d:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_xchg_d
dmb ish
arm64_lock_xchg_d_0:
// address is x0, value is x1, return old value in x0
@@ -123,7 +139,17 @@ arm64_lock_xchg_d_0:
mov w0, w2
ret
arm64_atomic_xchg_d:
dmb ish
// address is x0, value is x1, return old value in x0
swpal w1, w0, [x0]
ret
arm64_lock_xchg_h:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_xchg_h
dmb ish
arm64_lock_xchg_h_0:
// address is x0, value is x1, return old value in x0
@@ -133,7 +159,17 @@ arm64_lock_xchg_h_0:
mov w0, w2
ret
arm64_atomic_xchg_h:
dmb ish
// address is x0, value is x1, return old value in x0
swpalh w1, w0, [x0]
ret
arm64_lock_xchg_b:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_xchg_b
dmb ish
arm64_lock_xchg_b_0:
// address is x0, value is x1, return old value in x0
@@ -143,7 +179,17 @@ arm64_lock_xchg_b_0:
mov w0, w2
ret
arm64_atomic_xchg_b:
dmb ish
// address is x0, value is x1, return old value in x0
swpalb w1, w0, [x0]
ret
arm64_lock_storeifnull:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_storeifnull
dmb ish
1:
// address is x0, value is x1, x1 store to x0 only if [x0] is 0. return old [x0] value
@@ -155,7 +201,20 @@ arm64_lock_storeifnull:
mov x0, x2
ret
arm64_atomic_storeifnull:
dmb ish
// address is x0, value is x1, x1 store to x0 only if [x0] is 0. return old [x0] value
mov x2, xzr
casal x2, x1, [x0]
mov x0, x2
ret
arm64_lock_storeifnull_d:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_storeifnull_d
dmb ish
1:
// address is x0, value is w1, w1 store to x0 only if [x0] is 0. return old [x0] value
@@ -168,7 +227,19 @@ arm64_lock_storeifnull_d:
mov w0, w2
ret
arm64_atomic_storeifnull_d:
dmb ish
// address is x0, value is w1, w1 store to x0 only if [x0] is 0. return old [x0] value
mov x2, xzr
casal w2, w1, [x0]
mov w0, w2
ret
arm64_lock_storeifref:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_storeifref
dmb ish
1:
// address is x0, value is x1, x1 store to x0 only if [x0] is x2. return new [x0] value (so x1 or old value)
@@ -183,7 +254,23 @@ arm64_lock_storeifref:
mov x0, x3
ret
arm64_atomic_storeifref:
dmb ish
// address is x0, value is x1, x1 store to x0 only if [x0] is x2. return new [x0] value (so x1 or old value)
mov x3, x2
casal x2, x1, [x0]
cmp x2, x3
mov x0, x1
ret
2:
mov x0, x3
ret
arm64_lock_storeifref_d:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_storeifref_d
dmb ish
1:
// address is x0, value is w1, w1 store to x0 only if [x0] is w2. return new [x0] value (so x1 or old value)
@@ -198,7 +285,23 @@ arm64_lock_storeifref_d:
mov w0, w3
ret
arm64_atomic_storeifref_d:
dmb ish
// address is x0, value is w1, w1 store to x0 only if [x0] is w2. return new [x0] value (so w1 or old value)
mov w3, w2
casal w2, w1, [x0]
cmp w2, w3
mov w0, w1
ret
2:
mov w0, w3
ret
arm64_lock_storeifref2_d:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_storeifref2_d
dmb ish
1:
// address is x0, value is w1, w1 store to x0 only if [x0] is w2. return old [x0] value
@@ -211,6 +314,13 @@ arm64_lock_storeifref2_d:
mov w0, w3
ret
arm64_atomic_storeifref2_d:
dmb ish
// address is x0, value is w1, w1 store to x0 only if [x0] is w2. return old [x0] value
casal w2, w1, [x0]
mov w0, w2
ret
arm64_lock_decifnot0b:
dmb ish
1:
@@ -242,6 +352,10 @@ arm64_lock_decifnot0:
ret
arm64_lock_incif0:
adrp x3, arm64_atomics
add x3, x3, #:lo12:arm64_atomics
ldr w3, [x3]
cbnz w3, arm64_atomic_incif0
dmb ish
1:
ldaxr w1, [x0]
@@ -254,6 +368,13 @@ arm64_lock_incif0:
mov w0, w1
ret
arm64_atomic_incif0:
mov w1, #1
dmb ish
swpal w1, wzr, [x0]
mov w0, w1
ret
arm64_lock_store:
str w1, [x0]
dmb ish
@@ -275,3 +396,24 @@ arm64_lock_get_d:
arm64_lock_get_dd:
ldaxr x0, [x0]
ret
arm64_crc:
//x0 is address, w1 is len
mov x2, x0 // address is x2 now
mov w0, wzr // crc is w0
1:
cmp w1, #8
blo 2f
ldr x3, [x2], #8
crc32x w0, w0, x3
subs w1, w1, #8
bne 1b
2:
cbz w1, 4f
3:
ldrb w3, [x2], #1
crc32b w0, w0, w3
subs w1, w1, #1
bne 3b
4:
ret
+9
View File
@@ -29,30 +29,39 @@ extern int arm64_lock_write_dq(uint64_t a, uint64_t b, void* addr);
// Atomically exchange value at [p] with val, return old p
extern uintptr_t arm64_lock_xchg_dd(void* p, uintptr_t val);
extern uintptr_t arm64_atomic_xchg_dd(void* p, uintptr_t val);
// Atomically exchange value at [p] with val, return old p
extern uint32_t arm64_lock_xchg_d(void* p, uint32_t val);
extern uint32_t arm64_atomic_xchg_d(void* p, uint32_t val);
// Atomically exchange value at [p] with val, return old p
extern uint32_t arm64_lock_xchg_h(void* p, uint32_t val);
extern uint32_t arm64_atomic_xchg_h(void* p, uint32_t val);
// Atomically exchange value at [p] with val, return old p
extern uint32_t arm64_lock_xchg_b(void* p, uint32_t val);
extern uint32_t arm64_atomic_xchg_b(void* p, uint32_t val);
// Atomically store value to [p] only if [p] is NULL. Return old [p] value
extern uint32_t arm64_lock_storeifnull_d(void*p, uint32_t val);
extern uint32_t arm64_atomic_storeifnull_d(void*p, uint32_t val);
// Atomically store value to [p] only if [p] is NULL. Return old [p] value
extern void* arm64_lock_storeifnull(void*p, void* val);
extern void* arm64_atomic_storeifnull(void*p, void* val);
// Atomically store value to [p] only if [p] is ref. Return new [p] value (so val or old)
extern void* arm64_lock_storeifref(void*p, void* val, void* ref);
extern void* arm64_atomic_storeifref(void*p, void* val, void* ref);
// Atomically store value to [p] only if [p] is ref. Return new [p] value (so val or old)
extern uint32_t arm64_lock_storeifref_d(void*p, uint32_t val, uint32_t ref);
extern uint32_t arm64_atomic_storeifref_d(void*p, uint32_t val, uint32_t ref);
// Atomically store value to [p] only if [p] is ref. Return new [p] value (so val or old)
extern uint32_t arm64_lock_storeifref2_d(void*p, uint32_t val, uint32_t ref);
extern uint32_t arm64_atomic_storeifref2_d(void*p, uint32_t val, uint32_t ref);
// decrement atomically the byte at [p] (but only if p not 0)
extern void arm64_lock_decifnot0b(void*p);
+3
View File
@@ -22,6 +22,9 @@ arm64_next:
stp x16, x17, [sp, (8 * 8)]
stp x18, x27, [sp, (8 * 10)] // also save x27(rip) to allow change in LinkNext
#ifdef _WIN32
ldr x18, [x0, 3120]
#endif
mov x2, x30 // "from" is in lr, so put in x2
add x3, sp, 8*11 // x3 is address to change rip
// call the function
+143 -38
View File
@@ -2,6 +2,7 @@
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
#include "arm64_printer.h"
#include "debug.h"
@@ -407,9 +408,9 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
if(sf) {
uint64_t noti=~(((uint64_t)imm)<<(hw*16));
if(!hw)
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x\t; 0x%lx", Xt[Rd], imm, noti);
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x\t; 0x%"PRIx64, Xt[Rd], imm, noti);
else
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x LSL %d\t; 0x%lx", Xt[Rd], imm, 16*hw, noti);
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x LSL %d\t; 0x%"PRIx64, Xt[Rd], imm, 16*hw, noti);
} else {
uint32_t noti=~(((uint32_t)imm)<<(hw*16));
if(!hw)
@@ -554,16 +555,26 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "SUBS %s, %s, %s %s %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], shifts[shift], imm);
return buff;
}
if(isMask(opcode, "f1001011001mmmmmoooiiinnnnnddddd", &a)) {
const char* shifts[2][8] = {{ "UXTB", "UXTH", "LSL", "UXTX", "SXTB", "SXTH", "SXTW", "SXTX"}, {"UXTB", "UXTH", "UXTW", "LSL", "SXTB", "SXTH", "SXTW", "SXTX" }};
if(((sf==0 && shift==2) || (sf==1 && shift==3)) && imm==0)
snprintf(buff, sizeof(buff), "SUB %s, %s, %s", sf?XtSp[Rd]:WtSp[Rd], sf?XtSp[Rn]:WtSp[Rn], sf?XtSp[Rm]:WtSp[Rm]);
else if(shift==0)
snprintf(buff, sizeof(buff), "SUB %s, %s, %s %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], shifts[sf][shift]);
else
snprintf(buff, sizeof(buff), "SUB %s, %s, %s %s %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], shifts[sf][shift], imm);
return buff;
}
// ---- LOGIC
if(isMask(opcode, "f11100100Nrrrrrrssssssnnnnnddddd", &a)) {
uint64_t i = DecodeBitMasks(a.N, imms, immr);
if(!sf) i&=0xffffffff;
if(sf==0 && a.N==1)
snprintf(buff, sizeof(buff), "invalid ANDS %s, %s, 0x%lx", Wt[Rd], Wt[Rn], i);
snprintf(buff, sizeof(buff), "invalid ANDS %s, %s, 0x%"PRIx64, Wt[Rd], Wt[Rn], i);
else if(Rd==31)
snprintf(buff, sizeof(buff), "TST %s, 0x%lx", sf?Xt[Rn]:Wt[Rn], i);
snprintf(buff, sizeof(buff), "TST %s, 0x%"PRIx64, sf?Xt[Rn]:Wt[Rn], i);
else
snprintf(buff, sizeof(buff), "ANDS %s, %s, 0x%lx", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], i);
snprintf(buff, sizeof(buff), "ANDS %s, %s, 0x%"PRIx64, sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], i);
return buff;
}
if(isMask(opcode, "f1101010hh0mmmmmiiiiiinnnnnddddd", &a)) {
@@ -601,9 +612,9 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
uint64_t i = DecodeBitMasks(a.N, imms, immr);
if(!sf) i&=0xffffffff;
if(sf==0 && a.N==1)
snprintf(buff, sizeof(buff), "invalid ORR %s, %s, 0x%lx", Wt[Rd], Wt[Rn], i);
snprintf(buff, sizeof(buff), "invalid ORR %s, %s, 0x%"PRIx64, Wt[Rd], Wt[Rn], i);
else
snprintf(buff, sizeof(buff), "ORR %s, %s, 0x%lx", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], i);
snprintf(buff, sizeof(buff), "ORR %s, %s, 0x%"PRIx64, sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], i);
return buff;
}
if(isMask(opcode, "f0101010hh1mmmmmiiiiiinnnnnddddd", &a)) {
@@ -636,9 +647,9 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
uint64_t i = DecodeBitMasks(a.N, imms, immr);
if(!sf) i&=0xffffffff;
if(sf==0 && a.N==1)
snprintf(buff, sizeof(buff), "invalid EOR %s, %s, 0x%lx", Wt[Rd], Wt[Rn], i);
snprintf(buff, sizeof(buff), "invalid EOR %s, %s, 0x%"PRIx64, Wt[Rd], Wt[Rn], i);
else
snprintf(buff, sizeof(buff), "EOR %s, %s, 0x%lx", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], i);
snprintf(buff, sizeof(buff), "EOR %s, %s, 0x%"PRIx64, sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], i);
return buff;
}
if(isMask(opcode, "f1001010hh0mmmmmiiiiiinnnnnddddd", &a)) {
@@ -653,9 +664,9 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
uint64_t i = DecodeBitMasks(a.N, imms, immr);
if(!sf) i&=0xffffffff;
if(sf==0 && a.N==1)
snprintf(buff, sizeof(buff), "invalid AND %s, %s, 0x%lx", Wt[Rd], Wt[Rn], i);
snprintf(buff, sizeof(buff), "invalid AND %s, %s, 0x%"PRIx64, Wt[Rd], Wt[Rn], i);
else
snprintf(buff, sizeof(buff), "AND %s, %s, 0x%lx", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], i);
snprintf(buff, sizeof(buff), "AND %s, %s, 0x%"PRIx64, sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], i);
return buff;
}
if(isMask(opcode, "f0001010hh0mmmmmiiiiiinnnnnddddd", &a)) {
@@ -743,8 +754,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "BFC %s, %d, %d", sf?Xt[Rd]:Wt[Rd], lsb, width);
else
snprintf(buff, sizeof(buff), "BFI %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], lsb, width);
} else
snprintf(buff, sizeof(buff), "BFXIL %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1);
} else {
if(Rn==31 && immr==0)
snprintf(buff, sizeof(buff), "BFC %s, %d, %d", sf?Xt[Rd]:Wt[Rd], immr, imms-immr+1);
else
snprintf(buff, sizeof(buff), "BFXIL %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1);
}
return buff;
}
// ---- BRANCH / TEST
@@ -756,6 +771,13 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "BLR %s", Xt[Rn]);
return buff;
}
if(isMask(opcode, "1101011001011111000000nnnnn00000", &a)) {
if(Rn==30)
snprintf(buff, sizeof(buff), "RET");
else
snprintf(buff, sizeof(buff), "RET %s", Xt[Rn]);
return buff;
}
if(isMask(opcode, "01010100iiiiiiiiiiiiiiiiiii0cccc", &a)) {
int offset = signExtend(imm, 19)<<2;
snprintf(buff, sizeof(buff), "B.%s #+%di\t; %p", conds[cond], offset>>2, (void*)(addr + offset));
@@ -768,27 +790,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
}
if(isMask(opcode, "f0110100iiiiiiiiiiiiiiiiiiittttt", &a)) {
int offset = signExtend(imm, 19)<<2;
snprintf(buff, sizeof(buff), "CBZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset));
snprintf(buff, sizeof(buff), "CBZ %s, #%+di\t; %p", sf?Xt[Rt]:Wt[Rt], offset>>2, (void*)(addr + offset));
return buff;
}
if(isMask(opcode, "f0110101iiiiiiiiiiiiiiiiiiittttt", &a)) {
int offset = signExtend(imm, 19)<<2;
snprintf(buff, sizeof(buff), "CBNZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset));
return buff;
}
if(isMask(opcode, "f0110100iiiiiiiiiiiiiiiiiiittttt", &a)) {
int offset = signExtend(imm, 19)<<2;
snprintf(buff, sizeof(buff), "CBZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset));
snprintf(buff, sizeof(buff), "CBNZ %s, #%+di\t; %p", sf?Xt[Rt]:Wt[Rt], offset>>2, (void*)(addr + offset));
return buff;
}
if(isMask(opcode, "s0110110sssssiiiiiiiiiiiiiittttt", &a)) {
int offset = signExtend(imm, 14)<<2;
snprintf(buff, sizeof(buff), "TBZ %s, 0x%x, #%+di\t; %p", (imms<31)?Xt[Rt]:Wt[Rt], imms, offset>>2, (void*)(addr + offset));
snprintf(buff, sizeof(buff), "TBZ %s, %d, #%+di\t; %p", (imms<31)?Xt[Rt]:Wt[Rt], imms, offset>>2, (void*)(addr + offset));
return buff;
}
if(isMask(opcode, "s0110111sssssiiiiiiiiiiiiiittttt", &a)) {
int offset = signExtend(imm, 14)<<2;
snprintf(buff, sizeof(buff), "TBNZ %s, 0x%x, #%+di\t; %p", (imms<31)?Xt[Rt]:Wt[Rt], imms, offset>>2, (void*)(addr + offset));
snprintf(buff, sizeof(buff), "TBNZ %s, %d, #%+di\t; %p", (imms<31)?Xt[Rt]:Wt[Rt], imms, offset>>2, (void*)(addr + offset));
return buff;
}
@@ -1059,9 +1076,9 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
tmp64u |= 0xffLL<<(i*8);
if(a.Q)
snprintf(buff, sizeof(buff), "MOVI V%d.2D, #0x%016lx", Rd, tmp64u);
snprintf(buff, sizeof(buff), "MOVI V%d.2D, #0x%016"PRIx64, Rd, tmp64u);
else
snprintf(buff, sizeof(buff), "MOVI D%d, #0x%016lx", Rd, tmp64u);
snprintf(buff, sizeof(buff), "MOVI D%d, #0x%016"PRIx64, Rd, tmp64u);
return buff;
}
@@ -1102,7 +1119,7 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
// ADR
if(isMask(opcode, "0ss10000iiiiiiiiiiiiiiiiiiiddddd", &a)) {
snprintf(buff, sizeof(buff), "ADR, %s, %ld", Xt[Rd], signExtend((imm)<<2|(imms), 20));
snprintf(buff, sizeof(buff), "ADR, %s, %"PRId64, Xt[Rd], signExtend((imm)<<2|(imms), 20));
return buff;
}
@@ -1324,6 +1341,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "FCMP %c%d, %c%d", s, Rn, s, Rm);
return buff;
}
//FCMEQ
if(isMask(opcode, "010111100f1mmmmm111001nnnnnddddd", &a)) {
char s = (sf==0)?'S':'D';
snprintf(buff, sizeof(buff), "FCMEQ %c%d, %c%d, %c%d", s, Rd, s, Rn, s, Rm);
return buff;
}
//FCMP vector
if(isMask(opcode, "0QU01110cf1mmmmm111001nnnnnddddd", &a)) {
char s = (sf==0)?'S':((sf==1)?'D':'?');
@@ -1340,18 +1363,18 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "F%s %c%d, %c%d, %c%d", (option==3)?"MINNM":((option==2)?"MAXNM":((!option)?"MAX":"MIN")), s, Rd, s, Rn, s, Rm);
return buff;
}
if(isMask(opcode, "0Q001110of1mmmmm110001nnnnnddddd", &a)) {
if(isMask(opcode, "0QU01110of1mmmmm110001nnnnnddddd", &a)) {
char s = (sf==0)?'S':((sf==1)?'D':'?');
int n = (sf==0)?2:1;
n *= a.Q?2:1;
snprintf(buff, sizeof(buff), "F%sNM%s V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"MIN":"MAX", a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
snprintf(buff, sizeof(buff), "F%sNM%s%s V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"MIN":"MAX", a.U?"P":"", a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
return buff;
}
if(isMask(opcode, "0Q001110of1mmmmm111101nnnnnddddd", &a)) {
if(isMask(opcode, "0QU01110of1mmmmm111101nnnnnddddd", &a)) {
char s = (sf==0)?'S':((sf==1)?'D':'?');
int n = (sf==0)?2:1;
n *= a.Q?2:1;
snprintf(buff, sizeof(buff), "F%s%s V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"MIN":"MAX", a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
snprintf(buff, sizeof(buff), "F%s%s%s V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"MIN":"MAX", a.U?"P":"", a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
return buff;
}
// FMADD
@@ -1565,6 +1588,28 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "%cRHADD V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', Rd, Vd, Rn, Vd, Rm, Vd);
return buff;
}
//S/URSHR
if(isMask(opcode, "0QU011110iiiiiii001001nnnnnddddd", &a)) {
int shft = 0;
int sz = 0;
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
if(imm&0b1000000) {
sz = 3;
shft = imm&0b111111;
} else if(imm&0b100000) {
sz = 2;
shft = imm&0b1111;
} else if(imm&0b10000) {
sz = 1;
shft = imm&0b111;
} else if(imm&0b1000) {
sz = 0;
shft = imm&0b111;
}
const char* Vd = Y[(sz<<1) | a.Q];
snprintf(buff, sizeof(buff), "%cRSHR V%d.%s, V%d.%s, #%d", a.U?'U':'S', Rd, Vd, Rn, Vd, shft);
return buff;
}
//SQ(R)DMULH
if(isMask(opcode, "0QU01110ff1mmmmm101101nnnnnddddd", &a)) {
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "???"};
@@ -1574,12 +1619,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
}
// LD1/ST1 single structure
if(isMask(opcode, "0Q0011010L000000cc0Sffnnnnnttttt", &a)) {
if(isMask(opcode, "0Q0011010Lo00000cc0Sffnnnnnttttt", &a)) {
int scale = a.c;
int idx = 0;
const char* Y[] = {"B", "H", "S", "D"};
switch(scale) {
case 3: scale = sf; /* rep = 1; */ break;
case 3: scale = sf; /* rep = 1; */ idx=(8*(a.Q+1))>>scale; break;
case 0: idx = (a.Q<<3) | (a.S<<2) | sf; break;
case 1: idx = (a.Q<<2) | (a.S<<1) | (sf>>1); break;
case 2: if(!(sf&1))
@@ -1590,7 +1635,10 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
}
break;
}
snprintf(buff, sizeof(buff), "%s1 {V%d.%s}[%d], [%s]", a.L?"LD":"ST", Rt, Y[scale], idx, XtSp[Rn]);
if(!option && a.L && scale==3)
snprintf(buff, sizeof(buff), "LD1R {V%d.%d%s}, [%s]", Rt, idx, Y[scale], XtSp[Rn]);
else
snprintf(buff, sizeof(buff), "%s1 {V%d.%s}[%d], [%s]", a.L?"LD":"ST", Rt, Y[scale], idx, XtSp[Rn]);
return buff;
}
// LDUR/STUR
@@ -1619,6 +1667,17 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "%sR %s%d, [%s, %+d]", a.L?"LD":"ST", Y[sz], Rt, XtSp[Rn], imm);
return buff;
}
// LDP/STP vector
if(isMask(opcode, "ff1011010Liiiiiii22222nnnnnttttt", &a)) {
const char* Y[] = {"S", "D", "Q", "?"};
int sz = sf;
int offset = signExtend(imm, 7)<<(2+sz);
if(!offset)
snprintf(buff, sizeof(buff), "%sP %s%d, %s%d, [%s]", a.L?"LD":"ST", Y[sz], Rt, Y[sz], Rt2, XtSp[Rn]);
else
snprintf(buff, sizeof(buff), "%sP %s%d, %s%d, [%s, %s0x%x]", a.L?"LD":"ST", Y[sz], Rt, Y[sz], Rt2, XtSp[Rn], (offset<0)?"-":"", abs(offset));
return buff;
}
// (S/U)QXT(U)N
if(isMask(opcode, "0Q101110ff100001001010nnnnnddddd", &a)) {
@@ -1637,6 +1696,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "%cQXTN%s V%d.%s, V%d.%s", a.U?'U':'S', a.Q?"2":"", Rd, Vd, Rn, Va);
return buff;
}
if(isMask(opcode, "01U11110ff100001010010nnnnnddddd", &a)) {
const char Z[] = {'B', 'H', 'S', 'D', '?'};
snprintf(buff, sizeof(buff), "SQXT%sN %c%d, %c%d", a.U?"U":"", Z[sf], Rd, Z[sf+1], Rn);
return buff;
}
// (S/U)SSHL(2) / (U/S)XTL(2)
if(isMask(opcode, "0QU011110hhhhiii101001nnnnnddddd", &a)) {
@@ -1667,6 +1731,15 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
return buff;
}
// CNT
if(isMask(opcode, "0Q00111000100000010110nnnnnddddd", &a)) {
const char* Y[] = {"8B", "16B"};
const char* Vd = Y[a.Q];
const char* Va = Y[a.Q];
snprintf(buff, sizeof(buff), "CNT V%d.%s, V%d.%s", Rd, Vd, Rn, Va);
return buff;
}
// DUP
if(isMask(opcode, "0Q001110000iiiii000001nnnnnddddd", &a)) {
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
@@ -1712,15 +1785,47 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "PMULL%s V%d.%s, V%d.%s, V%d.%s", a.Q?"2":"", Rd, Vd, Rn, Vn, Rm, Vn);
return buff;
}
// DMB ISH
if(isMask(opcode, "11010101000000110011nnnn10111111", &a)) {
snprintf(buff, sizeof(buff), "DMB %s", (Rn==0b1011)?"ISH":"???");
// [S/U]MULL
if(isMask(opcode, "0QU01110ff1mmmmm110000nnnnnddddd", &a)) {
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "??"};
const char* Z[] = {"8H", "4S", "2D", "??"};
int sz = sf;
const char* Vn = Y[(sz<<1)|a.Q];
const char* Vd = Z[sz];
snprintf(buff, sizeof(buff), "%cMULL%s V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', a.Q?"2":"", Rd, Vd, Rn, Vn, Rm, Vn);
return buff;
}
// DSB ISH/ISHST
//XTN(2)
if(isMask(opcode, "0Q001110ff100001001010nnnnnddddd", &a)) {
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "??"};
const char* Z[] = {"8H", "4S", "2D", "??"};
int sz = sf;
const char* Vd = Y[(sz<<1)|a.Q];
const char* Vn = Z[sz];
snprintf(buff, sizeof(buff), "XTN%s V%d.%s, V%d.%s", a.Q?"2":"", Rd, Vd, Rn, Vn);
return buff;
}
// DMB
if(isMask(opcode, "11010101000000110011nnnn10111111", &a)) {
const char* barrier[] = {
"???", "???", "???", "???", // 0-3
"???", "???", "???", "???", // 4-7
"???", "ISHLD", "ISHST", "ISH", // 8-11
"???", "LD", "ST", "SY" // 12-15
};
snprintf(buff, sizeof(buff), "DMB %s", barrier[Rn]);
return buff;
}
// DSB
if(isMask(opcode, "11010101000000110011nnnn10011111", &a)) {
snprintf(buff, sizeof(buff), "DSB %s", (Rn==0b1011)?"ISH":((Rn==0b1010)?"ISHST":"???"));
const char* barrier[] = {
"???", "???", "???", "???", // 0-3
"???", "???", "???", "???", // 4-7
"???", "ISHLD", "ISHST", "ISH", // 8-11
"???", "LD", "ST", "SY" // 12-15
};
snprintf(buff, sizeof(buff), "DSB %s", barrier[Rn]);
return buff;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+245 -102
View File
@@ -5,14 +5,12 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
#include "emu/x64run_private.h"
#include "emu/x87emu_private.h"
#include "x64trace.h"
#include "dynarec_native.h"
@@ -436,21 +434,42 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
INST_NAME("IMUL Gw,Ew,Ib");
}
SETFLAGS(X_ALL, SF_PENDING);
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
nextop = F8;
GETSEW(x1, (opcode==0x69)?2:1);
if(opcode==0x69) i32 = F16S; else i32 = F8S;
MOV32w(x2, i32);
MULw(x2, x2, x1);
UFLAG_RES(x2);
gd=x2;
GWBACK;
UFLAG_DF(x1, d_imul16);
SET_DFNONE();
IFX(X_CF|X_OF) {
ASRw(x1, x2, 15);
CMPSw_REG_ASR(x1, x2, 31);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRw(x3, x2, 15);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, x2, x3);
break;
case 0x6A:
INST_NAME("PUSH Ib");
u16 = (uint16_t)F8S;
MOV32w(x2, u16);
i16 = F8S;
MOV32w(x2, (uint16_t)i16);
PUSH1_16(x2);
break;
@@ -643,9 +662,9 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
nextop=F8;
u8 = (nextop&0x38)>>3;
LDRH_U12(x3, xEmu, offsetof(x64emu_t, segs[u8]));
if((nextop&0xC0)==0xC0) { // reg <= seg
if (MODREG) {
BFIz(TO_NAT((nextop & 7) + (rex.b << 3)), x3, 0, 16);
} else { // mem <= seg
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
STH(x3, wback, fixedaddress);
SMWRITE2();
@@ -656,7 +675,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("MOV Seg,Ew");
nextop = F8;
u8 = (nextop&0x38)>>3;
if((nextop&0xC0)==0xC0) {
if (MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
} else {
SMREAD();
@@ -671,7 +690,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("POP Ew");
nextop = F8;
POP1_16(x1);
if((nextop&0xC0)==0xC0) {
if (MODREG) {
wback = TO_NAT((nextop & 7) + (rex.b << 3));
BFIz(wback, x1, 0, 16);
} else {
@@ -718,12 +737,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("POPF");
SETFLAGS(X_ALL, SF_SET);
SMREAD();
POP1_16(x1); // probably not usefull...
POP1_16(x1);
MOV32w(x2, 0x7FD7);
ANDw_REG(x1, x1, x2);
ORRw_mask(x1, x1, 0b011111, 0); //mask=0x00000002
BFIw(xFlags, x1, 0, 16);
MOV32w(x1, 0x3F7FD7);
ANDw_REG(xFlags, xFlags, x1);
ORRw_mask(xFlags, xFlags, 0b011111, 0); //mask=0x00000002
SET_DFNONE(x1);
SET_DFNONE();
if(box64_wine) { // should this be done all the time?
TBZ_NEXT(xFlags, F_TF);
// go to epilog, TF should trigger at end of next opcode, so using Interpreter only
@@ -732,7 +751,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xA1:
INST_NAME("MOV EAX,Od");
INST_NAME("MOV AX,Od");
if(rex.is32bits)
u64 = F32;
else
@@ -745,7 +764,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xA3:
INST_NAME("MOV Od,EAX");
INST_NAME("MOV Od,AX");
if(rex.is32bits)
u64 = F32;
else
@@ -761,17 +780,54 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("REP MOVSB");
CBZx_NEXT(xRCX);
TBNZ_MARK2(xFlags, F_DF);
IF_UNALIGNED(ip) {
MESSAGE(LOG_DEBUG, "\tUnaligned path");
// special optim for large RCX value on forward case only
// but because it's unaligned path, check if a byte per byt is needed, and do 4-bytes per 4-bytes only instead
if(BOX64DRENV(dynarec_safeflags)) {
SUBx_REG(x2, xRDI, xRSI);
CMPSx_U12(x2, 4);
B_MARK(cCC);
}
ORRw_REG(x1, xRSI, xRDI);
ANDw_mask(x1, x1, 0, 1); //mask = 3
CBNZw_MARK(x1);
MARK3;
CMPSx_U12(xRCX, 4);
B_MARK(cCC);
LDRw_S9_postindex(x1, xRSI, 4);
STRw_S9_postindex(x1, xRDI, 4);
SUBx_U12(xRCX, xRCX, 4);
CBNZx_MARK3(xRCX);
CBZx_MARKLOCK(xRCX);
} else {
if(BOX64DRENV(dynarec_safeflags)) {
SUBx_REG(x2, xRDI, xRSI);
CMPSx_U12(x2, 8);
B_MARK(cCC);
}
// special optim for large RCX value on forward case only
MARK3;
CMPSx_U12(xRCX, 8);
B_MARK(cCC);
LDRx_S9_postindex(x1, xRSI, 8);
STRx_S9_postindex(x1, xRDI, 8);
SUBx_U12(xRCX, xRCX, 8);
CBNZx_MARK3(xRCX);
CBZx_MARKLOCK(xRCX);
}
MARK; // Part with DF==0
LDRB_S9_postindex(x1, xRSI, 1);
STRB_S9_postindex(x1, xRDI, 1);
SUBx_U12(xRCX, xRCX, 1);
CBNZx_MARK(xRCX);
B_NEXT_nocond;
B_MARKLOCK_nocond;
MARK2; // Part with DF==1
LDRB_S9_postindex(x1, xRSI, -1);
STRB_S9_postindex(x1, xRDI, -1);
SUBx_U12(xRCX, xRCX, 1);
CBNZx_MARK2(xRCX);
MARKLOCK;
// done
} else {
INST_NAME("MOVSB");
@@ -818,9 +874,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 1:
case 2:
if(rep==1) {INST_NAME("REPNZ CMPSW");} else {INST_NAME("REPZ CMPSW");}
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
SETFLAGS(X_ALL, SF_SET_PENDING);
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_ALL);
SETFLAGS(X_ALL, SF_SET);
} else
SETFLAGS(X_ALL, SF_SET_PENDING);
CBZx_NEXT(xRCX);
TBNZ_MARK2(xFlags, F_DF);
MARK; // Part with DF==0
@@ -918,9 +976,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 1:
case 2:
if(rep==1) {INST_NAME("REPNZ SCASW");} else {INST_NAME("REPZ SCASW");}
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
SETFLAGS(X_ALL, SF_SET_PENDING);
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_ALL);
SETFLAGS(X_ALL, SF_SET);
} else
SETFLAGS(X_ALL, SF_SET_PENDING);
CBZx_NEXT(xRCX);
UXTHw(x1, xRAX);
TBNZ_MARK2(xFlags, F_DF);
@@ -962,9 +1022,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xBF:
INST_NAME("MOV Reg16, Iw");
u16 = F16;
MOV32w(x1, u16);
gd = TO_NAT((opcode & 7) + (rex.b << 3));
BFIz(gd, x1, 0, 16);
if(u16) {
MOV32w(x1, u16);
BFIz(gd, x1, 0, 16);
} else
BFCz(gd, 0, 16);
break;
case 0xC1:
@@ -972,7 +1035,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ew, Ib");
u8 = geted_ib(dyn, addr, ninst, nextop) & 15;
u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
if (u8) {
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 1);
@@ -986,7 +1049,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 1:
INST_NAME("ROR Ew, Ib");
if (geted_ib(dyn, addr, ninst, nextop) & 15) {
if (geted_ib(dyn, addr, ninst, nextop) & 0x1f) {
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 1);
u8 = (F8)&0x1f;
@@ -999,7 +1062,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 2:
INST_NAME("RCL Ew, Ib");
if (geted_ib(dyn, addr, ninst, nextop) & 31) {
if (geted_ib(dyn, addr, ninst, nextop) & 0x1f) {
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 1);
@@ -1013,7 +1076,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 3:
INST_NAME("RCR Ew, Ib");
if (geted_ib(dyn, addr, ninst, nextop) & 31) {
if (geted_ib(dyn, addr, ninst, nextop) & 0x1f) {
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 1);
@@ -1074,13 +1137,20 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
u16 = F16;
MOV32w(x1, u16);
BFIz(ed, x1, 0, 16);
if(u16) {
MOV32w(x1, u16);
BFIz(ed, x1, 0, 16);
} else
BFCz(ed, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, &lock, 0, 2);
u16 = F16;
MOV32w(x1, u16);
STH(x1, ed, fixedaddress);
if(u16) {
MOV32w(x1, u16);
STH(x1, ed, fixedaddress);
} else {
STH(xZR, ed, fixedaddress);
}
SMWRITELOCK(lock);
}
break;
@@ -1148,9 +1218,10 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ew, CL");
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_OF|X_CF);
}
SETFLAGS(X_OF|X_CF, SF_SUBSET);
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
UFLAG_IF {
ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
CBZw_NEXT(x2);
@@ -1159,50 +1230,58 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOV32w(x4, 16);
SUBx_REG(x2, x4, x2);
GETEW(x1, 0);
IFX2(X_OF, && !BOX64ENV(cputype)) {
LSRw(x4, ed, 14);
EORw_REG_LSR(x4, x4, x4, 1);
BFIw(xFlags, x4, F_OF, 1);
}
ORRw_REG_LSL(ed, ed, ed, 16);
LSRw_REG(ed, ed, x2);
EWBACK;
UFLAG_IF { // calculate flags directly
SUBw_U12(x2, x2, 15);
CBNZw_MARK(x2);
EORw_REG_LSR(x3, ed, ed, 15);
BFIw(xFlags, x3, F_OF, 1);
MARK;
IFX2(X_OF, && BOX64ENV(cputype)) {
EORxw_REG_LSR(x3, ed, ed, 15);
BFIw(xFlags, x3, F_OF, 1);
}
IFX(X_CF) {
BFIw(xFlags, ed, F_CF, 1);
UFLAG_DF(x2, d_none);
}
break;
case 1:
INST_NAME("ROR Ew, CL");
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_OF|X_CF);
}
SETFLAGS(X_OF|X_CF, SF_SUBSET);
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
UFLAG_IF {
ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
CBZw_NEXT(x2);
}
ANDw_mask(x2, xRCX, 0, 0b00011); //mask=0x00000000f
GETEW(x1, 0);
IFX2(X_OF, && !BOX64ENV(cputype)) {
EORw_REG_LSR(x4, ed, ed, 15);
BFIw(xFlags, x4, F_OF, 1);
}
ORRw_REG_LSL(ed, ed, ed, 16);
LSRw_REG(ed, ed, x2);
EWBACK;
UFLAG_IF { // calculate flags directly
SUBw_U12(x2, x2, 1);
CBNZw_MARK(x2);
LSRxw(x2, ed, 14); // x2 = d>>14
EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>14) ^ ((d>>14)>>1))
BFIw(xFlags, x2, F_OF, 1);
MARK;
IFX2(X_OF, && BOX64ENV(cputype)) {
LSRxw(x2, ed, 14); // x2 = d>>6
EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>14) ^ ((d>>14)>>1))
BFIw(xFlags, x2, F_OF, 1);
}
IFX(X_CF) {
BFXILw(xFlags, ed, 15, 1);
UFLAG_DF(x2, d_none);
}
break;
case 2:
INST_NAME("RCL Ew, CL");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
MESSAGE(LOG_DUMP, "Need Optimization (RCL Ex, CL)\n");
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_OF|X_CF);
} else {
READFLAGS(X_CF);
}
SETFLAGS(X_OF|X_CF, SF_SET_DF);
ANDw_mask(x2, xRCX, 0, 0b00100);
GETEW(x1, 0);
@@ -1211,10 +1290,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 3:
INST_NAME("RCR Ew, CL");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
MESSAGE(LOG_DUMP, "Need Optimization (RCR Ew, CL)\n");
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_OF|X_CF);
} else {
READFLAGS(X_CF);
}
SETFLAGS(X_OF|X_CF, SF_SET_DF);
ANDw_mask(x2, xRCX, 0, 0b00100);
GETEW(x1, 0);
@@ -1224,9 +1305,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 4:
case 6:
INST_NAME("SHL Ew, CL");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_ALL);
SETFLAGS(X_ALL, SF_SET);
} else
SETFLAGS(X_ALL, SF_SET_PENDING);
ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
UFLAG_IF {
CBZw_NEXT(x2);
@@ -1237,9 +1320,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 5:
INST_NAME("SHR Ew, CL");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_ALL);
SETFLAGS(X_ALL, SF_SET);
} else
SETFLAGS(X_ALL, SF_SET_PENDING);
ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
UFLAG_IF {
CBZw_NEXT(x2);
@@ -1250,9 +1335,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 7:
INST_NAME("SAR Ew, CL");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
if(box64_dynarec_safeflags>1)
MAYSETFLAGS();
if(BOX64DRENV(dynarec_safeflags)>1) {
READFLAGS(X_ALL);
SETFLAGS(X_ALL, SF_SET);
} else
SETFLAGS(X_ALL, SF_SET_PENDING);
ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
UFLAG_IF {
CBZw_NEXT(x2);
@@ -1264,7 +1351,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
}
break;
case 0xD9:
nextop = F8;
if(MODREG) {
@@ -1273,7 +1360,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 6:
INST_NAME("FNSTENV Ed");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FNSTENV16)\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3); // maybe only x87, not SSE?
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
@@ -1293,7 +1380,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 4:
INST_NAME("FRSTOR Ed");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FRSTOR16)\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
@@ -1301,7 +1388,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 6:
INST_NAME("FNSAVE Ed");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FNSAVE16)\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
@@ -1329,9 +1416,15 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 2:
INST_NAME("NOT Ew");
GETEW(x1, 0);
MVNw_REG(ed, ed);
EWBACK;
if(MODREG) {
CALCEW();
int mask = convert_bitmask_x(0xffff);
EORx_mask(wback, wback, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
} else {
GETEW(x1, 0);
MVNw_REG(ed, ed);
EWBACK;
}
break;
case 3:
INST_NAME("NEG Ew");
@@ -1342,25 +1435,66 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 4:
INST_NAME("MUL AX, Ew");
SETFLAGS(X_ALL, SF_PENDING);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETEW(x1, 0);
UXTHw(x2, xRAX);
MULw(x1, x2, x1);
UFLAG_RES(x1);
BFIz(xRAX, x1, 0, 16);
BFXILx(xRDX, x1, 16, 16);
UFLAG_DF(x1, d_mul16);
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSw_REG_LSR(xZR, x1, 16);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, 15);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 5:
INST_NAME("IMUL AX, Ew");
SETFLAGS(X_ALL, SF_PENDING);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETSEW(x1, 0);
SXTHw(x2, xRAX);
MULw(x1, x2, x1);
UFLAG_RES(x1);
BFIz(xRAX, x1, 0, 16);
BFXILx(xRDX, x1, 16, 16);
UFLAG_DF(x1, d_imul16);
SET_DFNONE();
IFX(X_CF|X_OF) {
ASRw(x2, x1, 15);
CMPSw_REG_ASR(x2, x1, 31);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, 15);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 6:
INST_NAME("DIV Ew");
@@ -1368,7 +1502,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
GETEW(x1, 0);
UXTHw(x2, xRAX);
BFIw(x2, xRDX, 16, 16);
if(box64_dynarec_div0) {
if(BOX64ENV(dynarec_div0)) {
CBNZw_MARK3(ed);
GETIP_(ip);
STORE_XEMU_CALL(xRIP);
@@ -1382,19 +1516,27 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed)
BFIz(xRAX, x3, 0, 16);
BFIz(xRDX, x4, 0, 16);
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
SET_DFNONE();
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_CF) {BFCw(xFlags, F_CF, 1);}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);} //mask=0x40
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);} //mask=0x04
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
case 7:
INST_NAME("IDIV Ew");
SKIPTEST(x1);
SETFLAGS(X_ALL, SF_SET);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL, SF_SET);
} else if(BOX64ENV(cputype)) {
SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
}
GETSEW(x1, 0);
if(box64_dynarec_div0) {
if(BOX64ENV(dynarec_div0)) {
CBNZw_MARK3(ed);
GETIP_(ip);
STORE_XEMU_CALL(xRIP);
@@ -1410,25 +1552,26 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed)
BFIz(xRAX, x3, 0, 16);
BFIz(xRDX, x4, 0, 16);
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
if(!BOX64ENV(dynarec_safeflags)) {
SET_DFNONE();
}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && BOX64ENV(cputype)) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
}
break;
case 0xF8:
INST_NAME("CLC");
SETFLAGS(X_CF, SF_SUBSET);
SET_DFNONE(x1);
SET_DFNONE();
BFCx(xFlags, F_CF, 1);
break;
case 0xF9:
INST_NAME("STC");
SETFLAGS(X_CF, SF_SUBSET);
SET_DFNONE(x1);
SET_DFNONE();
ORRx_mask(xFlags, xFlags, 1, 0, 0); // xFlags | 1
break;
File diff suppressed because it is too large. Load diff
+39 -50
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -58,17 +56,16 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 0);
} else {
grab_segdata(dyn, addr, ninst, x4, seg);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
ADDz_REG(x4, x4, ed);
ed = x4;
v1 = fpu_get_scratch(dyn, ninst);
if(rex.is32bits)
VLDR64_REG_SXTW(v1, x4, ed);
else
VLDR64_REG(v1, ed, x4);
VLD64(v1, ed, fixedaddress);
}
FCMPD(v0, v1);
FCOMI(x1, x2, 0, v0, v1, 0); //disable precise cmp
FCOMI(x1, x2);
break;
case 0x6F:
@@ -80,13 +77,11 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
VMOVQ(v0, v1);
} else {
GETGX_empty(v0);
grab_segdata(dyn, addr, ninst, x4, seg);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
SMREAD();
if(rex.is32bits)
VLDR128_REG_SXTW(v0, x4, ed);
else
VLDR128_REG(v0, ed, x4);
ADDz_REG(x4, x4, ed);
VLD128(v0, x4, fixedaddress);
}
break;
@@ -98,12 +93,10 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);
VMOVQ(v1, v0);
} else {
grab_segdata(dyn, addr, ninst, x4, seg);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(rex.is32bits)
VSTR128_REG_SXTW(v0, x4, ed);
else
VSTR128_REG(v0, ed, x4);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
ADDz_REG(x4, x4, ed);
VST128(v0, x4, fixedaddress);
SMWRITE2();
}
break;
@@ -117,12 +110,10 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3));
FMOVD(v1, v0);
} else {
grab_segdata(dyn, addr, ninst, x4, seg);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(rex.is32bits)
VSTR64_REG_SXTW(v0, x4, ed);
else
VSTR64_REG(v0, ed, x4);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
ADDz_REG(x4, x4, ed);
VST64(v0, x4, fixedaddress);
SMWRITE();
}
break;
@@ -138,7 +129,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0: //ADD
if(opcode==0x81) {INST_NAME("ADD Ew, Iw");} else {INST_NAME("ADD Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
grab_segdata(dyn, addr, ninst, x1, seg);
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
@@ -148,7 +139,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 1: //OR
if(opcode==0x81) {INST_NAME("OR Ew, Iw");} else {INST_NAME("OR Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
grab_segdata(dyn, addr, ninst, x1, seg);
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_or16c(dyn, ninst, x1, i16, x2, x4);
@@ -158,7 +149,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
if(opcode==0x81) {INST_NAME("ADC Ew, Iw");} else {INST_NAME("ADC Ew, Ib");}
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
grab_segdata(dyn, addr, ninst, x1, seg);
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
@@ -169,7 +160,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
if(opcode==0x81) {INST_NAME("SBB Ew, Iw");} else {INST_NAME("SBB Ew, Ib");}
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
grab_segdata(dyn, addr, ninst, x1, seg);
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
@@ -179,7 +170,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 4: //AND
if(opcode==0x81) {INST_NAME("AND Ew, Iw");} else {INST_NAME("AND Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
grab_segdata(dyn, addr, ninst, x1, seg);
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_and16c(dyn, ninst, x1, i16, x2, x4);
@@ -188,7 +179,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 5: //SUB
if(opcode==0x81) {INST_NAME("SUB Ew, Iw");} else {INST_NAME("SUB Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
grab_segdata(dyn, addr, ninst, x1, seg);
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
@@ -198,7 +189,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 6: //XOR
if(opcode==0x81) {INST_NAME("XOR Ew, Iw");} else {INST_NAME("XOR Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
grab_segdata(dyn, addr, ninst, x1, seg);
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_xor16c(dyn, ninst, x1, i16, x2, x4);
@@ -207,7 +198,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 7: //CMP
if(opcode==0x81) {INST_NAME("CMP Ew, Iw");} else {INST_NAME("CMP Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
grab_segdata(dyn, addr, ninst, x1, seg);
grab_segdata(dyn, addr, ninst, x1, seg, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
if(i16) {
@@ -233,15 +224,14 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
}
} else {
grab_segdata(dyn, addr, ninst, x4, seg);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(rex.w?3:1), rex.w?7:1, rex, NULL, 0, 0);
ADDz_REG(x4, x4, ed);
ed = x4;
if(rex.w) {
STRx_REG(gd, ed, x4);
STx(gd, ed, fixedaddress);
} else {
if(rex.is32bits)
STRH_REG_SXTW(gd, x4, ed);
else
STRH_REG(gd, ed, x4);
STH(gd, ed, fixedaddress);
}
SMWRITE();
}
@@ -261,16 +251,15 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
}
} else { // mem <= reg
grab_segdata(dyn, addr, ninst, x4, seg);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(rex.w?3:1), rex.w?7:1, rex, NULL, 0, 0);
ADDz_REG(x4, x4, ed);
ed = x4;
if(rex.w) {
LDRx_REG(gd, ed, x4);
LDx(gd, ed, fixedaddress);
} else {
if(rex.is32bits)
LDRH_REG_SXTW(x1, x4, ed);
else
LDRH_REG(x1, ed, x4);
LDH(x1, ed, fixedaddress);
BFIx(gd, x1, 0, 16);
}
}
+30 -19
View File
@@ -5,10 +5,9 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -158,6 +157,8 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
MARK3;
LDRH_U12(x1, wback, 0);
LDAXRB(x3, wback); // dummy read, to arm the write...
SUBw_UXTB(x3, x3, x1);
CBNZw_MARK3(x3);
CMPSw_REG(x6, x1);
B_MARK(cNE);
// EAX == Ed
@@ -166,8 +167,8 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
STRH_U12(gd, wback, 0);
}
}
SMDMB();
MARK;
SMDMB();
// Common part (and fallback for EAX != Ed)
UFLAG_IF {emit_cmp16(dyn, ninst, x6, x1, x3, x4, x5);}
BFIx(xRAX, x1, 0, 16);
@@ -295,30 +296,36 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
}
if(arm64_atomics) {
LDADDALH(x5, x1, wback);
UFLAG_IF {
emit_add16(dyn, ninst, x1, x5, x3, x4);
LDADDALH(x5, x1, wback);
} else {
STADDLH(x5, wback);
}
} else {
MARKLOCK;
LDAXRH(x1, wback);
emit_add16(dyn, ninst, x1, x5, x3, x4);
STLXRH(x3, x1, wback);
ADDw_REG(x4, x1, x5);
STLXRH(x3, x4, wback);
CBNZx_MARKLOCK(x3);
}
SMDMB();
if(!ALIGNED_ATOMICH) {
B_NEXT_nocond;
B_MARK2_nocond;
MARK; // unaligned! also, not enough
LDRH_U12(x1, wback, 0);
LDAXRB(x4, wback);
BFIw(x1, x4, 0, 8); // re-inject
emit_add16(dyn, ninst, x1, x5, x3, x4);
STLXRB(x3, x1, wback);
SUBw_UXTB(x4, x4, x1);
CBNZw_MARK(x4);
ADDw_REG(x4, x1, x5);
STLXRB(x3, x4, wback);
CBNZx_MARK(x3);
STRH_U12(x1, wback, 0); // put the whole value
STRH_U12(x4, wback, 0); // put the whole value
SMDMB();
}
MARK2;
UFLAG_IF {
emit_add16(dyn, ninst, x1, x5, x3, x4);
}
}
break;
case 1: //OR
@@ -472,30 +479,34 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
NEGw_REG(x4, x5);
UFLAG_IF {
LDADDALH(x4, x1, wback);
emit_sub16(dyn, ninst, x1, x5, x3, x4);
} else {
STADDLH(x4, wback);
}
} else {
MARKLOCK;
LDAXRH(x1, wback);
emit_sub16(dyn, ninst, x1, x5, x3, x4);
SUBw_REG(x4, x1, x5);
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
SMDMB();
if(!ALIGNED_ATOMICH) {
B_NEXT_nocond;
B_MARK2_nocond;
MARK; // unaligned! also, not enough
LDRH_U12(x1, wback, 0);
LDAXRB(x4, wback);
BFIw(x1, x4, 0, 8); // re-inject
emit_sub16(dyn, ninst, x1, x5, x3, x4);
STLXRB(x3, x1, wback);
SUBw_UXTB(x4, x4, x1);
CBNZw_MARK(x4);
SUBw_REG(x4, x1, x5);
STLXRB(x3, x4, wback);
CBNZx_MARK(x3);
STRH_U12(x1, wback, 0); // put the whole value
STRH_U12(x4, wback, 0); // put the whole value
SMDMB();
}
MARK2;
UFLAG_IF {
emit_sub16(dyn, ninst, x1, x5, x3, x4);
}
}
break;
case 6: //XOR
+1 -3
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
+86 -7
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -55,11 +53,86 @@ uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
#endif
switch(opcode) {
case 0xB8:
INST_NAME("POPCNT Gw, Ew");
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE();
nextop = F8;
GETGW(x2);
GETEW(x1, 0);
v1 = fpu_get_scratch(dyn, ninst);
VEORQ(v1, v1, v1);
VMOVQDfrom(v1, 0, ed);
CNT_8(v1, v1);
UADDLV_8(v1, v1);
VMOVHto(gd, v1, 0);
IFX(X_ALL) {
IFX(X_AF|X_PF|X_SF|X_OF|X_CF) {
MOV32w(x1, (1<<F_OF) | (1<<F_SF) | (1<<F_ZF) | (1<<F_AF) | (1<<F_CF) | (1<<F_PF));
BICw(xFlags, xFlags, x1);
}
IFX(X_ZF) {
CMPSw_U12(gd, 0);
IFNATIVE(NF_EQ) {}
else {
CSETw(x1, cEQ);
BFIw(xFlags, x1, F_ZF, 1);
}
}
}
GWBACK;
break;
case 0xBC:
INST_NAME("TZCNT Gw, Ew");
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
} else {
if(BOX64ENV(cputype)) {
SETFLAGS(X_ALL&~X_OF, SF_SUBSET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
}
SET_DFNONE();
nextop = F8;
GETEW(x1, 0);
GETGW(x2);
TSTxw_REG(ed, ed);
IFX(X_CF) {
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
}
RBITw(x3, ed); // reverse
CLZw(gd, x3); // x2 gets leading 0 == TZCNT
MOV32w(x3, 16);
CSELw(gd, x3, gd, cEQ); // if src is zero, use bit width as res
IFX(X_ZF) {
TSTxw_REG(gd, gd);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0?
}
if(BOX64ENV(dynarec_safeflags)) {
IFX(X_AF) BFCw(xFlags, F_AF, 1);
IFX(X_PF) BFCw(xFlags, F_PF, 1);
IFX(X_SF) BFCw(xFlags, F_SF, 1);
IFX2(X_OF, && !BOX64ENV(cputype)) BFCw(xFlags, F_OF, 1);
}
GWBACK;
break;
case 0xBD:
INST_NAME("LZCNT Gw, Ew");
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
SET_DFNONE(x1);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
} else {
if(BOX64ENV(cputype)) {
SETFLAGS(X_ALL&~X_OF, SF_SUBSET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
}
SET_DFNONE();
nextop = F8;
GETEW(x1, 0);
GETGW(x2);
@@ -68,14 +141,20 @@ uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
}
LSLw_IMM(ed, ed, 16);
CLZw(gd, ed);
SUBw_U12(gd, gd, 16); // sub zero cnt of high word
IFX(X_ZF) {
TSTxw_REG(gd, gd);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0?
}
EWBACK;
if(BOX64ENV(dynarec_safeflags)) {
IFX(X_AF) BFCw(xFlags, F_AF, 1);
IFX(X_PF) BFCw(xFlags, F_PF, 1);
IFX(X_SF) BFCw(xFlags, F_SF, 1);
IFX2(X_OF, && !BOX64ENV(cputype)) BFCw(xFlags, F_OF, 1);
}
GWBACK;
break;
default:
+162 -65
View File
@@ -5,16 +5,15 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
#include "emu/x64run_private.h"
#include "x64trace.h"
#include "dynarec_native.h"
#include "../dynablock_private.h"
#include "custommem.h"
#include "arm64_printer.h"
@@ -30,7 +29,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
uint8_t opcode = F8;
uint8_t nextop;
uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2, eb1, eb2;
uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2, eb1, eb2, q0, q1;
int64_t fixedaddress;
int unscaled;
int8_t i8;
@@ -38,6 +37,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
int32_t i32;
int64_t j64, i64;
int16_t i16;
uint64_t u64;
int cacheupd = 0;
int lock;
int v0, v1, s0;
@@ -57,7 +57,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
while(opcode==0x67) opcode = F8;
// reset rex after 67
GETREX();
@@ -197,6 +197,22 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0x29:
INST_NAME("MOVAPS Ex,Gx");
nextop = F8;
GETG;
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
if(MODREG) {
ed = (nextop&7)+(rex.b<<3);
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
VMOVQ(v1, v0);
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VST128(v0, ed, fixedaddress);
SMWRITE2();
}
break;
case 0x2E:
// no special check...
case 0x2F:
@@ -215,7 +231,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VLD32(s0, ed, fixedaddress);
}
FCMPS(v0, s0);
FCOMI(x1, x2, 0, v0, s0, 1); //disabled precise cmp
FCOMI(x1, x2);
break;
default:
DEFAULT;
@@ -747,6 +763,20 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0x76:
INST_NAME("PCMPEQD Gx,Ex");
nextop = F8;
GETGX(v0, 1);
if(MODREG) {
q0 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
} else {
q0 = fpu_get_scratch(dyn, ninst);
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VLD128(q0, ed, fixedaddress);
}
VCMEQQ_32(v0, v0, q0);
break;
case 0x7E:
INST_NAME("MOVD Ed,Gx");
nextop = F8;
@@ -786,6 +816,27 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0xEF:
INST_NAME("PXOR Gx,Ex");
nextop = F8;
GETG;
if(MODREG && ((nextop&7)+(rex.b<<3)==gd)) {
// special case for PXOR Gx, Gx
q0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VEORQ(q0, q0, q0);
} else {
q0 = sse_get_reg(dyn, ninst, x1, gd, 1);
if(MODREG) {
q1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
} else {
q1 = fpu_get_scratch(dyn, ninst);
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VLD128(q1, ed, fixedaddress);
}
VEORQ(q0, q0, q1);
}
break;
case 0xFE:
INST_NAME("PADDD Gx,Ex");
nextop = F8;
@@ -916,7 +967,11 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x6B:
INST_NAME("IMUL Gd, Ed, Ib");
SETFLAGS(X_ALL, SF_PENDING);
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
nextop = F8;
GETGD;
GETED32(1);
@@ -927,14 +982,9 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UFLAG_IF {
SMULH(x3, ed, x4);
MULx(gd, ed, x4);
SET_DFNONE(x1);
IFX(X_ZF | X_PF | X_AF | X_SF) {
MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
BICw(xFlags, xFlags, x1);
}
SET_DFNONE();
IFX(X_CF | X_OF) {
ASRx(x4, gd, 63);
CMPSx_REG(x3, x4);
CMPSx_REG_ASR(x3, gd, 63);
CSETw(x1, cNE);
IFX(X_CF) {
BFIw(xFlags, x1, F_CF, 1);
@@ -952,14 +1002,9 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SMULL(gd, ed, x4);
LSRx(x3, gd, 32);
MOVw_REG(gd, gd);
SET_DFNONE(x1);
IFX(X_ZF | X_PF | X_AF | X_SF) {
MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
BICw(xFlags, xFlags, x1);
}
SET_DFNONE();
IFX(X_CF | X_OF) {
ASRw(x4, gd, 31);
CMPSw_REG(x3, x4);
CMPSw_REG_ASR(x3, gd, 31);
CSETw(x1, cNE);
IFX(X_CF) {
BFIw(xFlags, x1, F_CF, 1);
@@ -972,6 +1017,13 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MULxw(gd, ed, x4);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, gd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, gd, x3);
break;
case 0x70:
@@ -1171,9 +1223,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
DEFAULT;
} else { // mem <= reg
addr = geted32(dyn, addr, ninst, nextop, &ed, gd, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=gd) {
MOVw_REG(gd, ed);
}
MOVw_REG(gd, ed); // need to trucate to 32bits as it's 67 prefixed
}
break;
@@ -1196,6 +1246,15 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0xA1:
INST_NAME("MOV EAX,Od");
u64 = F32;
MOV64z(x1, u64);
lock=isLockAddress(u64);
SMREADLOCK(lock);
LDRxw_U12(xRAX, x1, 0);
break;
case 0xA9:
INST_NAME("TEST EAX, Id");
SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -1457,7 +1516,11 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 4:
INST_NAME("MUL EAX, Ed");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETED32(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -1469,29 +1532,32 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVw_REG(xRAX, xRDX);
LSRx(xRDX, xRDX, 32);
}
UFLAG_IF {
SET_DFNONE(x4);
IFX(X_CF|X_OF) {
CMPSxw_U12(xRDX, 0);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSxw_U12(xRDX, 0);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
IFX(X_AF | X_PF | X_ZF | X_SF)
if(box64_dynarec_test) {
// to avoid noise during test
MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
BICw(xFlags, xFlags, x3);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 5:
INST_NAME("IMUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETED32(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -1503,9 +1569,24 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVw_REG(xRAX, xRDX);
LSRx(xRDX, xRDX, 32);
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
UFLAG_DF(x2, rex.w?d_imul64:d_imul32);
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 6:
INST_NAME("DIV Ed");
@@ -1543,17 +1624,25 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
SET_DFNONE();
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_CF) {BFCw(xFlags, F_CF, 1);}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);} //mask=0x40
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);} //mask=0x04
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
case 7:
INST_NAME("IDIV Ed");
NOTEST(x1);
SETFLAGS(X_ALL, SF_SET);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL, SF_SET);
} else if(BOX64ENV(cputype)) {
SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
}
if(!rex.w) {
GETSED32w(0);
MOVw_REG(x3, xRAX);
@@ -1585,12 +1674,13 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
if(!BOX64ENV(dynarec_safeflags)) {
SET_DFNONE();
}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && BOX64ENV(cputype)) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
}
break;
@@ -1613,7 +1703,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 2: // CALL Ed
INST_NAME("CALL Ed");
PASS2IF((box64_dynarec_safeflags>1) ||
PASS2IF((BOX64DRENV(dynarec_safeflags)>1) ||
((ninst && dyn->insts[ninst-1].x64.set_flags)
|| ((ninst>1) && dyn->insts[ninst-2].x64.set_flags)), 1)
{
@@ -1622,7 +1712,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_NODF); //Hack to put flag in "don't care" state
}
GETED32(0);
if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
if(BOX64DRENV(dynarec_callret) && BOX64DRENV(dynarec_bigblock)>1) {
BARRIER(BARRIER_FULL);
} else {
BARRIER(BARRIER_FLOAT);
@@ -1630,16 +1720,22 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
*ok = 0;
}
GETIP_(addr);
if(box64_dynarec_callret) {
if(BOX64DRENV(dynarec_callret)) {
SET_HASCALLRET();
// Push actual return address
if(addr < (dyn->start+dyn->isize)) {
// there is a next...
j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0;
if(BOX64DRENV(dynarec_callret)>1)
j64 = CALLRET_GETRET();
else
j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0;
ADR_S20(x4, j64);
MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2);
} else {
j64 = (dyn->insts)?(GETMARK-(dyn->native_size)):0;
if(BOX64DRENV(dynarec_callret)>1)
j64 = CALLRET_GETRET();
else
j64 = (dyn->insts)?(GETMARK-(dyn->native_size)):0;
ADR_S20(x4, j64);
MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2);
}
@@ -1647,7 +1743,8 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
PUSH1z(xRIP);
jump_to_next(dyn, 0, ed, ninst, rex.is32bits);
if(box64_dynarec_callret && addr >= (dyn->start + dyn->isize)) {
if(BOX64DRENV(dynarec_callret)>1) CALLRET_RET();
if(BOX64DRENV(dynarec_callret) && addr >= (dyn->start + dyn->isize)) {
// jumps out of current dynablock...
MARK;
j64 = getJumpTableAddress64(addr);
+21 -19
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -68,9 +66,10 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
if(MODREG) { // reg <= reg
MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), gd);
} else { // mem <= reg
grab_segdata(dyn, addr, ninst, x4, seg);
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, 0);
STRw_REG(gd, ed, x4);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
ADDz_REG(x4, x4, ed);
STz(gd, x4, fixedaddress);
}
break;
@@ -81,9 +80,10 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
if(MODREG) { // reg => reg
MOVxw_REG(gd, TO_NAT((nextop & 7) + (rex.b << 3)));
} else { // mem => reg
grab_segdata(dyn, addr, ninst, x4, seg);
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, 0);
LDRw_REG(gd, ed, x4);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
ADDz_REG(x4, x4, ed);
LDz(gd, x4, fixedaddress);
}
break;
@@ -94,17 +94,18 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
POP1_32(x1);
MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), x1);
} else { // mem <= reg
grab_segdata(dyn, addr, ninst, x4, seg);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
POP1_32(x1);
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, 0);
STRw_REG(x1, ed, x4);
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
ADDz_REG(x4, x4, ed);
STz(x1, x4, fixedaddress);
}
break;
case 0xA1:
INST_NAME("MOV EAX, Seg:[Od]");
i32 = F16;
grab_segdata(dyn, addr, ninst, x4, seg);
grab_segdata(dyn, addr, ninst, x4, seg, 0);
if(i32<4096 && !(i32&3)) {
LDRw_U12(xRAX, x4, i32);
} else if(i32<256) {
@@ -118,7 +119,7 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
case 0xA3:
INST_NAME("MOV Seg:[Od], EAX");
i32 = F16;
grab_segdata(dyn, addr, ninst, x4, seg);
grab_segdata(dyn, addr, ninst, x4, seg, 0);
if(i32<4096 && !(i32&3)) {
STRw_U12(xRAX, x4, i32);
} else if(i32<256) {
@@ -131,16 +132,17 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
case 0xFF:
nextop = F8;
grab_segdata(dyn, addr, ninst, x4, seg);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
switch((nextop>>3)&7) {
case 6: // Push Ed
INST_NAME("PUSH FS:Ew");
if((nextop&0xC0)==0xC0) { // reg
if (MODREG) {
DEFAULT;
} else { // mem <= i32
} else {
SMREAD();
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0, 0, 0);
LDRw_REG(x3, ed, x4);
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
ADDz_REG(x4, x4, ed);
LDW(x3, x4, fixedaddress);
PUSH1_32(x3);
}
break;
+26 -3
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -61,6 +59,31 @@ uintptr_t dynarec64_67_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
switch(opcode) {
case 0x0F:
opcode=F8;
switch(opcode) {
case 0x29:
INST_NAME("MOVAPS Ex,Gx");
nextop = F8;
GETG;
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
if(MODREG) {
ed = (nextop&7)+(rex.b<<3);
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
VMOVQ(v1, v0);
} else {
addr = geted16(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, 0);
VST128(v0, ed, fixedaddress);
SMWRITE2();
}
break;
default:
DEFAULT;
}
break;
case 64:
addr = dynarec64_6764_32(dyn, addr, ip, ninst, rex, rep, _FS, ok, need_epilog);
break;
+35 -14
View File
@@ -5,10 +5,9 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -85,15 +84,21 @@ uintptr_t dynarec64_67_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGD;
GETED32(0);
GETVD;
if(rex.w) {
// 64bits mul
UMULH(x3, xRDX, ed);
MULx(vd, xRDX, ed);
MOVx_REG(gd, x3);
if(rex.w) {
// 64bits mul
if((gd==xRDX) || (gd==ed) || (gd==vd))
gb1 = x3;
else
gb1 = gd;
UMULH(gb1, xRDX, ed);
if(gd!=vd) {MULx(vd, xRDX, ed);}
if(gb1==x3) {
MOVx_REG(gd, gb1);
}
} else {
// 32bits mul
UMULL(x3, xRDX, ed);
MOVw_REG(vd, x3);
if(gd!=vd) {MOVw_REG(vd, x3);}
LSRx(gd, x3, 32);
}
break;
@@ -111,23 +116,39 @@ uintptr_t dynarec64_67_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
GETG;
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
if(MODREG) {
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7)+(rex.b<<3));
ed = (nextop&7)+(rex.b<<3);
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
VMOV(v1, v0);
YMM0((nextop&7)+(rex.b<<3));
YMM0(ed);
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xfff<<3, 7, rex, NULL, 0, 0);
VSTR64_U12(v0, ed, fixedaddress);
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v0, ed, fixedaddress);
}
break;
case 0x6E:
INST_NAME("VMOVD Gx, Ed");
nextop = F8;
GETGX_empty(v0);
GETED(0);
VEORQ(v0, v0, v0); // RAZ vector
if(rex.w) {
FMOVDx(v0, ed);
} else {
FMOVSw(v0, ed);
}
YMM0(gd);
break;
default:
DEFAULT;
}
}
else {DEFAULT;}
if((*ok==-1) && (box64_dynarec_log>=LOG_INFO || box64_dynarec_dump || box64_dynarec_missing==1)) {
dynarec_log(LOG_NONE, "Dynarec unimplemented AVX opcode size %d prefix %s map %s opcode %02X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
if((*ok==-1) && (BOX64ENV(dynarec_log)>=LOG_INFO || dyn->need_dump || BOX64ENV(dynarec_missing)==1))
if(!dyn->size || BOX64ENV(dynarec_log)>LOG_INFO || dyn->need_dump) {
dynarec_log(LOG_NONE, " Dynarec unimplemented VEX opcode size %d prefix %s map %s opcode %02X\n", 128 << vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
}
return addr;
}
+415
View File
@@ -0,0 +1,415 @@
#include <stddef.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include "debug.h"
#include "dynablock.h"
#include "x64emu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "dynarec/dynablock_private.h"
#include "dynarec_arm64_arch.h"
#include "dynarec_arm64_functions.h"
#include "dynarec_native.h"
//order might be important, so define SUPER for the right one
#define SUPER() \
GO(flags) \
GO(x87) \
GO(mmx) \
GO(sse) \
GO(ymm) \
typedef struct arch_flags_s
{
uint8_t defered:1;
uint8_t nf:1;
uint8_t eq:1;
uint8_t vf:1;
uint8_t cf:1;
uint8_t inv_cf:1;
} arch_flags_t;
#define X87_ST_D 0
#define X87_ST_F 1
#define X87_ST_I64 2
typedef struct arch_x87_s
{
int8_t delta; //up to +/-7
uint8_t x87; // 1bit is STx present
uint16_t x87_type; // 2bits per STx type
uint32_t x87_pos; //4bits per STx position (well, 3 would be enough)
} arch_x87_t;
typedef struct arch_mmx_s
{
uint8_t mmx; //1bit for each mmx reg present
} arch_mmx_t;
typedef struct arch_sse_s
{
uint16_t sse; //1bit for each sse reg present
} arch_sse_t;
typedef struct arch_ymm_s
{
uint16_t ymm0; // 1bit for ymm0
uint16_t ymm; // 1bit for each ymm present
uint64_t ymm_pos; // 4bits for position of each ymm present
} arch_ymm_t;
typedef struct arch_arch_s
{
#define GO(A) uint16_t A:1;
SUPER()
#undef GO
uint16_t unaligned:1;
uint16_t seq:10; // how many instruction on the same values
} arch_arch_t;
typedef struct arch_build_s
{
#define GO(A) uint8_t A:1;
SUPER()
#undef GO
uint8_t unaligned;
#define GO(A) arch_##A##_t A##_;
SUPER()
#undef GO
} arch_build_t;
static arch_build_t static_build[MAX_INSTS+2] = {0};
static int arch_build(dynarec_arm_t* dyn, int ninst, arch_build_t* arch)
{
memset(arch, 0, sizeof(arch_build_t));
// flags
if((dyn->insts[ninst].f_entry.dfnone==0) || dyn->insts[ninst].need_nat_flags || dyn->insts[ninst].before_nat_flags) {
arch->flags = 1;
arch->flags_.defered = dyn->insts[ninst].f_entry.dfnone==0;
uint8_t flags = dyn->insts[ninst].need_nat_flags | dyn->insts[ninst].before_nat_flags;
arch->flags_.vf = flags&NF_VF;
arch->flags_.nf = flags&NF_SF;
arch->flags_.eq = flags&NF_EQ;
arch->flags_.cf = flags&NF_CF;
if(arch->flags_.cf)
arch->flags_.inv_cf = !dyn->insts[ninst].normal_carry;
}
// got through all naoncache to gather regs assignments
int idx;
for(int i=0; i<32; ++i)
if(dyn->insts[ninst].n.neoncache[i].v!=-1)
switch(dyn->insts[ninst].n.neoncache[i].t) {
case NEON_CACHE_XMMW:
arch->sse = 1;
arch->sse_.sse |= 1<<dyn->insts[ninst].n.neoncache[i].n;
break;
case NEON_CACHE_MM:
arch->mmx = 1;
arch->mmx_.mmx |= 1<<dyn->insts[ninst].n.neoncache[i].n;
break;
case NEON_CACHE_YMMW:
arch->ymm = 1;
arch->ymm_.ymm |= 1<<dyn->insts[ninst].n.neoncache[i].n;
idx = i;
if(idx>=EMM0 && idx<=EMM0+8)
idx-=EMM0;
else
idx-=SCRATCH0-8;
arch->ymm_.ymm_pos |= idx<<(dyn->insts[ninst].n.neoncache[i].n*4);
break;
case NEON_CACHE_ST_D:
arch->x87 = 1;
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
arch->x87_.x87_type = (X87_ST_D)<<(dyn->insts[ninst].n.neoncache[i].n*2);
break;
case NEON_CACHE_ST_F:
arch->x87 = 1;
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
arch->x87_.x87_type = (X87_ST_F)<<(dyn->insts[ninst].n.neoncache[i].n*2);
break;
case NEON_CACHE_ST_I64:
arch->x87 = 1;
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
arch->x87_.x87_type = (X87_ST_I64)<<(dyn->insts[ninst].n.neoncache[i].n*2);
break;
case NEON_CACHE_XMMR:
case NEON_CACHE_YMMR:
default:
// doing nothing, it's just a value read in memory
break;
}
// ymm0
if(dyn->insts[ninst].ymm0_out) {
arch->ymm = 1;
arch->ymm_.ymm0 = dyn->insts[ninst].ymm0_out;
}
// x87 top
if(dyn->insts[ninst].n.x87stack) {
arch->x87 = 1;
arch->x87_.delta = dyn->insts[ninst].n.x87stack;
}
// opcode can handle unaligned
arch->unaligned = dyn->insts[ninst].unaligned;
return arch->flags + arch->x87 + arch->mmx + arch->sse + arch->ymm + arch->unaligned;
}
static int sizeof_arch(arch_arch_t* arch)
{
int sz = sizeof(arch_arch_t);
#define GO(A) if(arch->A) sz+=sizeof(arch_##A##_t);
SUPER()
#undef GO
return sz;
}
static int sizeof_arch_build(arch_build_t* build)
{
int sz = sizeof(arch_arch_t);
#define GO(A) if(build->A) sz+=sizeof(arch_##A##_t);
SUPER()
#undef GO
return sz;
}
size_t get_size_arch(dynarec_arm_t* dyn)
{
arch_build_t* previous = NULL;
size_t sz = 0;
int seq = 0;
int nseq = 0;
int last = 0;
if(!dyn->size) return 0;
for(int i=0; i<dyn->size; ++i) {
arch_build_t* build = static_build+i;
last = arch_build(dyn, i, build);
if(i && (!memcmp(build, previous, sizeof(arch_build_t))) && (seq<((1<<10)-1))) {
// same sequence, increment
++seq;
} else {
seq = 0;
++nseq;
previous = build;
sz += sizeof_arch_build(build);
}
}
if(nseq==1 && !last)
return 0; //empty, no flags, no nothing
return sz;
}
static void build_next(arch_arch_t* arch, arch_build_t* build)
{
#define GO(A) arch->A = build->A;
SUPER()
#undef GO
arch->unaligned = build->unaligned;
arch->seq = 0;
void* p = ((void*)arch)+sizeof(arch_arch_t);
#define GO(A) \
if(build->A) { \
memcpy(p, &(build->A##_), sizeof(arch_ ##A##_t)); \
p+=sizeof(arch_##A##_t); \
}
SUPER()
#undef GO
}
void* populate_arch(dynarec_arm_t* dyn, void* p, size_t tot_sz)
{
arch_build_t* previous = NULL;
arch_arch_t* arch = p;
arch_arch_t* next = p;
int seq = 0;
size_t total = 0;
if(!tot_sz) return NULL;
for(int i=0; i<dyn->size; ++i) {
arch_build_t* build = static_build+i;
if(i && (!memcmp(build, previous, sizeof(arch_build_t))) && (seq<((1<<10)-1))) {
// same sequence, increment
arch->seq = ++seq;
} else {
int sz = sizeof_arch_build(build);
if(total+sz>tot_sz) {
printf_log(LOG_INFO, "Warning: populate_arch on undersized buffer (%d+%d/%d, inst %d/%d)\n", total, sz, tot_sz, i, dyn->size);
return NULL;
}
arch = next;
build_next(arch, build);
seq = 0;
previous = build;
total += sz;
next = (arch_arch_t*)((uintptr_t)arch+sz);
}
}
return p;
}
// NZCV N
#define NZCV_N 31
// NZCV Z
#define NZCV_Z 30
// NZCV C
#define NZCV_C 29
// NZCV V
#define NZCV_V 28
#ifndef _WIN32 // TODO: Implemented this for Win32
void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t x64pc)
{
if(!db->arch_size || !db->arch)
return;
int ninst = getX64AddressInst(db, x64pc);
dynarec_log(LOG_INFO, "adjust_arch(...), db=%p, x64pc=%p, nints=%d", db, (void*)x64pc, ninst);
if(ninst<0) {
dynarec_log_prefix(0, LOG_INFO, "\n");
return;
}
if(ninst==0) {
dynarec_log_prefix(0, LOG_INFO, "\n");
CHECK_FLAGS(emu);
return;
}
// look for state at ninst-1
arch_arch_t* arch = db->arch;
arch_arch_t* next = arch;
#define GO(A) arch_##A##_t* A = NULL;
SUPER()
#undef GO
int i = 0;
while(i<ninst-1) {
arch = next;
i += 1+arch->seq;
dynarec_log_prefix(0, (i<ninst-1)?LOG_DEBUG:LOG_INFO, "[ seq=%d%s%s%s%s%s ] ", arch->seq, arch->flags?" Flags":"", arch->x87?" x87":"", arch->mmx?" MMX":"", arch->sse?" SSE":"", arch->ymm?" YMM":"");
next = (arch_arch_t*)((uintptr_t)next + sizeof_arch(arch));
}
int sz = sizeof(arch_arch_t);
#define GO(A) \
if(arch->A) { \
A = (arch_##A##_t*)((uintptr_t)arch + sz); \
sz+=sizeof(arch_##A##_t); \
}
SUPER()
#undef GO
if(flags) {
dynarec_log_prefix(0, LOG_INFO, " flags[%s-%s%s%s%s] ", flags->defered?"defered":"", flags->nf?"S":"", flags->vf?"O":"", flags->eq?"Z":"", flags->cf?(flags->inv_cf?"C(inv)":"C"):"");
if(flags->defered) {
CHECK_FLAGS(emu);
//return;
}
if(flags->nf) {
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_N), F_SF);
}
if(flags->vf) {
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_V), F_OF);
}
if(flags->eq) {
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_Z), F_ZF);
}
if(flags->cf) {
if(flags->inv_cf) {
CONDITIONAL_SET_FLAG((p->uc_mcontext.pstate&(1<<NZCV_C))==0, F_CF);
} else {
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_C), F_CF);
}
}
}
struct fpsimd_context *fpsimd = NULL;
// find fpsimd struct
{
struct _aarch64_ctx * ff = (struct _aarch64_ctx*)p->uc_mcontext.__reserved;
while (ff->magic && !fpsimd) {
if(ff->magic==FPSIMD_MAGIC)
fpsimd = (struct fpsimd_context*)ff;
else
ff = (struct _aarch64_ctx*)((uintptr_t)ff + ff->size);
}
}
if(sse) {
dynarec_log_prefix(0, LOG_INFO, " sse[%x (fpsimd=%p)] ", sse->sse, fpsimd);
for(int i=0; i<16; ++i)
if(fpsimd && (sse->sse>>i)&1) {
int idx = 0;
if(i>7) {
idx = XMM8 + i - 8;
} else {
idx = XMM0 + i;
}
emu->xmm[i].u128 = fpsimd->vregs[idx];
}
}
if(ymm) {
dynarec_log_prefix(0, LOG_INFO, " ymm[%x, pos=%x, 0=%x (fpsimd=%p)] ", ymm->ymm, ymm->ymm_pos, ymm->ymm0, fpsimd);
for(int i=0; i<16; ++i) {
if(fpsimd && (ymm->ymm>>i)&1) {
int idx = (ymm->ymm_pos>>(i*4))&0xf;
if(i>7) {
idx = SCRATCH0 + i - 8;
} else {
idx = EMM0 + i;
}
emu->ymm[i].u128 = fpsimd->vregs[idx];
}
if(ymm->ymm0&(1<<i))
emu->ymm[i].u128 = 0;
}
}
if(mmx) {
dynarec_log_prefix(0, LOG_INFO, " mmx[%x (fpsimd=%p)] ", mmx->mmx, fpsimd);
for(int i=0; i<8; ++i)
if(fpsimd && (mmx->mmx>>i)&1) {
int idx = EMM0 + i;
emu->mmx[i].q = fpsimd->vregs[idx]&0xffffffffffffffffLL;
}
}
if(x87) {
dynarec_log_prefix(0, LOG_INFO, " x87[%x, pos=%x, type=%x (fpsimd=%p)] ", x87->x87, x87->x87_pos, x87->x87_type, fpsimd);
emu->top -= x87->delta;
for(int i=0; i<8; ++i) {
if(x87->x87&(1<<i)) {
int idx = EMM0 + (x87->x87_pos>>(i*4))&0x0f;
int t = (x87->x87_type>>(i*2))&0x3;
switch (t) {
case X87_ST_F:
emu->x87[(emu->top+i)&7].d = *(float*)&fpsimd->vregs[idx];
break;
case X87_ST_I64:
emu->x87[(emu->top+i)&7].d = *(int64_t*)&fpsimd->vregs[idx];
break;
case X87_ST_D:
emu->x87[(emu->top+i)&7].d = *(double*)&fpsimd->vregs[idx];
break;
}
}
}
}
dynarec_log_prefix(0, LOG_INFO, "\n");
}
#endif
int arch_unaligned(dynablock_t* db, uintptr_t x64pc)
{
if(!db)
return 0;
if(!db->arch_size || !db->arch)
return 0;
int ninst = getX64AddressInst(db, x64pc);
if(ninst<0) {
return 0;
}
// look for state at ninst
arch_arch_t* arch = db->arch;
arch_arch_t* next = arch;
int i = -1;
while(i<ninst) {
arch = next;
i += 1+arch->seq;
next = (arch_arch_t*)((uintptr_t)next + sizeof_arch(arch));
}
return arch->unaligned;
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef __DYNAREC_ARM_ARCH_H__
#define __DYNAREC_ARM_ARCH_H__
#include <stddef.h>
#include "x64emu.h"
#include "box64context.h"
#include "box64cpu.h"
#include "dynarec_arm64_private.h"
// get size of arch specific info (can be 0)
size_t get_size_arch(dynarec_arm_t* dyn);
//populate the array
void* populate_arch(dynarec_arm_t* dyn, void* p, size_t sz);
#ifndef _WIN32
#include <ucontext.h>
//adjust flags and more
void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t x64pc);
#else
#define adjust_arch(db, emu, p, x64pc)
#endif
// get if instruction can be regenerated for unaligned access
int arch_unaligned(dynablock_t* db, uintptr_t x64pc);
#endif // __DYNAREC_ARM_ARCH_H__
+4 -5
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -71,8 +69,9 @@ uintptr_t dynarec64_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ni
addr = dynarec64_AVX_F3_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
else {DEFAULT;}
if((*ok==-1) && (box64_dynarec_log>=LOG_INFO || box64_dynarec_dump || box64_dynarec_missing==1)) {
dynarec_log(LOG_NONE, "Dynarec unimplemented AVX opcode size %d prefix %s map %s opcode %02X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
if((*ok==-1) && (BOX64ENV(dynarec_log)>=LOG_INFO || dyn->need_dump || BOX64ENV(dynarec_missing)))
if(!dyn->size || BOX64ENV(dynarec_log)>LOG_INFO || dyn->need_dump) {
dynarec_log(LOG_NONE, " Dynarec unimplemented VEX opcode size %d prefix %s map %s opcode %02X\n", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
}
return addr;
}
+214 -88
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -81,11 +79,13 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
} else {
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
VLDR128_U12(v0, ed, fixedaddress); // no alignment issue with ARMv8 NEON :)
if(vex.l) {
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1, -1);
VLDR128_U12(v0, ed, fixedaddress+16);
v1 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1, -1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0x3f<<4, 15, rex, NULL, 1, 0);
VLDP128_I7(v0, v1, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VLD128(v0, ed, fixedaddress); // no alignment issue with ARMv8 NEON :)
}
}
if(!vex.l) YMM0(gd);
@@ -103,13 +103,15 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
v0 = ymm_get_reg(dyn, ninst, x1, gd, 0, ed, -1, -1);
v1 = ymm_get_reg_empty(dyn, ninst, x1, ed, gd, -1, -1);
VMOVQ(v1, v0);
}
} else YMM0(ed);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
VSTR128_U12(v0, ed, fixedaddress);
if(vex.l) {
v0 = ymm_get_reg(dyn, ninst, x1, gd, 0, ed, -1, -1);
VSTR128_U12(v0, ed, fixedaddress+16);
v1 = ymm_get_reg(dyn, ninst, x1, gd, 0, ed, -1, -1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0x3f<<4, 15, rex, NULL, 1, 0);
VSTP128_I7(v0, v1, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VST128(v0, ed, fixedaddress);
}
SMWRITE2();
}
@@ -139,17 +141,14 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 0x13:
nextop = F8;
INST_NAME("VMOVLPS Ex, Vx, Gx");
INST_NAME("VMOVLPS Ex, Gx");
GETGX(v0, 0);
GETVX(v2, 0);
if(v1!=v2)
VMOVQ(v0, v2);
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);
if(v0!=v1) VMOVeD(v1, 0, v0, 0);
DEFAULT;
return addr;
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
VST1_64(v0, 0, ed); // better to use VST1 than VSTR_64, to avoid NEON->VFPU transfert I assume
VST1_64(v0, 0, ed);
SMWRITE2();
}
break;
@@ -197,15 +196,18 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
YMM0(gd);
break;
case 0x17:
INST_NAME("VMOVHPS Ex,Gx");
INST_NAME("VMOVHPS Ex, Gx");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);
ed = (nextop&7)+(rex.b<<3);
v1 = sse_get_reg(dyn, ninst, x1, ed, 1);
VMOVeD(v1, 0, v0, 1);
YMM0(ed);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
VST1_64(v0, 1, ed);
SMWRITE2();
}
break;
@@ -225,11 +227,13 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
} else {
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
VLDR128_U12(v0, ed, fixedaddress);
if(vex.l) {
GETGY_empty(v0, -1, -1, -1);
VLDR128_U12(v0, ed, fixedaddress+16);
GETGY_empty(v1, -1, -1, -1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0x3f<<4, 15, rex, NULL, 1, 0);
VLDP128_I7(v0, v1, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VLD128(v0, ed, fixedaddress);
}
}
if(!vex.l) YMM0(gd);
@@ -246,13 +250,15 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
if(vex.l) {
GETGYEY_empty(v0, v1);
VMOVQ(v1, v0);
}
} else YMM0(ed);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
VSTR128_U12(v0, ed, fixedaddress);
if(vex.l) {
GETGY(v0, 0, -1, -1, -1);
VSTR128_U12(v0, ed, fixedaddress+16);
GETGY(v1, 0, -1, -1, -1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0x3f<<4, 15, rex, NULL, 1, 0);
VSTP128_I7(v0, v1, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VST128(v0, ed, fixedaddress);
}
SMWRITE2();
}
@@ -270,13 +276,15 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
if(vex.l) {
GETGYEY_empty(v0, v1);
VMOVQ(v1, v0);
}
} else YMM0(ed);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
VSTR128_U12(v0, ed, fixedaddress);
if(vex.l) {
GETGY(v0, 0, -1, -1, -1);
VSTR128_U12(v0, ed, fixedaddress+16);
GETGY(v1, 0, -1, -1, -1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0x3f<<4, 15, rex, NULL, 1, 0);
VSTP128_I7(v0, v1, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VST128(v0, ed, fixedaddress);
}
}
break;
@@ -290,11 +298,11 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX(v0, 0);
GETEXSS(s0, 0, 0);
FCMPS(v0, s0);
FCOMI(x1, x2, 0, v0, s0, 1); //disable precise cmp
FCOMI(x1, x2);
break;
case 0x50:
INST_NAME("VMOVMSPKPS Gd, Ex");
INST_NAME("VMOVMSKPS Gd, Ex");
nextop = F8;
GETGD;
MOV32w(gd, 0);
@@ -302,7 +310,7 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
// EX is an xmm reg
q0 = fpu_get_scratch(dyn, ninst);
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETEX(v0, 0, 0); } else { GETEY(v0); }
if(!l) { GETEX_Y(v0, 0, 0); } else { GETEY(v0); }
SQXTN_16(q0, v0); // reduces the 4 32bits to 4 16bits
VMOVQDto(x1, q0, 0);
LSRx(x1, x1, 15);
@@ -317,15 +325,14 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
} else {
// EX is memory
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, (0xfff<<3)-24, 7, rex, NULL, 0, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, (0x3f<<3)-16, 7, rex, NULL, 1, 0);
for(int l=0; l<1+vex.l; ++l) {
LDRx_U12(x1, ed, fixedaddress+16*l);
LDPx_S7_offset(x1, x2, ed, fixedaddress+16*l);
LSRx(x1, x1, 31);
BFIx(gd, x1, 0+(l*4), 1);
LSRx(x1, x1, 32);
BFIx(gd, x1, 1+(l*4), 1);
LDRx_U12(x1, ed, fixedaddress+8+16*l);
LSRx(x1, x1, 31);
LSRx(x1, x2, 31);
BFIx(gd, x1, 2+(l*4), 1);
LSRx(x1, x1, 32);
BFIx(gd, x1, 3+(l*4), 1);
@@ -336,9 +343,23 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("VSQRTPS Gx, Ex");
nextop = F8;
SKIPTEST(x1);
if(!BOX64ENV(dynarec_fastnan)) {
d0 = fpu_get_scratch(dyn, ninst);
d1 = fpu_get_scratch(dyn, ninst);
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_EX(q0, q1, 0); } else { GETGY_empty_EY(q0, q1); }
VFSQRTQS(q0, q1);
if(!l) { GETGX_empty_EX(v0, v1, 0); } else { GETGY_empty_EY(v0, v1); }
if(!BOX64ENV(dynarec_fastnan)) {
// check if any input value was NAN
VFCMEQQS(d0, v1, v1); // 0 if NAN, 1 if not NAN
VFSQRTQS(v0, v1);
VFCMEQQS(d1, v0, v0); // 0 => out is NAN
VBICQ(d1, d0, d1); // forget it in any input was a NAN already
VSHLQ_32(d1, d1, 31); // only keep the sign bit
VORRQ(v0, v0, d1); // NAN -> -NAN
} else {
VFSQRTQS(v0, v1);
}
}
if(!vex.l) YMM0(gd);
break;
@@ -440,22 +461,50 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
case 0x58:
INST_NAME("VADDPS Gx, Vx, Ex");
nextop = F8;
GETGX_empty_VXEX(v0, v2, v1, 0);
VFADDQS(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
q1 = fpu_get_scratch(dyn, ninst);
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
if(!BOX64ENV(dynarec_fastnan)) {
// check if any input value was NAN
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFADDQS(v0, v2, v1);
} else YMM0(gd)
if(!BOX64ENV(dynarec_fastnan)) {
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
VSHLQ_32(q1, q1, 31); // only keep the sign bit
VORRQ(v0, v0, q1); // NAN -> -NAN
}
}
if(!vex.l) YMM0(gd)
break;
case 0x59:
INST_NAME("VMULPS Gx, Vx, Ex");
nextop = F8;
GETGX_empty_VXEX(v0, v2, v1, 0);
VFMULQS(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
q1 = fpu_get_scratch(dyn, ninst);
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
if(!BOX64ENV(dynarec_fastnan)) {
// check if any input value was NAN
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFMULQS(v0, v2, v1);
} else YMM0(gd)
if(!BOX64ENV(dynarec_fastnan)) {
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
VSHLQ_32(q1, q1, 31); // only keep the sign bit
VORRQ(v0, v0, q1); // NAN -> -NAN
}
}
if(!vex.l) YMM0(gd)
break;
case 0x5A:
INST_NAME("VCVTPS2PD Gx, Ex");
@@ -480,27 +529,43 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
case 0x5C:
INST_NAME("VSUBPS Gx, Vx, Ex");
nextop = F8;
GETGX_empty_VXEX(v0, v2, v1, 0);
VFSUBQS(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
q1 = fpu_get_scratch(dyn, ninst);
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
if(!BOX64ENV(dynarec_fastnan)) {
// check if any input value was NAN
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFSUBQS(v0, v2, v1);
} else YMM0(gd)
if(!BOX64ENV(dynarec_fastnan)) {
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
VSHLQ_32(q1, q1, 31); // only keep the sign bit
VORRQ(v0, v0, q1); // NAN -> -NAN
}
}
if(!vex.l) YMM0(gd)
break;
case 0x5D:
INST_NAME("VMINPS Gx, Vx, Ex");
nextop = F8;
if(!box64_dynarec_fastnan) {
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
// FMIN/FMAX wll not copy a NaN if either is NaN
// but x86 will copy src2 if either value is NaN, so lets force a copy of Src2 (Ex) if result is NaN
VFMINQS(v0, v2, v1);
if(!box64_dynarec_fastnan && (v2!=v1)) {
VFCMEQQS(q0, v0, v0); // 0 is NaN, 1 is not NaN, so MASK for NaN
VBIFQ(v0, v1, q0); // copy dest where source is NaN
if(BOX64ENV(dynarec_fastnan)) {
VFMINQS(v0, v2, v1);
} else {
VFCMGTQS(q0, v1, v2); // 0 if NaN or v1 GT v2, so invert mask for copy
if(v0!=v1) VBIFQ(v0, v1, q0);
if(v0!=v2) VBITQ(v0, v2, q0);
}
}
if(!vex.l) YMM0(gd);
@@ -508,27 +573,43 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
case 0x5E:
INST_NAME("VDIVPS Gx, Vx, Ex");
nextop = F8;
GETGX_empty_VXEX(v0, v2, v1, 0);
VFDIVQS(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
q1 = fpu_get_scratch(dyn, ninst);
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
if(!BOX64ENV(dynarec_fastnan)) {
// check if any input value was NAN
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFDIVQS(v0, v2, v1);
} else YMM0(gd)
if(!BOX64ENV(dynarec_fastnan)) {
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
VSHLQ_32(q1, q1, 31); // only keep the sign bit
VORRQ(v0, v0, q1); // NAN -> -NAN
}
}
if(!vex.l) YMM0(gd)
break;
case 0x5F:
INST_NAME("VMAXPS Gx, Vx, Ex");
nextop = F8;
if(!box64_dynarec_fastnan) {
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
// FMIN/FMAX wll not copy a NaN if either is NaN
// but x86 will copy src2 if either value is NaN, so lets force a copy of Src2 (Ex) if result is NaN
VFMAXQS(v0, v2, v1);
if(!box64_dynarec_fastnan && (v2!=v1)) {
VFCMEQQS(q0, v0, v0); // 0 is NaN, 1 is not NaN, so MASK for NaN
VBIFQ(v0, v1, q0); // copy dest where source is NaN
if(BOX64ENV(dynarec_fastnan)) {
VFMAXQS(v0, v2, v1);
} else {
VFCMGTQS(q0, v2, v1); // 0 if NaN or v2 GT v1, so invert mask for copy
if(v0!=v1) VBIFQ(v0, v1, q0);
if(v0!=v2) VBITQ(v0, v2, q0);
}
}
if(!vex.l) YMM0(gd);
@@ -568,13 +649,35 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("VLDMXCSR Md");
GETED(0);
STRw_U12(ed, xEmu, offsetof(x64emu_t, mxcsr));
if(box64_sse_flushto0) {
MRS_fpcr(x1); // get fpscr
if(BOX64ENV(sse_flushto0)) {
MRS_fpcr(x2); // get fpscr
LSRw_IMM(x3, ed, 15); // get FZ bit
BFIw(x1, x3, 24, 1); // inject FZ bit
BFIw(x2, x3, 24, 1); // inject FZ bit
EORw_REG_LSR(x3, x3, ed, 1); // FZ xor DAZ
BFIw(x1, x3, 1, 1); // inject AH bit
MSR_fpcr(x1); // put new fpscr
BFIw(x2, x3, 1, 1); // inject AH bit
MSR_fpcr(x2); // put new fpscr
}
if(BOX64ENV(sse_flushto0)) {
// try to sync mxcsr with fpsr on the flag side
/* mapping is
ARM -> X86
0 -> 0 // Invalid operation
1 -> 2 // Divide by 0
2 -> 3 // Overflow
3 -> 4 // underflow
4 -> 5 // Inexact
5 -> 1 // denormal
*/
// doing X86 -> ARM here, 0 1 2 3 4 5 -> 0 2 3 4 5 1
if(ed!=x1)
MOVw_REG(x1, ed); // x1 = 543210
RORw(x3, x1, 2); // x3 = 10.....5432
BFIw(x1, x3, 1, 4); // x1 = 54320
RORw(x3, x3, 32-1); // x3 = 0.....54321
BFIw(x1, x3, 5, 1); // x1 = 154320
MRS_fpsr(x2);
BFIx(x2, x1, 0, 6);
MSR_fpsr(x2);
}
break;
case 3:
@@ -582,6 +685,17 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
LDRw_U12(x4, xEmu, offsetof(x64emu_t, mxcsr));
STW(x4, ed, fixedaddress);
if(BOX64ENV(sse_flushto0)) {
// sync with fpsr, with mask from mxcsr
MRS_fpsr(x1);
// doing ARM -> X86 here, 543210 => 432150
UBFXw(x2, x1, 1, 5); // x2 = 54321
BFIw(x1, x2, 2, 4); // x1 = 432110
LSRw(x2, x2, 4); // x2 = 5
BFIw(x1, x2, 1, 1); // x1 = 432150
//BFXILw(x3, x4, 7, 6); // this would the mask, but let's ignore that for now
BFIw(x4, x1, 0, 6); // inject back the flags
}
break;
default:
DEFAULT;
@@ -594,7 +708,7 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
q0 = fpu_get_scratch(dyn, ninst);
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 1); u8 = F8; } else { GETGY_empty_VYEY(v0, v2, v1); }
if(((u8&15)==3) || ((u8&15)==7) || ((u8&15)==8) || ((u8&15)==9) || ((u8&15)==10) || ((u8&15)==12) || ((u8&15)==13) || ((u8&15)==14)) {
if(((u8&15)==3) || ((u8&15)==7) || ((u8&15)==8) || ((u8&15)==9) || ((u8&15)==10) || ((u8&15)==12)) {
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(((u8&15)==7)?v0:q0, q0, q0); // 0 if NAN, 1 if not NAN
}
@@ -634,15 +748,21 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
u8 = F8;
if(v2==v1 && (u8&0x3)==((u8>>2)&3) && (u8&0xf)==((u8>>4)&0xf)) {
VDUPQ_32(v0, v2, u8&3);
} else if(v2==v1 && (u8==0xe0)) { // easy special case
} else if(v2==v1 && (u8==0xe0)) { // elements 3 2 0 0
VMOVQ(v0, v2);
VMOVeS(v0, 1, v0, 0);
} else if(v2==v1 && (u8==0xe5)) { // easy special case
} else if(v2==v1 && (u8==0xe5)) { // elements 3 2 1 1
VMOVQ(v0, v2);
VMOVeS(v0, 0, v0, 1);
} else if(MODREG && u8==0x88) {
} else if(v2==v1 && (u8==0xa0)) { // elements 2 2 0 0
VTRNQ1_32(v0, v1, v2);
} else if(v2==v1 && (u8==0xf5)) { // elements 3 3 1 1
VTRNQ2_32(v0, v1, v2);
} else if(v2==v1 && (u8==0xb1)) { // elements 2 3 0 1
VREV64Q_32(v0, v1);
} else if(MODREG && u8==0x88) { // elements 2 0 2 0
VUZP1Q_32(v0, v2, v1);
} else if(MODREG && u8==0xdd) {
} else if(MODREG && u8==0xdd) { // elements 3 1 3 1
VUZP2Q_32(v0, v2, v1);
} else {
if((v0==v1) || (v0==v2)) {
@@ -674,15 +794,21 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGY_empty_VY(v0, v2, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);
if(v2==v1 && (u8&0x3)==((u8>>2)&3) && (u8&0xf)==((u8>>4)&0xf)) {
VDUPQ_32(v0, v2, u8&3);
} else if(v2==v1 && (u8==0xe0)) {
} else if(v2==v1 && (u8==0xe0)) { // elements 3 2 0 0
VMOVQ(v0, v2);
VMOVeS(v0, 1, v0, 0);
} else if(v2==v1 && (u8==0xe5)) {
} else if(v2==v1 && (u8==0xe5)) { // elements 3 2 1 1
VMOVQ(v0, v2);
VMOVeS(v0, 0, v0, 1);
} else if(MODREG && u8==0x88) {
} else if(v2==v1 && (u8==0xa0)) { // elements 2 2 0 0
VTRNQ1_32(v0, v1, v2);
} else if(v2==v1 && (u8==0xf5)) { // elements 3 3 1 1
VTRNQ2_32(v0, v1, v2);
} else if(v2==v1 && (u8==0xb1)) { // elements 2 3 0 1
VREV64Q_32(v0, v1);
} else if(MODREG && u8==0x88) { // elements 2 0 2 0
VUZP1Q_32(v0, v2, v1);
} else if(MODREG && u8==0xdd) {
} else if(MODREG && u8==0xdd) { // elements 3 1 3 1
VUZP2Q_32(v0, v2, v1);
} else {
if(s0) d0 = v0;
+178 -27
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -39,6 +37,7 @@ uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, i
int q0, q1, q2;
int d0, d1, d2;
int s0;
int need_tst;
uint64_t tmp64u;
int64_t j64;
int64_t fixedaddress;
@@ -68,21 +67,32 @@ uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, i
GETGD;
GETED(0);
GETVD;
IFX(X_ZF)
need_tst = 0;
IFX(X_ZF) need_tst = 1;
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
IFXNATIVE(X_CF, NF_CF) need_tst = 1;
if(need_tst)
BICSxw(gd, ed, vd);
else
BICxw(gd, ed, vd);
IFX(X_ZF) {
CSETw(x1, cEQ);
BFIw(xFlags, x1, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(x1, cEQ);
BFIw(xFlags, x1, F_ZF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
}
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {BFCw(xFlags, F_CF, 1);}
}
IFX(X_OF)
BFCw(xFlags, F_OF, 1);
IFX(X_CF)
BFCw(xFlags, F_CF, 1);
IFX(X_SF) {
LSRxw_IMM(x1, gd, rex.w?63:31);
BFIw(xFlags, x1, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw_IMM(x1, gd, rex.w?63:31);
BFIw(xFlags, x1, F_SF, 1);
}
}
break;
case 0xF3:
@@ -99,24 +109,114 @@ uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, i
BFIw(xFlags, x3, F_CF, 1);
}
SUBxw_U12(x3, ed, 1);
IFX(X_ZF)
need_tst = 0;
IFX(X_ZF) need_tst = 1;
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
if(need_tst)
ANDSxw_REG(vd, ed, x3);
else
ANDxw_REG(vd, ed, x3);
IFX(X_ZF) {
CSETMw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETMw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(x3, vd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(x3, vd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
}
IFX(X_OF) BFCw(xFlags, F_OF, 1);
if(box64_dynarec_test) {
IFX(X_OF) {
IFNATIVE(NF_VF) {} else { BFCw(xFlags, F_OF, 1); }
}
if (BOX64ENV(dynarec_test)) {
IFX(X_AF) BFCw(xFlags, F_AF, 1);
IFX(X_PF) BFCw(xFlags, F_PF, 1);
}
break;
case 2:
INST_NAME("BLSMSK Vd, Ed");
SETFLAGS(X_ALL, SF_SET);
GETED(0);
GETVD;
IFX(X_CF) {
TSTxw_REG(ed, ed);
CSETMw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1);
}
SUBxw_U12(x3, ed, 1);
need_tst = 0;
IFX(X_ZF) need_tst = 1;
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
EORxw_REG(vd, ed, x3);
if(need_tst)
TSTxw_REG(vd, vd);
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETMw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1);
}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
LSRxw(x3, vd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else { BFCw(xFlags, F_OF, 1); }
}
if (BOX64ENV(dynarec_test)) {
IFX(X_AF) BFCw(xFlags, F_AF, 1);
IFX(X_PF) BFCw(xFlags, F_PF, 1);
}
break;
case 3:
INST_NAME("BLSI Vd, Ed");
SETFLAGS(X_ALL, SF_SET);
GETED(0);
GETVD;
IFX(X_CF) {
TSTxw_REG(ed, ed);
CSETMw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1);
}
NEGxw_REG(x3, ed);
need_tst = 0;
IFX(X_ZF) need_tst = 1;
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
if(need_tst)
ANDSxw_REG(vd, ed, x3);
else
ANDxw_REG(vd, ed, x3);
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETMw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1);
}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
LSRxw(x3, vd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else { BFCw(xFlags, F_OF, 1); }
}
if (BOX64ENV(dynarec_test)) {
IFX(X_AF) BFCw(xFlags, F_AF, 1);
IFX(X_PF) BFCw(xFlags, F_PF, 1);
}
break;
default:
DEFAULT;
}
@@ -131,27 +231,78 @@ uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, i
GETVD;
UXTBw(x1, vd);
CMPSw_U12(x1, rex.w?64:32);
CSETxw(x2, cPL);
IFX(F_CF) {
CSETMxw(x2, cPL);
IFX(X_CF) {
BFIw(xFlags, x2, F_CF, 1);
}
MVNxw_REG(x2, x2); //prepare mask
B_MARK(cPL);
LSLxw_REG(x2, x2, x1);
MARK;
IFX(X_ZF) {
need_tst = 0;
IFX(X_ZF) need_tst = 1;
IFXNATIVE(X_SF, NF_SF) need_tst = 1;
IFXNATIVE(X_OF, NF_VF) need_tst = 1;
if(need_tst) {
BICSxw(gd, ed, x2);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1);
} else
BICxw(gd, ed, x2);
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(x3, gd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(x3, gd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
}
IFX(X_AF) BFCw(xFlags, F_AF, 1);
IFX(X_PF) BFCw(xFlags, F_PF, 1);
IFX(X_OF) BFCw(xFlags, F_OF, 1);
IFX(X_OF) {
IFNATIVE(NF_VF) {} else { BFCw(xFlags, F_OF, 1); }
}
break;
case 0xF7:
INST_NAME("BEXTR Gd, Ed, Vd");
nextop = F8;
SETFLAGS(X_ALL, SF_SET);
GETGD;
GETED(0);
GETVD;
MOV64xw(x1, 0);
UXTBw(x2, vd); // start
BFXILw(x3, vd, 8, 8); // length
TSTw_REG(x3, x3);
B_MARK(cEQ);
LSRxw_REG(x1, ed, x2);
CMPSw_U12(x3, rex.w?64:32);
B_MARK(cGE);
MOV32w(x2, rex.w?64:32);
SUBw_REG(x2, x2, x3);
LSLxw_REG(x1, x1, x2);
LSRxw_REG(x1, x1, x2);
TSTxw_REG(x1, x1);
MARK;
MOVxw_REG(gd, x1);
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1);
}
}
IFX(X_AF) BFCw(xFlags, F_AF, 1);
IFX(X_PF) BFCw(xFlags, F_PF, 1);
IFX(X_CF) BFCw(xFlags, F_CF, 1);
IFX(X_OF) {
IFNATIVE(NF_VF) {} else { BFCw(xFlags, F_OF, 1); }
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else { BFCw(xFlags, F_SF, 1); }
}
break;
default:
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+137 -93
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -135,15 +133,21 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
if(!l) {
GETGX_empty_EX(v0, v1, 1);
u8 = F8;
if(v0==v1) {q1 = fpu_get_scratch(dyn, ninst); VMOVQ(q1, v1);}
} else {
GETGY_empty_EY(v0, v1);
if(v0==v1) {VMOVQ(q1, v1);}
}
if(((u8>>(l*2))&1)==((u8>>(1+l*2))&1))
VDUPQ_64(v0, (v0==v1)?q1:v1, ((u8>>(l*2))&1));
else for(int i=0; i<2; ++i)
VMOVeD(v0, i, (v0==v1)?q1:v1, (u8>>(i+l*2))&1);
switch(((u8>>(l*2))&3)) {
case 0b00:
case 0b11:
VDUPQ_64(v0, v1, ((u8>>(l*2))&1));
break;
case 0b10:
if(v0!=v1) VMOVQ(v0, v1);
break;
case 0b01:
VEXTQ_8(v0, v1, v1, 8); // invert 64bits values
break;
}
}
if(!vex.l) YMM0(gd);
break;
@@ -173,7 +177,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
VMOVQ(q1, v1);
v1 = q1;
}
switch(u8&0x0f) {
switch(u8&0b1011) {
case 0: if(v0!=v2) VMOVQ(v0, v2); break;
case 1: d2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, s0, -1); VMOVQ(v0, d2); break;
case 2: if(MODREG) { if(v0!=v1) VMOVQ(v0, v1); } else { VLDR128_U12(v0, ed, fixedaddress); } break;
@@ -183,7 +187,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
if((u8&0xf0)==0x10) { if((u8&0x0f)!=1) d2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, s0, -1); }
if(MODREG && ((u8&0xf0)==0x30)) { if((u8&0x0f)!=3) d1 = ymm_get_reg(dyn, ninst, x1, s0, 0, gd, vex.v, -1); }
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, s0, -1);
switch((u8>>4)&0x0f) {
switch((u8>>4)&0b1011) {
case 0: VMOVQ(v0, v2); break;
case 1: if(v0!=d2) VMOVQ(v0, d2); break;
case 2: if(MODREG) { if(v0!=v1) VMOVQ(v0, v1); } else { VLDR128_U12(v0, ed, fixedaddress); } break;
@@ -268,17 +272,21 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
} else if(q0==q1) {
for(int i=0; i<4; ++i)
if(u8&(1<<i)) {
VMOVeS(q0, i, q1, i);
//VMOVeS(q0, i, q1, i);
} else if(q0!=q2)
VMOVeS(q0, i, q2, i);
} else {
if(q0!=q2)
VMOVQ(q0, q2);
if((u8&15)==0b0011) {
if((u8&0b0011)==0b0011) {
VMOVeD(q0, 0, q1, 0);
} else if((u8&15)==0b1100) {
u8&=~0b0011;
}
if((u8&0b1100)==0b1100) {
VMOVeD(q0, 1, q1, 1);
} else for(int i=0; i<4; ++i)
u8&=~0b1100;
}
for(int i=0; i<4; ++i)
if(u8&(1<<i)) {
VMOVeS(q0, i, q1, i);
}
@@ -290,17 +298,21 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
} else if(q0==q1) {
for(int i=0; i<4; ++i)
if(u8&(1<<(i+4))) {
VMOVeS(q0, i, q1, i);
//VMOVeS(q0, i, q1, i);
} else if(q0!=q2)
VMOVeS(q0, i, q2, i);
} else {
if(q0!=q2)
VMOVQ(q0, q2);
if((u8>>4)==0b0011) {
if(((u8>>4)&0b0011)==0b0011) {
VMOVeD(q0, 0, q1, 0);
} else if((u8>>4)==0b1100) {
u8&=~0b00110000;
}
if(((u8>>4)&0b1100)==0b1100) {
VMOVeD(q0, 1, q1, 1);
} else for(int i=0; i<4; ++i)
u8&=~0b11000000;
}
for(int i=0; i<4; ++i)
if(u8&(1<<(i+4))) {
VMOVeS(q0, i, q1, i);
}
@@ -308,11 +320,11 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
} else YMM0(gd);
break;
case 0x0D:
INST_NAME("VPBLENDPD Gx, Vx, Ex, Ib");
INST_NAME("VBLENDPD Gx, Vx, Ex, Ib");
nextop = F8;
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(q0, q2, q1, 1); u8 = F8; } else { GETGY_empty_VYEY(q0, q2, q1); }
switch(u8>>(l*2)&3) {
switch((u8>>(l*2))&3) {
case 0b00: if(q0!=q2) VMOVQ(q0, q2); break; // VxVx
case 0b01: if(q0!=q1) VMOVeD(q0, 0, q1, 0); if(q0!=q2) VMOVeD(q0, 1, q2, 1); break; // Ex[0]Vx[1]
case 0b10: if(q0!=q2) VMOVeD(q0, 0, q2, 0); if(q0!=q1) VMOVeD(q0, 1, q1, 1); break; // Vx[0]Ex[1]
@@ -331,12 +343,8 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
MOVI_64(q0, u8);
SXTL_8(q0, q0); // expand 8bits to 16bits...
}
if(v0==v1) {
VBIFQ(v0, v2, q0);
} else {
if(v0!=v2) VMOVQ(v0, v2);
VBITQ(v0, v1, q0);
}
if(v0!=v2) VBIFQ(v0, v2, q0);
if(v0!=v1) VBITQ(v0, v1, q0);
}
if(!vex.l) YMM0(gd);
break;
@@ -378,6 +386,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
VMOVBto(ed, v0, u8&0x0f);
if(!MODREG) {
STB(ed, wback, fixedaddress);
SMWRITE2();
}
break;
case 0x15:
@@ -395,6 +404,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
VMOVHto(ed, v0, u8&7);
if(!MODREG) {
STH(ed, wback, fixedaddress);
SMWRITE2();
}
break;
case 0x16:
@@ -416,6 +426,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
}
if(!MODREG) {
STxw(ed, wback, fixedaddress);
SMWRITE2();
}
break;
case 0x17:
@@ -433,6 +444,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
VMOVSto(ed, v0, u8&3);
if(!MODREG) {
STW(ed, wback, fixedaddress);
SMWRITE2();
}
break;
case 0x18:
@@ -479,6 +491,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 1);
VST128(v0, ed, fixedaddress);
SMWRITE2();
}
F8; // read u8, but it's been already handled
break;
@@ -592,34 +605,62 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
u8 = geted_ib(dyn, addr, ninst, nextop);
q0 = fpu_get_scratch(dyn, ninst);
// first mask
wb1 = 0; // mask
for(int i=0; i<4; ++i)
if(u8&(1<<i))
wb1 |= (3<<(i*2));
MOVI_64(q0, wb1); // load 8bits value as a 8bytes mask
SXTL_16(q0, q0); // expand 16bits to 32bits...
q1 = fpu_get_scratch(dyn, ninst);
// second mask
wb1 = 0; // mask
for(int i=0; i<4; ++i)
if((u8>>4)&(1<<i))
wb1 |= (3<<(i*2));
MOVI_64(q1, wb1); // load 8bits value as a 8bytes mask
SXTL_16(q1, q1); // expand 16bits to 32bits...
if((u8&0x0f)!=0x0f) {
wb1 = 0; // mask
for(int i=0; i<4; ++i)
if(u8&(1<<i))
wb1 |= (3<<(i*2));
MOVI_64(q0, wb1); // load 8bits value as a 8bytes mask
SXTL_16(q0, q0); // expand 16bits to 32bits...
}
if((u8&0xf0)!=0xf0) {
q1 = fpu_get_scratch(dyn, ninst);
// second mask
wb1 = 0; // mask
for(int i=0; i<4; ++i)
if((u8>>4)&(1<<i))
wb1 |= (3<<(i*2));
MOVI_64(q1, wb1); // load 8bits value as a 8bytes mask
SXTL_16(q1, q1); // expand 16bits to 32bits...
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 1); u8 = F8; } else { GETGY_empty_VYEY(v0, v2, v1); }
VFMULQS(v0, v2, v1);
VANDQ(v0, v0, q1); // second mask
if((u8&0xf0)!=0xf0) {
VANDQ(v0, v0, q1); // second mask
}
VFADDPQS(v0, v0, v0);
FADDPS(v0, v0);
VDUPQ_32(v0, v0, 0);
VANDQ(v0, v0, q0); // first mask
if((u8&0x0f)!=0x0f) {
VANDQ(v0, v0, q0); // first mask
}
}
if(!vex.l) YMM0(gd);
break;
case 0x41:
INST_NAME("VDPPD Gx, Vx, Ex, Ib");
nextop = F8;
GETGX_empty_VXEX(v0, v1, v2, 0);
u8 = F8;
VFMULQD(v0, v1, v2);
// mask some, duplicate all, mask some
for(int i=0; i<2; ++i)
if(!(u8&(1<<(4+i)))) {
VMOVQDfrom(v0, i, xZR);
}
FADDPD(v0, v0);
VDUPQ_64(v0, v0, 0);
for(int i=0; i<2; ++i)
if(!(u8&(1<<i))) {
VMOVQDfrom(v0, i, xZR);
}
YMM0(gd);
break;
case 0x44:
INST_NAME("PCLMULQDQ Gx, Vx, Ex, Ib");
INST_NAME("VPCLMULQDQ Gx, Vx, Ex, Ib");
nextop = F8;
if(arm64_pmull) {
d0 = fpu_get_scratch(dyn, ninst);
@@ -648,34 +689,24 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
}
}
} else {
for(int l=0; l<1+vex.l; ++l) {
if(!l) {
GETG;
sse_forget_reg(dyn, ninst, gd);
sse_reflect_reg(dyn, ninst, vex.v);
GETG;
sse_forget_reg(dyn, ninst, gd);
sse_reflect_reg(dyn, ninst, vex.v);
MOV32w(x1, gd); // gx
MOV32w(x2, vex.v); // vx
if(MODREG) {
ed = (nextop&7)+(rex.b<<3);
sse_forget_reg(dyn, ninst, ed);
MOV32w(x3, ed);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
if(ed!=x3) {
MOVx_REG(x3, ed);
}
MOV32w(x1, gd); // gx
MOV32w(x2, vex.v); // vx
if(MODREG) {
if(!l) {
ed = (nextop&7)+(rex.b<<3);
sse_forget_reg(dyn, ninst, ed);
}
MOV32w(x3, ed);
} else {
if(!l) {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
if(ed!=x3) {
MOVx_REG(x3, ed);
}
} else {
ADDx_U12(x3, ed, 16);
}
}
if(!l) u8 = F8;
MOV32w(x4, u8);
CALL_(l?native_pclmul_y:native_pclmul_x, -1, x3);
}
u8 = F8;
MOV32w(x4, u8);
CALL_(vex.l?native_pclmul_y:native_pclmul_x, -1, x3);
}
if(!vex.l) YMM0(gd);
break;
@@ -702,12 +733,8 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
}
VSSHRQ_32(q0, q1, 31); // create mask
if(v0==v1)
VBIFQ(v0, v2, q0);
else {
if(v0!=v2) VMOVQ(v0, v2);
VBITQ(v0, v1, q0);
}
if(v0!=v2) VBIFQ(v0, v2, q0);
if(v0!=v1) VBITQ(v0, v1, q0);
}
if(!vex.l) YMM0(gd);
break;
@@ -731,45 +758,62 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
}
VSSHRQ_64(q0, q1, 63); // create mask
if(v0==v1)
VBIFQ(v0, v2, q0);
else {
if(v0!=v2) VMOVQ(v0, v2);
VBITQ(v0, v1, q0);
}
if(v0!=v2) VBIFQ(v0, v2, q0);
if(v0!=v1) VBITQ(v0, v1, q0);
}
if(!vex.l) YMM0(gd);
break;
case 0x4C:
INST_NAME("VBLENDPVB Gx, Vx, Ex, XMMImm8");
INST_NAME("VPBLENDVB Gx, Vx, Ex, XMMImm8");
nextop = F8;
q0 = fpu_get_scratch(dyn, ninst);
u8 = geted_ib(dyn, addr, ninst, nextop)>>4;
ed = (nextop&7)+(rex.b<<3);
for(int l=0; l<1+vex.l; ++l) {
if(!l) {
q1 = sse_get_reg(dyn, ninst, x1, u8, 0);
GETGX_empty_VXEX(v0, v2, v1, 1);
F8;
} else {
v2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
v2 = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, u8, (MODREG)?ed:-1);
if(MODREG)
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0, gd, vex.v, u8);
v1 = ymm_get_reg(dyn, ninst, x1, ed, 0, gd, vex.v, u8);
else
VLDR128_U12(v1, ed, fixedaddress+16);
q1 = ymm_get_reg(dyn, ninst, x1, u8, 0, vex.v, gd, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, u8, (MODREG)?((nextop&7)+(rex.b<<3)):-1);
q1 = ymm_get_reg(dyn, ninst, x1, u8, 0, vex.v, gd, (MODREG)?ed:-1);
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, u8, (MODREG)?ed:-1);
}
VSSHRQ_8(q0, q1, 7); // create mask
if(v0==v1)
VBIFQ(v0, v2, q0);
else {
if(v0!=v2) VMOVQ(v0, v2);
VBITQ(v0, v1, q0);
}
if(v0!=v2) VBIFQ(v0, v2, q0);
if(v0!=v1) VBITQ(v0, v1, q0);
}
if(!vex.l) YMM0(gd);
break;
case 0xDF:
INST_NAME("VAESKEYGENASSIST Gx, Ex, Ib");
nextop = F8;
GETG;
sse_forget_reg(dyn, ninst, gd);
MOV32w(x1, gd); // gx
if(MODREG) {
ed = (nextop&7)+(rex.b<<3);
sse_forget_reg(dyn, ninst, ed);
MOV32w(x2, ed);
MOV32w(x3, 0); //p = NULL
} else {
MOV32w(x2, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
if(ed!=x3) {
MOVx_REG(x3, ed);
}
}
u8 = F8;
MOV32w(x4, u8);
CALL(native_aeskeygenassist, -1);
YMM0(gd);
break;
default:
DEFAULT;
}
+213 -82
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -113,7 +111,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
if(vex.l) {
GETGY_empty(v0, -1, -1, -1);
ADDx_U12(x3, ed, 16);
VLDQ1R_64(v0, ed);
VLDQ1R_64(v0, x3);
}
}
if(!vex.l) YMM0(gd);
@@ -125,11 +123,17 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
GETGX_empty_VX(v0, v1);
GETED(0);
d1 = fpu_get_scratch(dyn, ninst);
if(BOX64ENV(dynarec_fastround)<2) {
u8 = sse_setround(dyn, ninst, x3, x4, x5);
}
if(rex.w) {
SCVTFDx(d1, ed);
} else {
SCVTFDw(d1, ed);
}
if(BOX64ENV(dynarec_fastround)<2) {
x87_restoreround(dyn, ninst, u8);
}
if(v0!=v1) VMOVQ(v0, v1);
VMOVeD(v0, 0, d1, 0);
YMM0(gd);
@@ -140,13 +144,23 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
nextop = F8;
GETGD;
GETEXSD(q0, 0, 0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround) && !arm64_frintts) {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
}
FCVTZSxwD(gd, q0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround) && arm64_frintts) {
v0 = fpu_get_scratch(dyn, ninst);
if(rex.w) {
FRINT64ZD(v0, q0);
} else {
FRINT32ZD(v0, q0);
}
FCVTZSxwD(gd, v0);
} else {
FCVTZSxwD(gd, q0);
}
if(!BOX64ENV(dynarec_fastround) && !arm64_frintts) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
@@ -161,17 +175,25 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
nextop = F8;
GETGD;
GETEXSD(q0, 0, 0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround) && !arm64_frintts) {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
}
u8 = sse_setround(dyn, ninst, x1, x2, x3);
d1 = fpu_get_scratch(dyn, ninst);
FRINTID(d1, q0);
if(!BOX64ENV(dynarec_fastround) && arm64_frintts) {
if(rex.w) {
FRINT64XD(d1, q0);
} else {
FRINT32XD(d1, q0);
}
} else {
FRINTID(d1, q0);
}
x87_restoreround(dyn, ninst, u8);
FCVTZSxwD(gd, d1);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround) && !arm64_frintts) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
@@ -188,17 +210,17 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
d1 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
if(!box64_dynarec_fastnan) {
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
q1 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FCMEQD(q0, v1, v1); // 0 if NAN, 1 if not NAN
}
FSQRTD(d1, v1);
if(!box64_dynarec_fastnan) {
if(!BOX64ENV(dynarec_fastnan)) {
FCMEQD(q1, d1, d1); // 0 => out is NAN
VBIC(q1, q0, q1); // forget it in any input was a NAN already
VSHLQ_64(q1, q1, 63); // only keep the sign bit
SHL_64(q1, q1, 63); // only keep the sign bit
VORR(d1, d1, q1); // NAN -> -NAN
}
if(v0!=v2) {
@@ -211,28 +233,54 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
case 0x58:
INST_NAME("VADDSD Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
q2 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FADDD(d1, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q1 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXD(q1, v0, v1); // propagate NAN
FCMEQD(q1, q1, q1); // 0 if NAN, 1 if not NAN
FADDD(q2, v1, v2); // the high part of the vector is erased...
FCMEQD(q0, q2, q2); // 0 => out is NAN
VBIC(q0, q1, q0); // forget it in any input was a NAN already
SHL_64(q0, q0, 63); // only keep the sign bit
VORR(q2, q2, q0); // NAN -> -NAN
} else {
FADDD(q2, v1, v2); // the high part of the vector is erased...
}
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeD(v0, 0, d1, 0);
VMOVeD(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x59:
INST_NAME("VMULSD Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
q2 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FMULD(d1, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q1 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXD(q1, v0, v1); // propagate NAN
FCMEQD(q1, q1, q1); // 0 if NAN, 1 if not NAN
FMULD(q2, v1, v2); // the high part of the vector is erased...
FCMEQD(q0, q2, q2); // 0 => out is NAN
VBIC(q0, q1, q0); // forget it in any input was a NAN already
SHL_64(q0, q0, 63); // only keep the sign bit
VORR(q2, q2, q0); // NAN -> -NAN
} else {
FMULD(q2, v1, v2); // the high part of the vector is erased...
}
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeD(v0, 0, d1, 0);
YMM0(gd)
VMOVeD(v0, 0, q2, 0);
YMM0(gd);
break;
case 0x5A:
INST_NAME("VCVTSD2SS Gx, Vx, Ex");
@@ -240,7 +288,13 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
d1 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FCVT_S_D(d1, v1);
if(BOX64ENV(dynarec_fastround)==2) {
FCVT_S_D(d1, v1);
} else {
u8 = sse_setround(dyn, ninst, x1, x2, x3);
FCVT_S_D(d1, v1);
x87_restoreround(dyn, ninst, u8);
}
if(v0!=v2) {
VMOVQ(v0, v2);
}
@@ -251,14 +305,27 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
case 0x5C:
INST_NAME("VSUBSD Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
q2 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FSUBD(d1, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q1 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXD(q1, v0, v1); // propagate NAN
FCMEQD(q1, q1, q1); // 0 if NAN, 1 if not NAN
FSUBD(q2, v2, v1); // the high part of the vector is erased...
FCMEQD(q0, q2, q2); // 0 => out is NAN
VBIC(q0, q1, q0); // forget it in any input was a NAN already
SHL_64(q0, q0, 63); // only keep the sign bit
VORR(q2, q2, q0); // NAN -> -NAN
} else {
FSUBD(q2, v2, v1); // the high part of the vector is erased...
}
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeD(v0, 0, d1, 0);
VMOVeD(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x5D:
@@ -269,7 +336,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
GETGX_empty_VX(v0, v2);
// VMINSD: if any input is NaN, or Ex[0]<Gx[0], copy Ex[0] -> Gx[0]
FCMPD(v2, v1);
FCSELD(d1, v1, v2, cCS);
FCSELD(d1, v1, v2, cCS); //CS: NAN or == or Vx > Ex
if(v0!=v2) {
VMOVQ(v0, v2);
}
@@ -279,27 +346,27 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
case 0x5E:
INST_NAME("VDIVSD Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
q2 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
if(!box64_dynarec_fastnan) {
q0 = fpu_get_scratch(dyn, ninst);
if(!BOX64ENV(dynarec_fastnan)) {
q1 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXD(q0, v2, v1); // propagate NAN
FCMEQD(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
FDIVD(d1, v2, v1);
if(!box64_dynarec_fastnan) {
FCMEQD(q1, d1, d1); // 0 => out is NAN
VBIC(q1, q0, q1); // forget it in any input was a NAN already
VSHLQ_64(q1, q1, 63); // only keep the sign bit
VORR(d1, d1, q1); // NAN -> -NAN
FMAXD(q1, v0, v1); // propagate NAN
FCMEQD(q1, q1, q1); // 0 if NAN, 1 if not NAN
FDIVD(q2, v2, v1); // the high part of the vector is erased...
FCMEQD(q0, q2, q2); // 0 => out is NAN
VBIC(q0, q1, q0); // forget it in any input was a NAN already
SHL_64(q0, q0, 63); // only keep the sign bit
VORR(q2, q2, q0); // NAN -> -NAN
} else {
FDIVD(q2, v2, v1); // the high part of the vector is erased...
}
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeD(v0, 0, d1, 0);
VMOVeD(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x5F:
@@ -309,7 +376,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FCMPD(v1, v2);
FCSELD(d1, v1, v2, cCS);
FCSELD(d1, v1, v2, cCS); //CS: NAN or == or Ex > Vx
if(v0!=v2) {
VMOVQ(v0, v2);
}
@@ -322,7 +389,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
nextop = F8;
d0 = fpu_get_scratch(dyn, ninst);
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETEX(v1, 0, 1); GETGX(v0, 1); u8 = F8; } else { GETGY(v0, 1, MODREG?((nextop&7)+(rex.b<<3)):-1, -1, -1); GETEY(v1); }
if(!l) { GETEX_Y(v1, 0, 1); GETGX(v0, 1); u8 = F8; } else { GETGY(v0, 1, MODREG?((nextop&7)+(rex.b<<3)):-1, -1, -1); GETEY(v1); }
if(u8==0b00000000 || u8==0b01010101 || u8==0b10101010 || u8==0b11111111) {
if(v0==v1) {
VMOVQ(d0, v1);
@@ -354,30 +421,85 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
case 0x7C:
INST_NAME("VHADDPS Gx, Vx, Ex");
nextop = F8;
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
q1 = fpu_get_scratch(dyn, ninst);
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
if(!BOX64ENV(dynarec_fastnan)) {
// check if any input value was NAN
VFMAXPQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFADDPQS(v0, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
VFCMEQQS(q1, v0, v0); // 0 => out is NAN
VBICQ(q1, q0, q1); // forget it in any input was a NAN already
VSHLQ_32(q1, q1, 31); // only keep the sign bit
VORRQ(v0, v0, q1); // NAN -> -NAN
}
}
if(!vex.l) YMM0(gd);
break;
case 0x7D:
INST_NAME("VHSUBPS Gx, Vx, Ex");
nextop = F8;
q0 = fpu_get_scratch(dyn, ninst);
if(!BOX64ENV(dynarec_fastnan))
q1 = fpu_get_scratch(dyn, ninst);
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
VUZP1Q_32(q0, v2, v1);
VUZP2Q_32(v0, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
// check if any input value was NAN
// but need to mix low/high part
VFMAXQS(q1, v0, q0); // propagate NAN
VFCMEQQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
}
VFSUBQS(v0, q0, v0);
if(!BOX64ENV(dynarec_fastnan)) {
VFCMEQQS(q0, v0, v0); // 0 => out is NAN
VBICQ(q1, q1, q0); // forget it in any input was a NAN already
VSHLQ_32(q1, q1, 31); // only keep the sign bit
VORRQ(v0, v0, q1); // NAN -> -NAN
}
}
if(!vex.l) YMM0(gd);
break;
case 0xC2:
INST_NAME("CMPSD Gx, Ex, Ib");
INST_NAME("VCMPSD Gx, Ex, Ib");
nextop = F8;
GETEXSD(v1, 0, 1);
GETGX_empty_VX(v0, v2);
u8 = F8;
FCMPD(v2, v1);
if(((u8&15)!=0x0b) && ((u8&15)!=0x0f)) {
if((u8&15)>7)
FCMPD(v1, v2);
else
FCMPD(v2, v1);
}
// TODO: create a test for this one, there might be an issue with cases 9, 10 and 13
if(v0!=v2) VMOVQ(v0, v2);
switch(u8&7) {
case 0: CSETMx(x2, cEQ); break; // Equal
case 1: CSETMx(x2, cCC); break; // Less than
case 2: CSETMx(x2, cLS); break; // Less or equal
case 3: CSETMx(x2, cVS); break; // NaN
case 4: CSETMx(x2, cNE); break; // Not Equal or unordered
case 5: CSETMx(x2, cCS); break; // Greater or equal or unordered
case 6: CSETMx(x2, cHI); break; // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
case 7: CSETMx(x2, cVC); break; // not NaN
switch(u8&15) {
case 0x00: CSETMx(x2, cEQ); break; // Equal
case 0x01: CSETMx(x2, cCC); break; // Less than
case 0x02: CSETMx(x2, cLS); break; // Less or equal
case 0x03: CSETMx(x2, cVS); break; // NaN
case 0x04: CSETMx(x2, cNE); break; // Not Equal or unordered
case 0x05: CSETMx(x2, cCS); break; // Greater or equal or unordered
case 0x06: CSETMx(x2, cHI); break; // Greater or unordered
case 0x07: CSETMx(x2, cVC); break; // not NaN
case 0x08: CSETMx(x2, cEQ); CSETMx(x3, cVS); ORRx_REG(x2, x2, x3); break; // Equal or unordered
case 0x09: CSETMx(x2, cHI); break; // Less than or unordered
case 0x0a: CSETMx(x2, cCS); break; // Less or equal or unordered
case 0x0b: MOV32w(x2, 0); break; // false
case 0x0c: CSETMw(x2, cNE); CSETMx(x3, cVS); BICx(x2, x2, x3); break; // Not Equal not unordered
case 0x0d: CSETMw(x2, cLS); break; // Greater or equal not unordered
case 0x0e: CSETMw(x2, cCC); break; // Greater not unordered
case 0x0f: MOV64x(x2, 0xffffffffffffffffLL); break; // true
}
VMOVQDfrom(v0, 0, x2);
YMM0(gd);
@@ -389,13 +511,16 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
q0 = fpu_get_scratch(dyn, ninst);
static float addsubps[4] = {-1.f, 1.f, -1.f, 1.f};
MAYUSE(addsubps);
TABLE64(x2, (uintptr_t)&addsubps);
MOV64x(x2, (uintptr_t)&addsubps);
VLDR128_U12(q0, x2, 0);
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); if(v0==v1) q1 = fpu_get_scratch(dyn, ninst); } else { GETGY_empty_VYEY(v0, v2, v1); }
if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
if(v0==v1) {
VFMULQS(q1, v1, q0);
VFADDQS(v0, v2, q1);
//TODO: find a better way
if(!l) q1 = fpu_get_scratch(dyn, ninst);
VMOVQ(q1, v2);
VFMLAQS(q1, v1, q0);
VMOVQ(v0, q1);
} else {
if(v0!=v2) VMOVQ(v0, v2);
VFMLAQS(v0, v1, q0);
@@ -412,12 +537,12 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
if(!l) {
GETEX_Y(v1, 0, 0);
GETGX_empty(v0);
if(!box64_dynarec_fastround || vex.l)
if(!BOX64ENV(dynarec_fastround) || vex.l)
d0 = fpu_get_scratch(dyn, ninst);
} else {
GETEY(v1);
}
if(box64_dynarec_fastround) {
if(BOX64ENV(dynarec_fastround)) {
VFRINTIDQ(l?d0:v0, v1);
VFCVTNSQD(l?d0:v0, l?d0:v0); // convert double -> int64
if(!l)
@@ -425,28 +550,35 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
else
SQXTN2_32(v0, d0); // convert int64 -> int32 with saturation in higher part
} else {
if(!l) {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
ORRw_mask(x4, xZR, 1, 0); //0x80000000
}
for(int i=0; i<2; ++i) {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
if(i) {
VMOVeD(d0, 0, v1, i);
FRINTID(d0, d0);
} else {
FRINTID(d0, v1);
if(arm64_frintts) {
VFRINT32XDQ(l?d0:v0, v1); // round, handling of overflow and Nan to 0x80000000
VFCVTNSQD(l?d0:v0, l?d0:v0); // convert double -> int64
if(!l)
SQXTN_32(v0, v0); // convert int64 -> int32 with saturation in lower part, RaZ high part
else
SQXTN2_32(v0, d0); // convert int64 -> int32 with saturation in higher part
} else {
if(!l) {
MRS_fpsr(x5);
ORRw_mask(x4, xZR, 1, 0); //0x80000000
}
FCVTZSwD(x1, d0);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TSTw_mask(x5, 0, 0); // mask = 1 = FPSR_IOC
CSELx(x1, x1, x4, cEQ);
VMOVQSfrom(v0, i+l*2, x1);
for(int i=0; i<2; ++i) {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
if(i) {
VMOVeD(d0, 0, v1, i);
FRINTID(d0, d0);
} else {
FRINTID(d0, v1);
}
FCVTZSwD(x1, d0);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TSTw_mask(x5, 0, 0); // mask = 1 = FPSR_IOC
CSELx(x1, x1, x4, cEQ);
VMOVQSfrom(v0, i+l*2, x1);
}
if(!vex.l && !l) VMOVQDfrom(v0, 1, xZR);
}
if(!vex.l && !l) VMOVQDfrom(v0, 1, xZR);
}
}
x87_restoreround(dyn, ninst, u8);
@@ -454,7 +586,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
break;
case 0xF0:
INST_NAME("LDDQU Gx,Ex");
INST_NAME("VLDDQU Gx,Ex");
nextop = F8;
GETG;
if(MODREG) {
@@ -467,11 +599,10 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
}
} else {
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
v1 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1, -1);
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 7, rex, NULL, 0, 0);
VLDR128_U12(v0, ed, fixedaddress);
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1, -1);
VLDR128_U12(v0, ed, fixedaddress+16);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0x3f<<4, 15, rex, NULL, 1, 0);
VLDP128_I7(v0, v1, ed, fixedaddress);
}
if(!vex.l) YMM0(gd);
break;
+41 -8
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -60,7 +58,36 @@ uintptr_t dynarec64_AVX_F2_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
rex_t rex = vex.rex;
switch(opcode) {
case 0xF5:
INST_NAME("PDEP Gd, Ed, Vd");
nextop = F8;
GETGD;
GETED(0);
GETVD;
if(gd==ed || gd==vd) {
gb1 = gd;
gd = x4;
} else {
gb1 = 0;
}
// x3 = mask of mask, loop while not 0
MOV32w(gd, 0);
MOV64x(x2, 1);
MOV64x(x3, 1);
MARK;
TSTxw_REG(ed, x3);
B_MARK2(cEQ);
TSTxw_REG(vd, x2);
B_MARK3(cEQ);
ORRxw_REG(gd, gd, x3);
MARK3;
LSLxw_IMM(x2, x2, 1);
MARK2;
LSLxw_IMM(x3, x3, 1);
CBNZxw_MARK(x3);
if(gb1)
MOVxw_REG(gb1, gd);
break;
case 0xF6:
INST_NAME("MULX Gd, Vd, Ed (,RDX)");
nextop = F8;
@@ -69,13 +96,19 @@ uintptr_t dynarec64_AVX_F2_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
GETVD;
if(rex.w) {
// 64bits mul
UMULH(x3, xRDX, ed);
MULx(vd, xRDX, ed);
MOVx_REG(gd, x3);
if((gd==xRDX) || (gd==ed) || (gd==vd))
gb1 = x3;
else
gb1 = gd;
UMULH(gb1, xRDX, ed);
if(gd!=vd) {MULx(vd, xRDX, ed);}
if(gb1==x3) {
MOVx_REG(gd, gb1);
}
} else {
// 32bits mul
UMULL(x3, xRDX, ed);
MOVw_REG(vd, x3);
if(gd!=vd) {MOVw_REG(vd, x3);}
LSRx(gd, x3, 32);
}
break;
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
+171 -72
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -108,7 +106,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
break;
case 0x16:
INST_NAME("MOVSHDUP Gx, Ex");
INST_NAME("VMOVSHDUP Gx, Ex");
nextop = F8;
GETEX_Y(q1, 0, 0);
GETGX_empty(q0);
@@ -125,11 +123,17 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
d1 = fpu_get_scratch(dyn, ninst);
GETGX_empty_VX(v0, v1);
GETED(0);
if(BOX64ENV(dynarec_fastround)<2) {
u8 = sse_setround(dyn, ninst, x3, x4, x5);
}
if(rex.w) {
SCVTFSx(d1, ed);
} else {
SCVTFSw(d1, ed);
}
if(BOX64ENV(dynarec_fastround)<2) {
x87_restoreround(dyn, ninst, u8);
}
if(v0!=v1) VMOVQ(v0, v1);
VMOVeS(v0, 0, d1, 0);
YMM0(gd);
@@ -140,13 +144,23 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
nextop = F8;
GETGD;
GETEXSS(d0, 0, 0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround) && !arm64_frintts) {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
}
FCVTZSxwS(gd, d0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround) && arm64_frintts) {
v0 = fpu_get_scratch(dyn, ninst);
if(rex.w) {
FRINT64ZS(v0, d0);
} else {
FRINT32ZS(v0, d0);
}
FCVTZSxwS(gd, v0);
} else {
FCVTZSxwS(gd, d0);
}
if(!BOX64ENV(dynarec_fastround) && !arm64_frintts) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
@@ -161,17 +175,25 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
nextop = F8;
GETGD;
GETEXSS(q0, 0, 0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround) && !arm64_frintts) {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
}
u8 = sse_setround(dyn, ninst, x1, x2, x3);
d1 = fpu_get_scratch(dyn, ninst);
FRINTIS(d1, q0);
if(!BOX64ENV(dynarec_fastround) && arm64_frintts) {
if(rex.w) {
FRINT64XS(d1, q0);
} else {
FRINT32XS(d1, q0);
}
} else {
FRINTIS(d1, q0);
}
x87_restoreround(dyn, ninst, u8);
FCVTZSxwS(gd, d1);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround) && !arm64_frintts) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
@@ -183,12 +205,24 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
break;
case 0x51:
INST_NAME("SQRTSS Gx, Ex");
INST_NAME("VSQRTSS Gx, Ex");
nextop = F8;
GETEXSS(d0, 0, 0);
GETGX_empty_VX(v0, v2);
d1 = fpu_get_scratch(dyn, ninst);
if(!BOX64ENV(dynarec_fastnan)) {
q0 = fpu_get_scratch(dyn, ninst);
q1 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FCMEQS(q0, v1, v1); // 0 if NAN, 1 if not NAN
}
FSQRTS(d1, d0);
if(!BOX64ENV(dynarec_fastnan)) {
FCMEQS(q1, d1, d1); // 0 => out is NAN
VBIC(q1, q0, q1); // forget it in any input was a NAN already
VSHL_32(q1, q1, 31); // only keep the sign bit
VORR(d1, d1, q1); // NAN -> -NAN
}
if(v0!=v2) VMOVQ(v0, v2);
VMOVeS(v0, 0, d1, 0);
YMM0(gd);
@@ -234,35 +268,53 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
case 0x58:
INST_NAME("VADDSS Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
q2 = fpu_get_scratch(dyn, ninst);
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
if(!BOX64ENV(dynarec_fastnan)) {
q1 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXS(q1, v0, v1); // propagate NAN
FCMEQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
FADDS(q2, v1, v2); // the high part of the vector is erased...
FCMEQS(q0, q2, q2); // 0 => out is NAN
VBIC(q0, q1, q0); // forget it in any input was a NAN already
VSHL_32(q0, q0, 31); // only keep the sign bit
VORR(q2, q2, q0); // NAN -> -NAN
} else {
FADDS(q2, v1, v2); // the high part of the vector is erased...
}
if(v0!=v2) {
if(v0==v1) {
VMOV(d1, v1);
v1 = d1;
}
VMOVQ(v0, v2);
}
FADDS(d1, v0, v1);
VMOVeS(v0, 0, d1, 0);
VMOVeS(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x59:
INST_NAME("VMULSS Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
q2 = fpu_get_scratch(dyn, ninst);
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
if(!BOX64ENV(dynarec_fastnan)) {
q1 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXS(q1, v0, v1); // propagate NAN
FCMEQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
FMULS(q2, v1, v2); // the high part of the vector is erased...
FCMEQS(q0, q2, q2); // 0 => out is NAN
VBIC(q0, q1, q0); // forget it in any input was a NAN already
VSHL_32(q0, q0, 31); // only keep the sign bit
VORR(q2, q2, q0); // NAN -> -NAN
} else {
FMULS(q2, v1, v2); // the high part of the vector is erased...
}
if(v0!=v2) {
if(v0==v1) {
VMOV(d1, v1);
v1 = d1;
}
VMOVQ(v0, v2);
}
FMULS(d1, v0, v1);
VMOVeS(v0, 0, d1, 0);
VMOVeS(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x5A:
@@ -271,41 +323,43 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
d1 = fpu_get_scratch(dyn, ninst);
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
if(v0!=v2) {
if(v0==v1) {
VMOV(d1, v1);
v1 = d1;
}
VMOVQ(v0, v2);
}
FCVT_D_S(d1, v1);
VMOVeD(v0, 0, d1, 0);
if(v0!=v2)
VMOVeD(v0, 1, v2, 1);
YMM0(gd);
break;
case 0x5B:
INST_NAME("VCVTTPS2DQ Gx, Ex");
nextop = F8;
d0 = fpu_get_scratch(dyn, ninst);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5);
ORRw_mask(x4, xZR, 1, 0); //0x80000000
}
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_EX(v0, v1, 0); } else { GETGY_empty_EY(v0, v1); }
if(box64_dynarec_fastround) {
if(BOX64ENV(dynarec_fastround)) {
VFCVTZSQS(v0, v1);
} else {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
for(int i=0; i<4; ++i) {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
VMOVeS(d0, 0, v1, i);
VFCVTZSs(d0, d0);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ(x5, FPSR_IOC, 4+4);
VMOVQSfrom(d0, 0, x4);
VMOVeS(v0, i, d0, 0);
if(arm64_frintts) {
VFRINT32ZSQ(v0, v1);
VFCVTZSQS(v0, v0);
} else {
for(int i=0; i<4; ++i) {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
if(i) {
VMOVeS(d0, 0, v1, i);
VFCVTZSs(d0, d0);
} else {
VFCVTZSs(d0, v1);
}
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ(x5, FPSR_IOC, 4+4);
VMOVQSfrom(d0, 0, x4);
VMOVeS(v0, i, d0, 0);
}
}
}
}
@@ -314,14 +368,27 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
case 0x5C:
INST_NAME("VSUBSS Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
q2 = fpu_get_scratch(dyn, ninst);
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FSUBS(d1, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q1 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXS(q1, v0, v1); // propagate NAN
FCMEQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
FSUBS(q2, v2, v1); // the high part of the vector is erased...
FCMEQS(q0, q2, q2); // 0 => out is NAN
VBIC(q0, q1, q0); // forget it in any input was a NAN already
VSHL_32(q0, q0, 31); // only keep the sign bit
VORR(q2, q2, q0); // NAN -> -NAN
} else {
FSUBS(q2, v2, v1); // the high part of the vector is erased...
}
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeS(v0, 0, d1, 0);
VMOVeS(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x5D:
@@ -331,7 +398,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FCMPS(v2, v1);
FCSELS(d1, v1, v2, cCS);
FCSELS(d1, v1, v2, cCS); //CS: NAN or == or Ex > Vx
if(v0!=v2) {
VMOVQ(v0, v2);
}
@@ -341,14 +408,27 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
case 0x5E:
INST_NAME("VDIVSS Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
q2 = fpu_get_scratch(dyn, ninst);
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FDIVS(d1, v2, v1);
if(!BOX64ENV(dynarec_fastnan)) {
q1 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXS(q1, v0, v1); // propagate NAN
FCMEQS(q1, q1, q1); // 0 if NAN, 1 if not NAN
FDIVS(q2, v2, v1); // the high part of the vector is erased...
FCMEQS(q0, q2, q2); // 0 => out is NAN
VBIC(q0, q1, q0); // forget it in any input was a NAN already
VSHL_32(q0, q0, 31); // only keep the sign bit
VORR(q2, q2, q0); // NAN -> -NAN
} else {
FDIVS(q2, v2, v1); // the high part of the vector is erased...
}
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeS(v0, 0, d1, 0);
VMOVeS(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x5F:
@@ -358,7 +438,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FCMPS(v1, v2);
FCSELS(d1, v1, v2, cCS);
FCSELS(d1, v1, v2, cCS); //CS: NAN or == or Ex > Vx
if(v0!=v2) {
VMOVQ(v0, v2);
}
@@ -370,22 +450,22 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
INST_NAME("VMOVDQU Gx, Ex");// no alignment constraint on NEON here, so same as MOVDQA
nextop = F8;
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
GETGX_empty(v0);
GETGX_empty_EX(v0, v1, 0);
VMOVQ(v0, v1);
if(vex.l) {
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0, gd, -12, -1);
GETGY_empty(v0, (nextop&7)+(rex.b<<3), -1, -1);
GETGY_empty_EY(v0, v1);
VMOVQ(v0, v1);
}
} else {
GETGX_empty(v0);
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
VLDR128_U12(v0, ed, fixedaddress);
if(vex.l) {
GETGY_empty(v0, -1, -1, -1);
VLDR128_U12(v0, ed, fixedaddress+16);
GETGY_empty(v1, -1, -1, -1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0x3f<<4, 15, rex, NULL, 1, 0);
VLDP128_I7(v0, v1, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VLD128(v0, ed, fixedaddress);
}
}
if(!vex.l) YMM0(gd);
@@ -395,7 +475,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
nextop = F8;
d0 = fpu_get_scratch(dyn, ninst);
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETEX(v1, 0, 1); GETGX(v0, 1); u8 = F8; } else { GETGY(v0, 1, MODREG?((nextop&7)+(rex.b<<3)):-1, -1, -1); GETEY(v1); }
if(!l) { GETEX_Y(v1, 0, 1); GETGX(v0, 1); u8 = F8; } else { GETGY(v0, 1, MODREG?((nextop&7)+(rex.b<<3)):-1, -1, -1); GETEY(v1); }
if(u8==0b00000000 || u8==0b01010101 || u8==0b10101010 || u8==0b11111111) {
VDUP_16(d0, v1, 4+(u8&3));
} else {
@@ -420,7 +500,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
break;
case 0x7E:
INST_NAME("MOVQ Gx, Ex");
INST_NAME("VMOVQ Gx, Ex");
nextop = F8;
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 0);
@@ -439,19 +519,38 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3));
ed = (nextop&7) + (rex.b<<3);
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
VMOVQ(v1, v0);
if(vex.l) {
GETGY(v0, 0, (nextop&7) + (rex.b<<3), -1, -1);
v1 = ymm_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3), gd, -1, -1);
GETGY(v0, 0, ed, -1, -1);
v1 = ymm_get_reg_empty(dyn, ninst, x1, ed, gd, -1, -1);
VMOVQ(v1, v0);
} // no ymm raz here it seems
} else YMM0(ed);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
VSTR128_U12(v0, ed, fixedaddress);
if(vex.l) {
GETGY(v0, 0, -1, -1, -1);
VSTR128_U12(v0, ed, fixedaddress+16);
IF_UNALIGNED(ip) {
MESSAGE(LOG_DEBUG, "\tUnaligned path");
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
for(int i=0; i<16; ++i) {
VST1_8(v0, i, i?x1:wback);
ADDx_U12(x1, i?x1:wback, 1);
}
if(vex.l) {
GETGY(v0, 0, -1, -1, -1);
for(int i=0; i<16; ++i) {
VST1_8(v0, i, x1);
ADDx_U12(x1, x1, 1);
}
}
} else {
if(vex.l) {
GETGY(v1, 0, -1, -1, -1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0x3f<<4, 15, rex, NULL, 1, 0);
VSTP128_I7(v0, v1, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VST128(v0, ed, fixedaddress);
}
}
SMWRITE2();
}
+30 -3
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -61,6 +59,35 @@ uintptr_t dynarec64_AVX_F3_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
switch(opcode) {
case 0xF5:
INST_NAME("PEXT Gd, Ed, Vd");
nextop = F8;
GETGD;
GETED(0);
GETVD;
if(gd==ed || gd==vd) {
gb1 = gd;
gd = x4;
} else {
gb1 = 0;
}
// x3 = mask of mask, loop while not 0
MOV32w(gd, 0);
MOV64x(x3, 1LL<<(rex.w?63:31));
MARK;
TSTxw_REG(ed, x3);
B_MARK2(cEQ); // mask not set
TSTxw_REG(vd, x3);
CSINCxw(gd, gd, gd, cEQ); // return gd if TRUE, else gd+1
RORxw(gd, gd, 1);
MARK2;
LSRxw_IMM(x3, x3, 1);
CBNZxw_MARK(x3);
RBITxw(gd, gd);
if(gb1)
MOVxw_REG(gb1, gd);
break;
case 0xF7:
INST_NAME("SARX Gd, Ed, Vd");
nextop = F8;
+66 -7
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -29,6 +27,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
uint8_t nextop = F8;
uint8_t ed;
uint8_t u8;
int64_t fixedaddress;
int unscaled;
int v1, v2;
@@ -51,11 +50,16 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FADD ST0, STx");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FADDS(v1, v1, v2);
} else {
FADDD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xC8:
case 0xC9:
@@ -68,11 +72,16 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FMUL ST0, STx");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FMULS(v1, v1, v2);
} else {
FMULD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xD0:
case 0xD1:
@@ -90,7 +99,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
break;
case 0xD8:
case 0xD9:
@@ -108,7 +117,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
@@ -122,11 +131,16 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FSUB ST0, STx");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FSUBS(v1, v1, v2);
} else {
FSUBD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xE8:
case 0xE9:
@@ -139,11 +153,16 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FSUBR ST0, STx");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FSUBS(v1, v2, v1);
} else {
FSUBD(v1, v2, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xF0:
case 0xF1:
@@ -156,11 +175,16 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FDIV ST0, STx");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FDIVS(v1, v1, v2);
} else {
FDIVD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xF8:
case 0xF9:
@@ -173,11 +197,16 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FDIVR ST0, STx");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FDIVS(v1, v2, v1);
} else {
FDIVD(v1, v2, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
default:
DEFAULT;
@@ -190,12 +219,17 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
s0 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
if(ST_IS_F(0)) {
FADDS(v1, v1, s0);
} else {
FCVT_D_S(s0, s0);
FADDD(v1, v1, s0);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 1:
INST_NAME("FMUL ST0, float[ED]");
@@ -203,12 +237,17 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
s0 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
if(ST_IS_F(0)) {
FMULS(v1, v1, s0);
} else {
FCVT_D_S(s0, s0);
FMULD(v1, v1, s0);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 2:
INST_NAME("FCOM ST0, float[ED]");
@@ -222,7 +261,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCVT_D_S(s0, s0);
FCMPD(v1, s0);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FCOMP ST0, float[ED]");
@@ -236,7 +275,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCVT_D_S(s0, s0);
FCMPD(v1, s0);
}
FCOM(x1, x2, x3, x4, v1, s0, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
@@ -245,12 +284,17 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
s0 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
if(ST_IS_F(0)) {
FSUBS(v1, v1, s0);
} else {
FCVT_D_S(s0, s0);
FSUBD(v1, v1, s0);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 5:
INST_NAME("FSUBR ST0, float[ED]");
@@ -258,12 +302,17 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
s0 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
if(ST_IS_F(0)) {
FSUBS(v1, s0, v1);
} else {
FCVT_D_S(s0, s0);
FSUBD(v1, s0, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 6:
INST_NAME("FDIV ST0, float[ED]");
@@ -271,12 +320,17 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
s0 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
if(ST_IS_F(0)) {
FDIVS(v1, v1, s0);
} else {
FCVT_D_S(s0, s0);
FDIVD(v1, v1, s0);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 7:
INST_NAME("FDIVR ST0, float[ED]");
@@ -284,12 +338,17 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
s0 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
if(ST_IS_F(0)) {
FDIVS(v1, s0, v1);
} else {
FCVT_D_S(s0, s0);
FDIVD(v1, s0, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
default:
DEFAULT;
+62 -24
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -128,7 +126,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD_0(v1);
}
FCOM(x1, x2, x3, x4, 0, 0, ST_IS_F(0)); // same flags...
FCOM(x1, x2, x3); // same flags...
break;
case 0xE5:
INST_NAME("FXAM");
@@ -270,7 +268,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xF0:
INST_NAME("F2XM1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (F2XM1)\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_f2xm1, -1);
@@ -278,7 +276,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xF1:
INST_NAME("FYL2X");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FYL2X)\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
@@ -288,11 +286,15 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xF2:
INST_NAME("FPTAN");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FPTAN)\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_ftan, -1);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
CALL_(native_ftan, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
x87_unstackcount(dyn, ninst, x1, i1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
if(PK(0)==0xdd && PK(1)==0xd8) {
MESSAGE(LOG_DUMP, "Optimized next DD D8 fstp st0, st0, not emitting 1\n");
u8 = F8;
@@ -308,17 +310,21 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xF3:
INST_NAME("FPATAN");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FPATAN)\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fpatan, -1);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
CALL_(native_fpatan, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
x87_unstackcount(dyn, ninst, x1, i1);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF4:
INST_NAME("FXTRACT");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FXTRACT)\n");
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 1);
@@ -327,8 +333,8 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xF5:
INST_NAME("FPREM1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
#if 0
MESSAGE(LOG_DUMP, "Need Optimization\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
@@ -407,7 +413,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xF9:
INST_NAME("FYL2XP1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FYL2XP1)\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
@@ -418,19 +424,28 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xFA:
INST_NAME("FSQRT");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FSQRTS(v1, v1);
} else {
FSQRTD(v1, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xFB:
INST_NAME("FSINCOS");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FSINCOS)\n");
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fsincos, -1);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
CALL_(native_fsincos, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
x87_unstackcount(dyn, ninst, x1, i1);
break;
case 0xFC:
@@ -453,27 +468,39 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xFD:
INST_NAME("FSCALE");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FSCALE)\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fscale, -1);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
CALL_(native_fscale, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
x87_unstackcount(dyn, ninst, x1, i1);
break;
case 0xFE:
INST_NAME("FSIN");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FSIN)\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_fsin, -1);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
CALL_(native_fsin, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
x87_unstackcount(dyn, ninst, x1, i1);
break;
case 0xFF:
INST_NAME("FCOS");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FCOS)\n");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_fcos, -1);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
CALL_(native_fcos, -1, BOX64ENV(dynarec_fastround) ? 0 : u8);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
x87_unstackcount(dyn, ninst, x1, i1);
break;
default:
@@ -483,7 +510,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("FLD ST0, float[ED]");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, box64_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, (BOX64ENV(dynarec_x87double)==1)?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v1, ed, fixedaddress);
if(!ST_IS_F(0)) {
@@ -497,7 +524,11 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
s0 = v1;
else {
s0 = fpu_get_scratch(dyn, ninst);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
FCVT_S_D(s0, v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
}
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VST32(s0, ed, fixedaddress);
@@ -507,14 +538,18 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
if(!ST_IS_F(0)) {
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
FCVT_S_D(v1, v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
}
VST32(v1, ed, fixedaddress);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FLDENV Ed");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FLDENV)\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3); // maybe only x87, not SSE?
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {
@@ -522,15 +557,18 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
MOV32w(x2, 0);
CALL(fpu_loadenv, -1);
NATIVE_RESTORE_X87PC();
break;
case 5:
INST_NAME("FLDCW Ew");
GETEW(x1, 0);
STRH_U12(x1, xEmu, offsetof(x64emu_t, cw)); // hopefully cw is not too far for an imm8
if(dyn->need_x87check)
UBFXw(x87pc, x1, 8, 2);
break;
case 6:
INST_NAME("FNSTENV Ed");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FNSTENV)\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3); // maybe only x87, not SSE?
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {
+35 -6
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -29,6 +27,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
int64_t j64;
uint8_t ed;
uint8_t wback;
uint8_t u8;
int v1, v2;
int d0;
int s0;
@@ -130,7 +129,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
@@ -148,7 +147,12 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
FADDD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 1:
INST_NAME("FIMUL ST0, Ed");
@@ -158,7 +162,12 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
FMULD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 2:
INST_NAME("FICOM ST0, Ed");
@@ -169,7 +178,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FCMPD(v1, v2);
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FICOMP ST0, Ed");
@@ -180,7 +189,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FCMPD(v1, v2);
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
@@ -191,7 +200,12 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
FSUBD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 5:
INST_NAME("FISUBR ST0, Ed");
@@ -201,7 +215,12 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
FSUBD(v1, v2, v1);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 6:
INST_NAME("FIDIV ST0, Ed");
@@ -211,7 +230,12 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
FDIVD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 7:
INST_NAME("FIDIVR ST0, Ed");
@@ -221,7 +245,12 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x5, x4);
FDIVD(v1, v2, v1);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
}
return addr;
+78 -72
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -127,16 +125,16 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xE2:
INST_NAME("FNCLEX");
LDRH_U12(x2, xEmu, offsetof(x64emu_t, sw));
MOV32w(x1, 0);
BFIw(x2, x1, 0, 8); // IE .. PE, SF, ES
BFIw(x2, x1, 15, 1); // B
BFCw(x2, 0, 8); // IE .. PE, SF, ES
BFCw(x2, 15, 1); // B
STRH_U12(x2, xEmu, offsetof(x64emu_t, sw));
break;
case 0xE3:
INST_NAME("FNINIT");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FNINIT)\n");
x87_purgecache(dyn, ninst, 0, x1, x2, x3);
CALL(reset_fpu, -1);
NATIVE_RESTORE_X87PC();
break;
case 0xE8:
case 0xE9:
@@ -155,7 +153,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOMI(x1, x2, x4, v1, v2, ST_IS_F(0));
FCOMI(x1, x2);
break;
case 0xF0:
case 0xF1:
@@ -174,7 +172,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOMI(x1, x2, x4, v1, v2, ST_IS_F(0));
FCOMI(x1, x2);
break;
default:
@@ -202,13 +200,17 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
BFCw(x5, FPSR_QC, 1); // reset QC bit
MSR_fpsr(x5);
FRINTZD(s0, v1);
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
VST32(s0, wback, fixedaddress);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_MARK3(x5, FPSR_IOC);
TBNZ_MARK2(x5, FPSR_IOC);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x5, 0x80000000);
STW(x5, wback, fixedaddress);
MARK3;
@@ -228,13 +230,17 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
BFCw(x5, FPSR_QC, 1); // reset QC bit
MSR_fpsr(x5);
FRINTXD(s0, v1);
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
VST32(s0, wback, fixedaddress);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_MARK3(x5, FPSR_IOC);
TBNZ_MARK2(x5, FPSR_IOC);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x5, 0x80000000);
STW(x5, wback, fixedaddress);
MARK3;
@@ -254,13 +260,17 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
BFCw(x5, FPSR_QC, 1); // reset QC bit
MSR_fpsr(x5);
FRINTXD(s0, v1);
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
VST32(s0, wback, fixedaddress);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_MARK3(x5, FPSR_IOC);
TBNZ_MARK2(x5, FPSR_IOC);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x5, 0x80000000);
STW(x5, wback, fixedaddress);
MARK3;
@@ -289,7 +299,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STRx_U12(x5, ed, 0);
STRH_U12(x6, ed, 8);
} else {
if(box64_x87_no80bits) {
if(BOX64ENV(x87_no80bits)) {
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
VLDR64_U12(v1, ed, fixedaddress);
} else {
@@ -298,77 +308,73 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
// sync top
s0 = x87_stackcount(dyn, ninst, x3);
x87_reflectcount(dyn, ninst, x3, x4);
CALL(native_fld, -1);
// go back with the top & stack counter
x87_unstackcount(dyn, ninst, x3, s0);
x87_unreflectcount(dyn, ninst, x3, x4);
}
}
break;
case 7:
INST_NAME("FSTP tbyte");
if(box64_x87_no80bits) {
if(BOX64ENV(x87_no80bits)) {
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v1, wback, fixedaddress);
} else {
#if 0
x87_forget(dyn, ninst, x1, x3, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {
MOVx_REG(x1, ed);
if(!BOX64ENV(dynarec_fastround)) {
x87_forget(dyn, ninst, x1, x3, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
x87_reflectcount(dyn, ninst, x3, x4);
CALL(native_fstp, -1);
x87_unreflectcount(dyn, ninst, x3, x4);
} else {
// Painfully long, straight conversion from the C code, shoud be optimized
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
FMOVxD(x1, v1);
// do special value first
TSTx_mask(x1, 1, 0b00000, 0b111110); //0x7fffffffffffffffL
B_MARK(cNE);
// Zero
LSRx(x3, x1, 63-15); //x3 = sign+exp
MOVZw(x5, 0); // x5 = mantisse
B_MARK3_nocond;
MARK;
// get sign, in main ouput x5 for sign+exp
ANDx_mask(x5, x1, 1, 1, 0); //0x8000000000000000
LSRx(x5, x5, 63-15); // x5 = sign
// get exp
LSRx(x3, x1, 52); // x3 = exp11
ANDw_mask(x3, x3, 0, 0b1010); //0x7ff
ANDSx_mask(x1, x1, 1, 0, 0b110011); //0x000fffffffffffffL
LSLx_IMM(x1, x1, 11); // mantice
CMPSw_U12(x3, 0x7ff);
B_MARK2(cNE);
// NaN and Infinite
ORRw_mask(x3, x5, 0, 0b1110); //x3 = sign | 0x7fff
ORRx_mask(x5, x1, 1, 1, 0); //0x8000000000000000
B_MARK3_nocond;
MARK2;
// regular / denormals
MOVZw(x4, 16383-1023); //BIAS80 - BIAS64
CBZw(x3, 4+4*4); // exp11 == 0?
// normals
ADDw_REG(x3, x3, x4); // x3 = exp16
ORRw_REG(x3, x3, x5); // x3 = sign | exp
ORRx_mask(x5, x1, 1, 1, 0); //0x8000000000000000 x5 = mantisse
B_MARK3_nocond;
// denormals
CLZx(x6, x1);
ADDw_U12(x6, x6, 1); // "one"
SUBw_REG(x3, x4, x6); // x3 = exp16
ORRw_REG(x3, x3, x5); // x3 = sign | exp16
LSLx_REG(x5, x1, x6); // x5 = mantisse
MARK3;
STRx_U12(x5, wback, 0);
STRH_U12(x3, wback, 8);
}
CALL(native_fstp, -1);
#else
// Painfully long, straight conversion from the C code, shoud be optimized
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
FMOVxD(x1, v1);
// do special value first
TSTx_mask(x1, 1, 0b00000, 0b111110); //0x7fffffffffffffffL
B_MARK(cNE);
// Zero
LSRx(x3, x1, 63-15); //x3 = sign+exp
MOVZw(x5, 0); // x5 = mantisse
B_MARK3_nocond;
MARK;
// get sign, in main ouput x5 for sign+exp
ANDx_mask(x5, x1, 1, 1, 0); //0x8000000000000000
LSRx(x5, x5, 63-15); // x5 = sign
// get exp
LSRx(x3, x1, 52); // x3 = exp11
ANDw_mask(x3, x3, 0, 0b1010); //0x7ff
MOV32w(x4, 0x7ff);
CMPSw_REG(x3, x4);
B_MARK2(cNE);
// NaN and Infinite
ORRw_mask(x3, x5, 0, 0b1110); //x3 = sign | 0x7fff
TSTx_mask(x1, 1, 0, 0b110011); //0x000fffffffffffffL
ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000
ORRx_mask(x4, xZR, 1, 0b10, 0b01); //0xc000000000000000
CSELx(x5, x5, x4, cEQ); // x5 = mantisse
B_MARK3_nocond;
MARK2;
// regular / denormals
ANDx_mask(x1, x1, 1, 0, 0b110011); //0x000fffffffffffffL
LSLx_IMM(x1, x1, 11); //x1 = mantisse missing "1"
MOVZw(x4, 16383-1023); //BIAS80 - BIAS64
CBZw(x3, 4+3*4); // exp11 == 0?
// normals
ADDw_REG(x3, x3, x4); // x3 = exp16
ORRw_REG(x3, x3, x5); // x3 = sign | exp
ORRx_mask(x5, x1, 1, 1, 0); //0x8000000000000000 x5 = mantisse
B_MARK3_nocond;
// denormals
CLZx(x6, x1);
ADDw_U12(x6, x6, 1); // "one"
SUBw_REG(x3, x4, x6); // x3 = exp16
ORRw_REG(x3, x3, x5); // x3 = sign | exp16
LSLx_REG(x5, x1, x6); // x5 = mantisse
MARK3;
STRx_U12(x5, wback, 0);
STRH_U12(x3, wback, 8);
#endif
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
+66 -7
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -29,6 +27,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
uint8_t nextop = F8;
uint8_t wback;
uint8_t u8;
int64_t fixedaddress;
int unscaled;
int v1, v2;
@@ -49,11 +48,16 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FADD STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FADDS(v1, v1, v2);
} else {
FADDD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xC8:
case 0xC9:
@@ -66,11 +70,16 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FMUL STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FMULS(v1, v1, v2);
} else {
FMULD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xD0:
case 0xD1:
@@ -88,7 +97,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
break;
case 0xD8:
case 0xD9:
@@ -106,7 +115,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
@@ -120,11 +129,16 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FSUBR STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FSUBS(v1, v2, v1);
} else {
FSUBD(v1, v2, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xE8:
case 0xE9:
@@ -137,11 +151,16 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FSUB STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FSUBS(v1, v1, v2);
} else {
FSUBD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xF0:
case 0xF1:
@@ -154,11 +173,16 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FDIVR STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FDIVS(v1, v2, v1);
} else {
FDIVD(v1, v2, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xF8:
case 0xF9:
@@ -171,11 +195,16 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FDIV STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FDIVS(v1, v1, v2);
} else {
FDIVD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
default:
DEFAULT;
@@ -188,7 +217,12 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
FADDD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 1:
INST_NAME("FMUL ST0, double[ED]");
@@ -196,7 +230,12 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
FMULD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 2:
INST_NAME("FCOM ST0, double[ED]");
@@ -205,7 +244,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
FCMPD(v1, v2);
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FCOMP ST0, double[ED]");
@@ -214,7 +253,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
FCMPD(v1, v2);
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
@@ -223,7 +262,12 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
FSUBD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 5:
INST_NAME("FSUBR ST0, double[ED]");
@@ -231,7 +275,12 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
FSUBD(v1, v2, v1);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 6:
INST_NAME("FDIV ST0, double[ED]");
@@ -239,7 +288,12 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
FDIVD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 7:
INST_NAME("FDIVR ST0, double[ED]");
@@ -247,7 +301,12 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
FDIVD(v1, v2, v1);
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
}
return addr;
+11 -11
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -118,7 +116,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
break;
case 0xE8:
case 0xE9:
@@ -136,7 +134,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
@@ -161,19 +159,20 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
s0 = fpu_get_scratch(dyn, ninst);
if(arm64_frintts) {
FRINT64ZD(s0, v1);
FCVTZSxD(x2, s0);
STx(x2, ed, fixedaddress);
VFCVTZSd(s0, s0);
VST64(s0, ed, fixedaddress);
} else {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
FRINTRRD(s0, v1, 3);
FCVTZSxD(x2, s0);
VFCVTZSd(s0, s0);
VST64(s0, ed, fixedaddress);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_MARK3(x5, FPSR_IOC);
ORRx_mask(x2, xZR, 1, 1, 0); //0x8000000000000000
MARK3;
STx(x2, ed, fixedaddress);
MARK3;
}
}
X87_POP_OR_FAIL(dyn, ninst, x3);
@@ -193,7 +192,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 4:
INST_NAME("FRSTOR m108byte");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FRSTOR)\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
@@ -201,12 +200,13 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 6:
INST_NAME("FNSAVE m108byte");
MESSAGE(LOG_DUMP, "Need Optimization\n");
MESSAGE(LOG_DUMP, "Need Optimization (FNSAVE)\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(native_fsave, -1);
CALL(reset_fpu, -1);
NATIVE_RESTORE_X87PC();
break;
case 7:
INST_NAME("FNSTSW m2byte");
+42 -7
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -29,6 +27,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
uint8_t nextop = F8;
uint8_t wback;
uint8_t u8;
int64_t fixedaddress;
int unscaled;
int v1, v2;
@@ -49,11 +48,16 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FADDP STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FADDS(v1, v1, v2);
} else {
FADDD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
@@ -67,11 +71,16 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FMULP STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FMULS(v1, v1, v2);
} else {
FMULD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD0:
@@ -90,7 +99,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD9:
@@ -102,7 +111,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
@@ -117,11 +126,16 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FSUBRP STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FSUBS(v1, v2, v1);
} else {
FSUBD(v1, v2, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE8:
@@ -135,11 +149,16 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FSUBP STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FSUBS(v1, v1, v2);
} else {
FSUBD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF0:
@@ -153,11 +172,16 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FDIVRP STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FDIVS(v1, v2, v1);
} else {
FDIVD(v1, v2, v1);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF8:
@@ -171,11 +195,16 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("FDIVP STx, ST0");
v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
if(!BOX64ENV(dynarec_fastround))
u8 = x87_setround(dyn, ninst, x1, x2, x4);
if(ST_IS_F(0)) {
FDIVS(v1, v1, v2);
} else {
FDIVD(v1, v1, v2);
}
X87_CHECK_PRECISION(v1);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
@@ -193,6 +222,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FADDD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
break;
case 1:
INST_NAME("FIMUL ST0, word[ED]");
@@ -204,6 +234,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FMULD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
break;
case 2:
INST_NAME("FICOM ST0, word[ED]");
@@ -215,7 +246,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FCMPD(v1, v2);
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FICOMP ST0, word[ED]");
@@ -227,7 +258,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FCMPD(v1, v2);
FCOM(x1, x2, x3, x4, v1, v2, ST_IS_F(0));
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
@@ -240,6 +271,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FSUBD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
break;
case 5:
INST_NAME("FISUBR ST0, word[ED]");
@@ -251,6 +283,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FSUBD(v1, v2, v1);
X87_CHECK_PRECISION(v1);
break;
case 6:
INST_NAME("FIDIV ST0, word[ED]");
@@ -262,6 +295,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FDIVD(v1, v1, v2);
X87_CHECK_PRECISION(v1);
break;
case 7:
INST_NAME("FIDIVR ST0, word[ED]");
@@ -273,6 +307,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FDIVD(v1, v2, v1);
X87_CHECK_PRECISION(v1);
break;
}
return addr;
+32 -27
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -109,7 +107,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOMI(x1, x2, x4, v1, v2, ST_IS_F(0));
FCOMI(x1, x2);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF0:
@@ -130,7 +128,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FCMPD(v1, v2);
}
FCOMI(x1, x2, x4, v1, v2, ST_IS_F(0));
FCOMI(x1, x2);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
@@ -175,12 +173,12 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VFCVTZSd(s0, v1);
SQXTN_S_D(s0, s0);
}
VMOVSto(x3, s0, 0);
SQXTN_H_S(s0, s0);
VMOVHto(x3, s0, 0);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBNZ_MARK2(x5, FPSR_IOC);
SXTHw(x5, x3); // check if 16bits value is fine
SUBw_REG(x5, x5, x3);
CBZw_MARK3(x5);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x3, 0x8000);
MARK3;
@@ -215,12 +213,12 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
}
VMOVSto(x3, s0, 0);
SQXTN_H_S(s0, s0);
VMOVHto(x3, s0, 0);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBNZ_MARK2(x5, FPSR_IOC);
SXTHw(x5, x3); // check if 16bits value is fine
SUBw_REG(x5, x5, x3);
CBZw_MARK3(x5);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x3, 0x8000);
MARK3;
@@ -245,6 +243,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
#else
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
BFCw(x5, FPSR_QC, 1); // reset QC bit
MSR_fpsr(x5);
if(ST_IS_F(0)) {
FRINTXS(s0, v1);
@@ -254,12 +253,12 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
}
VMOVSto(x3, s0, 0);
SQXTN_H_S(s0, s0);
VMOVHto(x3, s0, 0);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBNZ_MARK2(x5, FPSR_IOC);
SXTHw(x5, x3); // check if 16bits value is fine
SUBw_REG(x5, x5, x3);
CBZw_MARK3(x5);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x3, 0x8000);
MARK3;
@@ -355,16 +354,22 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
B_MARK3(c__);
MARK2;
}
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
FRINTXD(s0, v1);
VFCVTZSd(s0, s0);
VST64(s0, wback, fixedaddress);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_MARK3(x5, FPSR_IOC);
ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000
STx(x5, wback, fixedaddress);
if(arm64_frintts) {
FRINT64XD(s0, v1);
VFCVTZSd(s0, s0);
VST64(s0, wback, fixedaddress);
} else {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
FRINTXD(s0, v1);
VFCVTZSd(s0, s0);
VST64(s0, wback, fixedaddress);
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_MARK3(x5, FPSR_IOC);
ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000
STx(x5, wback, fixedaddress);
}
MARK3;
#endif
x87_restoreround(dyn, ninst, u8);
+43 -41
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -27,8 +25,8 @@ void emit_or32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3,
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, rex.w?d_or64:d_or32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
ORRxw_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -81,8 +79,8 @@ void emit_or32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int
}
IFX(X_PEND) {
SET_DF(s4, rex.w?d_or64:d_or32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
ORRxw_mask(s1, s1, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
@@ -130,8 +128,8 @@ void emit_xor32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, rex.w?d_xor64:d_xor32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
EORxw_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -177,17 +175,21 @@ void emit_xor32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
void emit_xor32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4)
{
int mask = convert_bitmask_xw(c);
if(!mask) {
if(!mask && !((!rex.w && c==0xffffffffLL) || (rex.w && c==0xffffffffffffffffLL))) {
MOV64xw(s3, c);
emit_xor32(dyn, ninst, rex, s1, s3, s3, s4);
return;
}
IFX(X_PEND) {
SET_DF(s4, rex.w?d_xor64:d_xor32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
if(!mask) {
MVNxw_REG(s1, s1);
} else {
EORxw_mask(s1, s1, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
}
EORxw_mask(s1, s1, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
@@ -233,8 +235,8 @@ void emit_and32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, rex.w?d_and64:d_and32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
IFX(X_ZF|X_SF|X_CF|X_OF) {
ANDSxw_REG(s1, s1, s2);
@@ -285,8 +287,8 @@ void emit_and32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in
}
IFX(X_PEND) {
SET_DF(s4, rex.w?d_and64:d_and32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
IFX(X_ZF|X_SF|X_CF|X_OF) {
ANDSxw_mask(s1, s1, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
@@ -332,8 +334,8 @@ void emit_or8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, d_or8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
ORRw_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -360,8 +362,8 @@ void emit_or8c(dynarec_arm_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4)
}
IFX(X_PEND) {
SET_DF(s4, d_or8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
ORRw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
@@ -383,8 +385,8 @@ void emit_xor8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, d_xor8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
EORx_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -411,8 +413,8 @@ void emit_xor8c(dynarec_arm_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4
}
IFX(X_PEND) {
SET_DF(s4, d_xor8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
EORw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
@@ -434,8 +436,8 @@ void emit_and8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, d_and8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
IFX(X_ZF) {
ANDSw_REG(s1, s1, s2);
@@ -479,8 +481,8 @@ void emit_and8c(dynarec_arm_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4
}
IFX(X_PEND) {
SET_DF(s4, d_and8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
IFX(X_ZF) {
ANDSw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
@@ -519,8 +521,8 @@ void emit_or16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, d_or16);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
ORRw_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -547,8 +549,8 @@ void emit_or16c(dynarec_arm_t* dyn, int ninst, int s1, int16_t c, int s3, int s4
}
IFX(X_PEND) {
SET_DF(s4, d_or16);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
ORRw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
@@ -570,8 +572,8 @@ void emit_xor16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, d_xor16);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
EORw_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -598,8 +600,8 @@ void emit_xor16c(dynarec_arm_t* dyn, int ninst, int s1, int16_t c, int s3, int s
}
IFX(X_PEND) {
SET_DF(s4, d_xor16);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
EORw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
@@ -622,8 +624,8 @@ void emit_and16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s4, d_and16);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
IFX(X_ZF) {
ANDSw_REG(s1, s1, s2);
@@ -667,8 +669,8 @@ void emit_and16c(dynarec_arm_t* dyn, int ninst, int s1, int16_t c, int s3, int s
}
IFX(X_PEND) {
SET_DF(s4, d_and16);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
IFX(X_ZF) {
ANDSw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
+59 -63
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -29,8 +27,8 @@ void emit_add32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRxw_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, rex.w?d_add64:d_add32b);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_AF) {
ORRxw_REG(s3, s1, s2); // s3 = op1 | op2
@@ -83,8 +81,7 @@ void emit_add32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
void emit_add32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4, int s5)
{
MAYUSE(s5);
if(s1==xRSP && (!dyn->insts || dyn->insts[ninst].x64.gen_flags==X_PEND))
{
if((s1==xRSP) && (BOX64DRENV(dynarec_safeflags)<2) && (!dyn->insts || (dyn->insts[ninst].x64.gen_flags==X_PEND) || (!BOX64ENV(dynarec_df) && (dyn->insts[ninst].x64.gen_flags==X_ALL)))) {
// special case when doing math on ESP and only PEND is needed: ignoring it!
if(c>=0 && c<0x1000) {
ADDx_U12(s1, s1, c);
@@ -99,8 +96,8 @@ void emit_add32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRxw_U12(s5, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, rex.w?d_add64:d_add32b);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
IFX(X_AF) {
IFX(X_PEND) {} else {MOV64xw(s5, c);}
@@ -167,8 +164,8 @@ void emit_sub32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRxw_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, rex.w?d_sub64:d_sub32);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_AF) {
ORNxw_REG(s3, s2, s1); // s3 = ~op1 | op2
@@ -224,8 +221,7 @@ void emit_sub32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
void emit_sub32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4, int s5)
{
MAYUSE(s5);
if(s1==xRSP && (!dyn->insts || dyn->insts[ninst].x64.gen_flags==X_PEND))
{
if(s1==xRSP && (BOX64DRENV(dynarec_safeflags)<2) && (!dyn->insts || (dyn->insts[ninst].x64.gen_flags==X_PEND) || (!BOX64ENV(dynarec_df) && (dyn->insts[ninst].x64.gen_flags==X_ALL)))) {
// special case when doing math on RSP and only PEND is needed: ignoring it!
if(c>=0 && c<0x1000) {
SUBxw_U12(s1, s1, c);
@@ -240,8 +236,8 @@ void emit_sub32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in
MOV64xw(s5, c);
STRxw_U12(s5, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, rex.w?d_sub64:d_sub32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
IFX(X_AF) {
IFX(X_PEND) {} else {MOV64xw(s5, c);}
@@ -311,8 +307,8 @@ void emit_add8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_add8b);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_AF | X_OF) {
ORRw_REG(s3, s1, s2); // s3 = op1 | op2
@@ -377,8 +373,8 @@ void emit_add8c(dynarec_arm_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRB_U12(s4, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_add8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_AF | X_OF) {
IFX(X_PEND) {} else {MOV32w(s4, c);}
@@ -420,8 +416,8 @@ void emit_sub8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_sub8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_AF|X_OF|X_CF) {
MVNw_REG(s3, s1);
@@ -467,8 +463,8 @@ void emit_sub8c(dynarec_arm_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRB_U12(s5, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_sub8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_AF|X_OF|X_CF) {
MVNw_REG(s3, s1);
@@ -514,8 +510,8 @@ void emit_add16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRH_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_add16b);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_AF) {
ORRw_REG(s3, s1, s2); // s3 = op1 | op2
@@ -573,7 +569,7 @@ void emit_add16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
// emit ADD16 instruction, from s1, const c, store result in s1 using s3 and s4 as scratch
//void emit_add16c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
// void emit_add16c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOVW(s3, c);
@@ -581,7 +577,7 @@ void emit_add16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s4, d_add16);
// } else IFX(X_ALL) {
// SET_DFNONE(s4);
// SET_DFNONE();
// }
// IFX(X_AF | X_OF) {
// MOV_REG(s4, s1);
@@ -647,8 +643,8 @@ void emit_sub16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRH_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_sub16);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_AF|X_OF|X_CF) {
ORNw_REG(s3, s2, s1); // s3 = ~op1 | op2
@@ -683,7 +679,7 @@ void emit_sub16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
// emit SUB16 instruction, from s1, constant c, store result in s1 using s3 and s4 as scratch
//void emit_sub16c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
// void emit_sub16c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOVW(s3, c);
@@ -691,7 +687,7 @@ void emit_sub16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s4, d_sub16);
// } else IFX(X_ALL) {
// SET_DFNONE(s4);
// SET_DFNONE();
// }
// IFX(X_AF|X_OF|X_CF) {
// MVN_REG_LSL_IMM5(s4, s1, 0);
@@ -750,7 +746,7 @@ void emit_sub16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
// emit INC32 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_inc32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4)
{
SET_DFNONE(s4);
SET_DFNONE();
IFX(X_AF) {
if(rex.w) {
ORRx_mask(s3, s1, 1, 0, 0); // s3 = op1 | op2
@@ -797,7 +793,7 @@ void emit_inc32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4
// emit INC8 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_inc8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
SET_DFNONE(s3);
SET_DFNONE();
IFX(X_AF | X_OF) {
ORRw_mask(s3, s1, 0, 0); // s3 = op1 | op2
ANDw_mask(s4, s1, 0, 0); // s4 = op1 & op2
@@ -825,7 +821,7 @@ void emit_inc8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
// emit INC16 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_inc16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
SET_DFNONE(s3);
SET_DFNONE();
IFX(X_AF | X_OF) {
ORRw_mask(s3, s1, 0, 0); // s3 = op1 | op2
ANDw_mask(s4, s1, 0, 0); // s4 = op1 & op2
@@ -853,7 +849,7 @@ void emit_inc16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
// emit DEC32 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_dec32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4)
{
SET_DFNONE(s4);
SET_DFNONE();
IFX(X_AF) {
MVNxw_REG(s3, s1);
if(rex.w) {
@@ -901,7 +897,7 @@ void emit_dec32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4
// emit DEC8 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_dec8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
SET_DFNONE(s3);
SET_DFNONE();
IFX(X_AF|X_OF) {
MVNw_REG(s3, s1);
ANDw_mask(s4, s3, 0, 0); // s4 = ~op1 & op2
@@ -943,7 +939,7 @@ void emit_dec8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
// emit DEC16 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_dec16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
SET_DFNONE(s3);
SET_DFNONE();
IFX(X_AF|X_OF) {
MVNw_REG(s4, s1);
}
@@ -990,8 +986,8 @@ void emit_adc32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRxw_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, rex.w?d_adc64:d_adc32b);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFNATIVE_BEFORE(NF_CF) {
if(INVERTED_CARRY_BEFORE) {
@@ -1056,7 +1052,7 @@ void emit_adc32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
}
// emit ADC32 instruction, from s1, constant c, store result in s1 using s3 and s4 as scratch
//void emit_adc32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
// void emit_adc32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOV32(s3, c);
@@ -1064,7 +1060,7 @@ void emit_adc32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s4, d_adc32);
// } else IFX(X_ALL) {
// SET_DFNONE(s4);
// SET_DFNONE();
// }
// IFX(X_AF) {
// MOV_REG(s4, s1);
@@ -1133,8 +1129,8 @@ void emit_adc8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_adc8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFNATIVE_BEFORE(NF_CF) {
if(INVERTED_CARRY_BEFORE) {
@@ -1197,8 +1193,8 @@ void emit_adc16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRH_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_adc16);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFNATIVE_BEFORE(NF_CF) {
if(INVERTED_CARRY_BEFORE) {
@@ -1246,7 +1242,7 @@ void emit_adc16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
// emit ADC16 instruction, from s1, const c, store result in s1 using s3 and s4 as scratch
//void emit_adc16c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
// void emit_adc16c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOVW(s3, c);
@@ -1254,7 +1250,7 @@ void emit_adc16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s3, d_adc16);
// } else IFX(X_ALL) {
// SET_DFNONE(s3);
// SET_DFNONE();
// }
// IFX(X_AF | X_OF) {
// MOV_REG(s4, s1);
@@ -1320,8 +1316,8 @@ void emit_sbb32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRxw_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, rex.w?d_sbb64:d_sbb32);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFNATIVE_BEFORE(NF_CF) {
if(!INVERTED_CARRY_BEFORE) {
@@ -1390,7 +1386,7 @@ void emit_sbb32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
}
// emit SBB32 instruction, from s1, constant c, store result in s1 using s3 and s4 as scratch
//void emit_sbb32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
// void emit_sbb32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOV32(s3, c);
@@ -1398,7 +1394,7 @@ void emit_sbb32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s4, d_sbb32);
// } else IFX(X_ALL) {
// SET_DFNONE(s4);
// SET_DFNONE();
// }
// IFX(X_AF) {
// MVN_REG_LSL_IMM5(s4, s1, 0);
@@ -1469,8 +1465,8 @@ void emit_sbb8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_sbb8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFNATIVE_BEFORE(NF_CF) {
if(!INVERTED_CARRY_BEFORE) {
@@ -1534,8 +1530,8 @@ void emit_sbb16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRH_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_sbb16);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFNATIVE_BEFORE(NF_CF) {
if(!INVERTED_CARRY_BEFORE) {
@@ -1584,7 +1580,7 @@ void emit_sbb16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
// emit SBB16 instruction, from s1, constant c, store result in s1 using s3 and s4 as scratch
//void emit_sbb16c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
// void emit_sbb16c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOVW(s3, c);
@@ -1592,7 +1588,7 @@ void emit_sbb16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s3, d_sbb16);
// } else IFX(X_ALL) {
// SET_DFNONE(s3);
// SET_DFNONE();
// }
// IFX(X_AF|X_OF|X_CF) {
// MVN_REG_LSL_IMM5(s4, s1, 0);
@@ -1656,8 +1652,8 @@ void emit_neg32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s3, rex.w?d_neg64:d_neg32);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_CF) {
TSTxw_REG(s1, s1);
@@ -1709,8 +1705,8 @@ void emit_neg16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s3, d_neg16);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_CF) {
TSTw_REG(s1, s1);
@@ -1758,8 +1754,8 @@ void emit_neg8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s3, d_neg8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
} else {
SET_DFNONE();
}
IFX(X_CF) {
TSTw_REG(s1, s1);
File diff suppressed because it is too large. Load diff
+13 -15
View File
@@ -5,10 +5,8 @@
#include "debug.h"
#include "box64context.h"
#include "dynarec.h"
#include "box64cpu.h"
#include "emu/x64emu_private.h"
#include "emu/x64run_private.h"
#include "x64run.h"
#include "x64emu.h"
#include "box64stack.h"
#include "callback.h"
@@ -30,7 +28,7 @@ void emit_cmp32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
STRxw_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, rex.w?d_cmp64:d_cmp32);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
IFX(X_AF) {
ORNxw_REG(s3, s2, s1); // s3 = ~op1 | op2
@@ -88,7 +86,7 @@ void emit_cmp32_0(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
SET_DF(s4, rex.w?d_cmp64:d_cmp32);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
SUBSxw_U12(s3, s1, 0); // res = s1 - 0
// and now the tricky ones (and mostly unused), PF and AF
@@ -134,7 +132,7 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, i
STRH_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_cmp16);
} else {
SET_DFNONE(s3);
SET_DFNONE();
}
IFX(X_AF) {
ORNw_REG(s3, s2, s1); // s3 = ~op1 | op2
@@ -206,7 +204,7 @@ void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
SET_DF(s3, d_cmp16);
} else {
SET_DFNONE(s3);
SET_DFNONE();
}
// bc = (res & (~d | s)) | (~d & s) = 0
IFX(X_CF | X_AF | X_OF) {
@@ -227,7 +225,7 @@ void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, in
STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s3, d_cmp8);
} else {
SET_DFNONE(s3);
SET_DFNONE();
}
IFX(X_AF) {
ORNw_REG(s3, s2, s1); // s3 = ~op1 | op2
@@ -298,7 +296,7 @@ void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
SET_DF(s3, d_cmp8);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
// bc = (res & (~d | s)) | (~d & s) = 0
IFX(X_CF | X_AF | X_OF) {
@@ -318,7 +316,7 @@ void emit_test32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
IFX_PENDOR0 {
SET_DF(s3, rex.w?d_tst64:d_tst32);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
@@ -362,7 +360,7 @@ void emit_test32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
IFX_PENDOR0 {
SET_DF(s3, rex.w?d_tst64:d_tst32);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
@@ -410,7 +408,7 @@ void emit_test16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4,
IFX_PENDOR0 {
SET_DF(s3, d_tst16);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 16);
@@ -458,7 +456,7 @@ void emit_test16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
IFX_PENDOR0 {
SET_DF(s3, d_tst16);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 16);
@@ -517,7 +515,7 @@ void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, i
IFX_PENDOR0 {
SET_DF(s3, d_tst8);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 24);
@@ -565,7 +563,7 @@ void emit_test8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
IFX_PENDOR0 {
SET_DF(s3, d_tst8);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 24);
File diff suppressed because it is too large. Load diff
Loaded 100 of 687 files, more files were not shown because too many files have changed in this diff. Show more