Compare commits

...
2443 Commits
Author SHA1 Message Date
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
ptitSeb 769c6c8f61 Bumped version to v0.3.2 2024-12-06 15:59:59 +01:00
Yang Liu b250056a61 [DYNAREC] Fixed a typo which leads to regression (#2121) 2024-12-06 15:21:23 +01:00
ptitSeb e305e5f1bb [BOX32][WRAPPER] Cosmetic fix an a function signature 2024-12-06 14:48:41 +01:00
rajdakin 18ce48e2c0 [WRAPPERHELPER] Fixed a use-after-free issue (#2118) 2024-12-06 13:29:20 +01:00
Leslie Zhai 06c93c93fe [LA64_DYNAREC] Added XOR AX, Iw opcode (#2116) 2024-12-06 10:40:02 +01:00
ptitSeb 869ddcfdda [WRAPPER] Another improved dlsym wrapped function, hopefully fixing regression (should help #2115) 2024-12-06 08:53:59 +01:00
ptitSeb 65e5e86c2b [RV64_DYNAREC] Improve native flag handling 2024-12-06 08:50:49 +01:00
ptitSeb 122b5e64e8 [BOX32][WRAPPER] Added a couple more 32bits wrapped functions to libc 2024-12-05 15:19:28 +01:00
ptitSeb 6c66d66b02 [BOX32][ELFLOADER] Be less strick when a symbol for R_386_32 relocation is missing 2024-12-05 15:19:02 +01:00
ptitSeb 85d694b36e [BOX32][WRAPPER] Fixed an issue wih an X11 32bits wrapped function 2024-12-05 15:11:49 +01:00
ptitSeb 44cff3ae25 [BOX32][WRAPPER] Added one more 32bits wrapped function to libc 2024-12-05 14:21:12 +01:00
Leslie Zhai c2d7dc573a [LA64_DYNAREC] Added HLT opcode (#2112) 2024-12-05 20:03:06 +08:00
ptitSeb a30433ea12 [NON4KPAGE] Some more adjustments for non-4Kpagesize system (should help #2110) 2024-12-05 11:12:02 +01:00
Yang Liu 6f7b462d53 [DYNAREC] Introduced TO_NAT to ease register mapping changes in future (#2111) 2024-12-05 10:16:22 +01:00
ptitSeb 95e5724117 [ANDROID] Install Android libs for android build 2024-12-04 18:43:24 +01:00
ptitSeb 1eaef70d2d [ANDROID] Updaed test21 for Android build 2024-12-04 18:27:24 +01:00
ptitSeb 3ed1e565f8 Disable another execution test when pagesize is not 4K 2024-12-04 17:52:05 +01:00
ptitSeb 8d0c976a18 [BOX32] Upped max number of x11 display slot from 4 to 16 2024-12-04 17:15:14 +01:00
ptitSeb 9165ec875a [BOX32] Some fixes to a few file related 32bits wrapped function (now windows gog installer can be used with box32 and wine) 2024-12-04 16:58:05 +01:00
ptitSeb 6a7997b41e [BOX32] Fix mystake on previous commit 2024-12-04 15:47:06 +01:00
ptitSeb 2a9d863131 [BOX32][WRAPPER] Added ldiv 32bits wrapped function (now Undertale works with box32, probably other linux gamestudio games too) 2024-12-04 15:20:14 +01:00
ptitSeb e3e9a86088 Added some more termux path to automatic ld_path 2024-12-04 14:35:41 +01:00
ptitSeb d5c787c213 [RCFILE] Better profile for dav1d 2024-12-04 13:57:30 +01:00
ptitSeb 559040e290 [BOX32][WRAPPER] Added a few more X11 32bits wrapped functions 2024-12-04 11:28:43 +01:00
ptitSeb 59ba5b7f0e [BOX32][WRAPPER] Fixed a typo in Xcursor wrapping (should help #2109) 2024-12-04 09:59:57 +01:00
ptitSeb 474a43a424 [BOX32][WRAPPER] Fixed typos from previous build 2024-12-03 19:48:34 +01:00
ptitSeb fb276bdc6b [BOX32][WRAPER] Fixed Xcursor wrapping 2024-12-03 18:45:46 +01:00
ptitSeb 1c1a26626b [ELFLOADER] Fixed a typo in a hack 2024-12-03 17:41:54 +01:00
ptitSeb 93f29d8cd9 Fix X64 build 2024-12-03 14:02:48 +01:00
ptitSeb 0054dde600 Restored old test21, the CI doesn't seems to like the new one 2024-12-03 12:54:54 +01:00
ptitSeb 794f2104bc Improved signal handling ([BOX32] Too) 2024-12-03 11:43:46 +01:00
Yang Liu 036af9f55f [LA64_DYNAREC] Fixed sign extension of 8-bit immediate in 66 opcodes (#2106) 2024-12-03 11:26:24 +01:00
ptitSeb 5bde45cc86 [DYNAREC] Made weakbarrier=1 and pause=3 default 2024-12-03 11:25:10 +01:00
ptitSeb ae1739f330 Improved dlsym wrapped function, will find more symbols from emulated libs 2024-12-03 10:23:18 +01:00
Yang Liu cfc09e0965 [WRAPPER] Wrapped more symbols in libcrypto3 (#2105) 2024-12-03 10:00:48 +01:00
ptitSeb 26c9b3426f [CI] Bumped test timeout to 120 sec 2024-12-03 09:25:39 +01:00
Yang Liu 963da34562 [CMAKE] Fixed typos (#2104) 2024-12-03 08:52:50 +01:00
ptitSeb 4adad381ce [BOX32] Improved test17 2024-12-02 17:14:42 +01:00
ptitSeb e561196f44 Improved test16 2024-12-02 17:01:08 +01:00
Yang Liu 14bd1368cc [RV64_DYNAREC] Added simple opcodes fusion as "native flags" (#2102)
* [RV64_DYNAREC] Added simple opcodes fusion as "native flags"

* Disable 16bit CMOV

* review
2024-12-02 16:58:20 +01:00
ptitSeb 415fc458be [ARM64_DYNAREC] Improved some x87 opcode behaviour 2024-12-02 16:19:06 +01:00
ptitSeb f2822f1a05 [INTERPRETER] Improved some x87 opcode behaviour 2024-12-02 16:18:41 +01:00
Leslie Zhai 646dd718f5 [LA64_DYNAREC] Added INSB, INSD, OUTSB and OUTSD opcodes (#2100) 2024-12-02 11:07:45 +01:00
ptitSebandrajdakin 83ed8ebb22 Android Long Double handling (#2101)
* [ANDROID] Try to handle LongDouble in vaarg correctly

* [ANDROID] Try to enable test07

* [WRAPPED] Fixed Android long double handling (#2096)

* [WRAPPED] Fixed Android long double handling

* [WRAPPED] Force casting to uintptr_t

* [WRAPPED] Fixed a typing issue, removed a warning in the CI

---------

Co-authored-by: rajdakin <[email protected]>
2024-12-02 10:50:21 +01:00
ptitSeb 88aab487f1 [BOX32] Some improvment on steam handling 2024-12-02 10:25:12 +01:00
ptitSeb 6d1e30cd3c [BOX32][WRAPPER] Improved 32bits freetype wrapping (wine explorer have correct fonts now) 2024-12-01 17:33:57 +01:00
ptitSeb ab73969ea4 [BOX32][WRAPPER] Improved networks functions 2024-12-01 12:32:33 +01:00
ptitSeb 93b371eb8c *[ARM64_DYNAREC] Fixed some cases of memory access on BTR/BTS opcodes (for #2093) 2024-12-01 10:03:25 +01:00
ptitSeb b7007a1bdd [BOX32][WRAPPER] Added a few more FreeType wrapped functions 2024-11-30 17:00:05 +01:00
ptitSeb a26c108464 [ARM64_DYNAREC] Added F2 0F 80..8F opcodes 2024-11-30 16:59:38 +01:00
ptitSeb 2971e9729c [BOX32][WRAPPER] This should fix the build 2024-11-30 15:07:01 +01:00
ptitSeb 6b2d923041 [WRAPPER] Added 1 more function to libgcrypt 2024-11-30 14:54:51 +01:00
ptitSeb cb30db320e [BOX32][WRAPPER] Added some more libc wrapped functions 2024-11-30 14:50:48 +01:00
ptitSeb e1ae914a1d [WRAPPER] Fixed libc wrappers includes 2024-11-30 14:25:08 +01:00
ptitSeb 51aa4b0416 Added a new memExist helper function and use it instead of getMmapped were it make sense 2024-11-30 14:02:28 +01:00
ptitSeb b0db168fb5 [INTERPRETER] Added 0F 30 ocpode ([RM64_DYNAREC] too) (for #2090) 2024-11-30 11:35:14 +01:00
ptitSeb 3b3338d132 [BOX32][WRAPPER] Added a few new wrapped functions 2024-11-29 20:45:40 +01:00
ptitSeb cc50331745 [BOX32][WRAPPED] Added one more obstack wrapped function 2024-11-29 19:15:01 +01:00
ptitSeb 2777bc142f Forgot this file on previous commit 2024-11-29 19:14:17 +01:00
ptitSeb c73545e25b [BOX32][WRAPPER] Added minimum libresolv wrapping 2024-11-29 19:10:11 +01:00
ptitSeb b862e74ae4 [BOX32][WRAPPER] Added obstack_vprintf wrapped symbol 2024-11-29 18:49:14 +01:00
ptitSeb 0d662b8543 [WRAPPER] Refactored some glib2 signal handling 2024-11-29 17:07:58 +01:00
ptitSeb ea0b23b783 Better hadnling of LD_PRELOAS on Steam Pressure Vessel wrapper 2024-11-29 17:07:31 +01:00
ptitSeb f15a187087 [TRACE] Show backtrace on emit_signal too if asked 2024-11-29 10:27:59 +01:00
ptitSeb 12a82cf91f [WRAPPER] Added back faked ITM weak functions 2024-11-29 10:27:23 +01:00
ptitSeb 5af2fa49c3 [WRAPPER] Fixed wrapped dlerror behaviour 2024-11-29 10:25:21 +01:00
Yang Liu 843fe30e46 [RV64] Added nan propagation emulation for interpreter and DynaRec (#2091)
* [RV64] Added nan propagation emulation for interpreter and DynaRec

* oops
2024-11-28 15:14:45 +01:00
ptitSeb 0da561cd20 [WRAPPER] Reworked sqlite3 with new wrapperhelper 2024-11-28 10:10:17 +01:00
rajdakin fd613de55e [WRAPPERHELPER] Transform from function to data if needed (#2089) 2024-11-28 09:17:00 +01:00
Leslie Zhai b2dc460db9 [RV64_DYNAREC] Fix PTEST X_CF typo (#2088) 2024-11-28 08:11:01 +01:00
Leslie Zhai e5b7dfb524 [LA64_DYNAREC] Added LEA opcode (#2087) 2024-11-28 08:09:49 +01:00
ptitSeb de0b602748 Added syscall 280 2024-11-27 19:52:52 +01:00
ptitSeb d0d85e684d [WRAPPER] More work on gtk/gstreamer wrapping 2024-11-27 19:52:52 +01:00
Yang Liu 05b322414a [RV64_DYNAREC] Fixed another regression in vector (#2086) 2024-11-27 17:11:25 +01:00
ptitSeb 38ee050a09 [BOX32] Added 32bits syscall 2 2024-11-27 16:05:22 +01:00
Yang Liu 1ee4959c05 [LA64_DYNAREC] Added nativeflags option support (#2084) 2024-11-27 10:38:46 +01:00
Yang Liu bc9086551b [RV64_DYNAREC] Fixed more regressions for vector (#2082) 2024-11-26 20:58:12 +01:00
ptitSeb f9f0c99c1b [WRAPPER] Reworked gstvideo with new wrapperhelper 2024-11-26 17:33:46 +01:00
ptitSeb a1b46711c4 [WRAPPER] Reworked gsttag with new wrapperhelper 2024-11-26 16:44:47 +01:00
ptitSeb f6bb071f84 [WRAPPER] Reworked gstsdp with new wrapperhelper 2024-11-26 16:41:14 +01:00
ptitSeb 746a0031f8 [WRAPPER] Reworked gst-rtp and gst-rtsp with new wrapperhelper 2024-11-26 16:36:13 +01:00
ptitSeb f78d0ae471 [WRAPPER] Reworked gstriff with new wrapperhelper 2024-11-26 16:27:53 +01:00
ptitSeb 7879a33cdc [WRAPPER] Reworked gst-pbutils with new wrapperhelper 2024-11-26 16:22:39 +01:00
ptitSeb a84a9847be [WRAPPER] Reworked gstnet with new wrapperhelper 2024-11-26 16:20:06 +01:00
ptitSeb 0c54e19c5f [WRAPPER] Reworked gst-gl with new wrapperhelper 2024-11-26 16:17:44 +01:00
rajdakin d507f8a6d0 [WRAPPERHELPER] Accept and ignore semicolons instead of declarations (#2081) 2024-11-26 13:56:18 +01:00
ptitSeb b18efe4e40 [WRAPPER] Reworked gstfft with new wrapperhelper 2024-11-26 11:55:05 +01:00
ptitSeb 83d69939f3 [WRAPPER] Reworked gstcontroller with new wrapperhelper 2024-11-26 11:53:08 +01:00
ptitSeb aee5032597 [WRAPPER] Reworked gstcheck with new wrapperhelper 2024-11-26 10:45:44 +01:00
ptitSeb c7cc78194f [ARM64_DYNAREC][TRACE] Use BLR on ret/retn with TRACE to allow relevant debug informations on bad returns 2024-11-26 10:34:12 +01:00
ptitSeb 089db91b39 [WRAPPER] Reworked gstbase with new wrapperhelper 2024-11-26 10:33:04 +01:00
rajdakin cb33043dd4 [WRAPPERHELPER] Fixed a parsing error (#2079) 2024-11-26 10:16:11 +01:00
Leslie Zhai b207ecad6a [LA64_DYNAREC] Added SBB opcodes (#2076)
* [LA64_DYNAREC] Added SBB opcodes

* [LA64_DYNAREC] clang-format and fix LOCK ADC wrong ed
2024-11-26 08:27:13 +01:00
xctan 48461001d2 [RV64_DYNAREC] Fixed vector packed logical shift opcodes (#2075)
* [RV64_DYNAREC] Fixed vector packed logical shift opcodes

* [RV64_DYNAREC] Fixed a operand violation in vector CVTSD2SS
2024-11-26 08:21:57 +01:00
ptitSeb 12649d04c7 [WRAPPER] Reworked gstaudio with new wrapperhelper 2024-11-25 18:51:48 +01:00
ptitSeb 5033738f73 [WRAPPER] Reworked gstapp with new wrapperhelper 2024-11-25 18:38:51 +01:00
ptitSeb df80b9c5de [WRAPPER] Reworked wrapping of gstallocators with new wrapperhelper 2024-11-25 18:33:35 +01:00
ptitSeb ffa94268d7 [WRAPPER] Reworked gstreamer with new wrapperhelper 2024-11-25 18:06:41 +01:00
xctan b7f0996459 [RV64_DYNAREC] Fixed vector SSE unpack opcodes (#2074) 2024-11-25 18:04:04 +01:00
Chi-Kuan Chiu dcf196c2ae [RBTREE] Document the rationale for memory management (#2060)
Enhanced the rbtree.h header with detailed documentation comments for
each function.
This comment aims to clarify the role of the red-black tree in memory
management and how these functions interact with and manage memory.
2024-11-25 17:08:05 +01:00
rajdakin a71856801b [WRAPPERHELPER] Added the --gst option (#2072) 2024-11-25 16:13:04 +01:00
Yang Liu 84608fc581 [ARM64_DYNAREC] Added DYNAREC_PAUSE option for hint instructions (#2070)
* [ARM64_DYNAREC] Added DYNAREC_PAUSE option for hint instructions

* Use sevl for wfe

* Add docs

* Fix typo

* use switch case
2024-11-25 11:28:19 +01:00
Leslie Zhai c30a392fe8 [LA64_DYNAREC] Add adc8, adc8c, adc16 and testadc (#2069)
* [LA64_DYNAREC] Add adc8, adc8c, adc16 and testadc

* [LA64_DYNAREC] Add missing testcase

* [LA64_DYNAREC] Change ANDI+OR to BSTRINS_D for ADC AL, Ib and removed testadc

* [LA64_DYNAREC] clang-format
2024-11-25 08:12:20 +01:00
rajdakin d8c16de2ec [WRAPPERHELPER] Fixed pragma once handling (#2067) 2024-11-24 22:19:28 +01:00
Yang Liu 2d04cbe97c [ARM64_DYNAREC] Use YIELD instead of WFE (#2066) 2024-11-24 20:04:01 +01:00
xctan ab65422034 [CORE] Enhanced BOX64_DYNAREC_RV64NOEXT (#2065) 2024-11-24 19:32:39 +01:00
xctan 3bde222242 [RV64_DYNAREC] Added, fixed, and optimized opcodes (#2059)
* [RV64_DYNAREC] Added 66 0F 38 37 PCMPGTQ opcode

* [RV64_DYNAREC] Added 66 0F 17 MOVHPD opcode

* [RV64_DYNAREC] Added 66 0F 38 15 PBLENDVPD opcode

* [RV64_DYNAREC] Optimized vector SSE packed compare

* [RV64_DYNAREC] Optimized vector MMX MOVD Gm, Ed

* [RV64_DYNAREC] Optimized vector SSE PMADDWD opcode

* [RV64_DYNAREC] Added vector PCMPGTQ opcode

* [RV64_DYNAREC] Added vector 66 0F 17 MOVHPD opcode

* [RV64_DYNAREC] Optimized vector 66 0F 16 MOVHPD opcode

* [RV64_DYNAREC] Added vector PBLENDVPD opcode

* [RV64_DYNAREC] Optimized vector PMADDUBSW opcode

* [RV64_DYNAREC] Optimized vector SSE logical shifts with Ex

* [RV64_DYNAREC] Optimized vector SSE unpack

* [RV64_DYNAREC] Added F0 F6 /2 LOCK NOT opcode

* [RV64_DYNAREC] Fixed vector packed logical shift
2024-11-24 16:57:34 +01:00
ptitSeb d0af86d5bf [VULKAN] Added a new extension and a missing function 2024-11-24 15:53:12 +01:00
ptitSeb 73b17d4add [ARM64_DYNAREC] Fix a regression, as 90 opcode is not always NOP depending on REX (should help #2064) 2024-11-24 15:28:21 +01:00
Yang Liu 93fa5323c5 [ARM64_DYNAREC] Generate corresponding hint instruction for PAUSE (#2063) 2024-11-24 11:19:36 +01:00
Yang Liu b0c10c9ae5 [RV64_DYNAREC] Minor optimizations on CMPXCHG (#2062) 2024-11-24 08:49:02 +01:00
rajdakin b8ed1b9646 [WRAPPERHELPER] Added support to cast to enum (#2061) 2024-11-23 22:01:40 +01:00
ptitSeb 0912e8f16d [ARM64_DYNAREC] Small optim for emit_shld32c CF flag computation 2024-11-23 14:37:19 +01:00
ptitSeb 327dc2c835 [DYNAREC] Better detection of wait slot 2024-11-23 13:06:26 +01:00
ptitSeb 8f937788ce [BOX32] Removed a debug leftover 2024-11-23 10:21:01 +01:00
Yang Liu 52ba725fa5 Reworked on mmap address alignments for a performance regression (#2057) 2024-11-22 12:06:55 +01:00
ptitSeb a39249454e Slightly better way to decode wrappers 2024-11-21 15:28:30 +01:00
ptitSeb c1f2304c88 Small fix for XSAVE/XRSTOR opcodes ([DYNAREC] too) 2024-11-21 12:08:43 +01:00
Yang Liu 85c6e28d47 [LA64_DYNAREC] Added more opcodes for JDK (#2055) 2024-11-21 11:44:47 +01:00
Yang Liu d1a253f469 [DYNAREC] Reuse strongmem infra for all backends (#2052) 2024-11-21 08:06:47 +01:00
ptitSeb 6aa57f5c73 [RCFILE] More adjustments with new strongmem 2024-11-20 21:02:08 +01:00
ptitSeb 023aeae9e6 Removed another debug leftover 2024-11-20 20:33:47 +01:00
ptitSeb 38880ab5a4 [TRACE] Don't try to decode a bridge if memory is not mapped or un-readable 2024-11-20 20:03:48 +01:00
ptitSeb 4e19324177 Removed a debug leftover 2024-11-20 20:03:10 +01:00
Yang Liu 9757d1b67a [ARM64_DYNAREC] More optimizations on strongmem emulation (#2051) 2024-11-20 18:59:20 +01:00
theofficialgman 5422b108af update pressure_vessel function with additional valid BOX86_LD_LIBRARY_PATH (#2050) 2024-11-20 18:15:03 +01:00
ptitSeb 0d650b183f [RCFILE] Addjusted some profile with new strongmem capabilities 2024-11-20 12:47:56 +01:00
Yang Liu fa432bb9d1 [ARM64_DYNAREC] Added weakbarrier=2 to disable last write barriers (#2049) 2024-11-19 21:22:55 +01:00
Yang Liu 81e4e26dc5 [ARM64_DYNAREC] Re-enable weakbarrier for dmb.ishst (#2048) 2024-11-19 19:59:43 +01:00
Yang Liu 4f6a66f9c6 [CI] Generate and upload .wcp file for Winlator (#2045)
* [CI] Generate and upload .wcp file for Winlator

* patch box64

* test box64 before the patch

* opt out static build

* typos
2024-11-19 13:49:35 +01:00
Yang Liu 127d273ada [DYNAREC] Reworked strong memory emulation (#2043)
* [ARM64_DYNAREC] Reworked strong memory emulation

* Simplify

* [RV64,LA64_DYNAREC] Reworked strong memory emulation

* forgot this

* more tweaks
2024-11-19 09:39:57 +01:00
liuli 469d4f81eb [WRAPPER]my_dbus_message_get_args() args type error (#2042)
* [WRAPPER]my_dbus_message_get_args() args type error

* [WRAPPER]my_dbus_message_get_args() args type error
2024-11-19 08:05:40 +01:00
ptitSeb 8f08a14115 Improved Signal handling ([ARM4_DYNAREC] too) 2024-11-18 17:18:41 +01:00
ptitSeb 4ac43047d0 [BOX32] Fixed previous commit 2024-11-18 11:14:07 +01:00
ptitSeb 4257fdded3 [BOX32] Fixed long double handling on printf like functions 2024-11-18 11:07:44 +01:00
ptitSeb 56298870f6 [ARM64_DYNAREC] Only propagate native flags if at least 1 opcode consume them 2024-11-17 15:14:13 +01:00
ptitSeb 48354185dd [WRAPPER] Added last 2 wrapped function for libexpat 2024-11-17 11:45:30 +01:00
ptitSeb 5f0cbcf26d [WRAPPER] Fixed an isue with __iso99_swcanf wrapped function 2024-11-17 11:45:00 +01:00
ptitSeb ffc875c2d6 [WRAPPER] Added wrapped libzstd.so.1 support, with new wrapperhelper 2024-11-17 11:30:30 +01:00
ptitSeb 8a180e3892 [ARM64_DYNAREC] Cancel native flags when an opcode use native flags not fully covered by the generated ones 2024-11-17 11:02:21 +01:00
ptitSeb c4d3d734b1 [DYNAREC] Mark existing block as dirty when re-creating a memory block 2024-11-17 11:00:28 +01:00
ptitSeb 6e8c244b77 [TRACE] Use lower case hex on rbtree 2024-11-17 10:59:34 +01:00
ptitSeb ac2ed68228 [WRAPPER] Added 2 more wrapped function to libcrypto.so.3 (for #1271) 2024-11-16 14:39:48 +01:00
ptitSeb fb27c89282 [WRAPPER][BOX32] Fixed a few wrapped functions (for hl2) 2024-11-16 14:31:46 +01:00
ptitSeb 74bed6edcb [ARM64_DYNAREC] Fixed potential issues with 0F A3/AB/B3/BB opcodes 2024-11-16 14:31:20 +01:00
ptitSeb 49a854fa7e [INTERPRETER] Fixed potential issue with 0F A3 opcode 2024-11-16 13:44:36 +01:00
ptitSeb 5adabbbcaa [ARM64_DYNAREC] Small optim in emit_sar8c helper 2024-11-16 13:23:23 +01:00
ptitSeb 42eae3e1b4 Expose a few more CPU features 2024-11-16 12:48:12 +01:00
ptitSeb 518d2b0129 Removed a debug leftover 2024-11-16 12:19:14 +01:00
ptitSeb bc8c786b80 Smal adjustment in singal handling for no-execution error 2024-11-16 12:16:51 +01:00
Yang Liu 5ab8a6f6f4 [WRAPPER] Fixed myStackAlignGVariantNew and refined the test too (#2038) 2024-11-15 21:37:36 +01:00
ptitSeb 385a31ec11 [ARM64_DYNAREC] Various fixes and improvments to a few random opcodes 2024-11-15 21:05:41 +01:00
ptitSeb 5c49954f69 [DYNAREC] Zero'd upper 32bits of regs when switching to 32bits from 64bits 2024-11-15 21:05:06 +01:00
ptitSeb 6ce7a1ba1f [INTERPRETER] Zero'd upper 32bits of regs when switching to 32bits from 64bits 2024-11-15 21:03:59 +01:00
ptitSeb 8c1335626f [ARM64_DYNAREC] A few fixes to 8/16bits logic/math opcodes 2024-11-15 15:34:22 +01:00
ptitSeb 8b0eec097b [TRACE] More info on signal 2024-11-15 15:34:00 +01:00
ptitSeb a39c8aa5c5 [INTERPRETER] Some cleanup on base logic/math/shift operations 2024-11-15 14:37:16 +01:00
ptitSeb 27745ceebb Added support for RDMSR, just in case 2024-11-15 14:36:42 +01:00
ptitSeb 64b213fe42 [ARM64_DYNAREC] Try to not call UpdateFlags when switching to a DFNONE state but dfnone is not needed 2024-11-15 14:27:43 +01:00
ptitSeb eaca84e9ba [ARM64_DYNAREC] Very small change on on emit_rol32c helper 2024-11-15 14:26:25 +01:00
xctan bca0f4d66d [RV64_DYNAREC] Added more MMX opcodes for vector (#2037)
* [RV64_DYNAREC] Added 0F 74-76 PCMPEQB/W/D opcodes

* [RV64_DYNAREC] Added 0F 64-66 PCMPGTB/W/D opcodes

* [RV64_DYNAREC] Added 0F E1-E2 PSRAW/D opcodes

* [RV64_DYNAREC] Added 0F 6E MOVD opcode

* [RV64_DYNAREC] Added 0F 73 /2 PSRLQ opcode

* [RV64_DYNAREC] Added 0F 73 /6 PSLLQ opcode
2024-11-15 10:11:11 +01:00
ptitSeb 8c17a37d1a [ARM64_DYNAREC] Reworked 8/16/32/64bits TEST opcodes 2024-11-14 18:54:40 +01:00
xctan 979a3232f9 [RV64_DYNAREC] Added more MMX opcodes for vector (#2035)
* [RV64_DYNAREC] Added 0F 68 PUNPCKHBW opcode

* [RV64_DYNAREC] Added 0F 69 PUNPCKHWD opcode

* [RV64_DYNAREC] Added 0F 6A PUNPCKHDQ opcode

* [RV64_DYNAREC] Updated 0F 68-69 PUNPCKHBW/WD opcodes

* [RV64_DYNAREC] Added 0F 60 PUNPCKLBW opcode

* [RV64_DYNAREC] Added 0F 61 PUNPCKLWD opcode

* [RV64_DYNAREC] Added 0F 62 PUNPCKLDQ opcode

* [RV64_DYNAREC] Simplified MMX PUNPCK{L,H}{BW,WD,DQ}
2024-11-14 17:41:28 +01:00
Yang Liu 47dbbe030c [DYNAREC] Added a experimental BOX64_DYNAREC_WEAKBARRIER option (#2033)
* [DYNAREC] Added a experimental BOX64_DYNAREC_WEAKBARRIER option

* Added it to the RCFILE
2024-11-14 17:41:12 +01:00
ptitSeb d05e719ce3 [ARM64_DYNAREC] Refactor 8/16/32/64bits CMP and REP CMPS/SCAS opcodes 2024-11-14 16:43:01 +01:00
Leslie Zhai 12f4afcba2 [LA64] Implement convert x64_va_list_t to sysv_varargs for float (#2025) (#2031)
* [LA64] Implement convert x64_va_list_t to sysv_varargs for float (#2025)

* [LA64] Implement myStackAlignGVariantNew (#2025)

* [LA64] Limit the log to LOG_DEBUG (#2055)

* [LA64] Add missing file (#2025)
2024-11-14 16:01:36 +01:00
ptitSeb cd2638d11a [ARM64_DYNAREC] Some refactor on 8/16/32/64bits SHL/SHR/SAR opcodes 2024-11-14 15:00:58 +01:00
ptitSeb c87796e51c [ARM64_DYNAREC] Minor change on 16bits neg opcode 2024-11-14 12:43:30 +01:00
ptitSeb d47b555e12 [ARM64_DYNAREC] Some rework on 8/16/32/64 INC/DEC opcodes 2024-11-14 11:20:57 +01:00
Yang Liu 4e568e1fdf Minor adjustments to README, updated README_CN (#2032) 2024-11-14 11:15:36 +01:00
Diego q 0688c53675 Update README.md (#2022)
* Update README.md

I made it more readable to the normal human being, kept all important info, rewrote everything to make it cleaner, and re-organized a few things, let me know if you want anything extra added

* Update README.md

Added And Fixed Some things as requested

* Update README.md

Fixed Everything Requested
2024-11-14 08:11:01 +01:00
ptitSeb 6d523f9c7f [ARM64_DYNAREC] Small optim for 8/16/32/64bits adc/sbb opcodes 2024-11-13 20:00:02 +01:00
ptitSeb 0f4f274bc7 [ARM64_DYNAREC] Various small fixes for some 16bits math/logic opcodes 2024-11-13 19:48:44 +01:00
xctan 09b8c3b94e [RV64_DYNAREC] Added more MMX opcodes for vector (#2027)
* [RV64_DYNAREC] Added 0F D5 PMULLW opcode

* [RV64_DYNAREC] Added 0F E5 PMULHW opcode

* [RV64_DYNAREC] Added 0F F5 PMADDWD opcode

* [RV64_DYNAREC] Added 0F 6B PACKSSDW opcode

* [RV64_DYNAREC] Added 0F 63 PACKSSWB opcode

* [RV64_DYNAREC] Added 0F 67 PACKUSWB opcode

* [RV64_DYNAREC] Removed useless vsetvli in MMX PACKUSWB/SSWB/SSDW
2024-11-13 19:43:57 +01:00
ptitSeb 1dbb676f38 [ARM64_DYNAREC] Reworked 8/16/32/64bits XOR opcodes 2024-11-13 18:46:47 +01:00
ptitSeb 331866bd1d [ARM64_DYNAREC] Fixed previous commit 2024-11-13 18:32:43 +01:00
ptitSeb 2515096f56 [ARM64_DYNAREC] Reworked 8/16/32/64 OR opcodes 2024-11-13 17:34:21 +01:00
ptitSeb 8868023ce9 [ARM64_DYNAREC] Reworked 8/16/32/64bits AND opcodes 2024-11-13 17:12:03 +01:00
ptitSeb dd9d6f8f83 [ARM64_DYNAREC] Small change in sbb32 helper 2024-11-13 15:18:56 +01:00
ptitSeb 21e403c908 [WRAPPER] Added more callback slots for libwaylend-client 2024-11-13 14:39:08 +01:00
ptitSeb f66aa57594 [ARM64_DYNAREC] Improved div/idiv opcode flags (non)handling 2024-11-13 14:38:14 +01:00
Yang Liu 506cb980b1 [RV64_DYNAREC] Prefer AMO* instructions over LR/SC when possible (#2028)
* [RV64_DYNAREC] Prefer AMO* instructions over LR/SC when possible

* fixes
2024-11-13 14:22:25 +01:00
ptitSeb 937e2cf853 [ARM64_DYNAREC] Improved 32/64bits imul/mul opcodes flags handling 2024-11-13 13:31:32 +01:00
xctan 82bf71ee19 [RV64_DYNAREC] Added more MMX opcodes for vector (#2026)
* [RV64_DYNAREC] Added 0F F8-FB PSUBB/W/D/Q opcodes

* [RV64_DYNAREC] Added 0F E8 PSUBSB opcode

* [RV64_DYNAREC] Added 0F D8-D9 PSUBUSB/W opcodes

* [RV64_DYNAREC] Added 0F F1-F3 PSLLW/D/Q opcodes

* [RV64_DYNAREC] Added 0F E9 PSUBSW opcode

* [RV64_DYNAREC] Added 0F EB POR opcode

* [RV64_DYNAREC] Added 0F DB PAND opcode

* [RV64_DYNAREC] Added 0F DF PANDN opcode

* [RV64_DYNAREC] Added 0F EF PXOR opcode

* [RV64_DYNAREC] Optimized rvv MMX PSLLW/D/Q
2024-11-13 11:04:43 +01:00
xctan eb9e7b9fee [RV64_DYNAREC] Added more MMX opcodes for vector (#2024)
* [RV64_DYNAREC] Added 0F D1-D3 PSRLW/PSRLD/PSRLQ opcode

* [RV64_DYNAREC] Added 0F EC PADDSB opcode

* [RV64_DYNAREC] Added 0F DC-DD PADDUSB/PADDUSW opcode

* [RV64_DYNAREC] Added 0F FC-FE PADDB/PADDW/PADDD opcodes

* [RV64_DYNAREC] Added 0F ED PADDSW opcode

* [RV64_DYNAREC] Added 0F 7F MOVQ opcode

* [RV64_DYNAREC] Fixed some typos

* [RV64_DYNAREC] Optimized RVV MMX PSRLW/D/Q to a mask-less version
2024-11-13 10:08:16 +01:00
Yang Liu b02942c0b0 [RV64_DYNAREC] Made eflags emulation branchless with xtheadcondmov (#2019)
* [RV64_DYNAREC] Made eflags emulation branchless with xtheadcondmov

* more
2024-11-11 19:53:55 +01:00
Yang Liu 56e813ccb7 [RV64_DYNAREC] Added more MMX opcodes for vector (#2017)
* [RV64_DYNAREC] Added more MMX opcodes for vector

* fixed
2024-11-11 12:29:55 +01:00
Yang Liu cf5b94d471 [CORE][LA64] Check LASX and display its existence (#2016) 2024-11-10 17:41:31 +01:00
ptitSeb 5d941f702a Preserve errno on mmap / munmap speicifc memory traqking operations 2024-11-10 11:09:33 +01:00
ptitSeb b46925e7e0 [WRAPPER] Added wrapped libXaw with new wrapperhelper (for #1990) 2024-11-09 18:36:27 +01:00
ptitSeb e676756cda [DYNAREC] Small chnage o hotpage detection to make it less sensitive 2024-11-09 18:12:43 +01:00
ptitSeb 591958c59c [RCFILE] advertise that BOX64_DYNAREC_TEST=1 is applied 2024-11-09 18:12:09 +01:00
ptitSeb 63a80ff696 This should fix LA64 Static build 2024-11-09 17:55:31 +01:00
ptitSeb ee6e3a7a96 [WRAPPER] Added a bunch of libc wrapped functions (for #2010) 2024-11-09 16:13:18 +01:00
ptitSeb 1d607cb937 [ARM64_DYNAREC] A small optim for a specific case of 0F C6 opcode 2024-11-09 16:12:26 +01:00
ptitSeb c5ced39665 [DYNAREC] Only test page protection when needed (and using a fester way) (should address the performance regression of #2009) 2024-11-09 14:02:45 +01:00
Yang Liu 7b2e77807d [RV64_DYNAREC] Added mmx infra for vector (#2011) 2024-11-09 11:58:41 +01:00
ptitSeb 7a623ef19c Improved getcontext/setcontext ([BOX32] too) 2024-11-08 18:13:42 +01:00
ptitSeb f292be40b2 Improved syscall 56 2024-11-08 18:03:03 +01:00
Yang Liu 0166330c73 [RV64_DYNAREC] Fixed some GETEX_vector usage (#2008) 2024-11-08 10:53:43 +01:00
ptitSeb 3cc9d47032 Added some weird 67 and 64/65 prefixed opcodes ([ARM64_DYNAREC] too) 2024-11-07 17:40:48 +01:00
ptitSeb 128708db2d [ELFLOADER] Better handling of symbols with COPY / GLOB_DAT (should helps #1412, but doesn't seems to help #1860, wich is strange) 2024-11-07 17:14:19 +01:00
ptitSeb 3027ee9f3e Removed a debug leftover 2024-11-07 17:13:04 +01:00
ptitSeb 51c673e62d [BOX32][WRAPPER] Added 1 more sdl2 wrapped function (Crimsonland works now) 2024-11-07 15:52:39 +01:00
ptitSeb 56bd83f6fb Added 64/65 D8..D9 opcodes 2024-11-07 15:52:10 +01:00
ptitSeb 2473bb6902 Added 64/65 69 opcode ([ARM64_DYNAREC] too) 2024-11-07 15:03:55 +01:00
ptitSeb da0e153a05 [BOX32] Improve errno handling, and added a few more libc wrapped functions 2024-11-07 13:26:55 +01:00
Jim Huang 394e81af45 [RBTREE] Unify naming and prevent unintended symbol exposure (#2005)
Red-black tree operations now consistently use the 'rbtree_' prefix, and
internal functions remain unexposed. Tested on RV64GC, resulting in a
498-byte reduction in the .text section size.
2024-11-06 21:56:34 +01:00
rajdakin 6af8d70cc1 [WRAPPED32] Added an errno-aware calling convention (#2006) 2024-11-06 21:52:34 +01:00
ptitSeb 2dea11a9e3 [TRACE] Better for 32bits wait wrapped function 2024-11-06 19:13:08 +01:00
ptitSeb cd55c12e44 Added a few wrapped function and fixed some other (for Steam) 2024-11-06 16:09:38 +01:00
ptitSeb cb2cf7c9b1 A bit more trace for emited signals 2024-11-06 16:09:14 +01:00
ptitSeb 494786be26 Fixed a small typo 2024-11-06 16:08:50 +01:00
ptitSeb 27013d6a03 [TRACE] A few more details for some speicifc CALL variant 2024-11-06 16:07:21 +01:00
ptitSeb 3ba91a6513 [CMAKE] Fixed SD865 profile, as a77.a55 is not supported in current build chain 2024-11-06 11:53:20 +01:00
ptitSeb c547090ee0 Fixed a typo 2024-11-05 15:42:14 +01:00
ptitSeb f87b9c15d3 [ARM64_DYNAREC] Fixed some issue with frintts uses 2024-11-05 14:42:09 +01:00
ptitSeb 3d76bcde2e [ARM64_DYNAREC] Fixed newly added frrintts use 2024-11-05 14:26:33 +01:00
ptitSeb 1a6f49ce45 [ARM64_DYNAREC] Reworked a bit FASTROUND 2024-11-05 14:13:01 +01:00
ptitSeb 745a7fc034 Silenced a signal message 2024-11-05 13:59:31 +01:00
ptitSeb 6158a0ad45 Disabling memory bit test when pagesize is not 4K 2024-11-05 13:55:14 +01:00
Yang Liu a51f684c41 [WRAPPER] Wrapped 3 more symbols for libc (#2000) 2024-11-05 13:10:10 +01:00
Yang Liu 681e207af5 [RV64_DYNAREC] Added more SSE opcodes for vector (#1999) 2024-11-05 09:43:30 +01:00
ptitSeb f651b7bfb0 [WRAPPER] forgot to handle libfontconfig also 2024-11-04 16:04:59 +01:00
ptitSeb 6c53e12b49 [WRAPPER] merged android naming so no more ifdef is needed 2024-11-04 15:06:44 +01:00
ptitSeb 01c9157fce [ANDROID] Try to fix libfontconfig not loading properly 2024-11-04 13:45:38 +01:00
ptitSeb 3448e94171 Improve handling of memory protection, and excution bit 2024-11-04 11:43:27 +01:00
ptitSeb 08085be360 [DYNAREC] Reverted last 2 commit, will use CancelFillblock mecanism instead 2024-11-03 20:01:56 +01:00
ptitSeb 3809866d99 [LA64_DYNAREC] This should fix Loongarch dynarec 2024-11-03 19:29:54 +01:00
ptitSeb 52a05c9f67 [DYNAREC] Make sure the emu structure is up-to-date each time LinkNext is called 2024-11-03 19:16:35 +01:00
ptitSeb ba5aa0c83b [ARM64_DYNAREC] Fixed an issue with native flags and opcode using C Helper that use flags, like rcr and rcl 2024-11-03 17:13:12 +01:00
ptitSeb 939486fa05 Forgot that file in earlier commit 2024-11-02 09:34:34 +01:00
ptitSeb c8d98f6901 [RCFIEL] Add an option to force usage of native EGL/GLESv2 library 2024-11-02 09:28:34 +01:00
ptitSeb 38cfeeb558 [WRAPPER] Small rework on wrapper return values 2024-11-02 09:20:42 +01:00
Yang Liu cf9f8d0535 [RV64_DYNAREC] Added more opcodes for vector (#1992) 2024-11-01 19:36:23 +01:00
Yang Liu 9e43737e18 [RV64_DYNAREC] Added more opcodes for vector (#1991) 2024-11-01 18:07:18 +01:00
ptitSeb 5d03ad24c3 Added a few more gtk3/gdk3 symbols (probably gtk/gdk 4.+ symbol actually) 2024-11-01 14:37:18 +01:00
Yang Liu ac6721edac [RV64_DYNAREC] Added more opcodes for vector (#1989) 2024-11-01 11:33:52 +01:00
Yang Liu 126cf27972 [RV64_DYNAREC] Added more opcodes for vector (#1987) 2024-10-31 17:38:16 +01:00
ptitSeb 0a677c7f83 Fixed a typo (for #1986) 2024-10-31 15:29:23 +01:00
ptitSeb 63e35941e2 Small (probably cosmetic) fix for CloneEmu helper function 2024-10-31 10:43:02 +01:00
ptitSeb 3ae6992641 [RCFILE] Added a profile for AlienIsolation linux version 2024-10-31 10:42:25 +01:00
ptitSeb a243532730 Added 65 6C..6F opcodes ([ARM64_DYNAREC] too) (for #1985) 2024-10-31 10:04:11 +01:00
zymayunyan ed99f5e6d2 [rebree]The name of rbtree is set error. (#1984) 2024-10-31 09:21:52 +01:00
Yang Liu 7d1bf95d93 [RV64_DYNAREC] Added more opcodes for vector (#1983) 2024-10-30 19:53:04 +01:00
Yang Liu 93cbf59e9e [Rv64_DYNAREC] Added more opcodes for vector (#1982) 2024-10-30 16:51:55 +01:00
ptitSeb e8f9796752 Fixed a small memory invalid read with my_execv 2024-10-30 16:33:14 +01:00
Yang Liu adb423d96b [RV64_DYNAREC] Added more opcodes for vector (#1981) 2024-10-30 13:10:47 +01:00
ptitSeb 74acad3628 [WRAPPER] Wrapped remaining 2 function to libbrotidec (for #1860) 2024-10-30 11:23:30 +01:00
ptitSeb 541adff4d4 Improved clone wrapped function compatibility 2024-10-30 11:12:51 +01:00
ptitSeb 39189a746b Generate a SIGILL on unimplemented opcode 2024-10-30 11:06:17 +01:00
ptitSeb f82e938ae8 [WRAPPER] Added more crypto3 and ssl3 function, and fixed some issue with hidden callback (for #1860) 2024-10-30 11:05:43 +01:00
Yang Liu 34520c0b4f [RV64_DYNAREC] Added more opcodes for vector (#1980) 2024-10-30 11:02:09 +01:00
Yang Liu 121148da72 [RV64_DYNAREC] Added more opcodes for vector (#1979) 2024-10-29 22:04:07 +01:00
Yang Liu 1e34db98a8 [RV64_DYNAREC] Added more opcodes for vector (#1978) 2024-10-29 21:01:14 +01:00
ptitSeb 9f821d6406 [WRAPPER] Reworked ssl3 and crypto3 with new wrapperhelper (for #1860) 2024-10-29 16:55:15 +01:00
rajdakin 70a6d96748 [WRAPPERHELPER] Added pragma once support, fixed a preprocessor bug, fixed the wrapperhelper Makefile (#1977) 2024-10-29 16:31:05 +01:00
ptitSeb 4a440b6f0a [ARM64_DYNAREC] Make sure neg on 16bits is correctly computed 2024-10-29 15:19:38 +01:00
ptitSeb fdfc5c4a41 [ARM64_DYNAREC] Fixed a potential issue with native flags used while some intermediary opcode doesn't support it 2024-10-29 15:19:11 +01:00
ptitSeb 6699c0ee7f [RCFILE] Update setup and install generic profile to not use native flags 2024-10-29 14:13:53 +01:00
Yang Liu 8807b1aa3c [INTERP] Fixed overflow checking for convertion opcodes (#1976) 2024-10-29 14:11:13 +01:00
ptitSeb 2aff4239cc [BOX32] Added an option to also add binfmt integration for box32 (for #1973) 2024-10-29 14:10:05 +01:00
ptitSeb d99d18759b [ARM64_DYNAREC] Also use Native Carry flags directly when possible 2024-10-29 13:09:51 +01:00
Yang Liu 68c3be3e16 [RV64_DYNAREC] Fixed 66 0F C2 CMPPD opcode for scalar and more (#1975)
* [RV64_DYNAREC] Fixed 66 0F C2 CMPPD opcode for scalar

* more minor fixes
2024-10-29 11:16:08 +01:00
Yang Liu f148b106a5 [RV64_DYNAREC] Fixed MAXSS and MAXSD for vector (#1974) 2024-10-28 23:10:17 +01:00
Yang Liu 9ffabf4c85 [RV64_DYNAREC] Added more opcodes for vector (#1972) 2024-10-28 22:34:49 +01:00
Yang Liu aebfd61539 [RV64_DYNAREC] Added more opcodes for vector (#1970) 2024-10-28 20:16:47 +01:00
Yang Liu 8dee79d380 [RV64_DYNAREC] Added more opcodes for vector (#1969) 2024-10-28 17:32:52 +01:00
Yang Liu d3c1ea5b0f [RV64_DYNAREC] Added more opcodes for vector (#1968) 2024-10-28 14:55:58 +01:00
Yang Liu 2835a2f87d [RV64_DYNAREC] Added more opcodes for vector (#1966) 2024-10-27 22:31:20 +01:00
ptitSeb 062a098ac5 [VULKAN] Fixed a typo in a vulkan extension 2024-10-27 08:44:00 +01:00
Yang Liu 5563103453 [RV64_DYNAREC] Implemented the first AVX128 opcode for scalar only (#1962) 2024-10-26 17:50:24 +02:00
Yang Liu a1d62eb92b [RV64_DYNAREC] Refined fpu_{push,pop}cache for vector (#1960) 2024-10-26 17:06:45 +02:00
ptitSeb 138a021fad [WRAPPER] Added some ssl3 and crypto3 wrapped functions (for #1860) 2024-10-25 17:25:01 +02:00
ptitSeb bdf0e95a12 [WRAPPER] Added wrapped libbrotlidec with new warpperhelper (for #1860) 2024-10-25 16:01:28 +02:00
ptitSeb 90674b825a [BOX32] Added 1 more sdl2 wrapped function (for #1957) 2024-10-25 10:48:51 +02:00
Yang Liu b3bc09f898 [RV64_DYNAREC] Added 1 more 66 0F opcode for vector (#1956) 2024-10-24 16:09:23 +02:00
ptitSeb 320459c2c6 Make BOX64_IGNOREINT3 also ignore other privilged instructions 2024-10-24 15:24:54 +02:00
Yang Liuandxctan 8d14c10b8c [RV64_DYNAREC] Optimized horizontal opcodes (#1955)
Co-authored-by: xctan <[email protected]>
2024-10-24 09:00:01 +02:00
Chi-Kuan Chiu 2c2b252dac [Box64] Fix compilation issues (#1938) (#1952)
Fixed compilation errors related to variable declarations within
switch-case statements without enclosing braces. This adjustment
ensures compatibility with older versions of compiler.

Resolves: #1938
2024-10-22 22:08:49 +02:00
ptitSeb 8efd1e3ae0 [ARM64_DYNAREC] Added AVX.F3.0F 53 opcode 2024-10-22 14:43:34 +02:00
ptitSeb e7adc6b7f9 [BOX32] Added 1 more sdl2 wrapped function 2024-10-22 09:24:06 +02:00
ptitSeb fc7d204d4b [ARM64_DYNAREC] More work around native flags handling 2024-10-20 21:47:21 +02:00
ptitSeb 2153e7098c [ARM64_DYNAREC] Fixed edgecase on MINSS/MAXSS when comparing 0.0 and -0.0 2024-10-20 14:57:31 +02:00
ptitSeb 29beabd683 [ARM64_DYNAREC] Added BOX64_DYNAREC_NATIVEFLAGS to disable the use of native flags, as there is still a bug or two in that mode (for #1947) 2024-10-20 13:21:08 +02:00
ptitSeb 80c346060f [ARM64_DYNAREC] Some small improvment to a few shift opcode, to use flagless jump when possible 2024-10-20 11:23:55 +02:00
ptitSeb 4e10cd654f Improved 0F 0D opcode ([ARM64_DYNAREC] too) (FF7RI now have sound) 2024-10-19 15:23:26 +02:00
ptitSeb a12653a25d [TRACE] Improved 32bits trace for FF 92 opocde 2024-10-19 15:22:52 +02:00
ptitSeb f683ae95c3 [BOX32][WRAPPER] Added a few more SDL2 32bits wrapped functions 2024-10-19 13:54:28 +02:00
ptitSeb 6bdeb18253 [BOX32] Fixed to a couple of wrapped libc functions 2024-10-19 12:40:33 +02:00
ptitSeb 8f1f23c991 [BOX32][TRACE] Better trace for a sscanf variant 2024-10-19 12:39:29 +02:00
ptitSeb 42345af443 [BOX32][WRAPPER] Added 32bits wrapped regex libc functions 2024-10-19 11:05:40 +02:00
ptitSeb a5797da100 [BOX32][WRAPPER] Added some more libc wrapped function, and 32bits globalsymbol infrastructure 2024-10-19 10:38:11 +02:00
ptitSeb 0821e6acc2 [BOX32][WRAPPER] Added a few symbols to libSDL2 2024-10-18 18:59:15 +02:00
ptitSeb 0fb87c7926 [WRAPPER] Added 1 missing symbol to libSDL2 2024-10-18 18:58:58 +02:00
ptitSeb b578487d01 [BOX32] A few more fixes to libX11 wrapping 2024-10-18 16:44:47 +02:00
ptitSeb cdf81eb1d7 Now x86_64 bash can be installed as box64-bash and will be automaticly used if present 2024-10-18 14:53:13 +02:00
ptitSeb 97491658c6 Fixed box32 hash table un-init crashing on regular box64 ([BOX32] and improved a bit hash selection patter) 2024-10-18 14:51:58 +02:00
ptitSeb b2b3653d67 [ARM64_DYNAREC] Fixed a regression with native flag commit (might help #1947) 2024-10-18 12:09:03 +02:00
ptitSeb de102bec5e [VULKAN] Added 2 more extensions 2024-10-18 11:38:06 +02:00
ptitSeb 3598f2855f [BOX32] A few more X11 wrapped functions and fixes 2024-10-18 10:23:08 +02:00
ptitSeb f36a479d0f [ARM64_DYNAREC][TRACE] Update LR on jumpnext on trace build so debug info in case of jump to NULL are accurate 2024-10-18 10:22:43 +02:00
ptitSeb 5363c013e6 [WRAPPER] Added gtk_marshal to gtk2 (for #1943) 2024-10-17 15:59:50 +02:00
ptitSeb b609328ac1 [WRAPPER] Reworked libcups wrapping with new wrapperhelper 2024-10-17 15:49:26 +02:00
ptitSeb 65c2b103b1 [ARM64_DYNAREC] Added directmapping of x86 flags to N, V and Z arm64 flags 2024-10-17 15:36:13 +02:00
ptitSeb 22a89ba914 Added 1 more wrapped symbol to gtk2 (for #1943) 2024-10-17 13:07:44 +02:00
ptitSeb fda9b6f75d [WRAPPER] Reworked libharfbuzz wrapping with new wrapperhelper 2024-10-17 12:57:52 +02:00
ptitSeb b29e9b706e [WRAPPER] Added alternative libname for libFLAC 2024-10-16 12:39:57 +02:00
Yang Liu bd145ad6b2 [RV64_DYNAREC] Added a few more opcodes for vector (#1941) 2024-10-15 14:47:25 +02:00
Yang Liu fc71ec9785 [RV64_DYNAREC][LA64_DYNAREC] Fixed various issues (#1940)
* [RV64_DYNAREC] Fixed more issues for vector

* more fixes and optims

* more

* more

* more

* more
2024-10-14 14:11:57 +02:00
ptitSeb cce43790d2 [NTERPRETER] Added 64 F6 opcodes (for #1932) 2024-10-13 18:57:19 +02:00
ptitSeb 1e31e1fff8 [BOX32] Fixed dlvsym for RTLD_NEXT, like dlsym 2024-10-13 18:50:44 +02:00
ptitSeb af2a0c9747 [BOX32] Some more 32bits wrapped symbols 2024-10-13 18:39:13 +02:00
ptitSeb d30488da87 [BOX32] Added some more 32bits wrapped function to libc 2024-10-13 17:44:14 +02:00
ptitSeb 59ba2fc7ab [BOX32][WRAPPER] Hacked some support for libGLX_nvidia.so.0 2024-10-13 17:43:51 +02:00
ptitSeb 1936052e79 [WRAPPER] Hacked some support for libGLX_nvidia.so.0 2024-10-13 17:43:27 +02:00
ptitSeb 103ec5d72a [BOX32] Added some posix_file_action wrapped function, and fixed posix_spawn/exec function argument handling 2024-10-13 14:46:21 +02:00
ptitSeb 9139ec3e5c [WRAPPER] Reworked libgnutls wrapping with new wrapperhelper 2024-10-13 13:16:09 +02:00
Yang Liu 7430463b33 [CORE] Refactored %pid trace file handling (#1933) 2024-10-13 13:08:18 +02:00
ptitSeb 6f2d067f3a [INTERPRETER] Added 64/65 85 opcode ([ARM64_DYNAREC] too) (for #1932) 2024-10-13 11:35:20 +02:00
ptitSeb d31b9c9caa [BOX32] Allow internal memory to be in 32bits space if needed 2024-10-13 11:20:25 +02:00
ptitSeb 2670d37542 [RCFILE] Added a profile 2024-10-13 11:19:37 +02:00
ptitSeb 617fd69bcc [BOX32] Reworked alignment for 32bits stacks 2024-10-13 11:19:19 +02:00
ptitSeb 5fcd9d45a3 [BOX32] Added a few 32bits wrapped function libSDL2 2024-10-13 10:01:06 +02:00
ptitSeb b6cd19b78b [BOX32] More work on libX11 and friends, using more shadow structure like Screen and Visual (help wine, probably other too) 2024-10-12 18:40:31 +02:00
Yang Liu 6a3a19da68 [RV64_DYNAREC] Fixed more issues for vector (#1928)
* [RV64_DYNAREC] Fixed emitter for xtheadvector

* MOVSD can be unaligned

* fixed unaligned issues
2024-10-12 12:46:08 +02:00
ptitSeb efd103004c [BOX32] Improved X11 event handling 2024-10-12 10:45:21 +02:00
Yang Liu 18e033cdd8 [RV64_DYNAREC] Fixed 66 0F 38 17 PTEST opcode for vector (#1927) 2024-10-11 21:27:51 +02:00
Yang Liu 2a4ecc1d28 [RV64_DYNAREC] Wrapped icuuc75 (#1926) 2024-10-11 21:27:17 +02:00
Yang Liu c0c91678ba [RV64_DYNAREC] Fixed an issue in CVTTSD2SI for vector (#1925) 2024-10-11 18:34:40 +02:00
ptitSeb 7a531ed272 [BOX32] Fixed some issues with X11 and XRandR 32bits wrapping 2024-10-11 13:25:28 +02:00
ptitSeb 93e3fcb386 [BOX32][TRACE] Better for XRRSetScreenSize 2024-10-11 13:20:14 +02:00
Yang Liu 143fc90a4c [RV64_DYNAREC] Split 660f.c to speedup compilation a bit (#1924) 2024-10-11 12:25:13 +02:00
ptitSeb f65feaf9da [BOX32] Added 2 more wrapped function to libc 2024-10-11 11:03:57 +02:00
ptitSeb a17b0effa1 [BOX32] Added 2 more 32bits wrapped functions 2024-10-11 10:44:07 +02:00
ptitSeb b0d5c7a1a5 [BOX32] Added 1 more 32bits wrapped function 2024-10-11 10:26:47 +02:00
Yang Liu 9c4a407fdc [RV64_DYNAREC] Added more opcodes for vector (#1923)
* [RV64_DYNAREC] Added more opcodes for vector

* fix
2024-10-11 09:36:59 +02:00
Yang Liu 67b2151e3c [RV64_DYNAREC] Added more opcode for vector and some fixes too (#1920) 2024-10-10 20:58:45 +02:00
ptitSeb b8024469da [ARM64_DYNAREC] Added a small optim for CALL 0 / POP reg type of sequence 2024-10-10 20:55:24 +02:00
ptitSeb 7f5c826bb1 [BOX32][TRACE] Fixed trace for memcmp, strncasecmp and strncmp 2024-10-10 20:54:40 +02:00
ptitSeb acad3f3963 [BOX32] Actually fixed dlsym on RTLD_NEXT 32bits call 2024-10-10 20:32:29 +02:00
ptitSeb 1f6ce24eaa [BOX32] Added and fixed some 32bits functions for libX11 and friends 2024-10-10 19:20:29 +02:00
ptitSeb 4a82f21cc3 [BOX32] Fixed 32bits dlsym on RTLD_NEXT not working 2024-10-10 19:20:29 +02:00
Yang Liu 0cf707599d [RV64_DYNAREC] Added more opcodes for vector (#1919) 2024-10-10 18:40:02 +02:00
ptitSeb e2e6bdc4cb [BOX32][WRAPPER] Added 32bits wrapped libXss (with new wrapperhelper) 2024-10-10 17:23:49 +02:00
ptitSeb 8136186554 [WRAPPER] Reworked libXss with new wrapperhelper 2024-10-10 17:11:00 +02:00
Yang Liu 9b733041af [RV64_DYNAREC] Added more opcodes for vector (#1918) 2024-10-10 17:08:50 +02:00
ptitSeb 9e01876747 [BOX32] Improved pthread_mutex handling 2024-10-10 15:57:28 +02:00
ptitSeb ee909b8c08 [BOX32] More 32bits SDL-1.2 wrapped functions 2024-10-10 15:57:08 +02:00
ptitSeb fdf1982982 [BOX32] Fixed getifaddrs 32bits wrapped function 2024-10-10 15:53:32 +02:00
Yang Liu 88ccd7f537 [RV64_DYNAREC] Added 1 more opcode for vector, some fixes too (#1917) 2024-10-10 15:30:41 +02:00
ptitSeb c6cd9ceb75 Fixed some command line handling regression 2024-10-10 15:11:52 +02:00
ptitSeb ce735357d6 [BOX32] More 32bits wrapped functions 2024-10-10 14:57:26 +02:00
Yang Liu 887dee83eb [RV64_DYNAREC] Added more boilerplate for vector (#1916) 2024-10-10 12:15:48 +02:00
ptitSeb fd73a2bc8b [BOX32] Morewrapped SDL2 function, and improved handling of SDL_PixelFormat 2024-10-10 09:46:32 +02:00
ptitSeb 21b5f90a33 Small changed to command line argument handling 2024-10-10 08:37:59 +02:00
ptitSeb d1c5cd7b0a [BOX32][TRACE] Small improvment to SDL_RWFromFile trace 2024-10-10 08:35:58 +02:00
ptitSeb 656a36061a [BOX32] More X11 wrapping fixes 2024-10-09 21:03:41 +02:00
ptitSeb 05384f581f [BOX32] Improved again, X11 and XImage handling 2024-10-09 15:56:07 +02:00
ptitSeb 84f3c104b2 [BOX32] Improved handlong of XImage 2024-10-09 11:48:22 +02:00
ptitSeb 761f7e40de [BOX32] Fixed 32bits libc syscall 240 2024-10-09 10:23:27 +02:00
Yang Liu b760c21414 [BOX32] Fixed fcntl flock macros definitions (#1915) 2024-10-09 10:01:26 +02:00
ptitSeb bb651298c4 [BOX32] Added better handling of fcntl (should help Wine when futex_waitv syscall is not available) 2024-10-08 20:48:13 +02:00
ptitSeb 8850a11072 [BOX32] Added some more libSDL2 wrapped function (now linux limbo works, with gamepad) 2024-10-08 20:29:40 +02:00
ptitSeb 499338e80d Fixed non-Box32 builds 2024-10-08 20:06:00 +02:00
ptitSeb c12f8fa254 [BOX32] Fixed some X11 function so wine launch (and added BOX64_X11SYNC to help debug X11 programs) 2024-10-08 19:44:20 +02:00
ptitSeb 7ae36b8667 [BOX32] More 32bits wrapped functions 2024-10-08 17:38:01 +02:00
ptitSeb 591e2db712 [BOX32] Refactored X11 wrapping, and add a few more functions 2024-10-08 16:34:20 +02:00
Yang Liu 8414563ad0 [RV64_DYNAREC] Added more opcodes and small optimizations (#1914)
* [RV64_DYNAREC] Added more opcodes and small optimizations

* more

* only applies to and32c
2024-10-08 13:58:32 +02:00
ptitSeb 85fc57faa3 Improve debugging trace of rb_tree 2024-10-08 13:11:42 +02:00
ptitSeb c8e10a004b [BOX32][DYNAREC] Allocate Dynarec memory in higher prereserve regions 2024-10-08 12:56:45 +02:00
ptitSeb e1fac2404c Removed wine prereserve hack on munmap now that prereserve is better handled 2024-10-08 12:21:19 +02:00
Yang Liu 65adf2a860 [RV64_DYNAREC] Fixed CVTSS2SD and CVTSD2SS opcodes (#1913) 2024-10-08 10:53:18 +02:00
ptitSeb dea6906ae9 [WRAPPER] Reworked libresolv with new wrapper helper ([STATICBUILD] fixed potential issue with static build) 2024-10-08 10:47:44 +02:00
ptitSeb 22ccae3301 Small adjustment in 32bits custom memory hinter 2024-10-08 10:40:09 +02:00
ptitSeb 58d58b0af7 [BOX32] More adjustments to x86 structures packing & alignment (or not) 2024-10-08 09:59:44 +02:00
ptitSeb ce5daaa835 Small change in custom Aligned Memory Allocator 2024-10-07 22:56:47 +02:00
ptitSeb 8fe0681681 Some cosmetic changes and more macro, to ease future testings on custom malloc 2024-10-07 18:39:35 +02:00
ptitSeb 3987e644a8 Added 66 6A opcode ([ARM64_DYNAREC] too) (for #1911) 2024-10-07 17:26:40 +02:00
ptitSeb f073415510 [BOX32] More work on 32bits wrapped functions 2024-10-07 17:17:55 +02:00
Yang Liu 4c69bcd97a [DYNAREC] Optimized CALL/RET RAS for out of dynablock jumps (#1909) 2024-10-07 16:57:47 +02:00
ptitSeb 05aac0879e [BOX32][WRAPPER] Reworked 32bits libGL with new wrapperhelper 2024-10-07 13:32:45 +02:00
ptitSeb cb5dafe8db [BOX32][WRAPPER] Reworked 32bits libasound with new wrapperhelper 2024-10-07 11:14:43 +02:00
ptitSeb 82c7d45c4b [BOX32] Added a couple of 32bits function to libc 2024-10-07 10:45:31 +02:00
ptitSeb f81677278f Reworked mmap allocator and wine prereserve handling ([BOX32] fix handling of wine prereserve) 2024-10-07 09:25:04 +02:00
ptitSeb 2ef6011c7a [ARM64_DYNAREC] Added 64 88 opcode 2024-10-07 08:53:15 +02:00
ptitSeb 6e0b5358fb [BOX32][WRAPPING] Added 32bits wrapped libXi (with new wrapperhelper) 2024-10-06 16:44:33 +02:00
ptitSeb e783e3c794 [BOX32] Added a few more 32bits libc symbols 2024-10-06 15:19:20 +02:00
ptitSeb 8965d9bd70 [BOX32][WRAPPER] Added 32bits libuuid (with new wrapperhelper) 2024-10-06 15:16:57 +02:00
ptitSeb 37fe9bad6d [WRAPPER] Reworked wrapped libXi with new wrapperhelper 2024-10-06 15:09:18 +02:00
ptitSeb a4daf4c228 [BOX32][WRAPPER] Added 32bits wrapped libXcomposite (with new wrapperhelper) 2024-10-06 14:48:10 +02:00
ptitSeb ae080c3ad3 [BOX32] Forgot a few more x86 structure to properly align 2024-10-06 14:31:51 +02:00
ptitSeb ad0c08c2de [BOX32] Proper alignment for x86 structures 2024-10-06 14:27:19 +02:00
ptitSeb 7b93791c3f [BOX32] Addes 3 more x86 libs for convenience 2024-10-06 14:03:30 +02:00
Yang Liu 172df2cd0c [DYNAREC] Tweaking indirect jumps for CALL/RET to use the return address stack (#1907) 2024-10-06 12:19:55 +02:00
ptitSeb b395cd7ccc [BOX32] More work on various wrapper, and some bug fixes 2024-10-06 12:14:53 +02:00
ptitSeb 8ec6b15dc2 [BOX32] More work on 32bits X11 wrapping (not 12 Labor of Hercules 6 works from Steam, but not Steam itself) 2024-10-05 18:42:51 +02:00
ptitSeb 2a2f82a745 [BOX32] Added many more 32bits wrapped function (some using wrapperhelper) 2024-10-05 16:36:31 +02:00
ptitSeb 13a7801421 [BOX32][WRAPPER] Added 32bits libXinerama, with new wrapperhelper 2024-10-05 14:30:29 +02:00
ptitSeb 1a5cd1c1ff [WRAPPER] Reworked libXinerama with new wrapperhelper 2024-10-05 14:23:53 +02:00
ptitSeb 224974f218 [WRAPPERHELPER] Removed double line added by mystake 2024-10-05 14:22:59 +02:00
ptitSeb b96556f80f [BOX32][WRAPPER] Reworked 32bits libX11, with new wrapperhelper 2024-10-05 14:17:48 +02:00
ptitSeb c29be5b945 [BOX32][WRAPEPR] Reworked 32bits libfontconfig with new wrapperhelper 2024-10-05 09:54:44 +02:00
ptitSeb 21b60db107 [BOX32][WRAPPER] Added more 32bits wrapped function to libfreetype 2024-10-05 09:38:01 +02:00
ptitSeb baa3f573ae [BOX32] Added some more wrapped function and a profile (PixelJunk Shooter linux version now Works) 2024-10-04 20:57:24 +02:00
Yang Liu 0243e93e97 [RV64] Allowed disabling more extensions (#1904) 2024-10-04 20:13:25 +02:00
ptitSeb 778bbc6d08 [BOX32][WRAPPER] Reworked 32bits libXext with new wrapperhelper 2024-10-04 18:22:43 +02:00
ptitSeb 6ae502f181 [BOX32] Initalized libX11 if used without loading (becauseit's loaded indirectly with SDL2 for example) 2024-10-04 18:18:18 +02:00
ptitSeb 088720db22 [BOX32][WRAPPER] Added wraped mostly empty 32bits libXext 2024-10-04 17:37:07 +02:00
ptitSeb 3d6ecc064f [WRAPEPR] Reworked libXext wrapping with new wrapperhelper 2024-10-04 16:56:37 +02:00
ptitSeb 333bf19c00 [ARM64_DYNAREC] Worked on CF IRET opcode 2024-10-04 16:19:24 +02:00
ptitSeb 25599b91b2 [INTERPRETER] Worked on CF IRET opcode 2024-10-04 16:19:03 +02:00
ptitSeb 18305a1994 [BOX32][WRAPPER] Fixed 32bits mktime 2024-10-04 15:52:34 +02:00
ptitSeb e6f56bf5fa Fixed x86_64 build 2024-10-04 14:24:02 +02:00
ptitSeb 681c6f4e5e [TRACE] Btter trace for ioctl 2024-10-04 13:12:37 +02:00
ptitSeb 11f1c3c4ff Return the correct errno when mmap can't allocated hinted memory address 2024-10-04 13:04:28 +02:00
ptitSeb 9f4eb36c99 [BOX32][WRAPPER] More wrapped function to libc, and many fixes some existing ones 2024-10-04 12:28:11 +02:00
Yang Liu cbbafafb46 [RV64_DYNAREC] Added more opcodes for xtheadvector (#1899) 2024-10-03 19:38:26 +02:00
ptitSeb 9e853e487d [BOX32] Added more 32bits wrapped function and reworked 32bits memory allocator 2024-10-03 19:36:42 +02:00
ptitSeb 0e91ad3ed3 [BOX32] Fixed scanf type function when grabing long/ptr type of data 2024-10-03 13:51:56 +02:00
ptitSeb c5e894aab2 [BOX32] More check for low alignment in memalign wrapped functions 2024-10-03 13:50:38 +02:00
rajdakin 49aaeb3080 [WRAPPER] Fixed RV64 isSimpleWrappers (#1898) 2024-10-03 12:49:18 +02:00
Yang Liu 1c7ac8c761 [RV64_DYNAREC] Added more opcodes for xtheadvector and fixed more issues (#1897)
* [RV64_DYNAREC] Added 1 more opcode for xtheadvector

* Disabled more opcodes does not apply to xtheadvector

* Added 1 more opcode

* Added 1 more opcode

* fix
2024-10-03 12:36:04 +02:00
ptitSeb e2492a1426 [BOX32][WRAPPER] Added full wrapped support for 32bits libudev0 and libudev1 2024-10-03 12:26:38 +02:00
ptitSeb f750391c2e [BOX32] Added rolling log print on Stack corrupted call 2024-10-03 12:26:11 +02:00
ptitSeb 95d65a02bc [TRACE] Fixed StopEmu on trace build when trace is not enabled 2024-10-03 12:25:17 +02:00
ptitSeb 2685037c82 [WRAPPER] Improved libudev1 wrapped logf function 2024-10-03 12:24:34 +02:00
ptitSeb 61c46994cd [WRAPPER] Reworked libudev1 wrapping with new wrapperhelper 2024-10-03 11:51:17 +02:00
ptitSeb 8b8e6501bc [BOX32][WRAPPER] Added a few more libX11 32bits wrapped functions 2024-10-03 11:36:36 +02:00
ptitSeb c4184ef733 [BOX32] Added workaround for posix_memalign when used with align of 4 2024-10-03 11:36:12 +02:00
ptitSeb 6a5049b22c [BOX32][TRACE] Some more improved trace 2024-10-03 11:35:41 +02:00
Yang Liu 6cbcfc7ab8 [DYNAREC] Added a new missing mode for fallback opcodes (#1896) 2024-10-02 20:44:04 +02:00
rajdakin 564d06e84c [WRAPPERHELPER] Forgot to add the Makefile (#1895)
* [WRAPPERHELPER] Forgot to add the Makefile

* [WRAPPERHELPER] Also sped up the build
2024-10-02 20:42:45 +02:00
Yang Liu 8398799e1c [CI] Added xtheadvector testing (#1894) 2024-10-02 17:50:47 +02:00
Yang Liu c43d34d0cf [RV64_DYNAREC] Added preliminary xtheadvector support (#1892)
* [RV64_DYNAREC] Added preliminary xtheadvector support

* [RV64_DYNAREC] Fixed more unaligned issue
2024-10-02 09:53:29 +02:00
ptitSeb a188f4ebfe [BOX32][WRAPPER] Added a bunch of wrapped 32bits functions, and fixed a few existing ones (Now Witcher 2 Linux boot and can enter tutorial, before crashing) 2024-09-30 21:06:56 +02:00
ptitSeb e59063a13c [BOX32] Added 2 more 32bits syscalls 2024-09-30 18:02:15 +02:00
ptitSeb 2f95534bd0 [BOX32] Set default FS to 0 for 32bits apps 2024-09-30 18:01:51 +02:00
ptitSeb 2b0c8d45fa [BOX32][WRAPPER] Added 32bits wrapping for SDL2_image 2024-09-30 17:41:47 +02:00
ptitSeb c88cf6359e [BOX32] Keep low memory free by default 2024-09-30 17:41:08 +02:00
ptitSeb 62405c79c3 [DYNAREC] Start with dynarec instead of interpreter 2024-09-30 17:40:40 +02:00
ptitSeb 28dedd66b3 [BOX32][WRAPPER] Added a few more wrapped functions to libGL, libasound and libX11 2024-09-30 16:35:11 +02:00
ptitSeb f26146bc23 [BOX32][WRAPPER] nl_langinfo signature needs t as return type 2024-09-30 15:40:07 +02:00
ptitSeb 2a0489a21c [BOX32] Handling of BOX64_MAXCPU for 32bits apps 2024-09-30 15:37:53 +02:00
ptitSeb 0980c4438a [BOX32][WRAPPER] More work on SDL2 Wrapping(but TheStanleyParable still don't have mouse input working) 2024-09-30 15:37:11 +02:00
ptitSeb f7c93b68d8 [BOX32] Fixed main Elf init not always called 2024-09-30 14:00:33 +02:00
ptitSeb f7e769f8c4 [BOX32] Enable futex robust_list hack for all 32bits software for now 2024-09-30 13:59:30 +02:00
ptitSeb 7f1ce6ebfd [BOX32][WRAPPER] Manualy changed wctype_t to h in libc wrapping 2024-09-30 12:59:57 +02:00
rajdakin 4715ef2633 [WRAPPERHELPER] Added box32 and line number support in the wrapperhelper (#1890) 2024-09-30 12:31:45 +02:00
rajdakin 703d19b256 Various box32 wrapped libs and script fixes (#1889)
* [WRAPPED32] Fixed the rebuild_wrappers_32 script, fixed some libc signatures

* [WRAPPED32] Added back xdr functions

* [WRAPPED32] Forgot to regenerate wrappers
2024-09-30 12:26:45 +02:00
ptitSeb f7d7fbb9b0 Revert a change ffrom previous build and pushed missing BOX32 generated files too 2024-09-29 22:30:40 +02:00
Pablo Labs a6baf1f370 [ANDROID][BOX32] Fix __libc_init, Fix Some Warnings (#1887)
* [ANDROID][BOX32] Fix __libc_init, Fix Some Warnings

* Fix More Warnings

* Revert fillALProcWrapper() change
2024-09-29 22:21:40 +02:00
ptitSeb 874238f61e [BOX32][WRAPPER] Added more SDL2 and freetype function, and fixed missing fonts in many games ([BOX64] also fixed some SDL2 signature on RWops) 2024-09-29 21:10:54 +02:00
Yang Liu 9968963b97 [RV64_DYNAREC] Eliminate redundant vsetvli by tracking its usage (#1886) 2024-09-29 15:15:20 +02:00
ptitSeb 5b68e46bb7 [BOX32] Added 3 more event type to SDL2 event conversion 2024-09-29 11:34:32 +02:00
Yang Liu 9a83521ad6 [RV64_DYNAREC] Minor optimization on vector_vsetvli (#1885) 2024-09-29 10:39:28 +02:00
Yang Liu 2a7eabfb1c [RV64_DYNAREC] Refined RISC-V vector emitter (#1884) 2024-09-29 10:38:49 +02:00
Pablo Labs b4a0ae20c9 [ANDROID][BOX32] Fix Android Build, and add correct libc, libm, libdl library names on library_list_32.h (#1883)
* [ANDROID][BOX32] Fix Android Build, and add correct libc, libm, libdl library names on library_list_32.h

* Fix Various Warnings
2024-09-29 00:45:20 +02:00
ptitSeb 87493a9bc9 [BOX32] Added 1event type for SDL2_Event conversions 2024-09-28 16:09:14 +02:00
ptitSeb 0f9dac511c [BOX32][WRAPPER] Added some more 32bits libc functions 2024-09-28 15:58:29 +02:00
ptitSeb 11724fd2ad [BOX32][WRAPPER] Added 32bits wrapped/hacked libtcmallocminimal 2024-09-28 15:19:08 +02:00
ptitSeb c0955d33de [BOX32][WRAPPER] Added some minimum 32bits wrpping for fontconfig, and some fixes for iconv wrapped function signature 2024-09-28 15:13:13 +02:00
ptitSeb bc5e686fde [WRAPPER] Reworked libfontconfig with new wrapperhelper 2024-09-28 13:51:22 +02:00
ptitSeb 541489da4d [BOX32][WRAPPER] Some fixes to libexpat 32bits wrapping and more other 32bits functions 2024-09-28 13:48:08 +02:00
ptitSeb 79200d4df6 [BOX32] Fixed wrapping for glShaderSourceARB 2024-09-28 12:32:01 +02:00
ptitSeb 578bae3c37 [BOX32][WRAPPER] Added some more 32bits wrapped function, and fixed one from SDL2 2024-09-28 12:27:00 +02:00
ptitSeb 37490d1a44 [BOX32] Added 2 more 32bits syscalls 2024-09-28 11:59:12 +02:00
ptitSeb 3919bb2e7d [BOX32][WRAPPER] Added 32bits wrapped libexpat and another batch of wrapped function for 32bits libfreetype and SDL2 2024-09-28 11:17:26 +02:00
ptitSeb 93e8434a87 [WRAPPER] Reworked wrapping of libexpat with new wrapperhelper 2024-09-28 10:20:21 +02:00
ptitSeb 97a1983c59 [BOX32][WRAPPER] Added a bunch of 32bits functions to SDL2 and libc 2024-09-28 10:15:55 +02:00
Yang Liu 42e60bc7c5 [BOX32][WRAPPER] Wrapped more SDL2 functions (#1881) 2024-09-27 19:00:08 +02:00
ptitSeb 93dc8fce10 [BOX32][TRACE] Better trace for recv 2024-09-27 17:27:17 +02:00
ptitSeb 34d4cde7c4 [BOX32][WRAPPER] Added 2 more 32bits wrapped function to freetype 2024-09-27 11:11:58 +02:00
xctan 66788af44d [RV64_DYNAREC] Refined RISC-V vector disassembler (#1880)
* [RV64_DYNAREC] Refined RISC-V vector disassembler

* [RV64_DYNAREC] Formated generated code
2024-09-27 09:03:24 +02:00
Yang Liu 1a8df98cf2 [ARM64_DYNAREC] Small optim on 0F C7 /1 inst name (#1878) 2024-09-26 19:46:26 +02:00
Yang Liu 0fb0ac7994 [LA64_DYNAREC] Added unaligned support to CMPXCHG8B (#1877) 2024-09-26 19:45:40 +02:00
ptitSeb 24f278c961 [BOX32][WRAPPER] Added some more 32bits wrapped functions 2024-09-26 15:21:52 +02:00
ptitSeb d45001e4c9 [BOX32][WRAPPER] Added 32bits empty wrapped libXxf86vm 2024-09-26 13:29:35 +02:00
ptitSeb 95a0e669a2 [WRAPPER] Reworked wrapped libXxf86vm with new wrapperhelper 2024-09-26 13:29:08 +02:00
ptitSeb b80e4c552a [BOX32] Minor changes to 32bits freetype wrapping 2024-09-26 13:20:07 +02:00
Yang Liu 933dc0f5c8 [LA64_DYNAREC] Fixed emit_add16 LBT implementation (#1875) 2024-09-26 10:04:20 +02:00
Yang Liu 6a3904fc48 [BOX32][WRAPPER] Refined SDL2 display mode wrapping (#1874)
* [BOX32][WRAPPER] Refined SDL2 display mode wrapping

* review
2024-09-26 09:24:32 +02:00
Yang Liu b045dbde0f [BOX32][WRAPPER] Added preliminary wrapper for SDL2 (postal1 works) (#1872)
* [BOX32][WRAPPER] Added preliminary wrapper for SDL2 (postal1 works)

* Handle more events
2024-09-26 08:17:15 +02:00
ptitSeb b85ebc73c9 [BOX32][WRAPPER] Improved 32bits wrapping for libfreetype (still not 100% ok) 2024-09-25 19:46:55 +02:00
ptitSeb 7d76fc4945 [WRAPPER] Added 1 GLX extension ([BOX32] too) 2024-09-25 15:46:58 +02:00
ptitSeb 90332ecf6e [BOX32] Removed a warning 2024-09-25 14:51:56 +02:00
ptitSeb 0c4c89f3ca [BOX32] Fixed some locale conversion (fixed FTL.x86 not going ingame) 2024-09-25 14:47:25 +02:00
Yang Liu 62177d2ca3 [BOX32][WRAPPER] Fixed null checking in my32_SDL_SetVideoMode (#1868) 2024-09-25 13:07:26 +02:00
ptitSeb 144830bc05 [BOX32][WRAPPER] Added some more 32bits wrapped function, and fixed a few more 2024-09-25 12:29:46 +02:00
Yang Liu 24a5917b44 [LA64_DYNAREC][BOX32] Improved some 66 prefix opcodes (#1867) 2024-09-25 09:06:22 +02:00
ptitSeb b38c5f095c [BOX32][WRAPPING] More fixes with intermediate structure conversions 2024-09-24 22:37:11 +02:00
ptitSeb d7ad7f0c70 [BOX32][WRAPPING] Fixed some issue with intermediate structure conversions 2024-09-24 22:26:44 +02:00
Yang Liu dc391439ba [RV64_DYNAREC][BOX32] Added more opcodes (#1866)
* [RV64_DYNAREC][BOX32] Added more opcodes

* more
2024-09-24 21:58:47 +02:00
Yang Liu e44c43deeb [RV64_DYNAREC][BOX32] Improved some 66 prefix opcodes (#1865) 2024-09-24 21:10:50 +02:00
Yang Liu c795faf167 [LA64_DYNAREC][BOX32] Added more opcodes (#1864) 2024-09-24 21:10:10 +02:00
ptitSeb dad0913dcb [BOX32][WRAPPER] Added some more 32bits wrapped function, and fixed a few x11/glX ones too 2024-09-24 21:04:58 +02:00
ptitSeb e5db9aa874 [ARM64_DYNAREC] Fixed some issue with a few 16bits opcodes on 64bits operations 2024-09-24 21:04:57 +02:00
Yang Liu 2d0b60898c [RV64_DYNAREC] Added more opcodes for vector (#1863)
* [RV64_DYNAREC] Added more opcodes for vector

* [RV64_DYNAREC] Added more opcodes for vector

* [RV64_DYNAREC] Added more opcodes
2024-09-24 17:03:11 +02:00
ptitSeb c25fc8cc24 [BOX32][WRAPPER] Added a few 32bits function to libxrandr 2024-09-24 16:50:18 +02:00
ptitSeb bddeac4b45 [BOX32] Silently enlarge thread stack size that are too small for platform 2024-09-24 16:49:52 +02:00
ptitSeb 1aa42a6779 [BOX32][TRACE] Fixed semop traces 2024-09-24 16:49:19 +02:00
ptitSeb 73b3aec3ed [ARM64_DYNAREC] Fixed reset of rex on 67 prefixed opcodes 2024-09-24 15:17:56 +02:00
ptitSeb 9568cbac0a [ARM64_DYNAREC] Added F1 opcode 2024-09-24 14:49:45 +02:00
ptitSeb a60c742fa4 [ARM64_DYNAREC] Added CA/CB ocpodes 2024-09-24 14:46:34 +02:00
ptitSeb 6313a31668 [INTEPRETER] Added a check on CS for CA/CB opecodes 2024-09-24 14:46:17 +02:00
ptitSeb 15a4be2db1 [ARM64_DYNAREC] Added 66 0F BF opcode (and cosmetic fix on interpreter) 2024-09-24 14:31:59 +02:00
ptitSeb 0c71d8d4e6 [ARM64_DYNAREC] Added 64 A8 opcode 2024-09-24 14:26:02 +02:00
ptitSeb 4409374c47 [ARM64_DYNAREC] Added 67 A9 opcode, and fixed 67 opcode with ignored REX prefix 2024-09-24 14:20:22 +02:00
ptitSeb 4299e0a3a3 [BOX32][WRAPPER] Added more 32bits wrapped functions 2024-09-24 14:13:45 +02:00
Yang Liu c4af15c2e2 [RV64_DYNAREC] Allowed disabling V extension (#1862) 2024-09-24 11:44:16 +02:00
Yang Liu eacde4008e [RV64_DYNAREC] Fixed 66 0F 38 2B PACKUSDW opcode (#1861) 2024-09-24 11:43:21 +02:00
ptitSeb 358e24ace5 [BOX32][WRAPPER] Added 32bits empty libfreetype 2024-09-24 10:18:10 +02:00
ptitSeb 7317472b5f [BOX32][WRAPPER] More 32bits wrapped functions, and a few fixes on threads handling 2024-09-23 19:45:13 +02:00
ptitSeb 9271684e5a [BOX32][WRAPPER] One more 32bits wrapped libX11 function 2024-09-23 15:12:24 +02:00
ptitSeb 929d462d05 [BOX32] Addeda few more 32bits wrapped x11 functions 2024-09-23 14:23:02 +02:00
ptitSeb e0ce06483c [NON4K][ELFLOADER] more Elfloader work for non-4k pagesize OS ([BOX32] too) 2024-09-23 14:13:28 +02:00
ptitSeb 95e78088d6 [NON4K] Fixed some typos ([BOX32] too) 2024-09-23 14:01:45 +02:00
ptitSeb dd72a4542e [BOX32][NON4K] Try to fix elfloader when elf wants to load at an address not-compatible with pagesize 2024-09-23 13:54:48 +02:00
ptitSeb 5fe0a68b46 [NON4K] Try to fix elfloader when elf wants to load at an address not-compatible with pagesize 2024-09-23 13:52:11 +02:00
ptitSeb 61486749f8 [BOX32][WRAPPER] More 32bits wrapped function to libX11 2024-09-23 13:42:09 +02:00
Yang Liu 31f574ed36 [RV64_DYNAREC] Added more opcodes for vector (#1857) 2024-09-23 12:42:59 +02:00
ptitSeb d9ff07b605 [BOX32] Improved semaphore wrapping 2024-09-23 11:39:07 +02:00
ptitSeb dbdb3d6af6 [WRAPPER] Reworked wrapped libwayland-client with new wrapperhelper 2024-09-23 10:39:30 +02:00
ptitSeb 4c0a213840 [BOX32][WRAPPER] Added 32bits wrapped openal 2024-09-23 10:19:42 +02:00
ptitSeb aa65bad62b [WRAPPER] Reworked wrapped libopenal with new wrapperhelper 2024-09-23 10:10:14 +02:00
ptitSeb 60c469ed06 [BOX32][WRAPPER] Added a couple of 32bits libx11 functions 2024-09-22 20:34:25 +02:00
ptitSeb cf87ae2e71 [WRAPPING] Fixed some (very) old issue with SDL2 RWops wrapping 2024-09-22 20:20:54 +02:00
Yang Liu ea443cfa21 [RV64_DYNAREC] Added more opcodes for vector (#1855) 2024-09-22 19:22:36 +02:00
ptitSeb 5e49e3cfaa [BOX32][WRAPPER] Added some more libX11 and libc 32bits wrapped function, and empty 32bits wrapped libXfixes, libXcursor, libXrender and libXrandr 2024-09-22 17:11:07 +02:00
ptitSeb 8574c575f5 [WRAPPER] Reworked wrapping of libXcurse, libXfixes, libXrender and libXrandr with new wrapperhelper 2024-09-22 17:10:03 +02:00
ptitSeb d2aecc0412 [BOX32][wrapper] Added some basic 32bits X11 wrapping, fixed 32bits sem_XXX wrapping, and more 32bits wrapped functions 2024-09-22 16:24:48 +02:00
Yang Liu 710d537f39 [RV64_DYNAREC] Added more opcodes for vector (#1853) 2024-09-22 15:36:25 +02:00
Yang Liu 9e44c65391 [RV64_DYNAREC] Added more opcodes for vector (#1852) 2024-09-22 11:24:08 +02:00
Yang Liu c36491cfb6 [RV64_DYNAREC] Added more opcode for vector and reinitialize sew after external call (#1851) 2024-09-22 08:36:18 +02:00
ptitSeb c2be0268b1 [BOX32][ELFLOADER] Fixed PROTECTED symbol that were not loaded correctly 2024-09-21 15:52:02 +02:00
ptitSeb 4cda6dbcfb [ELFLOADER] Fixed PROTECTED symbol that were not loaded correctly 2024-09-21 15:51:51 +02:00
ptitSeb e34afea346 [BOX32] Added some more 32bits wrapped functions 2024-09-21 14:55:42 +02:00
ptitSeb 1ea71c89a8 [BOX32] Fixed wrapping of __ctype_b, __ctype_tolower and __ctype_toupper 2024-09-21 14:22:21 +02:00
ptitSeb 856ffea797 [BOX32][TRACE] Better trace for a few more 32bits string functions 2024-09-21 14:21:49 +02:00
ptitSeb 9efae57162 [BOX32] Added 32bits wrapped libGLU 2024-09-21 12:35:26 +02:00
rajdakin 09d4cb7b38 [WRAPPERHELPER] Fixed wrapperhelper (#1850) 2024-09-21 12:29:28 +02:00
ptitSeb fb4f580922 [BOX32] Added some more 32bits wrapped functions (Chicken Invaders 3 works, but need SDL12COMPAT_OPENGL_SCALING=0) 2024-09-21 12:20:26 +02:00
Yang Liu 15842f3464 [RV64_DYNAREC] Added more opcodes for vector (#1848) 2024-09-20 18:42:04 +02:00
rajdakin e18846fac5 [WRAPPERHELPER] Fixed some bugs, added partial multiarch support (#1847) 2024-09-20 17:06:25 +02:00
Yang Liu 4aeb8ea1b0 [LA64_DYNAREC] Fixed a typo in GETGB (#1846) 2024-09-20 16:04:00 +02:00
ptitSeb 6a415b54d0 [WRAPPER] Reworked libX11 with new wrapperhelper 2024-09-20 15:28:13 +02:00
rajdakin 5abdfd9751 [WRAPPERHELPER] Added predefined mark-simple and conversions (#1845) 2024-09-20 14:32:26 +02:00
ptitSeb ab65619b99 [WRAPPER] Added an entry in gitignore for wrapperhelper 2024-09-20 12:52:54 +02:00
ptitSeb 88629f7aa6 [WRAPPER] Reworked libXft with new wrapperhelper (should help #1841) 2024-09-20 12:51:59 +02:00
ptitSeb fb11af5859 [WRAPPER] Added hack for parser helper to __attribute inline and noreturn 2024-09-20 12:49:01 +02:00
rajdakin 550b72200d Improve the wrapper helper (#1844)
* [WRAPPERHELPER] Fixed some issues, added better macros

* [WRAPPERHELPER] Fixed type_t_equal_lax
2024-09-20 12:40:06 +02:00
Yang Liu cd9d19a2bb [RV64_DYNAREC] Added more opcodes and fixed more issues for vector (#1842)
* [RV64_DYNAREC] Added 66 0F 6D PUNPCKHQDQ opcode

* [RV64_DYNAREC] Added more opcode

* [RV64_DYNAREC] Added more opcodes for vector

* [RV64_DYNAREC] Added more opcodes

* [RV64_DYNAREC] Added more opcodes

* [RV64_DYNAREC] Added more opcode

* More fixes
2024-09-20 11:30:11 +02:00
ptitSeb ca9e43d0f0 [WRAPPER] Added 1 wrapped function to libX11 (for #1204 and #1841) 2024-09-20 10:36:29 +02:00
ptitSeb 04d2f90ab3 Added Syscall 165 (for #1672) 2024-09-20 10:27:18 +02:00
LiZhuoheng 906cdb1584 [RV64_DYNAREC] Added 62 opcode (#1840) 2024-09-20 08:21:12 +02:00
Yang Liu 1978ec8b71 [RV64_DYNAREC] Fixed more issues catched on real machine (#1839) 2024-09-19 20:08:22 +02:00
ptitSeb 28f32a3ca6 [BOX32][WRAPPER] Added minimum 32bits libasound support 2024-09-19 18:57:32 +02:00
Yang Liu 3b7a448b07 [RV64_DYNAREC] Added more 66 0F opcodes for vector (#1838) 2024-09-19 17:07:59 +02:00
ptitSeb 8f0c1efc6f [WRAPPER] Reworked libasound with new wrapperhelper 2024-09-19 14:30:36 +02:00
ptitSeb c10b673fef Fixed a comment on x87 tags 2024-09-19 14:20:21 +02:00
ptitSeb bfd9f79267 [WRAPPER] Some rework on a few wrapped function foor glib2, libxcb and libxcb-private 2024-09-19 13:22:28 +02:00
ptitSeb f7c596317b [TRACE] Fixed a potential segfault when trying to trace a function from a dlopenn'd lib 2024-09-19 13:20:45 +02:00
ptitSeb e4debaf4ba [TRACE] Some better trace for a few function call 2024-09-19 13:20:02 +02:00
ptitSeb 4eeba053d5 Fixed some x87 tag handling 2024-09-19 13:19:12 +02:00
Yang Liu 7263a2e7ab [RV64_DYNAREC] Added more opcodes for vector (#1837) 2024-09-19 12:06:07 +02:00
Yang Liu ef7f25481c [RV64_DYNAREC] Added more opcodes for vector (#1836) 2024-09-19 10:43:23 +02:00
Yang Liu 35d17abeb0 [RV64_DYNAREC] Fixed more unaligned issues for vector (#1835) 2024-09-19 08:11:02 +02:00
Yang Liu 33472d3a8e [RV64_DYNAREC] Fixed some found issues in vector (#1834)
* [RV64_DYNAREC] Fixed 66 0F 63/6B PACKSSWB opcode

* [RV64_DYNAREC] Fixed 66 0F 3A 0F PALIGNR opcode

* [RV64_DYNAREC] GETGX_empty_vector should come after GETEX_vector

* [RV64_DYNAREC] Fixed unaligned memory access

* [RV64_DYNAREC] Fixed more unaligned issue

* Fix CI
2024-09-18 20:27:45 +02:00
ptitSeb e60ddf7ecd [WRAPPER] Reworked libGLU with new wrapper helper 2024-09-18 11:52:00 +02:00
ptitSeb 579332db7d [WRAPPER] Reworked libEGL with new wrapperhelper 2024-09-18 11:38:25 +02:00
ptitSeb b34c031139 [WRAPPER] Reworked libgobject-2.0 with new wrapperhelper 2024-09-18 11:31:29 +02:00
ptitSeb 46bc2e7183 [WRAPPER] Reworked wrapped libpsl.so.5 with new wrapperhelper 2024-09-18 11:00:49 +02:00
ptitSeb 26ddbf9466 [WRAPPER] Reworked wrapping glib-2.0 (stil with new wrapperhelper) 2024-09-18 10:55:00 +02:00
ptitSeb b67dc452b2 [WRAPPER] Reworked wrapped libgio-2.0 2024-09-18 10:09:59 +02:00
Yang Liu b37b6addac [RV64_DYNAREC] Added more opcodes for vector (#1833)
* [RV64_DYNAREC] Added more opcodes for vector

* review
2024-09-18 09:23:54 +02:00
ptitSeb a2dfe70cd8 [WRAPEPR] Reworked wrapping of libgdk3 2024-09-17 19:10:10 +02:00
ptitSeb 20a2b4e051 [WRAPPER] Reworked gtk3 wrapping 2024-09-17 18:36:03 +02:00
ptitSeb d7c3c3fcf9 Save flags and defered flags when runing EmuCall ([DYNAREC] Same for DynaCall) 2024-09-17 16:39:54 +02:00
ptitSeb 7d77a4b31f [DYNAREC] Track if a dynablock is for 32bits code (for future use) 2024-09-17 16:33:59 +02:00
Yang Liu 59217ccbbe [RV64_DYNAREC] Added more 66 0F opcodes for vector (#1832) 2024-09-17 13:31:47 +02:00
Yang Liu f674953b87 [RV64_DYNAREC] Added more 66 0F opcodes for vector (#1831) 2024-09-17 09:35:15 +02:00
Yang Liu b8798c580f [RV64_DYNAREC] Added more opcodes for vector (#1830) 2024-09-16 19:38:37 +02:00
Yang Liu 2b58e8a253 [RV64_DYNAREC] Added more 66 0F opcodes for vector (#1829) 2024-09-16 19:13:21 +02:00
ptitSeb f744513941 Fixed non-box32 builds 2024-09-16 19:03:50 +02:00
ptitSeb e8ecbbdc6a [BOX32][TRACE] Improved some trace and function calls for 32bits process 2024-09-16 17:53:24 +02:00
ptitSeb 1f7c69e19e [BOX32] Added 1 more wrapped 32bits libc function 2024-09-16 17:52:47 +02:00
ptitSeb de4044d5b1 [BOX32] Fixed an issue with using 32bits OpenGL with SDL1.2 2024-09-16 17:42:22 +02:00
ptitSeb 1503241c7a [BOX32] Added some more 32bits wrapped function, and fixing some SDL ones 2024-09-16 17:25:06 +02:00
ptitSeb 37a1261693 [DYNAREC] Forgot some files in previous commit 2024-09-16 16:18:19 +02:00
ptitSeb 446d57122c [DYNAREC] Make sure jump address is wrapped on 32bits address space 2024-09-16 16:10:29 +02:00
ptitSeb 1e8807ac0a [BOX32][TRACE] Added a warning when executing 32bits code in 64bits address space 2024-09-16 16:09:11 +02:00
ptitSeb 40ac1bca84 [BOX32] Partial handling of wrapped dl_iterate_phdr 2024-09-16 15:31:46 +02:00
ptitSeb bff3b935fb Better handling of argv[0] 2024-09-16 15:30:39 +02:00
ptitSeb 9faa9f41e0 [ARM64_DYNAREC] Fixed most CD xx opcodes 2024-09-15 15:22:35 +02:00
ptitSeb 9fa43f2386 Added a hack so program that wprintf to the console actualy work if box64 already printed something 2024-09-14 17:36:45 +02:00
ptitSeb f2397256e2 [BOX32][WRAPPER] Added more 32bits sdl1 and libc symbols 2024-09-14 16:46:13 +02:00
ptitSeb e5ad7c36ec [BOX32][ELFLOADER] Fixed some issue with symbol resolver 2024-09-14 16:45:44 +02:00
ptitSeb 3b8ba5dfa6 Added 66 F3 0F BD opcode ([ARM64_DYNAREC] Too) 2024-09-14 15:21:15 +02:00
ptitSeb 2e1b58a876 [BOX32] Added a few libc 32biyts wrapped functions 2024-09-14 11:37:22 +02:00
ptitSeb de7baa0b41 [BOX32] Added (mostly untested) wrapped libGL and minimum SDL1 (SDLgears and zsnes works) 2024-09-14 10:26:38 +02:00
ptitSeb b361a0d2ff Fixed flags for AVX.0F38 F2 opcode ([ARM64_DYNAREC] too) 2024-09-14 08:46:23 +02:00
Yang Liu 0acd849f18 [RV64_DYNAREC] Added 1 more opcode for vector and some refactor and fixes too (#1824) 2024-09-13 12:16:09 +02:00
ptitSeb ed4ff15682 [BOX32][TRACE] More improved trace for some 32bits functions call 2024-09-13 12:09:35 +02:00
ptitSeb de276ddfa9 [BOX32][TRACE] Better trace for 32bits call to strtol and strtoul 2024-09-13 11:19:47 +02:00
ptitSeb 192347ea3a [BOX32] More small 32bits signature adjustments 2024-09-13 11:19:12 +02:00
ptitSeb d618cfdf0e [BOX32][TRACE] Better trace for 32bits strncasecmp calls 2024-09-13 11:15:44 +02:00
ptitSeb 0f0762a24c [BOX32] Added one more wrapped 32bits libc function 2024-09-13 11:12:41 +02:00
ptitSeb 89a49db558 [BOX32] Adjusted some 32bits wrapped functions 2024-09-13 11:08:40 +02:00
ptitSeb 1ee51a54de [BOX32][TRACE] Better trace for some 32bits wrapped function calls 2024-09-13 11:08:10 +02:00
ptitSeb 68f394a38b [TRACE] Better trace for 32bits FF 52 opcode 2024-09-13 11:07:31 +02:00
ptitSeb 32c94ac31a [BOX32] Fixed 32bits wrapped localeconv (for #1780) 2024-09-13 10:58:10 +02:00
ptitSeb af476e0d10 [BOX32] Fixed gethostbyname 32bits wrapped function (for #1780 but still crashing) 2024-09-13 10:47:47 +02:00
JunChi1022 b504d07afe [DYNAREC] fix page calculation error (#1822) 2024-09-12 19:04:28 +02:00
Yang Liu 9544fbdff9 [RV64_DYNAREC] Refactored vector SEW tracking (#1820) 2024-09-12 19:03:00 +02:00
Yang Liu 431365d1f8 [RV64_DYNAREC] Fixed a typo on vector_sew initialization (#1819) 2024-09-12 14:14:54 +02:00
ptitSeb 693b4adb4b [STATIC] Forgot this definition 2024-09-12 14:07:15 +02:00
ptitSeb 1a637cb1d8 Fixed a typo 2024-09-12 14:01:53 +02:00
ptitSeb 0d952641ed [STATIC] Try to fix static build 2024-09-12 13:56:52 +02:00
ptitSeb 418e2a00ce [BOX32] Simplified 32bits old pthread cond functions 2024-09-12 10:32:33 +02:00
ptitSeb d1d2de33e6 [WRAPPER] Added handling of old pthread cond functions 2024-09-12 10:32:11 +02:00
ptitSeb ab84faa3ca [WRAPPER] Added 1 wrapped function to glibc2 2024-09-12 10:31:29 +02:00
ptitSeb fc7f83c60b [BOX32][WRAPPER] Added support for old pthread_kill (fixing hanging steamcmd) 2024-09-11 18:01:23 +02:00
ptitSeb af028c9bad [WRAPPER] Small fixes for x86_64 build when using old pthread_kill 2024-09-11 18:00:45 +02:00
ptitSeb 29daae551c [BOX32] Improved 32bits unsupported syscall warning, and added syscall 240 2024-09-11 16:55:42 +02:00
ptitSeb e1a91ea420 [BOX32] Improved trace for 32bits pthread_setname_np 2024-09-11 16:54:17 +02:00
ptitSeb bd60ed8df0 [BOX32] Improved hash<->64bits handling 2024-09-11 16:53:51 +02:00
Yang Liu 6b6d20732e [RV64_DYNAREC] Added more 0F opcodes for vector (#1817) 2024-09-11 14:26:50 +02:00
Yang Liu 4d60b75240 [RV64_DYNAREC] Added more 0F opcodes for vector and optimized some opcodes too (#1816)
* [RV64_DYNAREC] Optimized 66 0F 67 PACKUSWB opcode

* [RV64_DYNAREC] Optimized 66 0F 6C PUNPCKLQDQ opcode

* [RV64_DYNAREC] Added some 0F opcodes for vector

* review
2024-09-11 10:25:04 +02:00
Yang Liu fc9900c8f6 [RV64_DYNAREC] Added more 66 0F opcodes for vector (#1815)
* [RV64_DYNAREC] Added more 66 0F opcodes for vector

* [RV64_DYNAREC] Fixed PACKUSWB for vlen >= 256
2024-09-10 21:11:58 +02:00
Aidan 629346b6a7 [SDORYON1] Oryon1 (Snapdragon Elite) support (#1786) 2024-09-10 19:57:36 +02:00
ptitSeb e95be7cd3f Improved legendary stability 2024-09-10 19:21:15 +02:00
ptitSeb 1bfb50f29a [WRAPPER] Updat generated wrapper files 2024-09-10 19:20:43 +02:00
rajdakin 8187c35ea8 [WRAPPERS] Fixed some wrong wrappings (#1814) 2024-09-10 17:46:10 +02:00
rajdakin 0d6028d837 [WRAPPERHELPER] Added per-arch override, always include 'stdc-predef.h', better parsing (#1813) 2024-09-10 17:25:37 +02:00
ptitSeb 2127eaea22 [BOX32] Put back pthread_t behind hash, but ease hash range to have more native values 2024-09-10 16:55:25 +02:00
ptitSeb 7794a623aa [BOX32] Fix and simplified 32bits threads handling 2024-09-10 15:10:28 +02:00
ptitSeb 0443edc034 [BOX32] Fixed wrapping 32bits version of __cxa_finalize 2024-09-10 15:09:45 +02:00
ptitSeb a7f8dbac56 [WRAPPER] Minors adjustments to pulse audio wrapping 2024-09-10 11:25:07 +02:00
Yang Liu b0ec124329 [RV64_DYNAREC] Added 66 0F D4 PADDQ opcode for vector and fixes SEW cache transform (#1812)
* [RV64_DYNAREC] Added 66 0F D4 PADDQ opcode for vector

* [RV64_DYNAREC] Transform SEW cache after fpu cache
2024-09-10 10:52:04 +02:00
ptitSeb b40121c9b0 [VULKAN] Added missing wrapper for vkCreateSamplerYcbcrConversionKHR 2024-09-10 10:43:54 +02:00
ptitSeb cc9984a082 Fixed alignement of thread funcitons (fixed regression for #1810) 2024-09-10 10:32:45 +02:00
Yang Liu c22758d794 [RV64_DYNAREC] Added more 66 0F opcodes for vector (#1811) 2024-09-10 08:58:22 +02:00
ptitSeb 1b48cd157a [RCFILE] Slightly changed how BOX64_ARGS behave, and added BOX64_INSERT_ARGS 2024-09-09 19:45:48 +02:00
ptitSeb 362402ffbf Improved wrapped function clone handling of CLONE_NEWUSER flag 2024-09-09 17:11:29 +02:00
ptitSeb 5ce868b100 When showing opcode on SEGFAULT/SIGBUS, show if it's x86 or x64 2024-09-09 17:10:04 +02:00
ptitSeb 823d1cc004 [DYNAREC] Simplified a bit getX64Address utility function 2024-09-09 17:07:16 +02:00
ptitSeb 2ce5beae56 [WRAPPER] Added H as paramterand, added 2 wrapped function from libatomic (for linux BeamNG) 2024-09-09 17:03:46 +02:00
ptitSeb 34fcbbd7b7 [TRACE] Better trace for F3 0F 1E FA opcode 2024-09-09 16:02:37 +02:00
ptitSeb bdde96be95 [ARM64_DYNAREC] Added 64 0F 28/29 opcodes 2024-09-09 16:02:04 +02:00
rajdakin 26b7a49d82 [WRAPPERHELPER] Fixed preprocessor logic, moved type validation to machine (#1808) 2024-09-08 22:26:35 +02:00
ptitSeb fa8a5a2033 [WRAPPER] Added 2 wrapped function to libatomic 2024-09-08 17:25:58 +02:00
rajdakin c87a56ef37 [WRAPPERHELPER] Major enhancements in output quality, allow for generic type mapping (#1807) 2024-09-08 16:43:16 +02:00
rajdakin 2e04ff93ca [WRAPPED] Fixed some libc wrapped functions (#1806)
* [WRAPPED] Fixed some libc wrapped functions

* [WRAPPED] Fixed static build, added back

* [WRAPPED] Fixed unlimited wrapping

* [WRAPPED] Forgot to update
2024-09-08 15:10:45 +02:00
ptitSeb a9f96b9d62 Show x86opcode at segfault if segfault address is not pc 2024-09-08 15:06:54 +02:00
ptitSeb 8f855f5dde [ARM64_DYNAREC] Avoid computing flags if they are just recomputed at jump point 2024-09-08 14:18:03 +02:00
ptitSeb 6d3fa25d5f [ARM64_DYNAREC] Small optim for 0F C6 opcode 2024-09-08 14:03:47 +02:00
ptitSeb 57b7bcf8f4 [WRAPPING] Updated gtk3 wrapping (still more work to do) 2024-09-08 10:02:39 +02:00
rajdakin f30d75ae5d [WRAPPERHELPER] General improvements (#1804)
* [WRAPPERHELPER] Automatic headers detection, various bug fixes, added some cast support

* [WRAPPERHELPER] Keep comments untouched
2024-09-07 20:53:51 +02:00
ptitSeb e087e7782c [WRAPPER] Fixed some OpenGL function signatures 2024-09-07 19:06:04 +02:00
ptitSeb 17fa93035a Added some more wrapeed function to libusb1 (for #1802) 2024-09-07 15:48:22 +02:00
rajdakin f0d7582845 Upgraded the wrapper helper (#1803)
* [WRAPPERHELPER] Fixed unsigned comparison in macros, added macro expanding in include commands, added -I option

* [WRAPPERHELPER] Forgot the README
2024-09-07 15:20:17 +02:00
ptitSeb 75bdb32828 Added a small fix in signe handler ucntx construction 2024-09-07 11:59:34 +02:00
ptitSeb fd633d2cee Allow dynarec_dump=2 and forbid dynarec_test=2 (fixed a regression with command line params) 2024-09-07 09:40:50 +02:00
ptitSeb a6d7d83fb3 Added a workaround with syscall if statx function is not defined in libc 2024-09-07 09:20:45 +02:00
ptitSeb a450b9d12f [ARM64_DYNAREC] Improved AVX.66.0F38 8C opcode 2024-09-06 18:01:40 +02:00
ptitSeb 5ac3eeef11 Fixed name of opcode in comment 2024-09-06 18:00:00 +02:00
ptitSeb 9838c2ccff Fixed a typo 2024-09-06 17:59:38 +02:00
ptitSeb 16cee6feb2 Added 1 wrapped function libxkbcommon 2024-09-06 16:13:35 +02:00
rajdakin 21c86f9ac6 [WRAPPED] Update libc wrappers (#1800)
* [WRAPPED] Fixed some issues in libc_private.h and the wrapper generator

* [WRAPPED] Forgot to run the Python script

* [WRAPPED] Oops
2024-09-06 15:08:01 +02:00
rajdakin 6044feb7fd Wrapper helper (#1799)
* [WRAPPERHELPER] Added wrapperhelper v0.1, tested on libc

* [WRAPPED] Removed updates to libc from this branch

* [WRAPPERHELPER] Removed GPL header and added modified LGPL header, added notes about licensing issues
2024-09-06 15:07:38 +02:00
Yip Coekjan 7dc59ac342 Eliminate duplicate hash calculations for getSymbolInSymbolMaps (#1801) 2024-09-06 14:35:32 +02:00
ptitSeb 16f156be3f Added 1 wrapped function to libgdk3 2024-09-06 10:59:03 +02:00
rajdakin 64dd09becc [WRAPPED] Removed GOS, renamed GODW into GOWD (#1797) 2024-09-05 20:26:45 +02:00
ptitSeb 19dc18f7c5 Fixed a regression introduced with box32 that broke Bladur's Gate 3 (and probably a few other) 2024-09-05 19:12:19 +02:00
Yang Liu 4e63b82f5e [CI] Refactored CI (#1795)
* [CI] Enable Box32 tests on LA64

* upgrade QEMU

* [COSIM] Removed thread-safe tests

* Use regular cosim in CI

* [CI] Simplified "Test Box64"

* exclude certain tests when testing with cosim

* review

* box64.pod too
2024-09-05 11:07:27 +02:00
ptitSeb 6bc2abae3b [ARM64_DYNAREC] Added 67 66 0F 7E opcode 2024-09-04 21:04:20 +02:00
ptitSeb 6c7f306baa [ARM64_DYNAREC] Added AVX.66.0F 51 opcode 2024-09-04 20:56:23 +02:00
ptitSeb c56517b801 More work on Custom Mem speedup 2024-09-04 17:45:28 +02:00
ptitSeb b5e405b2b4 Added an rbtree is Custom Mem Manager to speedup customFree and customRealloc 2024-09-04 15:23:37 +02:00
ptitSeb 354f46f41b Some refactor (and small bugfixes) around Custom Mem Manager 2024-09-04 14:39:44 +02:00
Yang Liu b34a50b381 [X64LIBS] Changed x86/x64 libs install directory to prevent conflicts (#1791)
* [X64LIBS] Changed x86/x64 libs install directory to prevent conflicts

* Update pressure_vessel
2024-09-04 14:13:58 +02:00
ptitSeb a973c53ea2 [BOX32] This should fix NO_ALIGN box32 build 2024-09-04 11:28:11 +02:00
ptitSeb ee7b10f064 [BOX32] Small improvments on memory management 2024-09-04 11:00:43 +02:00
Yang Liu c1ad6b5829 [CI] Speedup CI by removing some unnecessary targets (#1790) 2024-09-04 09:59:27 +02:00
ptitSeb 9eaaaaa1e3 [BOX32] Added some more 32bits wrapped function to libc 2024-09-03 20:19:34 +02:00
ptitSeb 115707a0f1 [BOX32] Fixed a missing box_free 2024-09-03 20:19:34 +02:00
ptitSeb 3179357666 [BOX32] Better trace for 32bits posix_memalign 2024-09-03 20:19:34 +02:00
ptitSeb cb7433d70a [RCFILE] Fixed some missing box_free/box_strdup in rcfile 2024-09-03 20:19:34 +02:00
ptitSeb 62021fc291 [BOX32] Better log for 32bits pointer conversion error 2024-09-03 20:19:34 +02:00
ptitSeb ab3ff07c93 [BOX32] Fixed 32bits locale memory size 2024-09-03 20:19:34 +02:00
Yang Liu 22ab62a729 [WRAPPED] Added back some libc function wrappers (#1788) 2024-09-03 12:50:02 +02:00
ptitSeb ff7a8bfdae [BOX32] Various small fixes 2024-09-02 09:53:36 +02:00
Yang Liu 27ed109394 [BOX32] Fixed build with mold (#1785) 2024-09-01 20:58:10 +02:00
rajdakin ea807eda04 [WRAPPED] Merged types D/K and Y/y in 64bits wrapped libs (#1784)
* [WRAPPED] Merged types D/K and Y/y in 64bits wrapped libs

* [WRAPPERS] Version bump

* [WRAPPED] Fixed wrapped glib2 on non-LD80BITS builds
2024-09-01 19:06:03 +02:00
JunChi1022 36321f809d [DYNAREC]: fix BICS encoding (#1783) 2024-09-01 17:58:18 +02:00
ptitSeb 254df70148 [BOX32] Better handling for FILE* 2024-09-01 17:44:32 +02:00
ptitSeb 759cef6e01 [BOX32] Fixes and hacks to get steamcmd shows the prompt 2024-09-01 17:09:54 +02:00
ptitSeb 02364151bc [BOX32] Some fixes to strtol/strtoul and read 32bits wrapped functions 2024-09-01 13:59:51 +02:00
ptitSeb 9178effd9f [BOX32] More wrapped function and a few fixes for steamclient.so (still crashing) 2024-09-01 13:07:47 +02:00
ptitSeb cce9e280ce [BOX32] New batch of 32bits wrapped functions for steamconsole.so 2024-08-31 17:30:22 +02:00
ptitSeb 5468d8b08e [BOX32] One more 32bits wrapped function for libvstdlib_s.so 2024-08-31 17:20:01 +02:00
ptitSeb 497f629761 [BOX32] Another batch of 32bits wrapped function, for libvstdlib_s.so this time 2024-08-31 15:59:48 +02:00
ptitSeb 6f08601479 [BOX32] Another batch of 32bits wrapped function, for libtier0_s.so 2024-08-31 14:52:45 +02:00
ptitSeb 6d6739ccea [BOX32] More 32bits wrapped functions 2024-08-31 11:39:55 +02:00
ptitSeb d2511e66fb [RCFILE] Added support fro cursor (for #1778) 2024-08-31 09:05:36 +02:00
Yang Liu e23eb14809 [RV64_DYNAREC] Added xthead* extensions to the new printer (#1781) 2024-08-31 07:47:28 +02:00
Yang Liu f5dbe2156c [RV64_DYNAREC] Refactored rv64_printer (#1779)
* [RV64_DYNAREC] Refactored printer

* Fixed one more issue
2024-08-30 20:32:15 +02:00
ptitSeb 723b94da05 [BOX32] More 32bits wrapped function and fixes 2024-08-30 18:54:16 +02:00
ptitSeb 7ecdced486 [BOX32] Added more 32bits wrapped function and fixes 2024-08-30 15:59:07 +02:00
ptitSeb 13b72df762 [BOX32] Define native_statvfs to avoid build errors 2024-08-30 13:50:37 +02:00
Yang Liu 95b38b7f79 [CI] Added 60s timeout per test (#1777) 2024-08-30 13:24:15 +02:00
ptitSeb 3fb5052223 [BOX32] More 32bits wrapped functions and fixes 2024-08-30 13:22:48 +02:00
Yang Liu 62b93a0785 Wrapped 1 more function for libxcb (#1776) 2024-08-30 12:30:23 +02:00
ptitSeb 371b45c420 [BOX32] Added detection of steam and steamcmd 2024-08-30 10:13:42 +02:00
ptitSeb 4dcf14d026 [ARM64_DYNAREC] Added 67 F3 0F 38 F6 opcode (for #1775) 2024-08-30 10:02:49 +02:00
ptitSeb 854ee95d69 Added 67 F3 0F 38 F6 opcode (for #1775) 2024-08-30 09:58:42 +02:00
ptitSeb 9ac536a1dd [BOX32] More fixes to ctype_b_loc and added a few more wrapped functions 2024-08-29 18:17:57 +02:00
Yang Liu 9820bee5e7 [BOX32][LA64_DYNAREC] Added preliminary box32 support (#1773) 2024-08-29 17:16:39 +02:00
ptitSeb b02302a5cf [BOX32] Fixed 32bits localtime_r wrapped function 2024-08-29 16:32:14 +02:00
ptitSeb 9633ad35a8 [BOX32] Added more 32bits wrapped function and more fixes 2024-08-29 16:30:39 +02:00
ptitSeb 4bd6294862 [TRACE] Added one 32bits jump decoding dest address 2024-08-29 16:30:09 +02:00
ptitSeb 63e525697f [BOX32][TRACE] Improve function trace log 2024-08-29 16:29:21 +02:00
ptitSeb 4cdd46819f [TRACE] Improved trace on symbol name 2024-08-29 11:10:45 +02:00
Yang Liu 0450371e28 [RV64_DYNAREC] Fixed a falsy optimization, better EMIT macro (#1769) 2024-08-28 23:06:29 +02:00
Yang Liu d9e5f8183f [RV64_DYNAREC] Optimized jump_to_next using XTheadBb instructions (#1768)
* [RV64_DYNAREC] Optimized jump_to_next using XTheadBb instructions

* fixed some bad bad typos
2024-08-28 23:05:02 +02:00
Yang Liu abbaf9b593 [BOX32][RV64_DYNAREC] Fixed more issues and enable CI for box32 (#1767)
* [BOX32][RV64_DYNAREC] Fixed more issues

* fix

* fix

* enable Ci for box32

* add some comments
2024-08-28 19:48:22 +02:00
ptitSeb 126c59b4a4 [BOX32] More wrapped 32bits functions, and some fixes too 2024-08-28 18:35:24 +02:00
ptitSeb b7be225846 [BOX32] More 32bits wrapped functions 2024-08-28 17:12:00 +02:00
ptitSeb 041eb4e69d [BOX32] Adding some more 32bits wrapped functions 2024-08-28 15:03:16 +02:00
ptitSeb 04157f2502 [ARM64_DYNAREC] Not using simpleWrapper when dynarec_test is on 2024-08-28 15:02:48 +02:00
Yang Liu 189222cb66 [BOX32][RV64_DYNAREC] Added preliminary box32 support to RV64 (#1766)
* [BOX32][RV64_DYNAREC] Added preliminary box32 support to RV64

* fix

* fix fix

* fix
2024-08-28 14:01:50 +02:00
ptitSeb 6835c4aaf5 [BOX32] Fixed some error log in elfloader32 2024-08-28 12:44:53 +02:00
Yang Liu 875a2ef3a9 [RV64_DYNAREC] Added a fast path for some 16bit opcodes (#1765) 2024-08-27 20:23:42 +02:00
ptitSeb bfbf18688b [ARM64_DYNAREC] Small refactor around get_segdata usage 2024-08-27 18:57:36 +02:00
Yang Liu 9de694c46b [RV64_DYNAREC] Added a fast path for some 8bit opcodes (#1763)
* [RV64_DYNAREC] Added a fast path for some 8bit opcodes

* fix

* more

* more
2024-08-27 18:55:11 +02:00
KreitinnSoftware 220c5ee47d [CTEST] Use BOX64_LD_LIBRARY_PATH instead of default LD_LIBRARY_PATH (#1764) 2024-08-27 18:34:58 +02:00
ptitSeb 99f2207fd4 [ARM64_DYNAREC] Mark new upper YMM part as new, so the can be unwind too (for #1759) 2024-08-27 10:57:51 +02:00
KreitinnSoftware 50623f32f6 Revert "[ANDROID] Not use 'libbsd.so' as needed lib and don't define NEEDED_L…" (#1762)
This reverts commit a7c61d8e20.
2024-08-27 08:37:40 +02:00
b5105a1e57 Added preliminary Box32 support (#1760)
* Improve the ReserveHigMemory helper function

* [BOX32] Added some wrapping infrastructure

* [BOX32] More wrapped 32bits lib infrastructure

* [BOX32] Added callback and tls 32bits handling

* [BOX32] Added more 32bits, around wrappers and elfs

* [BOX32] Added the 32bits version of myalign

* [BOX32] More wrapped libs and 32bits fixes and imrpovments

* [BOX32] Added some 32bits tests

* [BOX32] Try to enable some Box32 build and test on the CI

* [BOX32] Disable Box32 testing on CI platform that use qemu

* [BOX32] Another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Small fix for another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Yet another fix for another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Fixed a typo in CI script

* [BOX32] Better scratch alighnment and enabled more tests

* [BOX32] Added (partial) wrapped 32bits librt

* [BOX32] Added mention of Box32 in README

* [BOX32] Added phtread handling, and numerous fixes to 32bits handling. [ARM64_DYNAREC] Fixed access to segment with negative offset

* [BOX32] Added system libs and cpp testing, plus some more fixes

* [BOX32] Fix previous commit

* [BOX32] Better stack adjustment for 32bits processes

* [BOX32] Added getenv wrapped 32bits function and friends

* [BOX32] Don't look for box86 for a Box32 build

* [BOX32] Don't do 32bits cppThreads test for now on CI

* [BOX32] Enabled a few more 32bits tests

* [BOX32] For ld_lib_path for both CppThreads tests

* [BOX32] [ANDROID] Some Fixes for Android Build

* [BOX32] Still need to disable cppThread_32bits test on CI for some reason

* [BOX32] [ANDROID] Don't show PreInit Array Warning (#1751)

* [BOX32] [ANDROID] One More Fix for Android Build That I forgotten to … (#1752)

* [BOX32] [ANDROID] One More Fix for Android Build That I forgotten to push before

* [BOX32] [ANDROID] Try to Create __libc_init

* [BOX32] [ANDROID] Try to disable NEEDED_LIBS for now (libdl is not wrapped)

* [BOX32] Updated generated files

* [BOX32] Added 32bits context functions

* [BOX32] Added 32bits signal handling

* [BOX32] Added some missing 32bits elfloader functions

* [BOX32] Fix build on x86_64 machine

* [BOX32] Better fix for x86_64 build

* [BOX32] Actually added missing libs, and re-enabled cppThreads_32bits test

* [BOX32] Added wrapped 32bits libdl

* [BOX32] Try to re-enabled Box32 test on CI for ARM64 builds

* [BOX32] fine-tuning Box32 test on CI for ARM64 builds

* [BOX32] More fine-tuning to Box32 test on CI for ARM64 builds

* [BOX32] Enabled Box32 test on CI for LA64 and RV64 builds too

* [BOX32] re-Disabled Box32 test on CI for LA64 and RV64 builds, not working for now

* [BOX32] Temporarily disabled cppThreads_32bits test on CI

---------

Co-authored-by: KreitinnSoftware <[email protected]>
Co-authored-by: KreitinnSoftware <[email protected]>
2024-08-26 17:45:13 +02:00
WANG Guidong 9beb745765 [RV64_DYNAREC] Fix some typos in docs and dynarec/rv64 (#1758)
* [Typo] fix some typo in docs and dynarec/rv64

* [Typo] fix some typo in docs and dynarec/rv64

* [Typo] fix some typo in dynarec/rv64

* [Typo] fix some typo in dynarec/rv64

* [Typo] fix some typo in docs
2024-08-26 08:19:06 +02:00
KreitinnSoftware 0b1dd757be [EMU] [ARM64_DYNAREC] Fix Some Warnings on Clang Compilers (#1757) 2024-08-26 08:15:55 +02:00
KreitinnSoftware a7c61d8e20 [ANDROID] Not use 'libbsd.so' as needed lib and don't define NEEDED_LIBS_234 for Android Too, Use BOX64_LD_LIBRARY_PATH instead of LD_LIBRARY_PATH on CTEST (#1754)
* [ANDROID] Not use 'libbsd.so', 'libpthread.so' as needed libs and don't define NEEDED_LIBS_234 for Android Too

* [ANDROID] Use 'libpthread.so' again

* [CTEST] Try to use BOX64_LD_LIBRARY_PATH instead of LD_LIBRARY_PATH
2024-08-25 19:53:09 +02:00
Yang Liu 4988fb27dc [RV64_DYNAREC] Fixed more issues in the vector infrastructure (#1755)
* [RV64_DYNAREC] Fixed SEW transformation for vector

* more tweaks

* more fixes

* More fixes

* more fixes

* re-enable vector extension by default
2024-08-25 19:52:50 +02:00
ptitSeb db1f0825ce Merge pull request #1750 from ksco/fix
[RV64_DYNAREC] Fixed various issues in vector infra
2024-08-24 21:03:55 +02:00
Yang Liu c7b2a5f2df More fixes 2024-08-25 02:24:57 +08:00
Yang Liu b9cbd29bc4 Try to fix SSE type transformation 2024-08-24 19:27:57 +08:00
Yang Liu 84b53ecb42 [RV64,LA64_DYNAREC] Remove useless #if directives 2024-08-20 13:49:01 +08:00
ptitSeb 66da28a02f Merge pull request #1746 from ksco/disable_vector
[RV64_DYNAREC] Disable vector extension by default until it's ready
2024-08-19 14:36:26 +02:00
Yang Liu 15f6bbebe1 [RV64_DYNAREC] Disable vector extension by default until it's ready. 2024-08-19 20:10:02 +08:00
ptitSeb 2daef545dd Forgot to expose adx extension in cpuinfo virtual file 2024-08-19 10:57:03 +02:00
ptitSeb aac6b3d02d Forgot to expose f16c, xsave and randr extensions in cpuinfo virtual file 2024-08-19 10:46:13 +02:00
ptitSeb fda0e9a4cb Merge branch 'box32' into main 2024-08-18 16:02:27 +02:00
ptitSeb f1da5d433a [RV64_DYNAREC] Set the log level to Info for the LOCK CMPXCHG16B warning, to avoid breaking winetricks 2024-08-18 15:57:14 +02:00
ptitSeb dead2003fa [HACK] Patch Heroic 2.15.1 to avoid some internal memory manager test, until a better solution is found (heroic is still a bit unstable) 2024-08-18 10:46:15 +02:00
Yang Liu 44dfa53d45 warn only once 2024-08-18 10:46:15 +02:00
Yang Liu 769a9f65a9 Slightly improved LOCK CMPXCHG16B opcode 2024-08-18 10:46:15 +02:00
Yang Liu 5b78159cb5 [RV64_DYNAREC] Added a warning on LOCK CMPXCHG16B opcode 2024-08-18 10:46:15 +02:00
ptitSeb c384d53d75 [HACK] Patch Heroic 2.15.1 to avoid some internal memory manager test, until a better solution is found (heroic is still a bit unstable) 2024-08-18 10:16:38 +02:00
ptitSeb 683e44baf9 [BOX32] Added 32bits elf reloc type rel handling 2024-08-17 16:59:55 +02:00
ptitSeb c845d0cf81 [BOX32] Added 32bits elf alloc and load 2024-08-17 15:59:09 +02:00
Yang Liu 243a4deae7 warn only once 2024-08-17 15:57:48 +02:00
Yang Liu fe80d6305c Slightly improved LOCK CMPXCHG16B opcode 2024-08-17 15:57:48 +02:00
Yang Liu a0e7113397 [RV64_DYNAREC] Added a warning on LOCK CMPXCHG16B opcode 2024-08-17 15:57:48 +02:00
ptitSeb d47b1b0e56 [BOX32] Added 32bits elf header parser and dumper 2024-08-17 14:25:04 +02:00
ptitSeb fa87b0fcef [BOX32] prepare elfheader_t structure for 32bits elfs 2024-08-17 12:24:26 +02:00
Yang Liu 0f1bce0f32 [RV64_DYNAREC] Added more opcodes (#1740)
* [RV64_DYNAREC] Added more opcodes

* more opcodes

* more
2024-08-16 18:47:21 +02:00
Yang Liu bc0b5b1181 [LA64_DYNAREC] Port recent RV64 fixes (#1739) 2024-08-16 18:47:21 +02:00
Yang Liu 38833b9cf4 Added more curl function wrapper (#1738) 2024-08-16 18:47:21 +02:00
Yang Liu dda4f48397 [RV64_DYNAREC] Added 66 0F 3A 63 PCMPISTRI opcode (#1735) 2024-08-16 18:47:21 +02:00
Yang Liu bb712b1ad5 Added 1 more gtk3 function wrapper (#1737) 2024-08-16 18:47:21 +02:00
Yang Liu 6ddb5b3477 [RV64,LA64_DYNAREC] Small change when handling long CC INT 3 opcode (#1736) 2024-08-16 18:47:21 +02:00
Yang Liu c4253b73fa [RV64_DYNAREC] Added more opcodes (#1740)
* [RV64_DYNAREC] Added more opcodes

* more opcodes

* more
2024-08-16 18:16:20 +02:00
Yang Liu 3c1f6c2436 [LA64_DYNAREC] Port recent RV64 fixes (#1739) 2024-08-16 12:10:17 +02:00
Yang Liu 83484cfb60 Added more curl function wrapper (#1738) 2024-08-16 12:09:26 +02:00
Yang Liu a106082397 [RV64_DYNAREC] Added 66 0F 3A 63 PCMPISTRI opcode (#1735) 2024-08-16 12:09:00 +02:00
Yang Liu 6498248cef Added 1 more gtk3 function wrapper (#1737) 2024-08-16 12:08:53 +02:00
ptitSeb b2f94b274c [BOX32] Start differentiate 64bits from 32bits in elf parser 2024-08-16 10:56:47 +02:00
ptitSeb 34b85b3560 Detect 32bits elf before loading 2024-08-16 10:52:36 +02:00
Yang Liu 7bb30efb50 [RV64,LA64_DYNAREC] Small change when handling long CC INT 3 opcode (#1736) 2024-08-15 20:14:33 +02:00
ptitSeb 7df2b6b252 Added BOX32 option to CMakeList.txt 2024-08-15 15:50:16 +02:00
ptitSeb 017d13a7b0 [ARM64_DYNAREC] Small change when handling lone CC INT 3 opcode 2024-08-15 15:46:19 +02:00
ptitSeb 513647b272 Added syscalls 444-446 2024-08-15 15:45:50 +02:00
ptitSeb 280b1576c3 [ARM64_DYNAREC] Added AVX.66.0F38 A6 opcode 2024-08-15 14:07:51 +02:00
ptitSeb 2dfd449561 [ARM64_DYNAREC] Added 67 90..97 opcodes 2024-08-15 14:00:34 +02:00
ptitSeb 65b1b9256a Fixed falsly detection of needed memory hack 2024-08-15 14:00:02 +02:00
ptitSeb 7866f116df [TRACE] Better trace for libc syscall 2024-08-15 13:59:18 +02:00
ptitSeb 4544e1556a Added syscalls 122-124 2024-08-15 13:58:46 +02:00
Yang Liu 8c7d96ad63 [RV64_DYNAREC] Fixed extcacheUnwind regression (#1734) 2024-08-15 10:17:27 +02:00
ptitSeb bd23e1f7fc [RCFILE] Fine tuned profile for on of the EALauncher process 2024-08-12 21:23:30 +02:00
ptitSeb 99187a2d22 Added (fake) syscall 175 to libs syscall 2024-08-12 21:22:23 +02:00
Yang Liu 8974caf162 [RV64_DYNAREC] Fixed 0F BA /5 BTS opcode (#1733) 2024-08-12 21:09:19 +02:00
xctan f364c03964 [RV64_DYNAREC] More fixes (#1732)
* [RV64_DYNAREC] Fixed pending flag type in emit_sar16

* [RV64_DYNAREC] Fixed imm12 overflow in geted

* [SYSCALL] Added fake sys_init_module
2024-08-12 20:11:19 +02:00
ptitSeb 730eb1f472 [ARM64_DYNAREC] Some small improvments to ROR/ROL/RCR/RCL opcodes 2024-08-11 14:56:13 +02:00
ptitSeb 3760be946f [WRAPPER] Wrapped libdrm_amdgpu.so.1 2024-08-10 20:04:56 +02:00
Yang Liu 7db74b84cf [RV64_DYNAREC] Fixed flags for shrd/shld with constant 0 shift (#1730) 2024-08-10 10:51:56 +02:00
xctan 4c0a25db2a [RV64_DYNAREC] Fixed ROL/ROR RCX, CL (#1729) 2024-08-10 10:51:44 +02:00
ptitSeb 67af8c2bad Added 67.AVX.0F.66 D6 opcode ([ARM64_DYNAREC] too) 2024-08-10 09:58:42 +02:00
ptitSeb 92531929f3 Added 64bits 67 F3 0F 7F opcode ([ARM64_DYNAREC] too) 2024-08-10 09:50:11 +02:00
ptitSeb 0256a6332c [ARM64_DYNAREC] Fixed flags for surd/shld with constant 0 shift 2024-08-10 09:40:05 +02:00
ptitSeb bd4454d8ad [ARM64_DYNAREC] Fixed pending flags for large 8 & 16 bit const shifts 2024-08-10 09:34:09 +02:00
xctan 4187581be5 [RV64_DYNAREC] Fixed pending flags for large 8 & 16 bit const shifts (#1728) 2024-08-10 09:17:02 +02:00
Yang Liu 2a07636623 [RV64_DYNAREC] Fixed more register conflicts (#1726) 2024-08-09 20:16:52 +02:00
ptitSeb 8893344b76 Fix non-Dynarec build 2024-08-09 18:17:16 +02:00
ptitSeb f0ea65dc36 [DOCS] Added entry in USAGE.md for newly introduced BOX64_ARGS 2024-08-09 17:44:05 +02:00
ptitSeb 53756ee966 Improved Steam wine compatibility, not perfect, but better (thanks Hugo for the args) 2024-08-09 17:41:01 +02:00
xctan 8a2ee1ed59 [RV64_DYNAREC] Fixed OF generation in emit_sar16c (#1724) 2024-08-09 17:31:13 +02:00
ptitSeb 9bc9c10fb3 [ARM64_DYNAREC] Added AVX.66.0F38 9A opcode 2024-08-09 14:30:32 +02:00
Yang Liu 4407a17551 [RV64_DYNAREC] Fixed fpu_flags handling and enabled cosim in CI (#1722)
* [RV64_DYNAREC] Fixed fpu_flags handling

* repeat until-pass
2024-08-09 13:31:58 +02:00
xctan c7d6395aa6 [RV64_DYNAREC] Fixed misused BNE_NEXT in emit_ro{l,r}32 (#1723) 2024-08-09 13:29:37 +02:00
Yang Liu 649a65b8ee [RV64_DYNAREC] Fixed FNSTSW opcode (#1721) 2024-08-09 12:03:20 +02:00
Yang Liu 949b64ca53 [DYNAREC_RV64] Removed TODOs on GETEX and GETEM macros (#1720) 2024-08-09 12:02:14 +02:00
xctan cef906b24d [RV64_DYNAREC] Fixed register conflict in the GETSEB marco (#1719) 2024-08-09 09:25:27 +02:00
xctan 040c2c3d1b [RV64_DYNAREC] Fixed register conflict with GETEB macro (#1718) 2024-08-08 17:29:56 +02:00
Yang Liu 91ed6a83c1 [INTERP] Fixed some undefined behaviour (#1717) 2024-08-08 17:05:00 +02:00
Yang Liu d8ac8a5f1c [LA64_DYNAREC] Fixed flag generation in IMUL/MUL opcode (#1716) 2024-08-08 08:27:35 +02:00
xctan 18954abf54 [RV64_DYNAREC] Fixed flag generation in IMUL/MUL opcode (#1715) 2024-08-08 08:25:05 +02:00
ptitSeb ed7ee12e7e [GTK] Added wrapped GstVideoBufferPool 2024-08-07 15:11:31 +02:00
ptitSeb 42d99d2b2a [ARM64_DYNAREC] Added AVX.F3.0F38 F7 opcode 2024-08-07 10:26:17 +02:00
ptitSeb d24f13cd73 Small optimisation on xsave / xrstor helper 2024-08-07 10:13:43 +02:00
ptitSeb e8fad11128 [ARM64_DYNAREC] Added F0 20 opcode 2024-08-04 09:48:18 +02:00
ptitSeb 27a8d19f31 Added 3 syscalls 2024-07-30 16:00:32 +02:00
ptitSeb 387a3eeba3 [DYNAREC] Remove BARRIER_NEXT macro 2024-07-29 22:47:43 +02:00
Ilya114 3a3578aecc Update README_UK.md (#1709) 2024-07-28 09:21:46 +02:00
ptitSeb a8784eff9f [RCFILE] Added support for generic names in RCFiles 2024-07-25 15:10:40 +02:00
ptitSeb b26ae5886d Added 67 66 0F EF opcode ([ARM64_DYNAREC] too) 2024-07-23 17:40:56 +02:00
ptitSeb e6696f8d23 Added 67 66 0F FE opcode ([ARM64_DYNAREC] too) 2024-07-23 17:13:24 +02:00
Yang Liu 2989afdf84 [RV64_DYNAREC] Fixed more issues in the vector infrastructure (#1706) 2024-07-23 13:30:06 +02:00
Yang Liu 9c1b015689 [RV64_DYNAREC] Fixed vector infra (#1705) 2024-07-22 21:45:54 +02:00
Yang Liu 3b1fbef95c [DYNAREC] Fixed CI failures for RV64 and LA64 (#1702)
* [DYNAREC] Fixed CI failures for RV64 and LA64

* comment out android tests for now
2024-07-22 09:19:27 +02:00
ptitSeb 2e6acc86e1 Improved exception/int 3 handling 2024-07-21 20:32:17 +02:00
ptitSeb c6e981a363 Better X11 callback in list handling 2024-07-21 18:49:02 +02:00
ptitSeb 43de5afcf6 Improved TF handling 2024-07-21 10:52:58 +02:00
ptitSeb fb40035957 [ARM64_DYNAREC] Add a test about arm64 addresses in pass3, and abort if wrong 2024-07-21 09:39:07 +02:00
ptitSeb 93549259a0 [DYNAREC] Fixed a typo in an error message 2024-07-21 09:38:31 +02:00
ptitSeb f39d3ea43e Leave low memory for wine if it's loaded 2024-07-21 09:38:00 +02:00
Yang Liu 7ad169c7a8 [LA64_DYNAREC] Added more opcodes (#1701) 2024-07-20 14:19:24 +02:00
Yang Liu 052bba4578 [LA64_DYNAREC] Added more opcodes (#1700) 2024-07-20 10:04:07 +02:00
Yang Liu d1eb01e535 [RV64_DYNAREC] Added more 66 0F 38 opcodes for vector (#1699) 2024-07-19 16:05:52 +02:00
Yang Liu 3e20a60c37 [RV64_DYNAREC] Added vector SEW cache (#1698)
* [RV64_DYNAREC] Added vector SEW cache

* handling reset_n
2024-07-19 11:34:45 +02:00
ptitSeb 984c136349 [RCFILE] Re-organized box64.box64rc and add EA/Origin launcher progress profiles 2024-07-18 17:53:59 +02:00
Yang Liu 81f92d8f62 [RV64_DYNAREC] Added 66 0F 38 00 PSHUFB for vector (#1697) 2024-07-18 11:39:48 +02:00
Yang Liu 427051d04c [RV64_DYNAREC] Added more 66 0F opcodes for vector (#1696) 2024-07-18 08:58:05 +02:00
Yang Liu c1a14f93d8 [RV64_DYNAREC] Show missing opcodes in vector implementation (#1695) 2024-07-18 08:13:44 +02:00
Yang Liu f07ee85078 [RV64_DYNAREC] Added vlen detection (#1694) 2024-07-18 08:12:40 +02:00
Yang Liu 51b118d516 [LA64_DYNAREC] Added more opcodes and fixed more issues (#1692) 2024-07-17 19:50:13 +02:00
ptitSeb d5ec4692d3 [INTERPRETER] Fixed some issue with INT opcodes and STEP logic 2024-07-17 12:05:04 +02:00
ptitSeb a62336d433 Added 1 more wrapped function to gstaudio 2024-07-17 10:09:34 +02:00
Yang Liu abb2cbeeaa [LA64_DYNAREC] Added more opcodes (#1690) 2024-07-17 08:15:41 +02:00
ptitSeb 33381857ff Change (again) how Wine prereserved memory is allocated and freed 2024-07-16 22:53:47 +02:00
Yang Liu f1abd95ed0 [LA64_DYNAREC] Added more opcodes (#1688) 2024-07-16 22:50:02 +02:00
Yang Liu 43b155e8b4 [LA64_DYNAREC] Fixed CMPSD (#1687) 2024-07-16 22:49:14 +02:00
Yang Liu 6ee5415ea4 [LA64_DYNAREC] Fixed some opcodes (#1686) 2024-07-16 21:38:19 +02:00
ptitSeb 886ae378c5 Changed how TRAPNO 12 is triggered 2024-07-16 17:24:49 +02:00
Yang Liu 60d886c052 [RV64_DYNAREC] Fixed GETGXSS_empty on upper bits handling (#1685) 2024-07-16 12:57:14 +02:00
Yang Liu d700cc1f55 [RV64_DYNAREC] Clear high 32bits when write back as single (#1684) 2024-07-16 08:57:53 +02:00
Yang Liu 5c212e92c3 [LA64_DYNAREC] Remove xMASK and fixed 86 XCHG opcode (#1683) 2024-07-16 08:18:14 +02:00
Yang Liu 1dde4ee959 [ARM64_DYNAREC] Fixed OR Ew, Gw (#1682) 2024-07-16 08:16:01 +02:00
xctan 9fe450f2dc [RV64_DYNAREC] Fixed some bugs for VMP (#1679)
* [RV64_DYNAREC] Fixed reg x3 conflict with the GETEW macro

* [RV64_DYNAREC] Fixed (LOCK) XCHG Eb, Gb again

* [RV64_DYNAREC] Fixed register conflict in (LOCK) XCHG Eb, Gb
2024-07-16 08:15:33 +02:00
Panda b84e5f25f2 build: fix PKGBUILD-rk3xxx pkgname was set to box86 (#1681) 2024-07-16 08:10:35 +02:00
Yang Liu b52ff061b4 [LA64_DYNAREC] Added 2 more opcodes (#1680) 2024-07-15 23:44:56 +02:00
kaixindeken b7ae79514f Fix hidden error in PR 1677 (#1678)
* Fix most of tiff5 and ltdl7 functions

* Adding missing file

* delete libltdl7 wrapped

* re-wrapped libtiff5 and list all symbols
2024-07-15 18:32:27 +02:00
ptitSeb a90c7af708 Added BOX64_SHAEXT to hide sha cpu extension ([RCFILE] And added a profile using it) 2024-07-15 13:43:53 +02:00
ptitSeb 176e092a6c Added missing generated files 2024-07-15 10:42:04 +02:00
kaixindeken 94ccde160a Wrapped libtiff5 and libltdl7 (#1677)
* Wrapped libtiff5

* no types generated

* libtiff5 added missing defs types undefs files

* wrapped libltdl7

* rerun actions

* add more wrapped function for tiff5 and ltdl7

* remove unused functions
2024-07-15 08:23:14 +02:00
ptitSeb d8746c6c70 Something is wrong, emulated gnutls.so.30 doesn't seems to work fine for now 2024-07-14 15:35:02 +02:00
ptitSeb 4ff4ca72d3 Wrapped lots of new function t be abble to run emulated libgnutls.so.30 2024-07-14 11:18:08 +02:00
ptitSeb 47055f92df [RCFILE] Update a profile, with a workaround, until fixed 2024-07-14 11:17:20 +02:00
Yip Coekjan 7a4a44292c Wrap sqlite3_exec for libsqlite3 (#1674) 2024-07-13 12:52:24 +02:00
ptitSeb 98270a8601 Fix signal stack handling on reentrant signal when using SigAltStack 2024-07-13 11:35:42 +02:00
ptitSeb 182ca255f7 [TRACE] Fixed some issue with function name printing 2024-07-13 10:10:45 +02:00
ptitSeb 3d33713c2b Fixed some issue on tracking when protecting memory with PROT=0 2024-07-13 10:07:39 +02:00
ptitSeb ebf698fdb6 Removed debug leftover 2024-07-12 17:35:47 +02:00
ptitSeb 9d089f9b18 Fixed flaky signal handler on 32bits code (mainly for Wine with new Wow64) 2024-07-12 17:29:15 +02:00
ptitSeb c976833f46 Added 1 syscall (for #1672) 2024-07-12 09:58:34 +02:00
ptitSeb 1819b7563a Revert "[Wrapped] Added sqlite3_exec (#1671)" (#1673)
This reverts commit 548a21a5ec.
2024-07-12 08:52:07 +02:00
kaixindeken 548a21a5ec [Wrapped] Added sqlite3_exec (#1671) 2024-07-12 07:24:49 +02:00
Ivan Melnikov ad1dce7fb1 [RV64_DYNAREC] Cleanup for removed rv64_lock_cas_dq (#1670)
Since rv64_lock_cas_dq is removed, we should also remove its
global symbol declaration and its prototype. Otherwise, we
get and undefined symbol reference, which breaks ELF checks
that some distros employ.

Fixes: 9dbd7fc7e0
2024-07-11 16:57:56 +02:00
ptitSeb 302a358476 [ARM64_DYNAREC] Added handling of FASTNAN=0 to MULSS opcode 2024-07-11 16:47:24 +02:00
ptitSeb 74dd9f2778 Boosted number of X11 callback to 100 2024-07-11 16:18:26 +02:00
ptitSeb 495262f902 Fixed a nasty bug on memory permission tracking 2024-07-11 12:16:31 +02:00
ptitSeb d10a078473 [STATICBUILD] removed Android staticbuild 2024-07-10 16:37:46 +02:00
ptitSeb 8d9fd7cb0e [STATICBUILD] build 2024-07-10 16:09:21 +02:00
ptitSeb 8bd8a923ba [STATICBUILD] Go green now 2024-07-10 16:00:31 +02:00
ptitSeb 764a0c31e5 [STATICBUILD] This is getting old already, turn to green now! 2024-07-10 15:25:49 +02:00
ptitSeb 1ea0382055 [STATICBUILD] Removed libbsd build dependancy 2024-07-10 15:20:27 +02:00
ptitSeb bd673dc791 [STATICBUILD] Yet another attempt to fix CI build 2024-07-10 14:58:37 +02:00
ptitSeb 4fa00ba283 [STATICBUILD] Another attempt to fix CI build 2024-07-10 14:39:06 +02:00
ptitSeb deef011dbf [STATICBUILD] Attempt to fix CI build 2024-07-10 14:31:47 +02:00
ptitSeb afeecf9d9f [STATICBUILD] Fixed some more errors 2024-07-10 12:49:55 +02:00
ptitSeb e792f00363 This should fix regular build 2024-07-10 12:22:54 +02:00
ptitSeb f7d9dd4824 [STATICBUILD] Try to fix staticbuild and add it to the CI (for #1377) 2024-07-10 12:15:27 +02:00
josch dfc60e8bf1 fix some spelling (#1668) 2024-07-10 11:06:02 +02:00
ptitSeb 655e752c07 [STATICBUILD] Fixed a warning (for #1377) 2024-07-10 10:40:11 +02:00
rajdakin ebdbd1767a [DYNAREC] Fixed ymm0_purge for some instructions (#1664)
* [DYNAREC] Fixed `ymm0_purge` for the first instruction of a block

* [DYNAREC] Also consider barriers as having a pred with `ymm0_out = 0`
2024-07-10 09:45:57 +02:00
Yip Coekjan 4eca49697a Remove the flags adjustment in GO_TRACE for RISC-V 64 (#1663) 2024-07-10 09:45:40 +02:00
Yang Liu 7fa2371bbd [LA64_DYNAREC] Added more opcodes and a minor fix too (#1662)
* [LA64_DYNAREC] Added more opcodes and a minor fix too

* saturation is considered necessary
2024-07-10 09:45:27 +02:00
ptitSeb 60c41cadba Fixed some X11 wrapping (for Interrogation: You will be deceived linux version #1414) 2024-07-10 09:44:12 +02:00
ptitSeb 97769b63ad [RCFILE] Added profile for Death Stranding 2024-07-10 09:43:01 +02:00
ptitSeb bc482e29b0 Started a new dev. cycle 2024-07-10 09:42:00 +02:00
ptitSeb 62695ceed4 Bumped version to v0.3.0 2024-07-09 11:02:43 +02:00
rajdakin 605d5a29c0 Fixes (#1659)
* Replaced some tabs with spaces

* Fixed some signedness warnings

* Added more debug info

* Fixed an improper alignment

* [WRAPPEDWAYLAND] Added return statements to wrappers

* [EMU] [AVX] Fixed some issues

* [ARM DYNAREC] Fixed some minor warnings

* [ARM DYNAREC] Removed unused macro arguments

* [EMU] Fixed a noisy warning

* [ARM DYNAREC] Removed "empty body" warnings

* [EMU] Fixed an opcode in dynarec, non-cosim builds

* [LA64 DYNAREC] Minor warning fixes

* [LA64 DYNAREC] Fixed empty body warnings

* [LA64 DYNAREC] Added parenthesis around assignments in if statements

* [LA64 DYNAREC] Fixed missing parenthesis in macro definitions

* [RV64 DYNAREC] Fixed minor warnings

* [RV64 DYNAREC] Fixed wrong/missing parentheses

* [WRAPPER] Fixed the WaylandClient callback signatures
2024-07-09 08:21:21 +02:00
Yang Liu fdc7e9d1e4 [LA64_DYNAREC] Fixed ADC/SBC usage (#1658) 2024-07-08 21:46:46 +02:00
ptitSeb dcc7ad45bc Added x64 version of libcrypto.so.1.0.0 and libssl.1.0.0 2024-07-08 18:18:04 +02:00
rajdakin 265f153449 [WRAPPED] Added NSS_Init (#1657) 2024-07-08 17:48:23 +02:00
ptitSeb ba9aa3657c Fixed wrapping of some rare opengl functions 2024-07-08 17:45:28 +02:00
ptitSeb 115d666fff [ARM64_DYNAREC] Small optim on some ROL/ROR opcodes 2024-07-08 17:45:27 +02:00
Yang Liu 42ce1a3b61 [LA64_DYNAREC] Added more opcodes (#1656) 2024-07-08 15:17:16 +02:00
Yang Liu a7b912393c [LA64_DYNAREC] Added more opcodes (#1654) 2024-07-08 14:26:28 +02:00
Yip Coekjan e82f17842e Mask rs2 when using bext instruction if rex.w is not set (#1653) 2024-07-08 13:55:32 +02:00
ptitSeb 4838c86ca9 Fixed deb packaging 2024-07-08 10:33:15 +02:00
ptitSeb d6b9fd2860 [VULKAN] Added 1 more extension 2024-07-07 20:17:19 +02:00
Yang Liu 60dac1aa29 Set last_ip to an unclean state at the end of CALL (#1650) 2024-07-07 17:39:54 +02:00
ptitSeb 8dd071bcfa [ARM64_DYNAREC] Fixed a warning 2024-07-07 17:30:35 +02:00
ptitSeb d92d693df3 [ARM64_DYNAREC] Added AVX.66.0F38 B6 opcode 2024-07-07 11:45:02 +02:00
ptitSeb d16bd5104e [ARM64_DYNAREC] Added AVX.F2.0F D0 opcode 2024-07-07 11:29:17 +02:00
ptitSeb d7e8da6321 [ARM64_DYNAREC] Fixed reflect cache for ymm0 2024-07-07 11:28:54 +02:00
ptitSeb aec3fd524a [VULKAN] Added 1 more extension 2024-07-07 10:39:35 +02:00
ptitSeb 14b0323bf6 [ARM64_DYNAREC] Reworked ymm0 propagation 2024-07-07 10:37:51 +02:00
Haichen Wu b482847779 [INTERPRETER] Added 64 66 8D opcode (#1648) 2024-07-06 08:12:16 +02:00
ptitSeb 8c5752de23 [ARM64_DYNAREC] Made AVX/AVX2 enabled by default, but only for ARM64 Dynarec configs 2024-07-05 21:57:20 +02:00
ptitSeb 267bffb0ec [ARM64_DYNAREC] More improvment on YMM handling 2024-07-05 18:53:32 +02:00
ptitSeb 0546216228 [ARM64_DYNAREC] Added Calling Convention as comment in emitter, for reference 2024-07-05 17:21:20 +02:00
ptitSeb a46ea2c07f Cosmetic change 2024-07-05 17:20:48 +02:00
ptitSeb ed4e1ee0ba Put a limit on how much the hardware counter can be shifted 2024-07-05 17:19:11 +02:00
Yip Coekjan 6ac3716594 Should not follow symlinks on file path resolution (#1644) 2024-07-05 11:02:09 +02:00
ptitSeb 42bad3ea6b Added 1 more wrapped funciton to libcups (for #1629) 2024-07-05 09:53:39 +02:00
ptitSeb f9c4eda1fc [VULKAN] Fixed a typo 2024-07-05 09:08:07 +02:00
KreitinnSoftware 688665e730 [VULKAN] Add Wrapped VK_KHR_android_surface (#1643) 2024-07-05 00:23:45 +02:00
ptitSeb a676255231 [VULKAN] Added 1 more extension 2024-07-04 22:48:04 +02:00
ptitSeb d227edeefd Cosmetic change 2024-07-04 20:09:02 +02:00
ptitSeb 34c3e2dab3 [ARM64_DYNAREC] Improved 0F C7 /6 opcode 2024-07-04 20:08:11 +02:00
Yang Liu 2c0bbc06b7 [DYNAREC] Fixed IMUL sign extension issue (#1639) 2024-07-04 18:47:45 +02:00
Yip Coekjan 299551428f Impl sys_getpgrp & sys_getpgid (#1637) 2024-07-04 18:42:22 +02:00
ptitSeb d0ac9c2a5a Fixed 2 warning 2024-07-04 16:36:16 +02:00
Yip Coekjan a69368e855 Wrap some functions for libc (#1635) 2024-07-04 16:31:26 +02:00
Yang Liu 84b0e2f113 [LA64_DYNAREC] Fixed F2 0F 70 PSHUFLW opcode (#1634) 2024-07-04 12:39:57 +02:00
Yang Liu eb695d5553 [RV64_DYNAREC] Added preliminary RVV infra and PXOR opcode for demonstration (#1632)
* [RV64_DYNAREC] Added preliminary RVV infra and PXOR opcode for demonstration

* keep sse_cache_s uint8_t as suggested

* use xor to do the wrap

* revert

* better fallback
2024-07-04 12:39:05 +02:00
LiZhuoheng b5946f3752 [RV64_DYNAREC] modify DF default /4 opcode (#1633)
* [RV64_DYNAREC] modify DF default /4 opcode

* [RV64_DYNAREC] added DF default /4 opcode
2024-07-04 07:59:54 +02:00
LiZhuoheng 371435afd0 [RV64_DYNAREC] Added DF default /4 opcode (#1631)
* [RV64_DYNAREC] Added DF default /4 opcode

* replace tabs to spaces
2024-07-03 14:44:47 +02:00
ptitSeb 0ba46403c6 Detect UnityPlayer.dll to apply strongmem=1 automatically (can be disabled with BOX64_UNITYPLAYER=0) 2024-07-03 11:19:55 +02:00
Diego q cac43a1f5f Updated box64.box64rc (#1630)
added two baldi games, one horror game, 2d superhot, and one game i had to fix for a friend
2024-07-03 08:18:27 +02:00
Yip Coekjan 7771a67abe Add missing func declarations: get_first_jump_addr (#1627) 2024-07-02 15:59:45 +02:00
Yip Coekjan 9cd8812d8b Handle .relr.dyn section (#1626) 2024-07-02 13:47:48 +02:00
ptitSeb 4b0b3fc98a [DYNAREC] Improved cache coherency and internal jump handling, [ARM64_DYNAREC] Improved YMM register tracking 2024-07-02 10:34:37 +02:00
ptitSeb c6afd44c1c Added one more wrapped function to gnutls 2024-07-02 09:29:14 +02:00
Yang Liu dbb84245a0 Wrapped libsqlite3 (#1625)
* Wrapped libsqlite3

* More functions
2024-07-01 18:58:17 +02:00
ptitSeb 15a7c4d8dd [DYNAREC] Reset fpu scratch after Instruction epilog 2024-07-01 15:21:51 +02:00
Yang Liu a842938cfe Wrapped more functions (#1624)
* Wrapped more gtk functions

* Wrapped 1 more gdk3 function

* Wrapped more gnutls functions

* Added generated files
2024-07-01 14:39:54 +02:00
ptitSeb 3f83038061 [DYNAREC] Keep internal jmp table to the end 2024-07-01 10:39:30 +02:00
ptitSeb 01568f8fd3 [ARM64_DYNAREC] Fixed some regression on internal jumps 2024-07-01 10:33:41 +02:00
ptitSeb 1ee4d5aaf4 [ARM64_DYNAREC] Added 64/65 70-7F/EB opcodes 2024-06-30 15:50:16 +02:00
ptitSeb f9b74642a2 {ARM64_DYNAREC] Small optimisation on F3 0F BC/BD opcodes 2024-06-28 18:51:16 +02:00
ptitSeb 401e3a7282 [ARM64_DYNAREC] Fixed printer for DUP opcode 2024-06-28 18:49:32 +02:00
ptitSeb 32b2b388c8 [ARM64_DYNAREC] Added AVX.66.0F38 91/93 opcodes 2024-06-28 10:35:59 +02:00
ptitSeb 013643782f [ARM64_DYNAREC] Fixed AVX.66.0F3A 06/46/21 opcodes 2024-06-28 10:35:11 +02:00
Yang Liu cb064f9e5a [RV64_DYNAREC] Added vector instructions emitter (#1621) 2024-06-27 08:44:11 +02:00
Yang Liu 52c97c47ab [RV64_DYNAREC] Detect vector extension (#1619) 2024-06-27 08:43:49 +02:00
ptitSeb 5f06d066e7 [ARM64_DYNAREC] Improved comment 2024-06-26 11:10:44 +02:00
liuli a7a211fc85 small fix for ROR and ROL (#1618) 2024-06-26 07:23:13 +02:00
KreitinnSoftware 5540601918 Compile Dynarec With ARMv8-A ASM Flags without Hardware Profile on Android Builds Too (#1617) 2024-06-26 07:22:11 +02:00
ptitSeb 22f99601d9 [INTERPRETER] Added 64/65 F3 0F 58 opcode 2024-06-25 18:12:32 +02:00
ptitSeb 2fe2e52249 [ARM64_DYNAREC] Small fixes to 0F C7 /6 opcode 2024-06-25 14:48:03 +02:00
Yang Liu 6caa598dd7 [RV64_DYNAREC] Fixed regression on D9 E5 FXAM opcode (#1616) 2024-06-25 14:19:17 +02:00
ptitSeb aeeb9b719a [COSIM] Added range handling in BOX64_DYNAREC_TEST ([RCFILE] too) 2024-06-24 20:32:16 +02:00
ptitSeb 36f1808615 [INTERPRETER] opcode F1 is valid alson in 64bits 2024-06-24 18:41:10 +02:00
ptitSeb 0ce5f34f8c [INTERPRETER] Added 32bits F1 opcode 2024-06-24 17:58:40 +02:00
ptitSeb 579ae99d1b [ARM64_DYNAREC] Added 0F C7 /6 opcode, with hardware support if present 2024-06-24 17:34:02 +02:00
ptitSeb fa702c0240 Improved CPUID a bit more, adding RDRAND (helps geekbench6 avx2 version) 2024-06-24 16:07:10 +02:00
ptitSeb 34bc807bd5 [ARM64_DYNAREC] Fixed AVX.66.0F38 90/92 opcodes 2024-06-24 16:05:57 +02:00
ptitSeb 71d49badcc Fixed AVX.66.0F38 90-93 opcodes (certain special cases) 2024-06-24 16:05:26 +02:00
ptitSeb 3dfcc278e0 [ARM64_DYNAREC] Minor fix on printer for SMOV/UMOV 2024-06-24 16:04:29 +02:00
ptitSeb e312fa392d [ARM64_DYNAREC] Reworked ymm_zero handling on internal jump 2024-06-23 20:38:54 +02:00
ptitSeb bda28e5882 [TRACE] Print offset in function in hex 2024-06-23 20:38:11 +02:00
ptitSeb 68c2abc429 [DYNAREC] Try to limit UpdateFlags on internal jumps 2024-06-23 20:26:43 +02:00
ptitSeb b0727d6f2b [ARM64_DYNAREC] Some small optims to a few AVX opcodes 2024-06-23 20:23:04 +02:00
ptitSeb c66be063aa Small improvment to 0F BC/BD opcodes ([ARM64_DYNAREC] too) 2024-06-23 20:22:02 +02:00
ptitSeb 1f0165f895 [ARM64_DYNAREC] Fixed printer for MOVI_64 2024-06-23 20:20:58 +02:00
ptitSeb b1ae5dc2b6 [ARM64_DYNAREC] Small optim on 0F BC/BD opcodes 2024-06-23 12:04:42 +02:00
ptitSeb df228f8829 [ARM64_DYNAREC] Fixed an issue with fpuCacheTransform (possible regression) 2024-06-22 20:33:06 +02:00
ptitSeb dc2d54edf2 Added 66 F2/F3 A4 opcode ({DYNAREC] too) 2024-06-22 18:05:03 +02:00
ptitSeb d39c554541 [ARM64_DYNAREC] Small improvement to 0F 5D/5F opcodes 2024-06-22 13:26:58 +02:00
ptitSeb 314b2a5583 [COSIM] Imprroved F2 0F prefixed opcodes 2024-06-22 13:26:14 +02:00
ptitSeb ce30c1179e Improved handling of cpuid leaf 0x80000006 2024-06-22 11:40:35 +02:00
ptitSeb cbb3126b28 [COSIM] Improved handling of AVX.66.0F38 3E/2F opcodes 2024-06-22 11:40:11 +02:00
ptitSeb a3413ba96d [ARM64_DYNAREC] Improved AVX.66.0F38 2E/2F to avoid segfault when mask is null 2024-06-21 21:22:43 +02:00
ptitSeb 2b625e4aa5 Small fix for a signature of a gnutls function 2024-06-21 21:18:49 +02:00
ptitSeb df74626ca2 [RCFILE] Improved hendling of BOX64_NODYNAREC 2024-06-21 21:17:49 +02:00
Yang Liu 10373ca6fc [RCFILE] Added Goat Simulator profile (#1609) 2024-06-21 14:03:25 +02:00
Yang Liu 3dcd08bd4a Wrapped pthread_cond_signal with aligned cond like others (#1608) 2024-06-21 13:08:53 +02:00
Yang Liu a945daf96d [RV64_DYNAREC] Added unaligned support for F0 /5 LOCK SUB opcode (#1607) 2024-06-20 16:20:36 +02:00
Michael Büchler 22116dabc3 Add missing wrappings for winewayland.so (#1599)
* Add missing wrappings for winewayland.so

These were missing on wine-9.9 built with `--enable-win64` and
`--with-wayland=yes` on Ubuntu 24.04 "noble".

Does not work at this point! Now there is a SIGILL during/after mapping
winewayland.so due to a missing zxdg_output_v1 listener.

* wrappedwaylandclient: add zxdg_output_v1 listener

This is used by wine's waylandclient.so. Tested with wine-9.9 regedit
and winecfg.
2024-06-20 08:24:48 +02:00
ptitSeb 5494d95b6b Added a few more symbols, used by latest steam for linux (for #1603) 2024-06-19 21:30:20 +02:00
theofficialgman 9ab686b3e0 switch to maintained Pi-Apps-Coders apt repo (#1605)
closes https://github.com/ptitSeb/box64/issues/1576
2024-06-19 18:39:03 +02:00
ptitSeb 5b24440e8c [ARM64_DYNAREC] Fixed AVX.F2.0F3A F0 opcode 2024-06-19 10:33:49 +02:00
salt431 44deff987c Update arm64_immenc.c (#1602)
combine if (!bitmask || !~bitmask) to (bitmask == 0 || bitmask == ~0ULL) to reduce overhead.

use bitwise operators instead of + operators.
2024-06-19 08:55:01 +02:00
Yang Liu 7273ac0d34 [RV64_DYNAREC] Fixed potential issue of jump_to_next (#1600) 2024-06-18 18:35:35 +02:00
ptitSeb ceb9834a27 [RCFILE] Better profile for Kingdom Rush Origin linux version 2024-06-18 18:23:31 +02:00
ptitSeb 4eebf25f1c Added BOX64_RESERVE_HIGH in rcfile handling 2024-06-18 17:25:32 +02:00
ptitSeb 865ef2ff6e Added 1 more wrapped symbol to libmpg123 2024-06-18 16:59:54 +02:00
ptitSeb 8138ba6ecb [ARM64_DYNAREC] Added a warning if allocating a scratch register after some YMM 2024-06-18 16:23:32 +02:00
ptitSeb f1c0b52677 [ARM64_DYNAREC] Fixed AVX.66.0F 6B opcode 2024-06-18 16:22:57 +02:00
ptitSeb a4cb62d6d6 [ARM64_DYNAREC] Restaured a better way to handle ymm register, now that the traking is improved 2024-06-18 15:58:57 +02:00
ptitSeb e4062c6031 [ARM64_DYNAREC] Fixed AVX.66.0F3A 19/39 opcodes 2024-06-18 15:24:30 +02:00
ptitSeb 08844f31c9 [ARM64_DYNAREC] Better tracking of used ymm (seems redundent with ymm0_sub) 2024-06-18 15:23:46 +02:00
ptitSeb 4dfdba001b [TRACE] Cosmetic change on ymm printout 2024-06-18 15:22:52 +02:00
LiZhuoheng 8dbf982ebe Added more wrapped functions to gmp and idn2 (#1598) 2024-06-18 11:35:09 +02:00
Yang Liu 031255a946 [RV64_DYNAREC] Improved 0F AE opcodes (#1596) 2024-06-18 10:01:54 +02:00
Yang Liu 8dfbe80b41 [LA64_DYNAREC] Added more opcodes (#1597) 2024-06-18 10:01:12 +02:00
Yang Liu 2bcc997e4b [RV64_DYNAREC] Fixed and refined F0 81,83 LOCK prefix opcodes (#1595) 2024-06-18 09:59:33 +02:00
LiZhuoheng 263e79be53 Added more wrapped functions (#1593) 2024-06-18 07:21:25 +02:00
ptitSeb d031a8b423 [ARM64_DYNAREC][COSIM] Do not test atomic operatin, they don't support double execution very well by nature 2024-06-17 22:15:48 +02:00
ptitSeb 7bec96e4b2 [COSIM] Some improvment to avoid segfault in edge cases 2024-06-17 22:15:03 +02:00
Yang Liu 6bb1bacfba Fixed some symbols not found error for libc and libresolv wrapping (#1591) 2024-06-17 18:40:16 +02:00
Yang Liu 95a4aaf8fd [LA64_DYNAREC] Added more opcodes (#1590) 2024-06-17 18:39:01 +02:00
ptitSeb 387c64b74c Fixed usage of getcpu, only enablign that for recent enough glibc (should help #1586) 2024-06-17 16:02:26 +02:00
ptitSeb 4d068eee26 This should fix slatest steam on linux not starting 2024-06-15 09:58:00 +02:00
Yang Liu ece732ba41 [DYNAREC_RV64] Fixed 16bit LOCK ADD issue (#1584) 2024-06-15 09:02:16 +02:00
Yang Liu 8f40dc1a8c Fixed some vulkan wrapper functions (#1585)
* Fixed some vulkan wrapper functions

* Forgot to submit generated files
2024-06-15 09:01:33 +02:00
ptitSeb c9a6d4c05a [ARM64_DYNAREC] Added AVX.66.0F38 8C/9C/9F/BE opcodes 2024-06-14 11:26:49 +02:00
ptitSeb a66b4e257a [ARM64_DYNAREC] Added AVX.F2.0F 7C/F0 opcodes 2024-06-14 11:25:50 +02:00
ptitSeb 3796805d98 [ARM64_DYNAREC] Added faked F3 0F AE /5 unsupported opcode 2024-06-14 11:24:59 +02:00
ptitSeb a3d09e95d5 Fixed an issue with BOX64_RDTSC_1GHZ being always active 2024-06-13 15:51:15 +02:00
ptitSeb 626846c37b [ANDROID] This should fix android build 2024-06-13 11:32:58 +02:00
ptitSeb 8bf1ac6577 [ARM64_DYNAREC] Added AVX.66.0F 7C opcode 2024-06-13 10:49:49 +02:00
ptitSeb 58c0bce4cf More work on RDTSC emulation 2024-06-13 10:22:33 +02:00
LiZhuoheng 3a82dc6aad Added more wrapped function to libunistring2 (#1582)
* Added more wrapped function to libunistring2

* add wrapper.c
2024-06-13 07:46:27 +02:00
ptitSeb e42b9e2866 [WAYLAND] Wrapped one more listener 2024-06-12 20:10:46 +02:00
ptitSeb 8a85acff32 Better wrapping for libwayland-client, removed the x64 versions of the libs, using wrapped one instead 2024-06-12 19:41:06 +02:00
ptitSeb b450ea24a2 Added the new x64 libs 2024-06-12 16:05:47 +02:00
ptitSeb 4fa92dc069 Removed wrapped libwayland-client and libwayland-cursor, the wrapping is wrong, and use native libs instead 2024-06-12 16:01:01 +02:00
LiZhuoheng 61a80c9b2d Wrapped libhogweed6 (#1579) 2024-06-12 15:27:37 +02:00
ptitSeb bcfd0f7ea3 Added one structure to libwayland-clinet and auto bridges all current interfaces 2024-06-11 18:02:02 +02:00
ptitSeb c404b3e0ab Fixed libudev.so.0 wrapping, removed functions from libudev.so.1 2024-06-11 16:41:44 +02:00
ptitSeb b246133b3b [ARM64_DYNAREC] Added AVX.0F 77 256bits opcode 2024-06-11 15:07:10 +02:00
ptitSeb 5b28d7bc03 [INTERPRETER] Added AVX.0F 77 256bits opcode 2024-06-11 15:06:50 +02:00
ptitSeb 8adaefcdb9 Remove and obsolete comment 2024-06-11 15:06:19 +02:00
ptitSeb e64b4d5c04 [ARM64_DYNAREC] Fixed AVX.66.0F E1-E3 opcodes and Added AVX.66.0F C6 and AVX.0F 17 opcodes 2024-06-11 13:33:24 +02:00
ptitSeb 59caccfeae [ARM64_DYNAREC] Added AVX.66.0F38 02/0B opcodes 2024-06-11 10:32:53 +02:00
ptitSeb bbd3333b5f [ARM64_DYNAREC] Fixed another issue with Ymm value when updating flags on internal jump 2024-06-11 10:21:52 +02:00
ptitSeb 1ce7f32b5d [ARM64_DYNAREC] Added AVX.66.0F38 5A opcode 2024-06-11 10:12:24 +02:00
ptitSeb 95f18dbf15 [ARM64_DYNAREC] Fixed another issue with Ymm0 mask and reset_cache on internal jump 2024-06-11 10:11:55 +02:00
LiZhuoheng 9ed2e3bbf2 Wrapped libunistring2 (#1577) 2024-06-11 08:02:11 +02:00
ptitSeb 8b3cd23045 [ARM64_DYNAREC] Added AVX.66.0F38 90/92 opcodes and added AVX.66.0F38 04 opcode 2024-06-10 15:18:06 +02:00
ptitSeb 072241eb10 [ARM64_DYNAREC] Fixed AVX.66.0F3A 00/01 opcodes 2024-06-10 15:17:03 +02:00
ptitSeb 84a8500323 [ARM64_DYNAREC] Fixed 256bits version of AVX.66.0F D1/D2/D3 opcodes 2024-06-10 15:15:57 +02:00
ptitSeb a8911fc979 [ARM64_DYNAREC] Cosmetic change 2024-06-10 15:14:55 +02:00
Diego q 04ba0b2f67 Update README.md (#1573)
Added Strong memory mode to the hint under unity games because freezing is also a common issue on PI-4 and PI-5 for games, also added the mention of PI-5 on the hint because the issues aren't limited to the PI-4 and also apply to the Pi-5
2024-06-09 22:49:35 +02:00
Diego q d1e5bc5c19 Update README.md (#1572)
Usage link was broken so i fixed it
2024-06-09 21:23:36 +02:00
ptitSeb 38364ef07f [COSIM] Fixed 66 48 xx type of opcodes 2024-06-09 17:45:36 +02:00
ptitSeb b25d8db994 [ARM64_DYNAREC] Fixed an issue when not purging Ymm0 on internal jump with less Ymm0 2024-06-09 17:12:06 +02:00
ptitSeb 989ed95891 [ARM64_DYNAREC] Fixed AVX.66.0F38 28 opcode 2024-06-09 17:05:33 +02:00
ptitSeb d15ffc48a3 [ARM64_DYNAREC] Fixed AVX.66.0F 7F opcode 2024-06-09 16:56:15 +02:00
ptitSeb 06df8c7bed [DYNAREC] Another fix for YMM Zero'd upper reg tracking 2024-06-09 14:51:41 +02:00
ptitSeb 950241d52f [ARM64_DYNAREC] Added AVX.66.0F38 41/8E/9B, AVX.66.0F3A 06 and AVX.66.0F F6 opcodes 2024-06-08 21:31:11 +02:00
ptitSeb a147c12f72 [ARM64_DYNAREC] Another fix for YMM selection on High registry pressure cases 2024-06-08 16:51:51 +02:00
ptitSeb 874828c2ac [ARM64_DYNAREC] Added AVX.66.0F 50/C2, AVX.66.0F3A 0D, AVX.66.0F38 16/28/29/2B/36/AC/BA and AVX.F2.0F 51 opcodes 2024-06-08 15:21:55 +02:00
ptitSeb 3369e5e755 Remove a warning on known unhandled arch_prctl commands 2024-06-08 15:19:46 +02:00
ptitSeb 9b3930ea62 [ARM64_DYNAREC] Small optim on 66 0F 50 opcode 2024-06-08 15:19:01 +02:00
ptitSeb 987d0db806 [INTERPRETER] Fixed AVX.66.0F 50 opcode not handling vex.l 2024-06-08 15:18:34 +02:00
ptitSeb 97530e4095 [ARM64_DYNAREC] Added AVX.66.0F E6, AVX.66.0F38 98 and fixed AVX.F2.0F E6 opcodes 2024-06-08 11:53:35 +02:00
ptitSeb 4c285d4d8a [ARM64_DYNAREC] Fixed an issue when purging an YMM that is used in the same opcode 2024-06-08 11:52:00 +02:00
ptitSeb cd5fbc1492 Added 2 wrapped function to libglib2 2024-06-08 09:50:10 +02:00
ptitSeb 2e379300a6 [RCFILE] Added a few more profiles 2024-06-07 20:02:57 +02:00
ptitSeb 65c19d073c Only expose xsave extension if avx is used 2024-06-07 17:04:14 +02:00
ptitSeb eb013f3492 [DYNAREC] This should fix RV64 and LA64 builds 2024-06-07 14:30:36 +02:00
ptitSeb b2fd651abe [ARM64_DYNAREC] Fixed YMM cache handling, espcially in high pressure regs cases 2024-06-07 13:34:22 +02:00
xctan d4b02e6a3f [RV64_DYNAREC] Fixed sign extension of 8-bit immediate in 66 opcodes (#1568) 2024-06-07 11:37:29 +02:00
ptitSeb 537cb65f26 [ARM64_DYNAREC] Added BMI.0F38 F2, F3/1 opcodes 2024-06-07 10:25:14 +02:00
ptitSeb f61367fc9a [ARM64_DYNAREC] That's just cosmetic... 2024-06-07 10:24:15 +02:00
LiZhuoheng 46e0505336 Wrapped libnettle8 (#1567) 2024-06-07 10:22:03 +02:00
xctan 75004d0b56 [RV64_DYNAREC] Fixed some opcodes caught by cosim (#1561)
* [RV64_DYNAREC] Fixed emit_shrd16c

* [RV64_DYNAREC] Fixed BSWAP Gw

* [RV64_DYNAREC] Fixed 32 bit RCL/RCR Ed, 1

* [RV64_DYNAREC] Fixed 32 bit BTR

* [RV64_DYNAREC] Fixed 32 bit SHLD

* [RV64_DYNAREC] Fixed 32 bit SHLD again

* [RV64_DYNAREC] Fixed 16 bit constant SHLD again

* [RV64_DYNAREC] Fixed 16-bit BTC

* [RV64_DYNAREC] Fixed 32-bit rotates using Zbb extension

* [RV64_DYNAREC] Fixed 16-bit SHLD opcode

* [RV64_DYNAREC] Fixed the mask of LAHF opcode

* [RV64_DYNAREC] Fixed LAHF again and handled OF2 before cosim

* [RV64_DYNAREC] Fixed XADD Eb, Gb when Eb == Gb

* [RV64_DYNAREC] Fixed XADD Ew, Gw when Ew == Gw

* [RV64_DYNAREC] Fixed zero extension of 32 bit Ed operand

* [RV64_DYNAREC] Fixed XADD Eb, Gb again for AH, BH, CH, DH

* [RV64_DYNAREC] Fixed various 16-bit immediate extension
2024-06-06 17:32:49 +02:00
ptitSeb 0dc5761ca6 [INTERPRETER] Added suport for F16C extension (linked to AVX flag) ([ARM64_DYNAREC] too) 2024-06-06 16:48:05 +02:00
ptitSeb df47fb5be8 Disable F16C for now, it's not ready yet 2024-06-06 13:59:09 +02:00
ptitSeb 0cedc70eb3 [ARM64_DYNAREC] Added a new small batch of AVX/BMI2 opcodes 2024-06-06 13:47:47 +02:00
ptitSeb 1612687acf [ARM64_DYNAREC] Fixed VCMPSS opcode 2024-06-06 13:47:14 +02:00
LiZhuoheng 67d587cd9b Wrapped libtasn1-6 (#1563) 2024-06-06 09:48:31 +02:00
LiZhuoheng 9e97e96b87 Wrapped libp11-kit (#1562) 2024-06-06 08:12:34 +02:00
ptitSeb 79c1ad1431 [ARM64_DYNAREC] Added a few more AVX opcodes 2024-06-05 20:40:26 +02:00
ptitSeb c0ebe09521 Added an AVX test (not on Android, needs to be build there) 2024-06-05 19:44:25 +02:00
ptitSeb b568cc529e [ARM64_DYNAREC] Added a bunch of AVX ocpodes and some fixes too 2024-06-05 19:44:02 +02:00
ptitSeb dc8e24c7b7 [INTERPRETER] Fixed VCMP opcode familly, that needs more cases on than con-vex CMP familly 2024-06-05 15:03:44 +02:00
ptitSeb ba411303e9 [DYNAREC] Improved handling of the Ymm0 attribute 2024-06-05 10:44:31 +02:00
ptitSeb 8848bc2e7f [ARM64_DYNAREC] Small optim for AVX.66.0F D7 opcode 2024-06-05 09:51:03 +02:00
Yang Liu f7798f361a [LA64_DYNAREC] Fixed LOCK DEC opcode (#1560) 2024-06-04 18:53:32 +02:00
ptitSeb 6a25427cb6 [DYNAREC] Small improvment to Dynarec infrastructure 2024-06-04 11:11:17 +02:00
ptitSeb a6c283f4ce [ARM64_DYNAREC] Added AVX.0F 16/50/53/C2 opcodes 2024-06-03 22:11:12 +02:00
Yang Liu 48bb907d2d [LA64_DYNAREC] Added more opcodes (#1558) 2024-06-03 22:04:28 +02:00
Yang Liu c2ce5d5557 [LA64_DYNAREC] Fixed emit_or16 (#1559) 2024-06-03 22:04:12 +02:00
ptitSeb 0d30fe90f8 [ARM64_DYNAREC] Added AVX.66.0F 5A/5C-5F/D0-D3 2024-06-03 21:29:14 +02:00
ptitSeb c434cef45e [ARM64_DYNAREC] Cosmetic change 2024-06-03 21:28:16 +02:00
ptitSeb d01970f731 [ARM64_DYNAREC] Added AVX.66.0F3A 02/08-09/0E/14/20/40/4A-4B opcodes 2024-06-03 20:28:32 +02:00
ptitSeb bb9beb75d1 [INTERPRETER] Fixed name in comment of an opcode 2024-06-03 20:28:32 +02:00
xctan ad3a9e6c55 [RV64_DYNAREC] Added more MMX opcodes and some optimizations too (#1557)
* [RV64_DYNAREC] Added 0F 38 0B PMULHRSW opcode

* [RV64_DYNAREC] Added 0F E4 PMULHUW opcode

* [RV64_DYNAREC] Added 0F F4 PMULUDQ opcode

* [RV64_DYNAREC] Added 0F F6 PSADBW opcode

* [RV64_DYNAREC] Added 0F 38 08 PSIGNB opcode

* [RV64_DYNAREC] Optimized 66 0F 38 08 PSIGNB opcode

* [RV64_DYNAREC] Added 0F 38 0A PSIGND opcode

* [RV64_DYNAREC] Optimized 66 0F 38 0A PSIGND opcode

* [RV64_DYNAREC] Added 0F 38 09 PSIGNW opcode

* [RV64_DYNAREC] Optimized 66 0F 38 09 PSIGNW opcode

* [RV64_DYNAREC] Added 0F F2 PSLLD opcode

* [RV64_DYNAREC] Added 0F F3 PSLLQ opcode

* [RV64_DYNAREC] Added 0F F1 PSLLW opcode

* [RV64_DYNAREC] Fixed 0F F1/F2 PSLLW/PSLLD opcode

* [RV64_DYNAREC] Added 0F E1 PSRAW opcode

* [RV64_DYNAREC] Added 0F D2 PSRLD opcode

* [RV64_DYNAREC] Added 0F D3 PSRLQ opcode

* [RV64_DYNAREC] Added 0F D1 PSRLW opcode

* [RV64_DYNAREC] Added 0F F8 PSUBB opcode

* [RV64_DYNAREC] Added 0F FA PSUBD opcode

* [RV64_DYNAREC] Added 0F FB PSUBQ opcode

* [RV64_DYNAREC] Added 0F E8 PSUBSB opcode and optimized 0F E9 PSUBSW opcode

* [RV64_DYNAREC] Added 0F D8 PSUBUSB opcode
2024-06-03 17:42:23 +02:00
ptitSeb 9a30b65180 [ARM64_DYNAREC] Added AVX.66.0F38 17/20-25/29/37-40/45-47/78-79/99/AA/AE-AF/BB-BD/F7 opcodes 2024-06-03 17:33:55 +02:00
ptitSeb cb548fe1fa [INTERPRETER] Fixed name in comment of an opcode 2024-06-03 17:31:17 +02:00
ptitSeb 0a8f049ced [ARM64_DYNAREC] Added AVX.66.0F38 19/1A and AVX.66.0F3A 22 opcodes 2024-06-03 14:43:21 +02:00
ptitSeb 890809069e [ARM64_DYNAREC] Fixed AVX.F2/F3.0F 5D/5F opcodes 2024-06-03 14:42:21 +02:00
ptitSeb ca9a6fe019 [ARM64_DYNAREC] Empty regs needs to be fetched last (again) 2024-06-03 13:54:49 +02:00
ptitSeb 94ccae727b [ARM64_DYNAREC] Fixed AVX Cache transform between internal jump points 2024-06-03 13:46:30 +02:00
ptitSeb 001e77952e [COSIM] Added more helpers to avoid segfault on rare cases 2024-06-03 13:45:55 +02:00
ptitSeb ac6a453833 [ARM64_DYNAREC] Empty register needs to be fetched last 2024-06-03 12:45:33 +02:00
ptitSeb 307915130c [INTERPRETER] Fixed VZEROUPPER opcode 2024-06-03 12:45:05 +02:00
Romain TISSERAND 3d225ef908 Try to fix mmap64 already defined error in custommem.c (#1552) 2024-06-03 08:07:11 +02:00
ptitSeb 1c9123637a [ARM64_DYNAREC] Added AVX.F3.0F 52, AVX.66.0F E4 and AVX.0F 52 opcodes 2024-06-02 20:31:32 +02:00
ptitSeb f1f690552f [ARM64_DYNAREC] Added AVX.66.0F38 08-0A/1C-1E/30-35/58/59/90/92/A8/A9/B8/B9 opcodes 2024-06-02 20:10:00 +02:00
ptitSeb 57dcf3401c [ARM64_DYNAREC] Remove parasite typo to fix build 2024-06-02 18:41:17 +02:00
ptitSeb 9e5df7957e [INTERPRETER] Added missing FMA opcodes, and fixed some existing ones 2024-06-02 17:26:26 +02:00
ptitSeb ca63389ea3 [INTERPRETER] Fixed opcode name in comment 2024-06-02 16:45:35 +02:00
ptitSeb 7b7ee070b9 [ARM64_DYNAREC] Added AVX.66.0F D6/E5/E7/F5 opcodes 2024-06-02 16:32:16 +02:00
ptitSeb 3aee16e9a0 [ARM64_DYNAREC] Added AVX.66.0F3A 00/01/04/05/0A/0B/46 opcodes 2024-06-02 15:18:04 +02:00
ptitSeb 06cb3624e2 [ARM64_DYNAREC] Fixed handling of YMM0 on forward jump 2024-06-02 13:56:13 +02:00
ptitSeb a1f83418b9 [COSIM] Fixed YMM handling in cosim, seems to work better now 2024-06-02 13:44:38 +02:00
ptitSeb e5a32ea129 [ARM64_DYNAREC] Added AVX.66.0F 60-63/67-6A/71 opcodes 2024-06-02 13:13:01 +02:00
ptitSeb eb209abe62 [ARM64_DYNAREC] Don't use fix scratch for x87 conversion, it might conflict with YMM handling 2024-06-02 13:12:06 +02:00
ptitSeb 13551fd410 [INTERPRETER] Small cosmetic changes on raz of ymm 2024-06-02 13:11:13 +02:00
ptitSeb 2493706315 [COSIM] Improved reliability with AVX (but there is still something wrong there) 2024-06-02 13:10:50 +02:00
ptitSeb b49273c079 [INTERPRETER] Added FMA cpu extension (linked to BOX64_AVX=2) 2024-06-02 11:26:16 +02:00
ptitSeb 7c1b161277 [ARM64_DYNAREC] Fixed YMM COSIM refreshing on each steps 2024-06-02 11:26:16 +02:00
ptitSeb d8a1dcc1b4 [COSIM] Fixed issue with YMM printing on difference 2024-06-02 11:26:16 +02:00
Yang Liu f44d60c58f [LA64_DYNAREC] Added more opcodes (#1549)
* [LA64_DYNAREC] Added more opcodes

* fastnan handling and fixed PALIGNR...
2024-06-02 10:25:57 +02:00
ptitSeb dc71840a5a [ARM64_DYNAREC] Added AVX.66.0F3A 21 and fixed a bunch of issues 2024-06-02 09:15:37 +02:00
ptitSeb 07b17cd0f6 [INTERPRETER] Small fixes for some rare case of AES with serc==dest 2024-06-02 08:41:29 +02:00
Yang Liu cf37e8ea83 [LA64_DYNAREC] Added more opcodes and fixed ADC opcode (#1548) 2024-06-01 20:08:33 +02:00
ptitSeb 5384489702 [ARM64_DYNAREC] Added AVX.F2.0F 58-5A/5C-5F opcodes 2024-06-01 19:38:28 +02:00
ptitSeb 1ad69d785f [ARM64_DYNAREC] Added AVX.66.0F C4/C5/D7 opcodes 2024-06-01 19:22:39 +02:00
ptitSeb ef3acd9f33 [ARM64_DYNAREC] Added BMI.F2.0F38 F7 opcode 2024-06-01 19:12:18 +02:00
ptitSeb 083b42fead [ARM64_DYNAREC] Added AVX.66.0F 10-17/29/29/2B/2E/2F/54-59/74-76/7E opcodes 2024-06-01 19:04:50 +02:00
ptitSeb c6814a6f97 [ARM64_DYNAREC] Added AVX.0F 28/29/2B/2E/2F/54-56/5A-5F opcodes, plus various small fixes 2024-06-01 18:03:24 +02:00
Yang Liu 9dbd7fc7e0 [INTERP] Rework on the 16b emulation for LA64 (#1547)
* [INTERP] Rework on the 16b emulation for LA64

* fix compiler issue
2024-06-01 17:14:23 +02:00
ptitSeb a79eff3b0d [ARM64_DYNAREC] Added AVX.F3.0F 10-12/16/2A/2C/2D/58-5F opcodes, plus a few other fixes 2024-06-01 15:32:37 +02:00
ptitSeb a89d7a2e2a [ARM64_DYNAREC] Added AVX.F2.0F 10-12/2A/2C/2D opcodes 2024-06-01 14:28:32 +02:00
ptitSeb 0336f6a987 [ARM64_DYNAREC] Added a few 67 prefixed opcodes 2024-06-01 13:33:20 +02:00
ptitSeb 6d68975ba5 [ARM64_DYNAREC] Added ADX RORX opcode 2024-06-01 13:17:50 +02:00
ptitSeb 2b07fd7c6a [ARM64_DYNAREC] Added AVX.66.0F3A 38/39 opcodes 2024-06-01 13:10:53 +02:00
ptitSeb f8cc423f3d [ARM64_DYNAREC] Added AVX.66.0F 72/7F/F8-FE 2024-06-01 12:37:37 +02:00
ptitSeb f4667fa3cf [ARM64_DYNAREC] Added AVX.F3.0F 7E opcode 2024-06-01 12:05:38 +02:00
Yang Liu d8f929755a Detects extensions even if dynarec is disable at runtime (#1546) 2024-06-01 11:55:45 +02:00
ptitSeb 031685e0a7 [ARM64_DYNAREC] Added AVX.66.0F38 00/DC-DF opcodes 2024-06-01 11:48:09 +02:00
ptitSeb 9f260eb86c [ARM64_DYNAREC] Fix issue with 66 0F 38 DC-DF when rare case of dest==src 2024-06-01 11:38:32 +02:00
ptitSeb 75878b24cd [ARM64_DYNAREC] Added AVX.F3.0F 7F opcode 2024-06-01 10:35:24 +02:00
ptitSeb fe0425eb80 [ARM64_DYNAREC] Added a couple of AVX.66.0F3A opcodes, and fixed some sse/avx function helpers 2024-06-01 09:49:35 +02:00
ptitSeb 453003da23 [ARM64_DYNAREC] Added some AVX.66.0F opcodes 2024-06-01 09:02:54 +02:00
Yang Liu eec08973bf [LA64_DYNAREC] Added LOCK CMPXCHG unaligned version (#1545) 2024-06-01 08:12:25 +02:00
Yang Liu c65f8da90f [RV64_DYNAREC] Fixed LOCK CMPXCHG unaligned version (#1544) 2024-06-01 07:52:03 +02:00
Yang Liu 2970ed5bfd [LA64_DYNAREC] Fixed 0F C2 CMPPS opcode (#1543) 2024-05-31 23:27:02 +02:00
ptitSeb bfebcba431 [ARM64_DYNAREC] Added a bunch of AVX/BMI2/ADX opcodes 2024-05-31 22:33:12 +02:00
ptitSeb dde85b761b [INTERPRETER] Added BMI1, BMI2 and ADX extensions 2024-05-31 15:59:11 +02:00
ptitSeb 34809e48d8 [ARM64_DYNAREC] Some fixes to AVX opcodes 2024-05-31 15:51:07 +02:00
xctan 6749c2d1a6 [RV64_DYNAREC] Added more MMX opcodes and some optimizations too (#1542)
* [RV64_DYNAREC] Added 0F 38 06 PHSUBD opcode

* [RV64_DYNAREC] Added 0F 38 07 PHSUBSW opcode

* [RV64_DYNAREC] Added 0F 38 05 PHSUBW opcode

* [RV64_DYNAREC] Added 0F C4 PINSRW opcode

* [RV64_DYNAREC] Added 0F 38 04 PMADDUBSW opcode

* [RV64_DYNAREC] Added 0F EE PMAXSW opcode

* [RV64_DYNAREC] Optimized SSE packed min/max

* [RV64_DYNAREC] Added 0F DE PMAXUB opcode

* [RV64_DYNAREC] Added 0F EA PMINSW opcode

* [RV64_DYNAREC] Added 0F DA PMINUB opcode

* [RV64_DYNAREC] Optimized 0F D9 PSUBUSW opcode

* [RV64_DYNAREC] Added 0F D7 PMOVMSKB opcode

* [RV64_DYNAREC] Optimized (66) 0F D7 PMOVMSKB opcode

* [RV64_DYNAREC] Switched to the simpler implementation for PMOVMSKB
2024-05-31 14:09:10 +02:00
ptitSeb 7eb24ff514 [ARM64_DYNBAREC] Added AVX.66.0F38 2C-2F opcodes 2024-05-30 21:26:10 +02:00
ptitSeb e367a2bcc9 [ARM64_DYNAREC] Added AVX.66.0F 64-66 opcodes 2024-05-30 20:25:01 +02:00
ptitSeb a02283264a [ARM64_DYNAREC] Fixed AVX.0F 12/13 opcodes 2024-05-30 20:24:34 +02:00
ptitSeb 7a7e9ee9af [ARM64_DYNAREC] Added AVX.0F 10-13 opcodes 2024-05-30 20:07:29 +02:00
ptitSeb b7f25a48c2 [ARM64_DYNAREC] Added AVX.0F 14/15/77/AE opcodes 2024-05-30 19:00:41 +02:00
ptitSeb 4477aa3159 [ARM64_DYNAREC] Added AVX.66.0F3A 15/16/17 opcodes 2024-05-30 18:40:07 +02:00
ptitSeb 4fd23c752c [ARM64_DYNAREC] Added AVX.66.0F 6B opcode 2024-05-30 18:21:16 +02:00
ptitSeb 60b625bc0f [ARM64_DYNAREC] Added AVX.66.F3A 19 opcodes and some various avx helper fixes 2024-05-30 18:13:01 +02:00
ptitSeb d1703b9bc0 [ARM64_DYNAREC] Added AVX.66.0F 5B/6F opcodes 2024-05-30 17:39:46 +02:00
ptitSeb eb9da7417f [RV64_DYNAREC] Fixed build 2024-05-30 17:16:28 +02:00
ptitSeb 782f497b20 [ARM64_DYNAREC] Added AVX.0F 58-59 opcodes, and fixed AVX.66.0F3A 18 opcode 2024-05-30 17:14:05 +02:00
ptitSeb 003a83b40b [ARM64_DYNAREC] Added AVX.66.0F38 18 and AVX.66.0F3A 0C opcodes 2024-05-30 16:53:39 +02:00
ptitSeb 2f8d28e7da [ARM64_DYNAREC] Added AVX.0F 57 opcode 2024-05-30 16:08:20 +02:00
ptitSeb fa591589c7 [ARM64_DYNAREC] Added AVX.66.0F3A 18 opcode 2024-05-30 15:47:19 +02:00
ptitSeb f0ea459c57 [ARM64_DYNAREC] That first avx opcode now is 256bits enabled 2024-05-30 15:17:13 +02:00
xctan f3d733c3ff [RV64_DYNAREC] Added more MMX opcodes and some optimizations too (#1539)
* [RV64_DYNAREC] Added 0F DF PANDN opcode

* [RV64_DYNAREC] Added 0F E0 PAVGB opcode

* [RV64_DYNAREC] Added 0F E3 PAVGW opcode

* [RV64_DYNAREC] Added 0F 74 PCMPEQB opcode

* [RV64_DYNAREC] Added 0F 76 PCMPEQD opcode

* [RV64_DYNAREC] Added 0F 64 PCMPGTB opcode

* [RV64_DYNAREC] Added 0F 66 PCMPGTD opcode and optimized 66 0F 66 PCMPGTD opcode

* [RV64_DYNAREC] Added 0F 65 PCMPGTW opcode

* [RV64_DYNAREC] Added 0F C5 PEXTRW opcode

* [RV64_DYNAREC] Added 0F 38 02 PHADDD opcode

* [RV64_DYNAREC] Optimized packed saturate add/sub

* [RV64_DYNAREC] Added 0F 38 03 PHADDSW opcode

* [RV64_DYNAREC] Added 0F 38 01 PHADDW opcode
2024-05-30 14:35:27 +02:00
LiZhuoheng 19ca78769f Wrapped libssh2 (#1538)
* Wrapped libssh2

* Add more libssh2 wrapped functions
2024-05-30 14:34:08 +02:00
ptitSeb 3e5784cbc5 [ARM64_DYNAREC] Added a fisrt 128bits only AVX opcode 2024-05-30 12:12:45 +02:00
xctan 98d9f36f9c Added more MMX opcodes and some optimizations too (#1537)
* [RV64_DYNAREC] Added 0F DD PADDUSW opcode and optimized 66 0F DD PADDUSW opcode

* [RV64_DYNAREC] Added 0F 3A 0F PALIGNR opcode

* [RV64_DYNAREC] Optimized 66 0F 3A 0F PALIGNR opcode
2024-05-30 10:54:48 +02:00
ptitSeb 22bc6872f4 [INTERPRETER] Last batch of avx/avx2 opcode 2024-05-29 16:36:43 +02:00
ptitSeb f6fe84afad [INTERPRETER] Added more avx/avx2 opcodes, and fixed vpxor 2024-05-29 15:14:26 +02:00
ptitSeb 4744534fc9 [INTERPRETER] Moar avx/avx2 opcodes 2024-05-29 12:09:21 +02:00
ptitSeb af05d7439f [INTERPRETER] yet more avx/avx2 opcodes 2024-05-29 10:53:38 +02:00
ptitSeb 6e22f4fd6d Added one xslt wrapped constant (for #1534) 2024-05-29 08:39:52 +02:00
ptitSeb 0e3d92148b Added a few libc wrapped function (for #1517 and #1531) 2024-05-29 08:26:18 +02:00
ptitSeb 06cf6d2ecc [INTERPRETER] and a bit more avx/avx2 opcodes 2024-05-28 22:42:12 +02:00
ptitSeb 7b5654eea4 [INTERPRETER] still more avx/avx2 opcodes 2024-05-28 22:09:50 +02:00
ptitSeb 503eb41939 [INTERPRETER] more and more avx/avx2 opcodes 2024-05-28 19:55:15 +02:00
ptitSeb a77db3c6a5 [INTERPRETER] Even more avx/avx2 opcodes, all the mov and more 2024-05-28 18:27:32 +02:00
ptitSeb 4e0889469a [INTERPRETER] Even more avx/avx2 opcodes, and a fix for android builds 2024-05-28 16:50:51 +02:00
xctan 7c5bf62fc0 [RV64_DYNAREC] Added more MMX opcodes and some optimizations too (#1535)
* [RV64_DYNAREC] Added 0F F7 MASKMOVQ opcode

* [RV64_DYNAREC] Added 0F 38 1C PABSB opcode

* [RV64_DYNAREC] Added 0F 38 1E PABSD opcode

* [RV64_DYNAREC] Added 0F 38 1D PABSW opcode

* [RV64_DYNAREC] Added 0F 63 PACKSSWB opcode

* [RV64_DYNAREC] Added 0F FC PADDB opcode

* [RV64_DYNAREC] Added 0F D4 PADDQ opcode

* [RV64_DYNAREC] Added 0F EC PADDSB opcode and optimized 66 0F EC PADDSB opcode

* [RV64_DYNAREC] Added 0F DC PADDUSB opcode and optimized 66 0F DC PADDUSB opcode
2024-05-28 15:04:41 +02:00
ptitSeb b79f86b8d1 [INTERPRETER] More avx/avx2 opcodes 2024-05-28 14:55:17 +02:00
ptitSeb b9f5929439 [INTERPRETER] More avx, avx2 and vaes opcodes 2024-05-28 10:42:41 +02:00
ptitSeb 3dc396a647 Fixed cpuid leaf d, component 2 (fixes wine 9.6+ not booting) 2024-05-27 16:50:26 +02:00
ptitSeb c358bf448f Fixed a warning 2024-05-27 14:58:34 +02:00
ptitSeb abd1d56d7f Correct hadnlign of upper 32bits value of mask for xsave/xrstor 2024-05-27 14:57:05 +02:00
ptitSeb 22b9c16351 [ARM64_DYNAREC] Added faked 0F C7 /4 opcode to get bigger dynablock 2024-05-27 14:56:27 +02:00
ptitSeb 0131958136 [INTERPRETER] Added more avx opcodes 2024-05-27 14:51:08 +02:00
ptitSeb 9f70767acf [ARM64_DYNAREC] Fixed some SHA1 opcode when source is same as dest 2024-05-27 13:45:35 +02:00
ptitSeb bdeb8d7ee2 [ARM64_DYNAREC] Some fixes to opcode when src is same as dest 2024-05-27 13:14:22 +02:00
ptitSeb de831ee5ac [INTERPRETER] Some fixes when opcode use with same reg as src and dest 2024-05-27 13:13:52 +02:00
ptitSeb da1cb42f2a [ARM64_DYNAREC] Fixed some pcmp[ei]stri flags 2024-05-27 13:07:01 +02:00
ptitSeb 2c366ef4bd Just clear AF flags on pcmp[i/e]stri helper 2024-05-27 13:06:28 +02:00
ptitSeb bc0f31407f [INTERPRETER] Added some more avx opcodes 2024-05-27 12:48:05 +02:00
ptitSeb 0d755e610b More avx infrastructure 2024-05-27 12:21:57 +02:00
ptitSeb 55ee7fcc33 [INTERPRETER] Some fixes and small refactor on avx handling 2024-05-27 11:13:15 +02:00
ptitSeb 10200d7b55 [INTERPRETER] Added avx (66 0F 38) 00 opcode 2024-05-27 10:23:56 +02:00
ptitSeb 1eab6a0c8e [INTERPRETER] Added avx (66 0F 3A) 0F opcode 2024-05-27 10:08:46 +02:00
ptitSeb fc2d50c7d3 [INTERPRETER] Added avx (F3 0F) 7F opcode 2024-05-27 10:02:33 +02:00
ptitSeb aaed0364bd [INTERPRETER] Added avx (66 0F 3A) 44 opcode 2024-05-27 09:53:49 +02:00
ptitSeb 9e0139f3c3 Small cleanup in my_cpuid 2024-05-27 09:53:29 +02:00
ptitSeb ec3c3b7eed [INTERPRETER] Added avx (66 0F) 6F ocpode 2024-05-27 09:11:50 +02:00
ptitSeb c67632722b [INTERPRETER] Added avx (66 0F) 6C/6D opcode and even more fixes to some avx opcodes 2024-05-26 16:48:26 +02:00
ptitSeb 580fbf47b2 [INTERPRETER] Added avx (66 0F) DB opcode and more fixes to some avx opcodes 2024-05-26 16:11:26 +02:00
ptitSeb 4bffdce8af [INTERPRETER] Added avx (66 0F) EB opcode and fixed other avx opcodes 2024-05-26 15:50:43 +02:00
ptitSeb f22e9bf1d2 [INTERPRETER] Added avx (66 0F) 64/65/66/72/73/EF opcodes 2024-05-26 15:20:52 +02:00
ptitSeb 95b516127a [INTERPRETER] Added avx (F3 0F) 6F and (66 0F) 70 2024-05-26 12:57:59 +02:00
ptitSeb da7474b1de Added 67 66 83 opcodes ([ARM64_DYNAREC] too) 2024-05-26 11:03:32 +02:00
ptitSeb 27aa9011ce Fixed xrstor helper 2024-05-26 10:42:16 +02:00
ptitSeb d09a48fd03 [INTERPRETER] my first avx opcode 2024-05-26 09:21:04 +02:00
Yip Coekjan b5c0a857ca Fix typo on box64 config file (#1533) 2024-05-25 15:02:32 +02:00
Yip Coekjan ab9f848dcd Fix unclosed item list (#1532) 2024-05-25 13:57:35 +02:00
ptitSeb 1b3350437c Added 67 66 0F D6 ([ARM64_dynarec] too) 2024-05-25 11:46:31 +02:00
ptitSeb 03749788e8 [TRACE] Group trace member of x64emu_t 2024-05-24 22:45:11 +02:00
ptitSeb 9a571cfb72 [RV64_DYNAREC] Fix dynarec build for RV64 2024-05-24 22:44:47 +02:00
ptitSeb 39303611ef more avx infrastructure 2024-05-24 20:17:35 +02:00
ptitSeb fcf0cf00d0 Added support for XSAVE/XRSTOR ([ARM64_DYNAREC] too) 2024-05-24 15:01:46 +02:00
Yang Liu 2ee846f48e Workaround on a race condition on SDL_GetThreadID (#1530) 2024-05-24 10:14:49 +02:00
Yang Liu 9c846a3e40 Redirect pthread_yield to sched_yield (#1529) 2024-05-24 09:40:31 +02:00
Yang Liu 712e8315f8 [LA64_DYNAREC] Added more opcodes (#1528) 2024-05-23 22:21:56 +02:00
ptitSeb 604ab22526 [ARM64_DYNAREC] Added 66 D9 /6 and 66 DD /4 /6 opcodes 2024-05-23 16:32:04 +02:00
ptitSeb 85d09df938 Some more x87 adjustment, but it still off a bit 2024-05-23 16:32:04 +02:00
Yang Liu 5ae93f8431 [LA64_DYNAREC] Added CMPXCHG8B and CMPXCHG16B opcodes (#1527) 2024-05-23 15:57:58 +02:00
ptitSeb 3aab8dd332 More fixes to x87 handling 2024-05-23 15:55:28 +02:00
Yang Liu bf9d297dcd [RV64_DYNAREC] Fixed LOCK XCHG byte opcode (#1526) 2024-05-23 12:04:09 +02:00
Yang Liu 080cc77208 [LA64_DYNAREC] Added more opcodes (#1525) 2024-05-23 10:51:07 +02:00
ZoHan 7ebd92be7d Wrapped libpsl5 (#1523)
* Wrapped libpsl5

* Recover files
2024-05-23 07:49:52 +02:00
ptitSeb 22b2f63917 [ARM64_DYNAREC] Small potential fix to D9 E5 opcode 2024-05-22 23:51:54 +02:00
ptitSeb 5bcfa34bea Fixed some x87 handling issues 2024-05-22 23:50:45 +02:00
Yang Liu 48c47423a4 [LA64_DYNAREC] Fixed more issues here and there (#1521)
* [LA64_DYNAREC] Fixed more issues here and there

* minor optim

* minor change
2024-05-22 23:00:13 +02:00
Yang Liu 229cae16d1 [LA64_DYNAREC] Fixed some non-lbt flags comutation issues (#1520) 2024-05-22 20:00:22 +02:00
Yang Liu 9edb89fc22 [LA64_DYNAREC] Fixed LOCK XCHG byte opcode fallback path (#1519)
* [LA64_DYNAREC] Fixed LOCK XCHG byte opcode fallback path

* fix
2024-05-22 18:22:08 +02:00
Yang Liu 3faabb478d [DYNAREC] Simplified emit_pf helper (#1518)
* [DYNAREC] Simplified emit_pf helper

* Remove unused function and outdated comments
2024-05-22 13:06:43 +02:00
ptitSeb 2c127fe69c [ARM64_DYANREC] Simplified emit_pf helper 2024-05-22 11:08:07 +02:00
ptitSeb 3765d9e6f7 Start of a new dev. cycle 2024-05-22 10:18:32 +02:00
ptitSeb 8545d0505f Bumped version to v0.2.8 2024-05-21 17:33:16 +02:00
Yang Liu 28b101aaf7 [RV64] Made Zba and Xthead* detection mutually exclusive (#1514) 2024-05-21 15:35:48 +02:00
ptitSeb 24d1250e66 [ARM64_DYNAREC] Some small fixes to D9 E5 opcode 2024-05-21 14:35:45 +02:00
ptitSeb 706ca3649e [RV64_DYNAREC] Fixed a bunch of x87 opcodes 2024-05-21 13:34:31 +02:00
Yang Liu bb537e4dd5 [RV64_DYNAREC] Fixed some MMX opcodes (#1513)
* Fixed MOVD opcode

* Fixed PSHUFW opcode
2024-05-21 11:54:08 +02:00
Yang Liu eb59ff2ebd [ARM64_DYNAREC] Fixed PSLLD/PSLLQ opcodes (#1512) 2024-05-21 10:27:13 +02:00
Yang Liu 7842c9e34d [INTERPRETER] Added more opcodes and fixed some opcodes too (#1511) 2024-05-21 09:55:59 +02:00
ptitSeb 3882a98755 [RV64_DYNAREC] Fixed a few more opcodes 2024-05-20 23:11:30 +02:00
ptitSeb 14c9dc5bdb [RV64_DYNAREC] Fixed some bit manipulation opcodes 2024-05-20 22:34:23 +02:00
ptitSeb 181457b69f [RV64_DYNAREC] Fixed some issue with shld/shrd emitter 2024-05-20 22:01:46 +02:00
ptitSeb 0b6f543bbd [RV64_DYNAREC] Fixed some rotation emiters 2024-05-20 21:06:42 +02:00
ptitSeb 01a386445c [RV64_DYNAREC] Fixed some math emiter issues 2024-05-20 18:50:40 +02:00
Yang Liu 3fce669f6e [LA64_DYNAREC] Fixed 66 0F 67 PACKUSWB opcode (#1508) 2024-05-20 18:12:38 +02:00
Yang Liu 8a701755d8 [LA64_DYNAREC] Fixed LOCK ADD opcode (#1507) 2024-05-20 14:08:52 +02:00
Yang Liu aead503f02 [INTERPRETER] Fixed CMPXCHG16B opcode for la64 (#1506)
it's not the best we can do, but it fixes things. Will came up something better with scq extension later.
2024-05-20 12:04:31 +02:00
ptitSeb 7ef2af2549 Wrapped another __isoc23 function 2024-05-20 10:12:28 +02:00
ptitSeb 1e44a93c87 Removed all traces of PAGE8K, PAGE16K and PAGE64K as it's now detected in runtime 2024-05-20 10:08:27 +02:00
ptitSeb 2e55dec949 Updated Wine details on README 2024-05-20 09:45:17 +02:00
ptitSeb c80a83485d Updated contributors 2024-05-20 09:42:28 +02:00
ptitSeb 8915484251 Wrapped one more __isoc23 function 2024-05-20 09:26:49 +02:00
ptitSeb ed3450388b [ARM64_DYNAREC] Some various fixes after double-check of code 2024-05-19 19:22:01 +02:00
ptitSeb a2d580e926 [ARM64_DYNAREC] Use optimized rcl/rcr emiter for remaining opcodes with 64/65/67 prefixes 2024-05-19 19:21:08 +02:00
ptitSeb 47085bb9c9 [INTERPRETER] Added unaligned handling for 32bits F0 83 /0 opcode 2024-05-19 19:19:57 +02:00
ptitSeb 73619f4d75 [ARM64_DYNAREC] Small optimisation for edge case on a few shift emiter 2024-05-18 08:03:16 +02:00
ptitSeb 5228338f97 Added 2 new syscalls 2024-05-17 21:25:12 +02:00
ptitSeb 71c0aff78f Added 2 wrapped function libsdl2mixer ('two months' works now) 2024-05-17 14:55:45 +02:00
ptitSeb 4d7e106088 Added empty wrapped libdecor-0.so.0 2024-05-17 14:46:22 +02:00
ptitSeb d7127ccc3d [ARM64_DYNAREC] Improved stability of RCL/RCR and added 32/64 bits with constant emiter 2024-05-17 14:29:58 +02:00
ptitSeb 04e960b0da [TARCE] Better trace for neverclean mmaps 2024-05-17 10:49:53 +02:00
ptitSeb 8d199cfc6c [ARM64_DYNAREC] Minor adjustments to a few complex x87 opcodes 2024-05-17 10:09:59 +02:00
ptitSeb ffa58e23f1 Added 1 more gstreamer symbol 2024-05-16 21:40:43 +02:00
ptitSeb 289f94599d [ARM64_DYNAREC] Small improvment to DD /1 opcode 2024-05-15 19:48:51 +02:00
ptitSeb d0b51ae18f [ARM64_DYNAREC] Added 64/65 13 opcode 2024-05-15 19:47:26 +02:00
ptitSeb cea459d1e3 [COSIM] Small change for D9 /6 opcode 2024-05-15 17:02:22 +02:00
ptitSeb f6cd825ab9 [ARM64_DYNAREC] Fixed a potential issue with 0F B1 opcode 2024-05-15 16:47:49 +02:00
ptitSeb f8fa438728 [COSIM] Fixed issue with 0F C7 opcode 2024-05-15 16:47:04 +02:00
ptitSeb 07aacc9b08 [DYNAREC] Small fixes to when to stop a block (fixes regression on EALauncher) 2024-05-15 14:45:27 +02:00
ptitSeb 50325785f5 [ARM64_DYNAREC] Small optim of 0F B1 opcode 2024-05-15 12:32:44 +02:00
Yang Liu ef49b97c75 Added more symbols for libcrypto (#1504) 2024-05-15 12:28:52 +02:00
Yang Liu 75110ac028 [LA64_DYNAREC] Added more opcodes (#1503) 2024-05-15 11:22:03 +02:00
ptitSeb 57bfa38328 Removed the export WINEFSYNC=0 at start, use BOX64_FUTEX_WAITV=0 to disable instead 2024-05-14 16:15:27 +02:00
ptitSeb 2c00386e99 [INTERPRETER] Added 1 unligned case for F0 83 group 2024-05-13 17:58:04 +02:00
ptitSeb 3b03b7aee6 Added some more wrapped functions 2024-05-13 16:31:39 +02:00
kaixindeken 1491270f1d [RV64_DYNAREC] Fix SIGABRT handling in x87cache testing (#1498) 2024-05-13 12:38:04 +02:00
Yang Liu 46dfaab639 [DYNAREC_LA64] Added more opcodes (#1496) 2024-05-11 10:49:16 +02:00
ptitSeb ff755facc0 [ARM64_DYNAREC] Fix and improvments on rcl/rcr helper 2024-05-09 22:03:25 +02:00
ptitSeb d38f659f42 Changed the workaround for MiniMetro/Steam, using rcfile now (for #1311) 2024-05-09 21:59:32 +02:00
ptitSeb 6d95a64412 Added some virtual files (if missing) to allow wine to compute cache size and coherency (for #1381 on Snapdragon, but BG3 still not working, probably a graphic driver issue now) 2024-05-07 21:20:13 +02:00
ptitSeb 21336c527a Small fix on a libc wrapped function signature 2024-05-07 20:02:15 +02:00
ptitSeb 3db2362c86 [ELFLOADER] Small change in the parser (for #1493) 2024-05-05 17:35:48 +02:00
ptitSeb 99b7ef0c92 [VULKAN] Added VK_AMDX_shader_enqueue extension 2024-05-05 14:23:16 +02:00
ptitSeb ff030fcbec [ELFLOADER] Added a fix for Uniengine Heaven linux crashing at load, but might need something more generic at some point 2024-05-05 12:39:27 +02:00
ptitSeb ecf19029f5 [ARM64] Add 1 more case of unaligned device memory access handling, plus better tracking 2024-05-04 14:33:42 +02:00
Yang Liu 9494801d0b [DYNAREC] Small improvements to atomic functions (#1492)
* [DYNAREC] Small improvements to atomic functions

* Support older version of gcc
2024-05-04 13:11:45 +02:00
Yang Liu 1501592fa8 [LA64_DYNAREC] Added more opcodes (#1491) 2024-05-03 21:18:42 +02:00
ptitSeb 12467916a4 [DYNAREC] Re-introduce a simple HotPage handling, to speedup heavily obfuscated program loading 2024-05-03 18:42:03 +02:00
ptitSeb 6f0eb56621 [LA64_DYNAREC] Fixed another typo (should fix Celeste) 2024-05-03 13:24:55 +02:00
Yang Liu 31dabf51ae [LA64_DYNAREC] Added more opcodes (#1490) 2024-05-03 12:41:49 +02:00
ptitSeb 22fd100b04 [LA64_DYNAREC] Fixed some typos 2024-05-03 11:05:24 +02:00
Yang Liu 20092ef1ac [RV64_DYNAREC] Fixed OF flag computation (#1489) 2024-05-03 10:35:44 +02:00
Yang Liu aad6a16984 [LA64_DYNAREC] Added more opcodes (#1488) 2024-05-03 09:42:25 +02:00
ptitSeb 9b00df93c2 [LA64_DYNAREC] Fixing the fix, and leave a comment for future me in case I want to fix that again 2024-05-03 00:01:30 +02:00
ptitSeb f1da71a8fe [DYNAREC] Stop a block when a unimplemented opcode is found 2024-05-02 23:27:18 +02:00
ptitSeb efd182971a [LA64_DYNAREC] Fixed some lock assembly helper 2024-05-02 22:24:26 +02:00
Yang Liu 40c5125a92 Added wrapping of libicuuc64 and libicui18n64 (#1487) 2024-05-02 22:08:06 +02:00
Yang Liu 0f6654bf95 [LA64_DYNAREC] Added more opcodes (#1486) 2024-05-02 21:42:41 +02:00
ptitSeb fa27ddecc5 [TRACE] Remove a trace that might crash when tracing 2024-05-02 21:38:55 +02:00
Yang Liu e5be67b005 [DYNAREC][32BITS] Fixed and improved 66 prefix opcodes (#1485)
* [DYNAREC][32BITS] Improved 66 prefix opcodes

* more fixes

* Removed some unintentional changes

* removed unnecessary improvements
2024-05-02 19:44:50 +02:00
ptitSeb 85458d1f20 [ARM64_DYNAREC] Added rcr16 / rcl16 emitter, plus some tiny fixes to other rotate operations 2024-05-02 15:44:14 +02:00
ptitSeb 5b5723c5a5 [ARM64_DYNAREC] Some small fixes to rcl8 / rcr8 emitters 2024-05-02 14:31:26 +02:00
Yang Liu e148e89091 [RV64_DYNAREC] Remove useless code (#1484) 2024-05-02 10:15:02 +02:00
Yang Liu 1d0614f0f3 [RV64_DYNAREC] Added some missing fastnan handling (#1483) 2024-05-02 10:14:36 +02:00
Yang Liu 2405e6c8e8 [LA64_DYNAREC] Added more opcodes (#1482) 2024-05-01 21:37:41 +02:00
Yang Liu 817408d247 [LA64_DYNAREC] Added more opcodes (#1481) 2024-05-01 18:09:44 +02:00
ptitSeb 8d77e39f4a Added 1 more wrapped function to waylandclient lib 2024-05-01 15:15:35 +02:00
Yang Liu 0fe7e7a88d [LA64_DYNAREC] Added more opcodes (#1480) 2024-05-01 11:04:50 +02:00
Yang Liu 08bc57045a [LA64_DYNAREC] Fixed dynarec infra (#1479) 2024-05-01 11:03:58 +02:00
ptitSeb ee58b6a734 [RV64_DYNAREC] Optimized F0 0F C7 32bits opcode 2024-04-30 21:43:09 +02:00
ptitSeb 2907e5a0bd [RV64_DYNAREC] Fixed adc32 helper 2024-04-30 21:42:33 +02:00
ptitSeb 4f229629c0 [RV64_DYNAREC] Improved/fixed flag handling (ported from ARM64_DYNAREC) 2024-04-30 17:50:11 +02:00
ptitSeb f0fd2bc30c [RV64_DYNAREC] Fix some x87 flags issue 2024-04-30 16:38:54 +02:00
Yang Liu 86e9a38384 [COSIM] Added thread-safe tests (#1477)
* [COSIM] Added thread-safe tests

* Added more notest

* Run cosim in CI

* Disable tests for RISC-V for now

* Simplify

* Initialize notest
2024-04-30 16:36:48 +02:00
ptitSeb 322f97ddbc Fixed wrapped function signature for xcb_image_put (should help #1450) 2024-04-30 15:22:06 +02:00
ptitSeb 695865f408 [ARM64_DYNAREC] Added CE opcode 2024-04-30 15:02:34 +02:00
ptitSeb 1f9834dc6b [RCFILE] More aggressive profile for FlatOut and FlatOut 2 2024-04-29 22:51:00 +02:00
ptitSeb d1555a4c78 [ARM64_DYNAREC] Fixed some more issue on x87 handling 2024-04-29 22:50:24 +02:00
ptitSeb 5fc4477a94 [DYNAREC] Allocate Dynarec memory by 2Mb batch, and advise for hugepage if available 2024-04-29 12:12:40 +02:00
ptitSeb a5753ec0b5 This should fix non-dynarec build 2024-04-29 12:11:10 +02:00
ptitSeb f256c48505 Fixed non-dynarec build by introducing BOX64_JVM to replace BOX64_DYNAREC_JVM 2024-04-29 11:23:35 +02:00
ptitSeb 71c5447b8a Added a way to hide SSE 4.2, as it might slow down things using the string opcodes. Also, looks like some java program have issue with current implementation of pcmp[ei]str[im] somehow, so diabling automaticaly when detecting libjvm.so (for SlayTheSpire in particular) 2024-04-29 10:57:19 +02:00
ptitSeb a9a338ff42 [INTERPRETER] Fixed pcmp[ei]strm opcodes 2024-04-28 23:05:45 +02:00
ptitSeb 06a21d490b [ARM64_DYNAREC] Some fixes to pcmp[ei]strm opcodes 2024-04-28 22:16:29 +02:00
ptitSeb ef0c9bd429 [DYNAREC] Change method to detect dead code in block (fixes Spintires on Wow64, maybe some other too) 2024-04-28 17:20:52 +02:00
ptitSeb f619df2773 [ARM64_DYNAREC] Cosmetic change on FCOM helper macro 2024-04-28 17:20:13 +02:00
xctan 41ae74757e [RV64_DYNAREC] Fixed DIV and IDIV for zero divisor (#1476)
* [RV64_DYNAREC] Fixed DIV Ed and IDIV Ed for zero divisor

* [RV64_DYNAREC] Fixed DIV Ew and IDIV Ew for zero divisor

* [LA64_DYNAREC] Added todos for zero divisor
2024-04-28 15:27:10 +02:00
ptitSeb 2304738336 [ARM64_DYNAREC] Added some comment on ARM64 jump condition 2024-04-28 15:18:56 +02:00
ptitSeb e70a9ba485 Added some comment to x87 sw flags 2024-04-28 15:18:28 +02:00
ptitSeb 61a759f802 [TRACE] Added C3..C0 to x87 trace 2024-04-28 15:18:04 +02:00
ptitSeb 3cb61ff840 Added 3 more functions on wrapped sdl2 (for VVVVVV) 2024-04-27 19:24:07 +02:00
Yang Liu b7a07c3816 Fixed my_prepare_thread in dynarec build (#1474) 2024-04-27 18:34:56 +02:00
Yang Liu ae386b3a7d [LA64_DYNAREC] Added more opcodes (#1473)
* Added 66 0F PSHUFB opcode

* Added 66 0F PHADDW opcode

* Added 66 0F 38 02 PHADDD opcode

* Added 66 0F 38 03 PHADDSW opcode

* Added 66 0F 38 04 PMADDUBSW opcode

* Added 66 0F 38 05..0A opcodes

* Upgrade QEMU
2024-04-27 18:33:58 +02:00
ptitSeb 2b8a8314c5 Changed how wine prereserve is handled on box64 2024-04-27 17:07:33 +02:00
ptitSeb eb28edbe58 [DYNAREC] Fix some flag propagation with partial SF_SET/SF_SET_DF 2024-04-27 15:24:36 +02:00
Yang Liu 8d683fc19c [LA64_DYNAREC] Added more opcodes and fixes (#1472)
* Fixed SHUFPS again

* Added 0F 28 MOVAPS opcode

* Added 0F 2E/2F [U]COMISS opcodes

* Added F3 0F 5A CVTSS2SD opcode

* Added 66 0F 7E MOVD opcode

* Added 66 0F 28 MOVAPD opcode

* fastnan handling

* Added F3 0F 5D MINSS opcode

* Added F3 0F 5F MAXSS opcode

* Added F3 0F C2 CMPSS opcode
2024-04-27 12:14:46 +02:00
ptitSeb 0c50f724e6 [RCFILE] Added 2 more optimized profile for wine new wow64 games 2024-04-27 12:10:10 +02:00
ptitSeb d406946c2d [ARM64_DYNAREC] Improved x87 stack handling on transformCache helper (helps callret and bigblock on 32bits wow64 games) 2024-04-27 12:10:10 +02:00
Yang Liu 1c7e620a86 [LA64_DYNAREC] Added more useful extensions detection (#1469) 2024-04-26 19:34:14 +02:00
Yang Liu c40096e128 [LA64_DYNAREC] Added more opcodes (#1468)
* Added 0F BF MOVSX opcode

* Added F7 /5 IMUL opcode

* Added 86 XCHG opcode

* Added 66 0F PADDQ opcode

* Added 0F C6 SHUFPS opcode

* Added 66 0F 69 PUNPCKHWD opcode

* Added 66 0F DB PAND opcode

* Test

* Review

* Review
2024-04-26 19:13:06 +02:00
ptitSeb 43d2817407 [DYNAREC] Fixed an issue with flags when using SF_SET_NODF (fixed regression with Freedom Planet 2 Wine/Wow64, probably a few other too) 2024-04-26 18:17:42 +02:00
ptitSeb ff14ccc0a5 [DYNAREC] More fixes on BIGBLOCK 2024-04-26 17:50:16 +02:00
ptitSeb 1222fee0d0 [ARM64_DYNAREC] Added 0F B1 opcode 2024-04-26 15:41:11 +02:00
ptitSeb b184a184c4 [DYNAREC] Stop building a block if opcode is garbbage or not redeable (should help BIGBLOCK=2) 2024-04-26 15:20:35 +02:00
ptitSeb e5dcb3f100 [RCFILE] Added a profile for beyond-all-reason (for #1412) 2024-04-26 14:03:45 +02:00
Yang Liu 411fe19ee5 [RCFILE] Update weixin profile (#1467) 2024-04-25 23:28:30 +02:00
Yang Liu 1c040117ec [DYNAREC] Fixed emit_shift functions and more (#1466)
* [LA64_DYNAREC] Fixed emit_shift functions

* [RV64_DYNAREC] Fixed emit_shift functions and more

* Fixed la64 build
2024-04-25 20:17:36 +02:00
ptitSeb 856d2653bc [DYNAREC] Fix for some rare (or less rare depending on the backend) case of jump incorectly computed (regression from previous commit) 2024-04-24 18:12:15 +02:00
ptitSeb 2a79b60454 Changed x87 way of handling FFREE opcode ([DYNAREC] too, improving x87 robustness overall) 2024-04-24 15:34:54 +02:00
ptitSeb db32e49879 Made minimum rdtsc frequency to 2GHz (seems 1GHz is not enough for Horizon Zero Dawn) 2024-04-23 13:16:19 +02:00
ptitSeb 65d83bb6f4 Autocalibrate RDTSC clock to 1GHz minimum, instead of 500MHz (helps HorizonZeroDawn speed) 2024-04-22 19:19:31 +02:00
ptitSeb 17b7ec6358 [ARM64_DYNAREC] Small optim on flags handling 2024-04-22 18:59:57 +02:00
ptitSeb 73c3190c86 [ANDROID] Need to regen test27 based on latest sources, disabling for now 2024-04-22 17:31:00 +02:00
ptitSeb b6f58caf24 [ARM64_DYNAREC] Improved some specific cases of pcmpestri opcode 2024-04-22 17:14:53 +02:00
ptitSeb 8c19c3a72c [INTERPRETER] Improved SSE4.2 String opcodes, and improved test27 2024-04-22 17:14:13 +02:00
ptitSeb c017d3e894 [ANDROID] Fix doesn't work, disabling test07 again 2024-04-22 15:57:17 +02:00
ptitSeb 35696508fb [ANDOIRD] Fix build 2024-04-22 15:52:25 +02:00
ptitSeb 7e3996b0d9 [TRACE] Fixed some dumpreg when x87stack is incoherent 2024-04-22 15:50:44 +02:00
ptitSeb a7ec8e7c55 [ANDROID] Try to fix test 07 2024-04-22 15:49:19 +02:00
ptitSeb dfaa6896c1 [ARM64_PRINTER] Added SHL printer 2024-04-22 10:03:24 +02:00
ptitSeb b64e6bdbba [RCFILE] Added 2 more profiles 2024-04-20 18:42:03 +02:00
ptitSeb e0ef248943 [ARM64_PRINTER] Fix some case of DecodeBit not working for 64bits values 2024-04-20 15:10:24 +02:00
Lily cdcb0a46dc [RCFILE] Added Yandare Simulator Profile (#1459) 2024-04-20 12:04:54 +02:00
ptitSeb e82e1f9905 Added 1 more sdl2 function (for #1458) 2024-04-19 08:15:33 +02:00
ptitSeb cb6616bba1 Added 2 wrapped functions to sdl2 2024-04-18 09:57:04 +02:00
Yang Liu e0f0afdf91 Wrapped 1 more function for mpg123 (#1454) 2024-04-17 19:23:38 +02:00
ptitSeb 5120e74b36 Added 66 68 opcode ([ARM64_DYNAREC] too) 2024-04-17 17:14:19 +02:00
Yang Liu 8f5fa863bf [DYNAREC] Fixed CF flag computation (#1453) 2024-04-17 16:43:59 +02:00
ZoHan d4e32fdbc0 [RV64_DYNAREC] Added more opcodes (#1451)
* [RV64_DYNAREC] Added more opcodes

* modify the format
2024-04-17 09:27:50 +02:00
Yang Liu 067cf75c65 [LA64_DYNAREC] Added more opcodes (#1447)
* Added B4..B7 MOV opcode

* Added 66 81,83 /5 SUB opcode

* Added 30 XOR opcode

* Added F0 01 LOCK ADD opcode

* Added 66 81,83 /0 ADD opcode

* Added 66 39 CMP opcode

* Added 66 0F D6 MOVQ opcode

* Added 0F 57 XORPS opcode

* Fix

* Added 66 0F 61 opcode
2024-04-14 20:39:31 +02:00
Yang Liu 7f16ddacf7 [LA64_DYNAREC] Added 1 more opcode and some fixes too (#1444)
* Added D3 /0 ROL opcode

* Refined emit_sub32c

* Fixed BSF and BSR
2024-04-14 12:47:42 +02:00
Yang Liu d936c072ea [DYNAREC] Fixed shift xw macros (#1443) 2024-04-14 09:26:42 +02:00
ptitSeb 7dee075c10 Fixed a few warning here and there... 2024-04-13 14:43:30 +02:00
Yang Liu b9ea2408c2 [LA64_DYNAREC] Added more opcodes (#1441)
* Added 66 C7 MOV opcode

* Added B0..B3 MOV opcode

* Added F0 87 LOCK XCHG opcode

* Added 35 XOR opcode

* Added F7 /7 IDIV opcode

* Added BC BSF opcode

* Added BD BSR opcode
2024-04-12 21:58:05 +02:00
ptitSeb 6ce570f4a5 Revert some cpuid changes, they are more wrong then right it seems 2024-04-12 18:14:51 +02:00
Yang Liu b95b99b3c9 [RV64_DYNAREC] Fixed 66 C7 MOV opcode (#1440) 2024-04-12 17:51:55 +02:00
Yang Liu 139197230d [LA64_DYNAREC] Added more opcodes and fixed more issues (#1439)
* Added F3 0F 10 MOVSS opcodes

* Added F3 0F 2A CVTSI2SS opcode

* Added F3 0F 5E opcode

* Added F3 0F 11 MOVSS opcode

* Added 0C OR opcode

* Added F3 0F 59 MULSS opcode

* Added 81,83 /3 SBB opcode

* Fixed 2 typos
2024-04-12 13:55:46 +02:00
Yang Liu 1d0e0307c4 [LA64_DYNAREC] Made the CALLRET optimization complete (#1438) 2024-04-12 13:13:30 +02:00
kaixindeken f94ab1be6f [RV64_DYNAREC] Implementation of some CRC32 instructions (#1435)
* [RV64_Dynarec] Implementation of some CRC32 instructions

* Use BEXTI to detect the lowest bit

* Prefer ANDI for lowest bit checking
2024-04-12 08:06:45 +02:00
Yang Liu 05c7596acb [LA64_DYNAREC] Small fix on emit_or32c LBT path (#1436) 2024-04-11 18:55:35 +02:00
Yang Liu b38d51ce37 [LA64_DYNAREC] Added more opcodes to the printer (#1433)
* Use ROTR

* Added more opcodes to the printer

* Added even more opcode to the printer

* Fixed typos

* More
2024-04-10 18:25:57 +02:00
Hypothalamus 5c0d765f59 Add Oxygen Not Included to box64rc based on https://github.com/ptitSeb/box86-compatibility-list/issues/298 (#1431)
Reported-by: ricoazzurro
2024-04-10 17:56:02 +02:00
Yang Liu db35542706 [LA64_DYNAREC] Refined MOV64 macros (#1430) 2024-04-09 18:33:41 +02:00
ptitSeb eda857cb10 Added 1 more function to icuucXX wrapped libs (for #1428) 2024-04-08 23:19:06 +02:00
ptitSeb b77c8fe5f1 [DYNAREC] Enabled larger dynablock 2024-04-07 19:23:44 +02:00
ptitSeb 0d864ed848 [ARM64_DYNAREC] Small change to stay in sync with other backend 2024-04-07 17:00:41 +02:00
Yang Liu 7c613198ce Fixed 0F A3 BT opcode (#1427) 2024-04-07 13:29:38 +02:00
xctan 1ca68a58fd [RV64_DYNAREC] Fixed various bugs in shift instructions (#1426)
* [RV64_DYNAREC] Optimized 8-bit constant shifts

* [RV64_DYNAREC] Fixed shl8c when c > 8

* [RV64_DYNAREC] Optimized 16-bit constant shifts

* [RV64_DYNAREC] Optimized 8-bit CL shifts

* [RV64_DYNAREC] Fixed SF generation of 32-bit SHL Ed, CL

* [RV64_DYNAREC] Optimized 16-bit CL shifts

* [RV64_DYNAREC] Fixed typo in 8-bit CL SHL and SHR

* [RV64_DYNAREC] Fixed the wrong mask in 8-bit SHL Eb, CL

* [RV64_DYNAREC] Fixed typo in SAR Ew, CL
2024-04-07 10:39:58 +02:00
Yang Liu b96139274f [LA64_DYNAREC] Added more opcodes (#1425)
* Added 0B OR opcode

* Added D3 /7 SAR opcode

* Added D3 /5 SHR opcode

* Added 80 /1 OR opcode

* Addeded  66 0F BE MOVSX opcode

* Fixed SRAxw

* Fix

* Added 0F C8..CF BSWAP opcode

* Added more opcodes
2024-04-06 14:45:22 +02:00
Yang Liu d84faf57ab [LA64_DYNAREC] Added more opcodes (#1424)
* [LA64_DYNAREC] Added 66 C1 /5 SHR opcode

* Added 69 IMUL opcode

* Added F7 /6 DIV opcode

* Added 6B IMUL opcode

* Added C1 /1 ROR opcode

* [LA64_DYNAREC] Added 87 XCHG opcode
2024-04-06 12:46:14 +02:00
Yang Liu 89f0c494e4 [LA64_DYNAREC] Added more opcode and fixes (#1423)
* Fixed F2 0F MOVSD opcode

* Added F3 0F 6F MOVDQU opcode

* Added F2,F3 A5 MOVSD opcode

* Added 80 /5 SUB opcode

* Fixed a typo in .clang-format

* Added 66 85 TEST opcode and a fix
2024-04-06 11:38:04 +02:00
Yang Liu 24f9263fa4 [LA64_DYNAREC] Added more opcodes (#1422)
* Added 1C SBB opcode

* Added 3A CMP opcode

* Added 38 CMP opcode

* Added 81,83 /6 XOR opcode

* Added F7 /4 MUL opcode
2024-04-06 10:50:10 +02:00
Haichen Wu 5f4f9337cd [LA64_DYNAREC] Added more SSE/SSE2 instructions (#1421)
* [LA64_DYNAREC] Added more SSE/SSE2 instructions

* [LA64_DYNAREC] Added more SSE/SSE2 instructions
2024-04-06 10:46:45 +02:00
Yang Liu 2a75d28386 [LA64_DYNAREC] Fixed missing LBT path and more (#1419)
* [LA64_DYNAREC] Fixed missing LBT path and more

* Fixed D3 /4/6 SHL opcode

* LA64 qemu is not stable too
2024-04-06 08:49:37 +02:00
Yang Liu 3e41289167 [DYNAREC] Fixed REP opcodes for correct register state recovery (#1420) 2024-04-06 08:48:00 +02:00
Yang Liu 9cf5373724 [LA64_DYNAREC] Added more opcodes (#1418)
* Added 0F A3 BT opcode

* Added 3C CMP opcode

* Added C0 /4/5/6/7 opcodes

* Added 6A PUSH opcode

* Added F2,F3 A6 CMPSB opcode
2024-04-05 20:11:09 +02:00
Yang Liu 6c5d35df6b [LA64_DYNAREC] Added more opcodes (#1417)
* Added 64 8B MOV opcode

* Added 64 33 XOR opcode

* Added 19 SBB opcode

* Smol fix
2024-04-05 17:56:24 +02:00
Yang Liu 4d26021705 [LA64_DYNAREC] Added more opcodes (#1416)
* [LA64_DYNAREC] Added 0F AF IMUL opcode

* Update clang-format rules

* Added 08 OR opcode

* Added F7 /3 NEG opcode and fixed some potential bugs
2024-04-05 16:34:59 +02:00
Yang Liu 2e9b8eff59 [LA64_DYNAREC] Fixed SSE issues (#1415)
* [LA64_DYNAREC] Fixed SSE issues

* Fixed MOVSD modreg
2024-04-05 11:55:41 +02:00
Haichen Wu a4142f68ce [LA64_DYNAREC] Added more SSE/SSE2 instructions (#1410) 2024-04-04 13:43:30 +02:00
ptitSeb 4a889e39ad Wrapped some more functions to gstreamer-1.0 and friends (for #1397) 2024-04-03 17:20:29 +02:00
ptitSeb d206d69b25 Wrapped 2 more functionto gstreamer-1.0 (for #1397) 2024-04-03 17:06:01 +02:00
ptitSeb 83e92d6298 Wrapped GstAudioFilter (for #1397) 2024-04-03 16:55:56 +02:00
ptitSeb e080551d54 [RCFILE] Make sure strdup is coherent with free 2024-04-03 16:43:01 +02:00
ptitSeb b40195d26d [INTERPRETER] Added aligned path to F0 0F C7 opcode 2024-04-03 16:43:01 +02:00
Yang Liu 316abec693 [RV64_DYNAREC] Added 0F 70 PSHUFW opcode (#1408) 2024-04-03 12:09:57 +02:00
ZoHan af685a263b [RV64_DYNAREC] Add 1E/1F opcode (#1407)
* [RV64_DYNAREC] Add 1E/1F opcode

* modify the format

* modify the format
2024-04-03 12:04:07 +02:00
ZoHan 31e8afa622 [RV64_DYNAREC] Add more opcodes (#1405)
* [RV64_DYNAREC] Add more opcodes

* modify the format
2024-04-03 08:01:49 +02:00
Yang Liu 1d500ad965 Force the use of spaces in .clang-format (#1406) 2024-04-03 07:38:31 +02:00
ptitSeb a8866c3f41 [ARM64_DYNAREC] Better fix for #1366, that should help #1383) 2024-04-02 23:21:21 +02:00
ptitSeb f64eca5d9b [DYNAREC] Small fixed on dynarec block protection 2024-04-02 23:21:21 +02:00
Yang Liu bdd5e7018a Create libssl/libcrypto symlinks (#1402) 2024-04-02 18:44:47 +02:00
ptitSeb 3d211143e0 [ELFLOADER] Fixed some residual issue with elfloader (espacially on non-4K pagesize) (should help #1398 #1271 maybe help #939 and probably others) 2024-04-02 15:49:51 +02:00
ptitSeb c1c11d8daa [DYNAREC] Improved CancelBlock function (might help #1383) 2024-04-02 15:42:00 +02:00
Yang Liu 0505b19378 [RV64_DYNAREC] Fixed some issue with x87 stack managment (ported from ARM64) (#1401) 2024-04-02 15:34:49 +02:00
ptitSeb e18e532846 Added wrapped libicuuc73 and libicui18n73 2024-04-02 15:16:26 +02:00
Yang Liu 10cec3de2f [LA64_DYNAREC] Added more SSE/SSE2 instructions (#1400)
* [LA64_DYNAREC] Added more SSE/SSE2 instructions

* Thank you test16
2024-04-02 13:44:40 +02:00
Yang Liu 76c0992d02 [LA64_DYNAREC] Fixed EBBACK (#1399) 2024-04-02 09:24:12 +02:00
ptitSeb e32a78a944 Added a couple of symbols to wrapped libcms2 and libgstaudio-1.0 2024-04-01 08:27:01 +02:00
ptitSeb 68d710cd94 [ARM64_DYNAREC] Fixed some issue with x87 stack managment 2024-03-29 11:05:53 +01:00
olegos2 da64a3eeab Add BOX64_RCFILE variable (#1392)
* Implement BOX64_RCFILE

* Update USAGE.md

* Should fix tests
2024-03-28 21:08:53 +01:00
Yang Liu 912622bf1f [LA64_DYNAREC] Added basic SSE infra and 66 0F 6E MOVD opcode (#1391) 2024-03-28 14:17:26 +01:00
Jiarui Wang 70fec208d8 update clang-format for IFX and QUOTE (#1390)
* update clang-format

* refactor: add more ifmacros
2024-03-28 12:44:33 +01:00
ptitSeb e1f69b9c61 Improve memory handling for wine, again 2024-03-27 15:01:16 +01:00
ptitSeb 81f25b219f Added some path for termux/glibc builds 2024-03-27 11:16:26 +01:00
ptitSeb d191b8c090 [ARM64_DYNAREC] More check to abort a block if x87 stack cache is incoherent 2024-03-26 16:24:17 +01:00
ptitSeb d53ff127ed Fixed some warning 2024-03-25 18:18:09 +01:00
howard97andhoward 50caca8fdc [REFACTOR] Refactor main.c (#1362)
Co-authored-by: howard <[email protected]>
2024-03-25 17:42:01 +01:00
ptitSeb 1dca97b4d3 Added 66 0F BF opcode 2024-03-21 04:08:14 +01:00
Yang Liu 14cf474167 [LA64_DYNAREC] Added CMOVcc opcodes and some fixes too (#1375) 2024-03-20 17:32:28 +01:00
Yang Liu 47b1203805 [LA64_DYNAREC] Added some FP/LSX/LASX instructions to the emitter (#1374)
* [LA64_DYNAREC] Added FP instructions to the emitter

* [LA64_DYNAREC] Added some LSX/LASX instructions to the emitter
2024-03-20 17:29:47 +01:00
ptitSeb 81ca016581 [DYNAREC] This should fix some issue with dynarec, like #1366 (but should be revisited soon, to many bytes writen there) 2024-03-19 02:30:22 +01:00
ptitSeb cd8bda7a29 Changed, again, RDTSC and Hardware counter, introducing auto calibration when hardware counter is too slow for modern standard (and removed BOX64_RDTSC env. var.) 2024-03-14 11:01:40 +01:00
ptitSeb 8115b47051 Added 64 66 83 opcodes ([ARM64_DYNAREC] too) 2024-03-14 10:01:00 +01:00
Tristan Morgan 6384cc6e86 Update GH-Actions workflows to remove Node.js deprecation warning. (#1359) 2024-03-14 08:36:53 +01:00
ptitSeb 2f68df2b5f [ARM64_DYNAREC] Try to improve strongmem=4 method, with a completly different approach 2024-03-13 18:17:37 +01:00
ptitSeb ed2697d6ad [RCFILE] Fixed some issues with wine program detection 2024-03-12 16:43:10 +01:00
ptitSeb df928fd2d0 [RCFILE] Added 2 new rcfile only option, and try to apply wine program parameter earlier, before wien load to be able to change command line and maxcpu 2024-03-12 11:39:11 +01:00
ptitSeb 52c50a2fd4 Changed in commented code, for more internal use 2024-03-12 11:36:31 +01:00
ptitSeb 666d051806 Changed how cpu cores are reported in cpuid for large number (>64) 2024-03-12 11:33:44 +01:00
Yang Liu 1e80316a7d [LA64_DYNAREC] Added more LBT instructions to the printer (#1356) 2024-03-11 15:35:43 +01:00
ptitSeb 65404cba33 Do not expose FMA cpu extension, it's associated to AVX by some engines 2024-03-11 15:22:08 +01:00
Yang Liu ac0519a046 [LA64_DYNAREC] Added more opcodes and some fixes (#1355)
* Added F0 B1 /0 LOCK CMPXCHG opcode

* Added 0F BE MOVSX opcode

* Added 81/83 /7 CMP opcodes

* Fixed emit_shl32c

* Added missing default

* Added A0 MOV opcode
2024-03-11 12:27:52 +01:00
Yang Liu 90a6306bbe [LA64_DYNAREC] Added more opcodes (#1354)
* Added 38 CMP opcode

* Added 0F B6 MOVZX opcode

* Added 88 MOV opcode

* Fixed 0F B6 MOVZX opcode

* Added 81/83 LOCK ADD opcodes

* Added 98 CWDE opcode

* Rebase
2024-03-11 09:05:10 +01:00
ptitSeb a5a7d9382e [DYNAREC] Limit temporary memory allocation on FillBlock64 2024-03-10 20:45:26 +01:00
ptitSeb bc770d908a [VULKAN] Added 1 more NV extension 2024-03-10 15:23:13 +01:00
ptitSeb 20724ceb17 [ELFLOADER] small change on free elf memory 2024-03-10 13:52:21 +01:00
ptitSeb 6ae6ac0272 [TRACE] Slighlty better log when emiting SIGILL 2024-03-10 13:51:38 +01:00
ptitSeb 5aa5015348 [TRACE] slignthly better log for ExitEmulation bridge 2024-03-10 13:50:52 +01:00
ptitSeb 411aecde6f Don't expose BMI1 for now, it's not really supported 2024-03-10 13:49:58 +01:00
ptitSeb e89b93285e [ARM64_DYNAREC] Added 64/65 0B opcode 2024-03-10 13:49:13 +01:00
ptitSeb 4e702cfeda [ARM64_DYNAREC] Fixed printer for MVN with shift 2024-03-10 13:48:40 +01:00
ptitSeb 33846405d8 Improved unload of libs (help wine when dlopen / dlclose is supposed to unload the lib so it can be dlopen again) 2024-03-09 14:10:09 +01:00
ptitSeb 378eb79ad3 Put back 8 slots for xcb_connection_t wrapping 2024-03-09 14:08:51 +01:00
ptitSeb da71b81d01 Don't try to load libstdc++ when loaing libGL if it's wine (helps mobox, maybe other android version of box64 too) 2024-03-09 08:57:16 +01:00
ptitSeb 35d734e6ac [TRACE] Better trace for (f)getxattr 2024-03-08 18:35:32 +01:00
ptitSeb 3937fc4b71 [DYNAREC] Small changeon the critical section handling of custommem 2024-03-08 18:17:08 +01:00
ptitSeb 5debac4c98 Change wrapping of _exit to just exit immediatly as expected 2024-03-08 18:16:36 +01:00
ptitSeb 3737abe081 [ARM64_DYNAREC][RV64_DYNAREC] Fixed some case where MOVS/B/W/D/Q is used on a protected page of code, and SI gets wrongly incremented (for #1347) 2024-03-08 18:01:33 +01:00
ptitSeb d0013c0700 [INTERPRETER] Added 64 EB opcode (for #1347) 2024-03-08 16:59:48 +01:00
ptitSeb 460277289b POPF opcode should not overwrite IF bit 2024-03-08 16:47:00 +01:00
ptitSeb 35ed305718 [ARM64_DYNAREC] Added 66 64 0F 6F opcode (for #1349) 2024-03-08 15:01:17 +01:00
ptitSeb d3c57eecbc [INTERPRETER] Added 66 64 0F 6F opcode (for #1349) 2024-03-08 15:00:47 +01:00
ptitSeb ad75da8502 [ARM64_DYNAREC] Added 67 64 8B opcode 2024-03-08 14:03:55 +01:00
ptitSeb c7c6880a01 [ARM64_DYNAREC] Added 67 64 8F opcode 2024-03-08 13:55:00 +01:00
ptitSeb 5ed3ef918d [INTERPRETER] Added 67 64 8F opcodes, and fixed 67 64 89/8B opcodes 2024-03-08 13:54:34 +01:00
ptitSeb c0f78342e1 [ARM64_DYNAREC] Improved MOV32w and MOV64x with a funciton with more speciall cases 2024-03-08 12:05:09 +01:00
Yang Liu 75494978ad [DYNAREC] Revert some fasly changes to the shift opcodes (#1346)
* [DYNAREC] Revert some fasly changes to the shift opcodes

* Prefer ZEROUP

* More fixes

* Fixed one more typo

* Should not revert this

* Fix fix fix
2024-03-08 11:51:39 +01:00
Yang Liu 602c015321 [DYNAREC] Made shift operations handle count==0 more uniformly (#1345) 2024-03-08 10:34:28 +01:00
Yang Liu 55c2c9ee59 [ARM64_DYNAREC] Fixed a falsy optimization on PSHUFHW (#1344)
* [ARM64_DYNAREC] Reverted a falsy optimization on PSHUFHW

* Fix it instead of a lazy revert
2024-03-08 08:39:05 +01:00
ptitSeb 8fef5f2c69 [ARM64_DYNAREC] Use convert_bitmask in logic emitters and in MAX32w and MOV64x 2024-03-07 21:25:11 +01:00
ptitSeb 9a4a62ff2d [ARM64_DYNAREC] Added 0F E1 opcode 2024-03-07 18:51:53 +01:00
ptitSeb 4ebc462e23 Added 1 more syscall 2024-03-07 18:49:25 +01:00
Haichen Wu 08e93a0fe9 [LA64_DYNAREC] Added C1 /4 and /6 opcodes and some fix (#1341)
* [LA64_DYNAREC] Added C1 /4 and /6 opcodes

* [LA64_DYNAREC] Some fix of C1 opcodes
2024-03-07 17:49:24 +01:00
rajdakin 4096869c50 [ARM] Added immediate encoding (#1340) 2024-03-07 17:48:35 +01:00
ptitSeb 3cd87e68c7 [RCFILE] Added profile for Capcom Arcade Statium 2024-03-07 17:48:17 +01:00
ptitSeb 7165ff7b84 More work on X11 wrapping, allowing gtk to run fully emulated 2024-03-07 17:31:40 +01:00
ptitSeb 81d906fd3b More wrapped functions on libs harfbuzz and fontconfig 2024-03-07 14:55:05 +01:00
ptitSeb b51bdf3d5e [NOGTK] libpangoft2 is also part of the gtk family 2024-03-07 14:41:59 +01:00
ptitSeb c8ca7876c3 [ARM64_DYNAREC] Slightly better trace when dynarec log unknown opcode 2024-03-07 14:41:28 +01:00
ptitSeb c181a6dcc8 [INTERPRETER] Generate a SIGILL when executing 3F opcode in 64bits 2024-03-07 14:40:43 +01:00
ptitSeb b763c22ef4 [TRACE] Improved logs on NULL-sized block 2024-03-07 14:40:02 +01:00
ptitSeb 5c83475c95 [VULKAN] Added one more vulkan extension 2024-03-07 14:15:23 +01:00
ptitSeb 1d1670864b [ARM64_DYNAREC] Fixed F0 0F AB opcode 2024-03-07 14:14:48 +01:00
ptitSeb 5e980767b9 [ARM64] Added 1 more special case of SIGBUS when accessing device memory (Help Planet Coaster on NVidia) 2024-03-07 13:42:36 +01:00
ptitSeb 2b3c9b95af Some work on gtk and co wrapping 2024-03-07 11:11:47 +01:00
ptitSeb 09232ad0b6 [ARM64_DYNAREC] A bot more work on shift opcodes 2024-03-07 10:17:39 +01:00
ptitSeb 2533197a3c [ARM64_DYNAREC] Small optim to SAHF & more cosmetics stuffs 2024-03-06 16:46:33 +01:00
ptitSeb 71c43b0de7 Added 1 more function to libpng16 2024-03-06 16:45:50 +01:00
ptitSeb 6606b7b097 Add more slot to gobject2 callbacks 2024-03-06 16:45:36 +01:00
Lily 5c994ff222 some gcrypt wrapping (#1338)
* some gcrypt wrapping (needed to check sign)

* little more wrapping in gcrypt

* correcting sign
2024-03-06 16:12:16 +01:00
ptitSeb 9372b96e47 Some more improvment to xcb wrapping 2024-03-06 15:20:31 +01:00
ptitSeb 24e133e006 Added back full handling of winepreloader prereserve memory 2024-03-06 12:41:39 +01:00
Yang Liu 995fa013a6 Fixed a warning (#1335)
* Fixed some warnings

* Revert
2024-03-06 11:14:01 +01:00
ptitSeb 4af1f56713 Improved wrapping of xcb (xcb_XXX_iterator_t and xcb_contection_t) 2024-03-06 11:11:36 +01:00
Yang Liu 584b258241 [RV64_DYNAREC] Added 66 0F 38 61 PCMPESTRI opcode and some refactors too (#1337) 2024-03-06 09:58:04 +01:00
Yang Liu fb13ce2baf [ARM64_DYNAREC] Fixed some typos (#1336) 2024-03-06 09:56:12 +01:00
Lily f910a70c8a Added 2 pthread wraps (#1334) 2024-03-05 19:52:14 +01:00
Yang Liu fedb8bd816 [LA64_DYNAREC] Added more opcodes and more instructions in emitter and printer (#1332) 2024-03-05 17:59:15 +01:00
Yang Liu c3f97dd730 [LA64_DYNAREC] Added more opcodes and some fixes too (#1331)
* [LA64_DYNAREC] Added 66 90..97 NOP/XCHG opcodes

* Added AB REP STOSD opcode

* Fixed a bug in emit_sar32c

* [LA64_DYNAREC] Added 0F B7 MOVZX opcode

* Why I keep forgetting the TO_LA64 thing?!

* Added 20..24 AND opcodes
2024-03-05 16:29:52 +01:00
ptitSeb b1ebf9dc79 Added 1 more function to libXrandr (should fix VampireSurvivors 1.9+) 2024-03-05 16:07:25 +01:00
ptitSeb d07ea96570 Adjusted dependancies for some X11 libs 2024-03-05 15:59:51 +01:00
ptitSeb dc3bdd89c1 Added a few more flags on of_convert to limit warnings 2024-03-05 15:59:27 +01:00
Yang Liu 7e92c912b2 [LA64_DYNAREC] Added more opcodes and some fixes in the printer (#1330)
* Added 90..97 NOP/XCHG opcodes

* More instructions and fixes to the emitter and printer

* Added F0 0F C1 LOCK XADD opcode

* Fix

* Fix
2024-03-05 12:03:41 +01:00
Yang Liu 5d5c3aec3c [LA64_DYNAREC] Made eflags synchronization lazy (#1329)
* [LA64_DYNAREC] Made eflags synchronization lazy

* A smol optim

* Fixed CLEAR_FLAGS
2024-03-05 09:49:19 +01:00
Yang Liu 0ba63ea272 [LA64_DYNAREC] Added more opcodes (#1327)
* [LA64_DYNAREC] Added F7 /2 NOT opcode

* [LA64_DYNAREC] Added 09 OR opcode

* [LA64_DYNAREC] Added 64 MOVSXD opcode

* [LA64_DYNAREC] Added more instructions to the emitter and printer, and fixed typos

* Remove unused code

* [LA64_DYNAREC] Added  D3 /4 /6 SHL opcode

* [LA64_DYNAREC] Added 0D OR opcode

* [LA64_DYNAREC] Fixed a bug when LBT is present

* Revert
2024-03-04 22:07:11 +01:00
Yang Liu a242a8e277 [LA64_DYNAREC] Added more and more opcodes (#1326)
* [LA64_DYNAREC] Added 81/83 /1 OR opcode

* [LA64_DYNAREC] Added F6 /0 /1 TEST opcode

* Added A9 TEST opcode

* Added A8 TEST opcode

* [LA64_DYNAREC] Added 80 /4 AND opcode

* [LA64_DYNAREC] Added 0F 90..9F SETcc opcodes

* [LA64_DYNAREC] Added 84 TEST opcode

* [LA64_DYNAREC] Added 0F 01 XGETBV opcode

* [LA64_DYNAREC] Added E0..E3 opcodes
2024-03-04 19:35:37 +01:00
Yang Liu cc86e94cd5 [LA64] Detect the existence of LBT extension (#1325) 2024-03-04 17:49:57 +01:00
Yang Liu 1c10ae443d [LA64_DYNAREC] Utilizing bitmanip instructions because they're great (#1324)
* [LA64_DYNAREC] Added bitmanip instructions to emitter and printer

* [LA64_DYNAREC] Utilizing bitmanip instructions because they're great

* Review
2024-03-04 17:48:59 +01:00
ptitSeb d44f3d9bae [ARM64_DYNAREC] Small optims for SSE/SSE2 & strongmem>1 2024-03-04 17:20:56 +01:00
ptitSeb d71e5f968a Added DF D0..D7 ([ARM64_DYNAREC] too) 2024-03-04 16:21:44 +01:00
ptitSeb 4aa9fba4fa [ARM64_DYNAREC] Stop a block on CC opcode (unless they are ignored) 2024-03-04 16:21:22 +01:00
xctan 8aaaddde03 [WRAPPER] Fixed a typo in the signature of my___libc_start_main (#1323) 2024-03-04 15:16:20 +01:00
Haichen Wu d5176ba278 [LA64_DYNAREC] Added more opcodes (#1322) 2024-03-04 15:15:22 +01:00
ptitSeb 13a8108e1e Added 2 more symbols to wrapped libicuuc 2024-03-04 15:08:53 +01:00
ptitSeb 82b19f6f69 Added a few more libc wrapped functions 2024-03-04 13:52:36 +01:00
ptitSeb 9e37dd008d [ELFLOADER] Fixes some issue with symbol version matching and unload of failled libs (for #1311, probably other too) 2024-03-04 13:40:57 +01:00
ptitSeb 5b1057fe08 [TRACE] Better trace when trying to run on very low address 2024-03-04 13:40:57 +01:00
ptitSeb 460fa3f3d7 Added libstdc++ when loading libGL (only if libgcc_s is already loaded), helps some linux Unity games 2024-03-04 13:40:57 +01:00
Yang Liu 61de3532c2 [LA64_DYNAREC] Added more opcodes (#1321)
* [LA64_DYNAREC] Added 0F 80..8F Jcc opcodes

* [LA64_DYNAREC] Added 31/33 XOR opcodes

* [LA64_DYNAREC] Added 0F A2 CPUID opcode

* [LA64_DYNAREC] Added 81/83 /4 AND opcode

* [LA64_DYNAREC] Added 25 AND opcode

* [LA64_DYNAREC] Added F7 /0 /1 TEST opcodes

* Fix
2024-03-04 11:36:27 +01:00
ptitSeb ddfc699809 Added 64 66 0F 7F opcode ([ARM64_DYNAREC] too) (for #1320) 2024-03-04 09:43:43 +01:00
Yang Liu d0edf2e8dd [LA64_DYNAREC] Added more opcodes and more fixes, SuperHexagon is working (#1319)
* Made printer slightly better

* [SIGNAL] Fixed a typo

* Removed useless comma

* Another typo

* Keep'em in order

* Added more opcodes and more fixes

* A big fix of GOCOND macro

* [LA64_DYNAREC] Added E8 CALL opcode

* [LA64_DYNAREC] Added C6 MOV opcode

* [LA64_DYNAREC] Added 39 CMP opcode

* [LA64_DYNAREC] Added 0F 1F NOP opcode

* BEWARE: shift instructions are NOT sign-extended!

* More fixes

* Try to be safe

* Fixed printer

* Fixed emitter & printer for B, briing superhexagon back
2024-03-03 21:41:31 +01:00
Yang Liu a159cb5efe [LA64_DYNAREC] Enable co-simulation and fixed an important issue (#1317) 2024-03-03 08:50:48 +01:00
Yang Liu 26371bb9dd Added a warning on interpreter only build when DynaRec is available (#1316) 2024-03-03 08:49:45 +01:00
Yang Liu de4ffcc8bc [LA64_DYNAREC] Added more and more opcodes (#1314)
* [LA64_DYNAREC] Added C1 /5 SHR opcode

* [LA64_DYNAREC] Added C1 /7 SAR opcode

* [LA64_DYNAREC] Added D1 /7 SAR opcode

* [LA64_DYNAREC] Added D1 /5 SHR opcode

* [LA64_DYNAREC] Added FF /4 JMP opcode

* [LA64_DYNAREC] Added 66 0F 1F NOP opcode

* [LA64_DYNAREC] Added B8..BF MOV opcodes

* [LA64_DYNAREC] Added C7 MOV opcode

* [LA64_DYNAREC] Added 0F 05 SYSCALL opcode
2024-03-02 20:10:04 +01:00
Yang Liu ebaedca708 [LA64_DYNAREC] Added more opcodes (#1313)
* [LA64_DYNAREC] Added F30F 1E NOP opcode

* [LA64_DYNAREC] Added E9/EB JMP opcodes
2024-03-02 18:26:07 +01:00
Yang Liu a86f597239 [LA64_DYNAREC] Added CC native call support, fixed call_c (#1312) 2024-03-02 18:10:44 +01:00
ptitSeb b72d3a77e9 [ARM64_DYNAREC] More fixes and optim on IMUL flags 2024-03-02 17:31:47 +01:00
ptitSeb 64fdf54156 [ARM64_DYNAREC] Fixed flags for 69 opcode, and small optim for 0F AF opcode 2024-03-02 16:36:54 +01:00
ptitSeb 463e31251f [ARM64_DYNAREC] Small optim on some cases of F2 0F 70 opcode 2024-03-02 14:09:31 +01:00
ptitSeb 9032f24a56 [ARM64_DYNAREC] Small optim on flag computation for 69 opcode 2024-03-02 14:05:17 +01:00
Yang Liu c5828803c6 [LA64_DYNAREC] Added more opcodes with CALL/RET optimization (#1310)
* [LA64_DYNAREC] Added FF /2 CALL Ed opcode

* [LA64_DYNAREC] Added 81/83 /0 ADD opcode

* [LA64_DYNAREC] Added C3 RET opcode
2024-03-02 13:11:20 +01:00
Yang Liu 9883c6464e [LA64_DYNAREC] Adopt to ARM64 way of CALL/RET optim since there is a dedicated register (#1309) 2024-03-02 11:14:48 +01:00
ptitSeb 67006f2809 [LA64_DYNAREC] Added xSavedSP to emitter for later use 2024-03-02 10:10:42 +01:00
ptitSeb e49728aa82 Added more hardware contributor, thanks! 2024-03-02 10:00:37 +01:00
Yang Liu 829c254b1f [LA64_DYNAREC] Added 70-7F Jcc opcodes, refine printer and some fixes too (#1307)
* [LA64_DYNAREC] Added 70-7F Jcc opcodes and some fixes too

* [LA64_DYNAREC] Added more instructions to the printer and made the format prettier

* Make LBT truely optional

* Do not test LBT in CI

* Format

* Optimize

* Fixed printer format

* Fixed CLEAR_FLAGS macro

* Fixed xMASK

* Use $r22 ($sp) in the prolog/epilog for better semantics

* Fixed la64_next
2024-03-02 09:45:55 +01:00
ptitSeb 8bf54eda56 Added 66 F8/F9 ([ARM64_DYNAREC] too) 2024-03-01 20:35:15 +01:00
Yang Liu c58adce8f6 [LA64_DYNAREC] Added 1 more opcode and more fixes (#1305)
* Fixed printer name mapping

* Fixed emit_sub32c

* Remove a useless macro

* Added 85 TEST opcode
2024-02-29 19:33:36 +01:00
Yang Liu 92532b0fd1 [LA64_DYNAREC] Added more opcodes and fixed more things (#1304)
* [LA64_DYNAREC] Fixed GETED macro

* [LA64_DYNAREC] Added 81/83 /5 SUB opcode

* Use xMASK when possible

* Added 8B MOV opcode

* Fix
2024-02-29 17:48:23 +01:00
Yang Liu 8cba5d55ce [LA64_DYNAREC] Added LBT support to all implemented emit functions and fixed some typos (#1303) 2024-02-29 17:10:47 +01:00
Yang Liu da1ac7beee [LA64_DYNAREC] Added basic LBT support, setup xMASK (#1302)
* [LA64] Added basic LBT support, setup xMASK

* [CI] Run tests without LBT
2024-02-29 16:11:52 +01:00
Yang Liu 28b79626d9 [LA64_DYNAREC] Removed F_OF2 trick as it's unnecessary (#1300) 2024-02-29 15:13:35 +01:00
Yang Liu 867059dfae [LA64_DYNAREC] Added some LBT instructions (#1299) 2024-02-29 14:05:52 +01:00
ptitSeb 50250bd2ca Added wrapped support for EGL/GLESv2 2024-02-29 12:55:57 +01:00
Yang Liu 0e71c3a2ac [CI] Added loongarch64 (#1298) 2024-02-29 08:49:47 +01:00
Haichen Wu db01a92edf [LONGAARCH_DYNAREC] Added 00...05 and 28...2D opcodes (#1297)
* [LONGAARCH] More renamed arch to LA64

* [LONGAARCH_DYNAREC] Added 00...05 and 28...2D opcodes
2024-02-29 08:16:40 +01:00
ptitSeb 6a9836912d [LONGAARCH] Renamed arch to LA64, as LA464 is code name for 3a5000, so that way it's more generic (and sorry about that late minute change) 2024-02-28 16:37:18 +01:00
Haichen Wu bdcfd69795 LARCH64 dynarec (#1295)
* LARCH64_DYNAREC dynarec

* [LARCH64_DYNAREC] Change mapping for the registers
2024-02-28 16:10:13 +01:00
ptitSeb dbe1bb0ec4 Added all wrapped function to libpci 2024-02-28 14:11:03 +01:00
ptitSeb d76841bdc1 Even more slot for X11 callbacks 2024-02-28 12:25:42 +01:00
ptitSeb 0251a29841 Small change on steam-pressure-vessel emulation 2024-02-28 12:25:21 +01:00
ptitSeb 32b0c173f0 [ELFLOADER] Fixed another warning 2024-02-28 10:28:41 +01:00
ptitSeb 90167afc2b [ELFLOADER] Fixed a warning 2024-02-28 10:27:36 +01:00
Yang Liu 6a4a58185e [RV64_INTERP] Added TSC freq support (#1293)
* [RV64_INTERP] Added TSC freq support

* Simplify
2024-02-28 10:10:30 +01:00
Yang Liu 6cffabacb3 [CI] Repeat until-pass for unstable platform (#1292)
* [CI] Repeat until-pass for unstable platform

Also removes useless --rerun-failed

* Fix
2024-02-28 08:11:29 +01:00
Yang Liu d658c47cd0 [RV64_DYNAREC] Fixed RDTSC handling (#1291)
* [LIBWRAP] Fixed a typo in the clocksource wrapping

* [RV64_DYNAREC] Added hardware timer support for RDTSC

* [INTERP] Optmize RV64 ReadTSC using rdtime

* [RV64_DYNAREC] Added 0F 01 F9 RDTSCP opcode

* Fixed typo

* Fixed another typo
2024-02-27 20:44:34 +01:00
ptitSeb 21b06ace43 [ANDROID] Small change on my___libc_init signature 2024-02-27 20:02:31 +01:00
ptitSeb 7a27b95df7 Added some more wrapped libm functions 2024-02-27 18:23:01 +01:00
ptitSeb a730935e6e Added 1 more syscall 2024-02-27 18:22:37 +01:00
ptitSeb ef705ed494 Added empty command 14 to CPUID 2024-02-27 17:44:09 +01:00
ptitSeb fb6915b059 [ARM64_DYNAREC] Added FF /3 opcode 2024-02-27 15:52:51 +01:00
ptitSeb 20d675ea48 [ARM64_DYNAREC] copied code for F0 87 to 87 opcode, as they should behavee the same way 2024-02-27 15:40:47 +01:00
ptitSeb 900dbc2a47 [32BITS][ARM64_DYNAREC] Added 67 E0..E3 opcodes 2024-02-27 15:40:47 +01:00
xctan d8affd8564 [RV64_DYNAREC] Optimized XOR Ew, Gw when Ew == Gw (#1289) 2024-02-27 15:13:00 +01:00
ptitSeb f3d4a1e1c3 Added some more vulkan extensions 2024-02-27 14:05:55 +01:00
ptitSeb d5ebea7928 [ARM64_DYNAREC] Added C8 opcode (for CP2077) 2024-02-27 14:05:42 +01:00
ptitSeb bd95c7a366 [ARM64_DYNAREC] Added 66 F0 01 opcode (for CP2077) 2024-02-27 14:05:20 +01:00
ptitSeb 20fc160230 [ARM64_DYNAREC] Fixed a potential issue with F0 87 opcode 2024-02-27 14:04:07 +01:00
ptitSeb c786e6d576 Added some more slots for X11 callbacks (help Cyberpunk 2077) 2024-02-27 14:03:33 +01:00
Yang Liu e9ce6a4f80 [RV64_INTERP] Comply CMPXCHG16B with dynarec (#1288) 2024-02-27 10:29:55 +01:00
ptitSeb 0024e4b970 [ANDROID] BBBBUUUIIIIILLLLDDDD 2024-02-26 21:18:39 +01:00
ptitSeb cf8ea5953e [ANDROID] Now build, stop complaining 2024-02-26 21:16:06 +01:00
ptitSeb 65ddcdeabb Fix Android tests 2024-02-26 21:00:12 +01:00
ptitSeb 6576686b36 Fix Android build 2024-02-26 19:47:03 +01:00
ptitSeb 13404ed090 Added ability to staticaly build box64 (for #1045 and #310, maybe a few others tickets) 2024-02-26 19:22:53 +01:00
ptitSeb ff6cc84482 Added CA opcode 2024-02-25 14:34:59 +01:00
ptitSeb 02caee0c02 Added some hack to rename wine binary process too (help mesa pick up the correct binary being run) 2024-02-24 14:12:36 +01:00
ptitSeb 7260da63af Fixed a warning 2024-02-24 12:27:59 +01:00
ptitSeb ec0d333d81 Improve emulation of clocksource 2024-02-24 12:10:08 +01:00
ptitSeb d3eb6b8a11 Small memory leak fixed with PRELOAD library 2024-02-24 12:09:32 +01:00
ptitSeb cc0ce73d39 This should improve stability when unloading libs 2024-02-24 12:09:09 +01:00
ptitSeb 2eb92951af [32BITS] Added 0E opcode ([ARM64_DYNAREC] too) 2024-02-24 12:08:16 +01:00
ptitSeb f8202096f1 Added 0F 01 F9 opcode ([ARM64_DYNAREC] too 2024-02-24 12:07:37 +01:00
ptitSeb f470d552cf Small changes in signal safe function handling 2024-02-24 09:56:04 +01:00
ptitSeb be50bbc149 [ARM64_DYNAREC] Handling of EB FF hacky jump 2024-02-24 09:55:26 +01:00
ptitSeb 50c49a1692 [RCFILE] Adjusted settings for windows steam 2024-02-24 09:54:29 +01:00
ptitSeb 70496c9bde Improved cpu detection for cpuid 2024-02-24 09:23:12 +01:00
ptitSeb f7f7c1c9af Fixed a typo in readme 2024-02-24 09:23:12 +01:00
Yang Liu f02d5fc28f [RV64_DYNAREC] Added missing 0F 38 00 PSHUFB opcode for test23 (#1282) 2024-02-23 19:33:33 +01:00
Yang Liu 422a982917 [RV64_DYNAREC] Added all missing 66 0F opcodes for test17 (#1281)
* Added 66 0F 38 14 PBLENDVPS opcode

* Added 66 0F 3A 40 DPPS opcode

* Added 66 0F 38 20 PMOVSXBW opcode

* Added 66 0F 38 21 PMOVSXBD opcode

* Added 66 0F 38 22 opcode

* Added 66 0F 38 23/24 opcodes
2024-02-23 19:06:00 +01:00
ptitSeb ce60a8cfa2 Fix Android build 2024-02-23 18:59:51 +01:00
ptitSeb f0026927e3 Added some various wrapped function (for rpcs3, but still not working) 2024-02-23 18:09:18 +01:00
ptitSeb d1388dd7eb Fix Android builds 2024-02-23 17:40:34 +01:00
ptitSeb ffda782c3d Better handling of Hardware counter for rdtsc emulation (ARM64 only for now), more cpuid leafs, and introduce BOX64_RDTSC env.var. with a profile that use it 2024-02-23 16:41:44 +01:00
ptitSeb 3a6df996dc Added 67 FF /2 opcode ([ARM64_DYNAREC] too) 2024-02-22 19:59:09 +01:00
Yang Liu 6141376977 [RV64_DYNAREC] Added 2 more 66 0F opcodes for test17 (#1278)
* Added 66 0F 38 03 PHADDSW opcode

* Added 66 0F 38 05 PHSUBW opcode
2024-02-22 19:10:56 +01:00
Yang Liu 3ec2ebabfc [RV64_DYNAREC] Added more opcodes (#1277)
* Added 66 0F 38 25 PMOVSXDQ opcode

* Added 0F 3A CC opcode

* Added 67 F7 /4 MUL opcode

* Added 67 C1 /5 SHR opcode
2024-02-22 13:37:46 +01:00
ptitSeb 77dcb025fd Hardened the my_sigaltstack wrapped function 2024-02-22 11:15:38 +01:00
ptitSeb bbaa01af79 [INTERPRETER] Added CB opcode 2024-02-22 11:15:02 +01:00
ptitSeb d033f34a45 [ARM64_DYNAREC] Added 0F E2 opcode 2024-02-22 10:39:59 +01:00
Yang Liu f2eb5326af [RV64_DYNAREC] Added more opcodes (#1276)
* Added 66 9C/9D PUSHF/POPF opcodes

* Added 0F E2 PSRAD opcode

* Fix

* More readable
2024-02-22 10:39:33 +01:00
ptitSeb f09b541ab7 [ARM64_DYNAREC] Added RCR 8bits with constant optimisation, and fixed RCL 8bit with const 2024-02-21 18:13:49 +01:00
ptitSeb e71df7eb67 [ARM64_DYNAREC] Optimized rcl 8bits with constant 2024-02-21 15:31:09 +01:00
ptitSeb 9d1e6b9b96 [INTERPRETER] SHRD/SHLD with cnt==0 should not change flags 2024-02-21 15:14:55 +01:00
ptitSeb 0d43b16fd5 [ARM64] Used Hardware counter for RDTSC emulation ([ARM64_DYNAREC] too) 2024-02-21 12:27:53 +01:00
Yang Liu b179bd2415 [DYNAREC_RV64] Minor OF flag fixes and optimizations for emit shift utils (#1275)
* Minor OF flag fixes and optimizations for emit shift utils

* original operand
2024-02-21 11:34:44 +01:00
ptitSeb 64fbd3db46 [ARM64_DYNAREC] Fixed some inf/nan detection for FXAM opcode 2024-02-21 11:25:31 +01:00
ptitSeb ea096cd593 [ARM64_DYNAREC] Adjusted some FLAGS productions of AAA/AAS/DAA/DAS ocpodes 2024-02-21 11:12:13 +01:00
ptitSeb 7934e3ad5c Small adjustment to flags computation on the AAA/AAS/AAD/AAM/DAA/DAS opcodes 2024-02-21 11:08:27 +01:00
ptitSeb 52a5335770 Small adjustment to one flags computation 2024-02-21 11:07:40 +01:00
Yang Liu f3d1ffbe01 [LIBTOOL] Fixed my_pthread_attr_init (#1274) 2024-02-21 09:00:23 +01:00
ptitSeb b40a17fc51 [ARM64_DYNAREC] Fixed some case of ROL/ROR 8/16bits not computing CF flag correctly 2024-02-20 16:32:41 +01:00
ptitSeb 02fadef9e7 [INTERPRETER] Fix shl/sar/shr for large shft value on 8 and 16bits operations 2024-02-20 16:31:44 +01:00
ptitSeb 6e4d2470d2 [TRACE] Slightly better trace for dynarec block writing on own page 2024-02-20 16:30:19 +01:00
ptitSeb 8e4faa3de2 Added 1 more profile for wine/new wow64 2024-02-20 16:29:09 +01:00
Yang Liu 4f3b9f19a7 [DYNAREC_RV64] Added more opcodes and some minor optimizations (#1272)
* Added DD /1 FISTTP i64 opcode

* Some small optimizations

* Added 0F AD SHRD opcode and some minor optimizations on the CF flag computation
2024-02-20 12:06:38 +01:00
ptitSeb e562baf30b Added some more symbol to wrapped libgnutls 2024-02-18 11:18:54 +01:00
ptitSeb efefd13bf5 Added VK_KHR_calibrated_timestamps extension to wrapped vulkan (for #1256) 2024-02-18 09:32:06 +01:00
ptitSeb 4314ef1ca8 [DYNAREC] Adjusted the PUSH/POP x87 macro (and fix RV64 test infinite loop) 2024-02-17 20:12:50 +01:00
KreitinnSoftware 477e531af9 [ANDROID] Fix Build When Compiling with NDK 26b, [CI] Download Basic Android Libs from 'termux-docker' and update NDK to 26b (#1270)
* [CI] Download Basic Android Libs from termux-docker for speed-up CI build

* [ANDROID] Fix 'SHT_CHECKSUM' error when compiling on NDK 26b

* [CI] Update NDK for 26b
2024-02-17 19:26:49 +01:00
ptitSeb 47b8e2a983 [INTERPRETER] Added a few unaligned path for some F0 math opcodes 2024-02-17 15:14:26 +01:00
ptitSeb cc01018223 [ARM64_DYNAREC] Added F0 31 opcode 2024-02-17 14:02:05 +01:00
ptitSeb 7a28084b63 [ARM64_DYNAREC] Added unligned path for F0 01 and F0 39 2024-02-17 13:46:16 +01:00
ptitSeb ea86b0e32f [RV64_DYNAREC] Fix build 2024-02-17 12:57:50 +01:00
ptitSeb 96169af71e [DYNAREC] Try to fix some issue with x87 stack and skipped code being incoherent 2024-02-17 12:54:45 +01:00
ptitSeb 4633817374 Small optim to speedup mmap64 2024-02-17 12:44:18 +01:00
ptitSeb a190910cbf [ARM64_DYNAREC] Fixed D9 E4 opcode 2024-02-17 11:45:10 +01:00
ptitSeb 6170fc8e43 Removed some debug leftover (at least change from LOG_INFO to LOG_DEBUG) 2024-02-17 11:10:31 +01:00
ptitSeb aa279c332d Better handling of 26/2E/36/3E prefix on F0 prefixed opcode ([ARM64_DYNAREC] too) 2024-02-17 09:37:50 +01:00
ptitSeb a79e1be034 Added 67 C6 opcode ([ARM64_DYNAREC] too) 2024-02-17 09:25:00 +01:00
ptitSeb 5924a8eca1 [ARM64_DYNAREC] Fixed 8C opcode 2024-02-16 18:38:21 +01:00
ptitSeb fc920b0838 Show box64 version inside trace file 2024-02-16 18:36:26 +01:00
ptitSeb e33d51641f [ARM64_DYNAREC][32BITS] Added C4 /m and C5 /m opcodes 2024-02-16 16:58:26 +01:00
ptitSeb 4b979bf206 [ARM64_DYNAREC] Added 0F A0/A1/A8/A9 opcodes 2024-02-16 16:31:05 +01:00
ptitSeb bc5afbea89 [ARM64_DYNAREC] Added better handling for DD C0 D9 F7 sequence 2024-02-16 14:22:05 +01:00
ptitSeb 65f75b0cc0 [ELFLOADER] Better handling of STB_GNU_UNIQUE binded symbol (prevent dlclose) 2024-02-16 13:44:54 +01:00
ptitSeb c50b0ef9e8 Added a few more function to libicuuc.so.* 2024-02-16 13:44:12 +01:00
ptitSeb 10c479034f Added some more wrapped function to libc, libXt and libX11 2024-02-16 12:41:13 +01:00
ptitSeb 3c95826c5c Added wrapped libanl 2024-02-16 11:40:19 +01:00
ptitSeb fa11368599 [ELFLOADER] Improved inter-library dependancie managment 2024-02-16 11:35:13 +01:00
ptitSeb f4fd01c777 [ANDROID][TERMUX] Fix build 2024-02-15 19:03:55 +01:00
ptitSeb 96941c9978 Fixe builds (non trace and android/termux) 2024-02-15 18:23:48 +01:00
ptitSeb c5a6875de9 [ELFLOADER] Huge refactor of elfloader and symbol resolution. Some more cleaning need to be done, but that's a first step (should help #422, #360, #1046 and probably others) 2024-02-15 18:11:57 +01:00
KreitinnSoftwareandPablo Carlos 549e042e67 [CI] Add Android Tests (#1263)
* [CI] Add Android Tests

* Remove a Build of Box64 that I placed and forgot to remove before

* Fix some tests checking

* Disable Test07 and Test17 for now

* Comment set_tests_proprieties (I have forgotten)

* Add mmx test and benchfloat for Android

* Fix build for Clang-17 on non-Termux

* Update NDK to 26b and add Termux Build/Testing

* Revert to NDK 25b, something is wrong

* Add -DTERMUX=1 to Termux Build

* Add LD_LIBRARY_PATH for Termux Testing

* Set LD_LIBRARY_PATH on QEMU_SET_ENV

* Move data folder to current dir before testing on Termux

* Copy Termux Data Libs for /data

* Try to set QEMU_SET_ENV on GITHUB_ENV

---------

Co-authored-by: Pablo Carlos <[email protected]>
2024-02-14 09:14:01 +01:00
ptitSeb c70581abc9 Added support for RTLD_DEEPBIND flag on dlopen 2024-02-11 16:46:21 +01:00
ptitSeb 5e6af37532 [ARM64_DYNAREC] Improved FFREE handling (fixing gameplay of Serious Sam 2, probably some other game too) 2024-02-11 16:12:46 +01:00
ptitSeb c0184f926d Small fix for FindNearestSymbolName 2024-02-11 15:39:25 +01:00
ptitSeb a69e81f034 [ARM64_DYNAREC] Improved FFREE/FXAM opcodes (helps 32bits games like SeriousSam2) 2024-02-11 11:52:58 +01:00
ptitSeb 5c01fbabac [INTERPRETER] Improved FXAM handling 2024-02-11 11:31:31 +01:00
Coreforge fed47bea4a more wrapped functions in libxcb-randr and libcap (#1260)
* wrapped a few xcbrandr functions for steamvr

* wrapped parts of libcap for vrcompositor-launcher
2024-02-10 19:15:06 +01:00
ptitSeb 213c063895 Fixed previous wrapped lib refactor when ALTMY macro is used 2024-02-10 18:20:16 +01:00
KreitinnSoftwareandPablo Carlos 632af46137 [ANDROID] BOX64_SHOWBT Now show Emulated BT on Android (#1258)
Co-authored-by: Pablo Carlos <[email protected]>
2024-02-10 16:44:28 +01:00
rajdakin b527ebbf5b Wrapped libraries refactor (#1257)
* [MISC] Removed a warning caused by tab/space mismatch

* [WRAPPED] Factored out `getMy` and `freeMy` calls

* [WRAPPED] Small cleanup of the init header

* [WRAPPED] Factored out `SETALT`

* [WRAPPED] Factored out needed libs
2024-02-10 15:06:08 +01:00
ptitSeb ad55cfde7f Added 0F 01 E0..E7 opcodes ([ARM64_DYNAREC] too) 2024-02-10 13:10:33 +01:00
ptitSeb 44e77de620 Increased default size for number of elf in the tls dts zone 2024-02-09 18:40:34 +01:00
ptitSeb 40de8e16ec Simplified (and improved?) handling of phtread_attr_t 2024-02-09 17:43:35 +01:00
ptitSeb d36f9e4dbb [ELFLOADER] Do not memset the remaining of page when mmap'ing, it's already done (and might not be possible depending on the protection) 2024-02-09 17:33:00 +01:00
ptitSeb a65f448856 Added some more libc wrapped functions 2024-02-09 15:58:40 +01:00
ptitSeb 8cba593882 Added 1 syscall 2024-02-09 15:47:19 +01:00
ptitSeb 0715dd145f Added some wrapped function to libxml2 2024-02-09 15:47:08 +01:00
ptitSeb 5a20322251 [WRAPPING] Added supot for the 'long double complex' type 2024-02-09 15:19:05 +01:00
ptitSeb 89b5e1163d Added some more symbols to wrapped libm 2024-02-09 14:37:07 +01:00
ptitSeb 6a9dbe3d89 Prefer emulated version tbbmalloc.so.2 if present 2024-02-09 13:59:01 +01:00
ptitSeb 8e6ae3aa01 Hack to add some paramter when launching steam under wine to easy memory and cpu load 2024-02-08 18:28:21 +01:00
ptitSeb e46707750b [ARM64_DYNAREC] Added F0 21 opcode 2024-02-08 18:27:21 +01:00
ptitSeb b1f6ea8ae6 More work on libcurl and friends (and set to used emulated version of curl if possible) 2024-02-08 16:49:02 +01:00
ptitSeb 82ae65f477 Added wrapped (empty) libpam.so.0 2024-02-07 21:58:38 +01:00
ptitSeb 4a3595133a [ARM64_DYNAREC] Improved stability when USCAT extention is supported, qn d improved reliqbility of unaligned fallback for LOCK CMPXCHG8B/CMPXCHG16B opcodes 2024-02-07 19:31:35 +01:00
ptitSeb 4c9a6a5d98 [DYNAREC] Jumptable now use custom Malloc instead of regular one 2024-02-07 18:02:07 +01:00
ptitSeb a2e01c36ba [ARM64_DYNAREC] 32bits Shift with 0 amount still wipe upper part of register on 64bits 2024-02-07 18:02:07 +01:00
ptitSeb 774d872f41 [DYNAREC] Tests for emited coded size limit (usefull for DYNAREC_TEST for example) 2024-02-07 18:02:07 +01:00
ptitSeb fa19435d24 [DYNAREC_TEST] Have a proper TestEw that only copy/tests 2 bytes instead of 4 2024-02-07 18:02:07 +01:00
factfinding 902186bdff [DYNAREC_RV64] f23 and f24 are save in a same place (#1251) 2024-02-07 17:27:35 +01:00
ptitSeb 6996c06909 TEGRAX1 config also have BOX64_MMAP32 activated by default 2024-02-07 16:42:13 +01:00
ptitSeb 315068b111 [ARM64_DYNAREC] Added 0F C7 /1 opcode 2024-02-07 14:13:05 +01:00
ptitSeb 4047d1ba3c [ARM64_DYNAREC] More fixes to F0 0F C7 opcode 2024-02-07 13:56:45 +01:00
ptitSeb d74bee3596 Disabling WINEFSYNC for now, that seems to be not working fine 2024-02-07 12:39:02 +01:00
ptitSeb aea1049223 Fixed a warning 2024-02-07 11:24:59 +01:00
ptitSeb 3548195fbe [ARM64_DYNAREC] Fixed F0 0F C7 opcode that was broken on previous commit 2024-02-06 22:02:13 +01:00
ptitSeb 8d0cc15eb0 [ARM64_DYNAREC] Reworked, again, strongmem emulation 2024-02-06 18:21:37 +01:00
ptitSeb ee2580a57f Reworked, again, exit process 2024-02-06 18:20:11 +01:00
ptitSeb 255d5c661e Do not force mmap alginement if wine not detected (shoudl help #1249) 2024-02-06 18:16:42 +01:00
ptitSeb a60d945968 [ARM64_DYNAREC] Added an unaligned path for F0 0F C7 /1 opcode 2024-02-06 16:13:36 +01:00
ptitSeb f8fa53aa3b Changed a bit how SGDT/SIDT are faked ([ARM64_DYNAREC] too) 2024-02-06 14:42:51 +01:00
KreitinnSoftware 1642327015 [ANDROID] Fix GLib and GObject Library Names (#1247)
* [ANDROID] Fix GLib and GObject Library Names

* [ANDROID] Fix gdk3, gdkpixbuf2, gio2, gmodule2, gtkx112, gdkx112, pangocairo Library Names
2024-02-06 12:26:50 +01:00
ptitSeb 399478d635 [ARM64_DYNAREC] Added BOX64_DYNAREC_DIV0 option to check/trigger Divide by 0 when needed 2024-02-05 20:35:31 +01:00
ptitSeb 608c13ebba Added curl_url api to wrapped libcurl 2024-02-04 20:46:27 +01:00
ptitSeb 99694d67ca Added some more function to wrapped libcrypto.so.3 and libssl.so.3 2024-02-04 20:39:35 +01:00
ptitSeb bde279f2fa [ARM64_DYANREC] Try to fix DD /1 opcode with FRINT extension 2024-02-04 19:50:00 +01:00
ptitSeb e4f56f0b23 [INTERPRETER] CE opcode is only for 32bits 2024-02-04 16:49:34 +01:00
ptitSeb 3e8da0cc1a [RV64_DYNAREC] Fixed build 2024-02-04 14:43:20 +01:00
ptitSeb ca0e12d93f [RV64_DYNAREC][32BITS] Added optim for 32bits jumptable and fix build 2024-02-04 12:31:58 +01:00
ptitSeb 0c41d9810f [ARM64_DYNAREC][32BITS] Small optim on jump table for 32bits access (1 less read, or 2 in SAVE_MEM configuration) 2024-02-04 11:34:29 +01:00
ptitSeb 165961f27e [ARM64_DYNAREC] Small D8..DF opcodes refactor 2024-02-04 10:39:25 +01:00
ptitSeb 81386b7a56 [INTERPRETER] Small D8..DF opcodes refactor 2024-02-04 10:32:42 +01:00
ptitSeb 5bf2a7d51b Updated wrapped SDL2 (will help #1225) 2024-02-04 10:24:14 +01:00
ptitSeb 3fa527b45b [ARM64_DYNAREC] Reworked STRONGMEM 2 & 3 2024-02-03 18:03:26 +01:00
ptitSeb 121d986b11 [DYNAREC] Reworked a bit the Strange SEGSIGV handling 2024-02-03 18:01:13 +01:00
ptitSeb f18f5c9b85 [DYNAREC_TEST] Force enabled x87double when using DYNAREC_TEST to limit false positive 2024-02-03 17:59:18 +01:00
ptitSeb d5808f6be3 [ARM64_DYNAREC] Improved 0F AE opcodes 2024-02-03 17:57:16 +01:00
ptitSeb 2984d30118 [INTERPRETER] Improved 0F AE opcodes 2024-02-03 17:56:45 +01:00
ptitSeb efbb5a2ae5 [ARM64_DYNAREC] DD /6 opcode also perform x87 init 2024-02-03 17:56:04 +01:00
ptitSeb 31aafe23b7 [ARM64_DYNAREC] Use frint extension for DD /1 opcode 2024-02-03 17:35:03 +01:00
ptitSeb 09779e294c [RCFILE] Adjested/Added profiles 2024-02-03 17:00:56 +01:00
Lily 2fe872de3d [X64EMU] Fix for linux clang (#1243) 2024-02-02 21:19:11 +01:00
ptitSeb 153d8d2cf0 Block signals while traicking memory protection 2024-02-02 16:44:50 +01:00
ptitSeb 1b07a10b5d Refactored a bit protection traking to avoid re-entrance 2024-02-02 15:59:12 +01:00
ptitSeb d743c8235f Fixed a warning on non-dynarec build 2024-02-02 10:40:58 +01:00
ptitSeb 7781bfcbac Added 0F 0E opcode support ([ARM64_DYNAREC] too) 2024-02-01 20:09:22 +01:00
rajdakin 0fd81e067f [WRAPPER] Regenerated the wrapper files (#1241) 2024-02-01 19:04:55 +01:00
ptitSeb acc2f2e3d5 [32BITS] Added 67 64 89 opcode ([ARM64_DYNAREC] too) 2024-02-01 18:58:01 +01:00
ptitSeb a2be60cce8 [32BITS] Added 67 64 A1 opcode ([ARM64_DYNAREC] too) 2024-02-01 18:42:37 +01:00
ptitSeb 1344b18379 [DYNAREC] Handling of memfd_create backed mmap on dynarec (help #1234 but doesn't solve it completly) 2024-02-01 16:42:16 +01:00
ptitSeb 1deec05f3d [DYNAREC] Improved trace a bit 2024-02-01 16:42:16 +01:00
Lily 2ee5bcf933 [DOCS] Fix a typo in temrux building (#1240) 2024-02-01 15:46:48 +01:00
ptitSeb 5f57de017c [INTERPRETER] Added CE opcode 2024-01-31 18:38:52 +01:00
josch 508a153973 When BOX64_VERSION is set, just print the version and exit (#1238)
When set, box64 will only print its version and then exit. This option
is analogous to QEMU_VERSION used by binfmt_misc emulation of qemu-user.
Its purpose is the same: provide a way to soft-disable binfmt_misc
emulation as well as for identifying box64 as the registered binfmt_misc
emulator.

This commit enables adding support for box64 to the arch-test utility.
With this change, arch-test is able to soft-disable box64 as the x86_64
emulator in the same way as it does this for qemu and wine already.
Without this change, arch-test will report an architecture as natively
executable by the processor, disregarding that it actually gets emulated
by box64.

Furthermore, this commit enables identifying box64 as the currently
registered emulator for x86_64. This way, applications that know that
their emulation requirements cannot work with box64 can add a check to
find out that it is box64 doing the emulation and are able to print a
helpful error message.

Closes: #1237
2024-01-31 18:29:34 +01:00
ptitSeb 5d8b70cc0d Made PageSize detection / Handling dynamic. nd fixed elfloading for pagesize not 4K. The define are still there but might be removed shortly (for #1231, #1226, #1189, #1175, #999, #384 and probably a few other) 2024-01-31 16:04:49 +01:00
ptitSeb d60ba04cf4 [ANDROID] Fix build 2024-01-31 15:35:33 +01:00
Yang Liu 8b3949497a Added mknod syscall (#1236)
* Added mknod syscall

* Add ifndef

* A comma is needed
2024-01-31 15:29:34 +01:00
ptitSeb 754b69f746 Consider libutil as integral part of glibc 2024-01-31 15:20:45 +01:00
ptitSeb 55c99e9ad7 [LOONGARCH] Fixed potential compilation issue 2024-01-31 12:19:34 +01:00
josch aa2e212480 system/box64.conf.cmake: change rule name to be box64 specific (#1233)
Having an entry named x86_64 in /proc/sys/fs/binfmt_misc/ is not ideal
because:

 - it does not indicate who the binfmt provider is (others start with
   llvm-*, python* or qemu-* to indicate this)
 - it is a namespace grab -- there is no justification for box64 to grab
   the identifier "x86_64" over all other potential binfmt providers
2024-01-31 00:19:29 +01:00
Lily 96c6abc889 [X64LIBS] mbedtls libs (#1232)
* [CMAKE] Prepare for mbedtls libs

* [X64LIBS] mbedtls libs

* [GITIGNORE] Reverting this
2024-01-30 22:06:26 +01:00
ptitSeb 74a73dfc97 Added SOPHGO as hardware donator 2024-01-30 22:03:28 +01:00
ptitSeb d3b5553433 [RV64_DYNAREC] Fixed 0F AF 32bits (for #1210) 2024-01-30 18:59:03 +01:00
ptitSeb b8856af18c [ARM64_DYNAREC] Added UDF printer 2024-01-30 18:57:48 +01:00
ptitSeb 63428d0b2e [ARM64_DYNAREC] Small changes on 32BITS E9 opcode to ensure 32bits jump destination 2024-01-30 14:05:54 +01:00
ptitSeb 22afd245a8 [RCFILE] Added a profile for DaveTheDiver 2024-01-30 14:05:11 +01:00
ptitSeb 26fdf2275a [RV64_DYNAREC] Fixed some isue wiht sse_get_reg helper function tht would incorectly mark a regs as changed single/non-single 2024-01-29 22:50:38 +01:00
ptitSeb 1ad38124df [32BITS] Small improvment to E8/E9 opcode to trucate address to 32bits 2024-01-29 22:46:52 +01:00
ptitSeb aaa4fd1265 [INTERPRETOR] More finetunning to shrd16/shld16 2024-01-29 20:48:04 +01:00
ptitSeb 9793c3b142 [ARM64_DYNAREC] ROL/ROR/RCL/RCR might not update OF if count is not 1 2024-01-29 20:00:25 +01:00
ptitSeb 5a753761dd [ARM64_DYNAREC] Small improvments to SHLD/SHRD helpers 2024-01-29 19:59:46 +01:00
ptitSeb 37be26e539 [INTERPRETER] Small improvements to shr/shl to limit fals-positive on DYNAREC_TEST 2024-01-29 19:58:58 +01:00
ptitSeb 96023f2274 [DYNAREC_TEST] Fixed some potential fals-positive on some CMP opcodes 2024-01-29 16:58:19 +01:00
ptitSeb 30b83f4f9c [ARM64_DYNAREC] Fixed 66 50-5F opcodes (helps Dave the Diver) 2024-01-29 14:46:36 +01:00
ptitSeb 265f969a44 [TRACE] Slightly better trace for some dynarec runtime issues 2024-01-29 14:46:36 +01:00
xctan d5b182cac0 [WRAPPERS] Fixed some typos in rebuild_wrappers.py (#1227) 2024-01-29 13:24:40 +01:00
ptitSeb ce296f0e32 [ARM64_DYNAREC] Added 67 6B opcode 2024-01-29 09:59:18 +01:00
ptitSeb 6d5c3489c9 [ARM64_DYNAREC] Added F0 0F C0 opcode 2024-01-29 09:58:44 +01:00
ptitSeb d48ab49437 Added more slot for X11 Callbacks wrapping 2024-01-29 09:57:46 +01:00
ptitSeb 8ee250e9ac [DYNAREC] Small improvment in dynablock/protectDB handling 2024-01-29 09:57:02 +01:00
ptitSeb e485fe1d18 [ARM64_DYNAREC] Removed old unused code 2024-01-29 09:54:08 +01:00
ptitSeb 35a32481c6 [DYNAREC] Narrow the cases for Strange SIGSEGV to protextion with READ & WIRTE 2024-01-28 13:21:41 +01:00
ptitSeb beaf543012 [RCFIEL] Fixed BOX64_IGNOREINT3 2024-01-28 09:45:20 +01:00
ptitSeb c40e31f374 Fixed SnapDragon builds 2024-01-27 21:16:27 +01:00
ptitSeb f9c09293bf Added BOX64_IGNOREINT3 env. var. to ignore INT3 in the code ([RCFILE] too) 2024-01-27 20:42:32 +01:00
ptitSeb cdffe2388e Rollback vfork changes, it broke SlayTheSpire, and probably other too (for #1221) 2024-01-27 20:13:01 +01:00
ptitSeb 6c0af2dbb9 [ARM64_DYNAREC] Added E4/E5/E6/E7 opcodes 2024-01-27 17:56:48 +01:00
ptitSeb eee428afe5 [ARM64_DYNAREC][32BITS] Added D4/D5 opcodes 2024-01-27 17:49:22 +01:00
ptitSeb 047815c764 [ARM64_DYNAREC][32BITS] Added 37 opcode 2024-01-27 17:45:00 +01:00
ptitSeb 3b8e0d69a3 [ARM64_DYNAREC][32BITS] Added 27 opcode 2024-01-27 17:42:27 +01:00
ptitSeb 56f2749da0 [ARM64_DYNAREC][32BITS] Added 2F opcode 2024-01-27 17:37:39 +01:00
ptitSeb 7d85753350 [RCFILE] Added Celeste.exe profile 2024-01-27 17:37:16 +01:00
ptitSeb 367363a8bd [RCFILE] Fixed Unturned profile 2024-01-27 17:02:41 +01:00
ptitSeb 30d0836329 [RCFILE] Added Unturned profile 2024-01-27 17:00:56 +01:00
ptitSeb 1680dc63d9 [ARM64_DYNAREC] Improved shld16 opcode 2024-01-27 17:00:34 +01:00
ptitSeb 806298843f [ARM64_DYNAREC] Fixed 66 8C opcode and improved many 66 prefix opcode on 32BITS 2024-01-27 17:00:03 +01:00
ptitSeb 7cee4e2453 [TEST_DYNAREC] Improved accuracy of some tests, and avoid a some false-positive 2024-01-27 16:53:57 +01:00
ptitSeb 82f21de83e [ARM64_DYNAREC] Removed unused code 2024-01-27 14:33:32 +01:00
ptitSeb 65c4f9d9c3 [INTERPRETER] Add code for unaligned 32bits F0 87 opcode 2024-01-27 14:31:51 +01:00
ptitSeb 8043f53d7d Track protection even if 0 2024-01-27 13:32:01 +01:00
ptitSeb 124672b811 [ARM64_DYNAREC] Fixed/Improved D9 E5 opcode and add hack for FLD1/FLD1/FPATAN sequence 2024-01-27 13:31:07 +01:00
ptitSeb 28ef6cdefc Improved fxam helper 2024-01-27 13:26:15 +01:00
ptitSeb 5e38ea28b6 [ARM64_DYNAREC] Fixed previous commit 2024-01-26 15:53:18 +01:00
ptitSeb 1d0d7e9e09 Reworked 0F 01 opcode ([ARM64_DYNAREC] too) 2024-01-26 15:39:05 +01:00
ptitSeb aab6bc0869 Added 66 8F opcode ([ARM64_DYNAREC] too) 2024-01-26 14:18:11 +01:00
ptitSeb 77213bee1d [32BITS] Added 16/17 ocodes ([ARM64_DYNAREC] too) 2024-01-26 12:39:53 +01:00
ptitSeb 90fc1d93ad [INTERPRETER] Ignore 36/26 segment prefix for 66 prefixed opcodes 2024-01-26 12:35:53 +01:00
ptitSeb e51f36c651 [32BITS] Added some more opcode to the 32bits part of interpreter, to run more protected binaries 2024-01-26 11:56:50 +01:00
KreitinnSoftware fc63442ded Add 'BOX64_MMAP32' to help info (#1220)
* Add 'BOX64_MMAP32' to help info

* [CI] Update NDK to 25b for Android Builds
2024-01-26 08:20:53 +01:00
leonpano2006 0ee5174e18 add optimize build flag for Jetson orin and xavier (#1219)
* add optmized options for Jetson xavier and orin

* Update CMakeLists.txt

* Update COMPILE.md

add info for build on jetson orin and xavier
2024-01-25 23:04:20 +01:00
ptitSeb 0004f19325 [MMAP32] 31bits address space is in fact 3GB address space (so 31.5 bits?) 2024-01-24 14:58:18 +01:00
ptitSeb da724e3dd5 [MMAP32] Fixed mmap32 behaviour 2024-01-24 14:12:16 +01:00
ptitSeb 96ccf0dab9 [ARM64_DYNAREC] Fixed 67 66 prefixed REX reading 2024-01-24 14:00:47 +01:00
ptitSeb aba3e4a460 Small improvment to MMAP32 managment 2024-01-23 19:41:10 +01:00
ptitSeb bc852aebeb Added a new option BOX64_MMAP32 to use 32bits mapping on external MMAP (help Snapdragon device running Vulkan with Wine/Wow64, active by default on SD845/SD888/SD8G2 profiles) 2024-01-23 15:56:11 +01:00
ptitSeb 89da530898 [DYNAREC] use an rbtree for dynablock size and max_db_size update 2024-01-23 10:01:11 +01:00
Yang Liu 2367e7df50 [DYNAREC_RV64] Enable basic simple wrapper optimization (#1215) 2024-01-23 09:23:49 +01:00
ptitSeb 2ca85a4976 Added 1 syscall 2024-01-22 17:28:37 +01:00
ptitSeb e3860cf09c [TRACE] Slightly improved trace 2024-01-22 17:28:17 +01:00
ptitSeb 07be405f48 Make sure Stack is aligned properly... (should help #1187 and ~1188) 2024-01-22 16:46:45 +01:00
ptitSeb 92d5210e37 [ELFLOADER] Zero'd memory when using mmap and filesize smaller than memsize 2024-01-21 12:22:55 +01:00
ptitSeb 01bf7aa774 Removed a useless test in getProtection utility function 2024-01-21 12:22:47 +01:00
ptitSeb 427ca732fe [TRACE] Improved trace for __libc_start_main init handling 2024-01-21 12:22:08 +01:00
ptitSeb ca92a0b90a Used rb_stree for mapallmem too 2024-01-20 15:28:21 +01:00
ptitSeb db4547115c Added a few wrapped function to libcups 2024-01-20 10:01:09 +01:00
ptitSeb 3ad4a3ae3a Use rbtree for mmapmem tracking 2024-01-19 18:51:31 +01:00
ptitSeb 7bef772488 Fix build on some older compiler 2024-01-19 15:23:00 +01:00
ptitSeb e4c64073c5 Reworked exit, unloading libs and running Fini as it should (plus a workaround for nvidia driver not unloading) 2024-01-19 15:09:20 +01:00
ptitSeb 0ff15e91d9 [RCFILE] Update & Added a few profiles 2024-01-19 15:07:54 +01:00
ptitSeb a584aa7df8 Added 1 more wrapped libc function (for #1208) 2024-01-19 10:18:19 +01:00
ptitSeb 57ca9dfdbc Reworked wrapping of callback in X11 Va args 2024-01-18 22:48:09 +01:00
rajdakin 3a2073f785 Fixes (#1207)
* Fixed signed/unsigned issues and other cosmetics

* [WRAPPERS] Fixed missing `return`s in `my_` functions

* [EMU] More fixes

* [STEAM] Forgot one cleanup

* [WRAPPER] Fixed wrappedpulse callback signatures
2024-01-18 18:57:20 +01:00
ptitSeb e963d99d5e Partial Wrapping of libxkbregistry 2024-01-18 18:53:19 +01:00
ptitSeb bbe188d4f9 Fixed an issue with a failsafe that was not working 2024-01-18 14:23:47 +01:00
ptitSeb 9df1ed0b3b [DYNAREC] Fixed a warning 2024-01-18 14:23:22 +01:00
ptitSeb 742998b477 Added 1 more wrapped function to libc 2024-01-18 12:06:02 +01:00
ptitSeb a577fac1c5 [DYNAREC] Test when changing page on building a dynablock if it's safe 2024-01-18 11:59:39 +01:00
ptitSeb d08abf05ff Added 1 more wrapped function to libgconf2 2024-01-18 11:54:02 +01:00
ptitSeb cd6af18183 [RCFILE] Adjusted steamwebhelper profile for better stability 2024-01-17 17:44:42 +01:00
ptitSeb a425275108 Some more fixes to new memory protection tracking (should help #1202 and #1200) 2024-01-17 15:45:10 +01:00
ptitSeb 92f7b6fd9e Wrapped libpulse-mainloop-glib (for #1203, untested) 2024-01-16 18:22:52 +01:00
ptitSeb 68c7586c4c [INTERPRETER] Fixed D7 opcode 2024-01-16 17:56:43 +01:00
ptitSeb 9549a3599c [ARM64_DYNAREC] Fixed some special case for shrd/shld opcodes 2024-01-16 17:42:39 +01:00
ptitSeb b826049893 Added 1 more syscall 2024-01-16 17:34:22 +01:00
ptitSeb 88d950bafb [RCFILE] Added and Adjusted a few more profile 2024-01-16 10:21:21 +01:00
ptitSeb 50242c6eaa Ficxed an issue with rbtree rb_get_end utility function 2024-01-16 10:20:55 +01:00
ptitSeb e5649d90e7 Round size to pagesize on the tracked memory 2024-01-16 10:20:16 +01:00
ptitSeb d22e6f28a1 Used AddCheckBridge were the check could make sense 2024-01-16 10:19:44 +01:00
ptitSeb 307acee9d3 [INTERPRETER] Fixed VM Detection (TF trick) for interpreter 2024-01-15 17:48:54 +01:00
ptitSeb 184b2cc26b Small fix for a faked wrapped function 2024-01-15 17:20:13 +01:00
ptitSeb 613781e6c0 Fixed xcb_connect wrapping 2024-01-15 17:11:28 +01:00
ptitSeb 92c3c1f829 Added 1 more wrapped function to libgmp 2024-01-15 13:50:29 +01:00
ptitSeb 6268367b22 [ELFLOADER] Fixed some issue with COPY/GLOB_DATA symbol relocations 2024-01-15 12:50:27 +01:00
xctan 4c174a42f8 [RV64_DYNAREC] Fixed 66 87 XCHG opcode (#1198) 2024-01-13 17:25:53 +01:00
rajdakin 71463476f6 [RBTREE] Reverted memory tracking to 32 bits (#1201) 2024-01-13 08:45:52 +01:00
ptitSeb 20b388c1d2 [ARM64_DYNAREC] Re-enable Atomics, seems stable now 2024-01-12 18:43:14 +01:00
ptitSeb 3ab7648384 [TRACE] Better trace for wrapped dladdr1 calls 2024-01-12 18:42:47 +01:00
ptitSeb 9fb84e3ef2 Removed a debug leftover 2024-01-12 18:42:20 +01:00
ptitSeb d6bfce9a5d [VULKAN] Added some more extensions (for #424) 2024-01-12 11:28:10 +01:00
xctan 328d5c6275 [RV64_DYNAREC] Fixed 66 0F B6 MOVZX opcode (#1196) 2024-01-11 17:12:39 +01:00
ptitSeb 19be6b5e17 Added 1 more wrapped function to libcups 2024-01-10 19:54:11 +01:00
ptitSeb 499f9633ba [VULKAN] Wrapped VK_EXT_device_fault extension (for #424) 2024-01-10 16:41:06 +01:00
ptitSeb 774ca6cd80 [VULKAN] Wrapped VK_KHR_map_memory2 extension (for #424) 2024-01-10 15:29:43 +01:00
ptitSeb 22b5cf3536 [VULKAN] Wrapped VK_EXT_host_image_copy extension (for #424) 2024-01-10 14:51:33 +01:00
ptitSeb 18fa8af728 [VULKAN] Completed wrapping of VK_NV_scissor_exclusive extension (for #424) 2024-01-10 13:26:53 +01:00
ptitSeb 0f01bdad13 [VULKAN] Completed wrapping of VK_EXT_discard_rectangles extension (for #424) 2024-01-10 12:18:45 +01:00
Yang Liu d787f67ab8 [DYNAREC_RV64] Added more opcodes and fixed X87_PUSH/POP macros (#1194)
* [DYNAREC_RV64] Added DB F0..F7 FCOMI opcodes

* [DYNAREC_RV64] Added more DA opcodes

* Try to fix X87_PUSH_OR_FAIL

* [DYNAREC_RV64] Added D7 XLAT opcode

* Fix X87_PUSH_OR_FAIL for aarch64 too
2024-01-09 15:26:54 +01:00
Yang Liu 16de80f46a [DYNAREC_RV64] Fixed a wrong Zba optimization (#1193) 2024-01-09 08:20:55 +01:00
ptitSeb 294bc51f83 [ELFLOADER] More elf alignment sections adjustments 2024-01-08 19:20:31 +01:00
ptitSeb 70987fc55f [ELFLOADER] Another attempt at elf allignement fixes 2024-01-08 18:58:52 +01:00
ptitSeb 5b700cb6e6 [ELFLOADER] Try to harden the memory allocation 2024-01-08 17:52:49 +01:00
ptitSeb dcb31fa783 [ARM64_DYNAREC] Fixed 66 0F 3A 17 opcode (should help UE games) 2024-01-08 16:16:24 +01:00
Frank Benkstein 411a52e16f expose minimal libxcb-xinput wrapper (#1192)
Expose minimal libxcb-xinput interface, enough to run the Enpass
password manager. Also expose XkbGetIndicatorState since that is also
required.
2024-01-08 00:05:15 +01:00
ptitSeb 41bfd757ad Added libutil and libresolv to the list of essential libs (not affected by BOX64_PREFER_EMULATED) 2024-01-07 15:25:37 +01:00
ptitSeb d94c6f2132 Added 2 more wrapped function to libgtk3 (for epsxe) 2024-01-07 11:07:32 +01:00
ptitSeb 29052c7a90 Added (much) more slot for genereic GCallback on gobject2 2024-01-07 11:00:47 +01:00
ptitSeb 48de41137d Added ncurses6 as alias to ncurses5 as it's deprecated on modern OS 2024-01-07 11:00:08 +01:00
ptitSeb 203d06831e Added profile for Unigine Heaven Linux version 2024-01-06 17:23:47 +01:00
ptitSeb 3e9c435ed1 Added alias for wrapped libresolv.so 2024-01-06 17:23:13 +01:00
ptitSeb e65fda875a Added 1 more wrapped function to libcups 2024-01-06 17:22:53 +01:00
ptitSeb 70c745dd84 Added 1 syscall 2024-01-06 10:58:28 +01:00
ptitSeb 870b71afec [INTERPRETER] Added 67 66 8D opcode ([ARM64_DYNAREC] too) 2024-01-06 10:58:02 +01:00
ptitSeb 18e0af6b38 [INTERPRETER] Added support for unaligned F0 0F BA /5 opcode 2024-01-06 10:56:59 +01:00
ptitSeb ed87cc1b1e [INTERPRETER] Improved 0F 01 opcode ([ARM64_DYNAREC] too) 2024-01-06 10:56:03 +01:00
ptitSeb 5d6ff69e8d [RCFILE] Added more option to rcfile and added geekbench5 profile 2024-01-06 10:48:18 +01:00
ptitSeb cbea2b5443 Rollback commit 9201559 as it breaks some programs using getopts (should help #1190) 2024-01-06 10:30:31 +01:00
ptitSeb a891e1f85d Added wrapped libicuuc and libicui18n v74 2024-01-05 17:05:21 +01:00
Yang Liu ade0aa770a [DYNAREC_RV64] Added CALL/RET optimization (#1183)
* [DYNAREC_RV64] Added CALL/RET optimization

* More hacks on the call/ret optimization

* Small fixes, but still not working

* More fixes

* More fixes
2024-01-05 16:55:25 +01:00
ptitSeb a5f2f3b3f1 [ARM64_DYNAREC] A few more FRINTTS extension use 2024-01-05 14:58:45 +01:00
ptitSeb 077ba65f7e [ARM64_DYNAREC] More FRINTTS use 2024-01-05 14:22:13 +01:00
ptitSeb 6f6a426424 [ARM64_DYNAREC] Attempt to use FRINTTS extension 2024-01-05 13:55:17 +01:00
ptitSeb 163158cf12 [ARM64_DYNAREC] Simplified a bit CALLRET fallback handling on stack unsync 2024-01-05 12:15:03 +01:00
rajdakin e4821aa9e1 [WRAPPERS] Add a isSimpleWrapper function for RV64 (#1185)
* [WRAPPERS] Added an isSimpleWrapper function for RV64

* [WRAPPERS] Version bump
2024-01-05 08:22:56 +01:00
ptitSeb 9b23c3272b Added 1 more symbol to wrapped libgnutls 2024-01-04 18:58:26 +01:00
ptitSeb 3454afb3e4 [RCFILE] Add profile for Broforce and change 3dSen to limit cmax core to 4, it actualy speedup emulation if many cares are present 2024-01-04 11:04:43 +01:00
ptitSeb ab99ae6951 [ARM64_DYNAREC] Fixed CALLRET optim when unsync occur, should help stability 2024-01-04 11:03:46 +01:00
ptitSeb a609452cfd [DYNAREC] Switched back CALLRET to 0 by Default, many things like GoG Wine Installer needs that 2024-01-02 18:50:48 +01:00
ptitSeb ee1256a676 [RCFILE] Add a function to quickly get current process name 2024-01-02 18:38:38 +01:00
ptitSeb a9837a3aaf [TRACE] Better trace for read wrapped function 2024-01-02 18:38:02 +01:00
Tristan Morgan 499492e10a Remove FASTPAGE/HOTPAGE docs, related to #1180 (#1181) 2024-01-02 08:09:04 +01:00
ptitSeb 6e77ce999a [ARM64] Improved fast path for unaligned access to device memory (for NVidia cards) 2024-01-01 00:00:08 +01:00
ptitSeb dd05eeb821 Fixed issue on rbtree on rb_get_end when end is another block 2023-12-31 19:19:29 +01:00
ptitSeb 919f8faeee More xcb_connection_t wrapping for vulkan 2023-12-31 18:46:27 +01:00
ptitSeb b0db8e1ae0 [ARM64_DYNAREC] Some more warning fixes 2023-12-31 16:02:26 +01:00
ptitSeb 3e0f2bfc4a Fixed some (nasty sometimes) warning 2023-12-31 15:54:45 +01:00
rajdakin 5e9e1faedc [MEMORY] Switched from a sparse array to a red-black tree (#1180)
* [MEMORY] Switched from a sparse array to an RB tree

* [RBTREE] Fixed the Android build
2023-12-31 15:49:57 +01:00
Yang Liu dba6a88341 [DYNAREC_RV64] Fixed a nasty bug in GETEX, but left optim opportunity for later (#1178) 2023-12-28 13:31:15 +01:00
Yang Liu ee0b86c0c2 [WRAPPER] Added 4 more wrapped glib2 functions (for #1175) (#1176) 2023-12-28 13:26:17 +01:00
Creeper-xie 7ea2e1bf51 [CMakelist] Remove a "#" (#1173)
It seems be added by mistake.
2023-12-27 20:47:04 +01:00
Yang Liu c801f2d4a5 [RCFILE] Disable CALL/RET optimization for zoom (#1170) (#1174)
* [WRAPPER] Added 1 more wrapped libc functions

* [RCFILE] Disable CALL/RET optimization for zoom (#1170)

* Do not delete BOX64_DYNAREC_CALLRET=1 in case we make it not default again
2023-12-27 20:07:42 +01:00
ptitSeb ae84f02bd0 Added 2 more wrapped gtk3 functions 2023-12-26 16:23:11 +01:00
ptitSeb a6c73e2840 Merge branch 'main' of https://github.com/ptitSeb/box64 2023-12-26 15:18:50 +01:00
ptitSeb e6bc1d7c22 More work on xcb wrapping, as xcb_connection_t needs alignment 2023-12-26 15:18:41 +01:00
xctan e2abb6b6db [DYNAREC_RV64] Added more opcodes for VMP-protected GI (#1168)
* [DYNAREC_RV64] Added 66 0F B3 BTR opcode

* [DYNAREC_RV64] Added 66 0F BA /7 BTC opcode

* [DYNAREC_RV64] Added 66 {D1,D3} /{2,3} RCL/RCR opcodes

* [DYNAREC_RV64] Added 66 0F BA /{5,6} BTS/BTR opcodes

* [DYNAREC_RV64] Added 0F C1 XADD opcode

* [DYNAREC_RV64] Added 0F C0 XADD opcode

* [DYNAREC_RV64] Added D3 /2 RCL opcode

* [DYNAREC_RV64] Removed redundant declaration of wb2 in 0F

* [DYNAREC_RV64] Enable 66 0F BD BSR again

* [DYNAREC_RV64] Added 66 1D SBB opcode
2023-12-26 12:55:25 +01:00
xctan cb63cdcd42 [DYNAREC_RV64] Added more opcodes for VMP-protected GI (#1164)
* [DYNAREC_RV64] Added 66 0F C8-CF BSWAP opcode

* [DYNAREC_RV64] Added 66 0F BB BTC opcode

* [DYNAREC_RV64] Added D2 /3 RCR opcode

* [DYNAREC_RV64] Added 66 0F BA /4 BT opcode

* [DYNAREC_RV64] Added 66 D3 /1 ROR opcode

* [DYNAREC_RV64] Added D2 /2 RCL opcode

* [DYNAREC_RV64] Added 66 D3 /0 ROL opcode

* [DYNAREC_RV64] Added 66 0F BC BSF opcode

* [DYNAREC_RV64] Added 66 0F A4 SHLD opcode

* [DYNAREC_RV64] Added 66 0F AB BTS opcode

* [DYNAREC_RV64] Added 36 SS prefix

* [DYNAREC_RV64] Added D3 /3 RCR opcode

* [DYNAREC_RV64] Added C1 /3 RCR opcode

* [DYNAREC_RV64] Added 66 0F AC SHRD opcode

* [DYNAREC_RV64] Fixed emit_shrd16c, emit_shld16c declaration

* [DYNAREC_RV64] Added C1 /2 RCL opcode

* [DYNAREC_RV64] Added 66 0F BD BSR opcode

* [DYNAREC_RV64] Added 66 0F A3 BT opcode

* [DYNAREC_RV64] Added 66 0F C1 XADD opcode

* [DYNAREC_RV64] Added 0F A5 SHLD opcode

* [DYNAREC_RV64] Added C0 /2 RCL opcode

* [DYNAREC_RV64] Added C0 /3 RCR opcode

* [DYNAREC_RV64] Added 66 99 CWD opcode

* [DYNAREC_RV64] Fixed 66 99 CWD opcode

* [DYNAREC_RV64] Revert 66 0F BD BSR opcode

VMP anti-debugger message will break with this opcode
2023-12-25 21:54:42 +01:00
Yang Liu 1f28b9f98d [INTERP] Added 64 66 39 CMP opcode (#1166) 2023-12-25 16:32:03 +01:00
ptitSeb 7fcc0ba8a4 New attempts at mmap fixing 2023-12-25 10:01:04 +01:00
ptitSeb 6773ac88af Merge branch 'main' of https://github.com/ptitSeb/box64 2023-12-25 09:09:34 +01:00
ptitSeb 46bee1d532 Small change with not 48bits memory space for mmap64 (might help #1163) 2023-12-25 09:09:28 +01:00
Yang Liu 10062373d1 [DYNAREC_RV64] Added more opcodes for ets2 (#1162)
* [DYNAREC_RV64] Added F2 0F 7C HADDPS opcode

* [DYNAREC_RV64] Added 0F 38 C8..CD opcodes

* [DYNAREC_RV64] Added DF C0..C7 FFREEP opcodes
2023-12-24 18:03:41 +01:00
ptitSeb 68e3c2be9b Merge branch 'main' of https://github.com/ptitSeb/box64 2023-12-24 17:16:37 +01:00
ptitSeb 099df7a0ee Reviewed signatures of libxcb and libdbus libs 2023-12-24 17:16:27 +01:00
xctan 21b6537215 [DYNAREC_RV64] Ported INT 3/29 from arm (#1161) 2023-12-24 15:50:29 +01:00
ptitSeb eb70f6d18e Added more wrapped signature to libnuma and libxcb (should help #531) 2023-12-24 14:00:13 +01:00
xctan 4ee6ae5da1 [DYNAREC_RV64] Fixed shift masks for GI (#1160)
* [DYNAREC_RV64] Fixed SHLD for GI

* [DYNAREC_RV64] Fixed SHRD for GI

* [DYNAREC_RV64] Fixed shamt mask of 16-bit shifts
2023-12-24 13:50:51 +01:00
ptitSeb 2c8d2d8643 Merge branch 'main' of https://github.com/ptitSeb/box64 2023-12-23 18:36:59 +01:00
ptitSeb 0582b45389 Apply parameters when binary is behind a symlink 2023-12-23 18:36:52 +01:00
ptitSeb f7cbe71bd9 [RCFILE] Refiled GridAutosport profile again 2023-12-23 12:53:43 +01:00
ptitSeb 1b87600658 [INTERPRETER] Added 64/65 86 opcode (for #1156) 2023-12-23 12:18:08 +01:00
Yang Liu 446fb9c99f [DYNAREC_RV64] Added more opcodes for ets2 (#1158)
* [DYNAREC_RV64] Added F3 0F 52 RSQRTSS opcode

* [DYNAREC_RV64] Added F0 81 /6 LOCK XOR opcode (aligned only)

* [DYNAREC_RV64] Added F3 0F 16 MOVSHDUP opcode

* Format
2023-12-23 10:26:34 +01:00
ptitSeb c774cb0c27 [RCFILE] Made so that BOX64_MAXCPU is the minimum value if set both on command line and a/many profile 2023-12-23 09:34:11 +01:00
ptitSeb 8ff9427a04 Small imrpovment to wrapped libc and mmap 2023-12-23 09:33:03 +01:00
ptitSeb b427e67619 Addedempty wrapped libidn2 (for quake 2 rtx) 2023-12-23 09:32:26 +01:00
xctan 6163f98020 Cleanup some code (#1157)
* Fix the size of random bytes in the auxiliary vector (AT_RANDOM) to 16 bytes

* [ELFLOADER] Remove an unused statement
2023-12-23 09:02:38 +01:00
Yang Liu 316b2fc98a [DYNAREC_RV64] Fixed some bugs in the dynarec for ETS2 (#1155)
* [DYNAREC_RV64] Fixed BSWAP

* [DYNAREC_RV64] Fixed 0F C2 CMPPS opcode
2023-12-22 20:27:10 +01:00
Yang Liu 9c73204224 [DYNAREC_RV64] Added more opcodes and fixes (#1154)
* [DYNAREC_RV64] Added 66 0F 38 28 PMULDQ opcode

* [DYNAREC_RV64] Added DD /6 FSAVE opcode

* [DYNAREC_RV64] Added 66 8C MOV opcode

* [DYNAREC_RV64] Fixed DF /1 /2 opcodes

* [DYNAREC_RV64] Added DB /1 FISTTP opcode
2023-12-22 16:51:33 +01:00
ptitSeb 7da59d5a39 [ARM64_DYNAREC] Added 64/65 23 opcode 2023-12-22 14:13:14 +01:00
ptitSeb a34b63b80d [ARM64_DYNAREC] Partial rollback of previous commit, it was not good 2023-12-22 12:38:01 +01:00
ptitSeb 5b335f0f26 [ARM64_DYNAREC] Small optim on CF flag computation for 8/16bits add/sub operations 2023-12-22 10:50:08 +01:00
ptitSeb 28af18f36e [RCFILE] Limit number of cores to 16 for Hue 2023-12-22 09:59:43 +01:00
liuli 10bb9f7079 [WRAPPER] add dbus_message_iter_get_element_count auto wrapper (#1153) 2023-12-22 09:10:23 +01:00
ptitSeb ed7006bbf4 [RCFILE] Refixed GridAutosport profile 2023-12-21 17:55:53 +01:00
ptitSeb b272f6bf15 Added/Fix some 16bits PUSH POP opcode ([ARM64_DYNAREC] too) (for DaveTheDiver, but not enough for it to run yet) 2023-12-21 16:05:54 +01:00
ptitSeb 715ce5dbe9 Introduce new BOX64_MAXCPU to cap the number of cpu core exposed, and created profile for wine, wine64 and GridAutosport using it 2023-12-21 15:51:55 +01:00
ptitSeb 7d0f807880 Allocated more cleanup when needed to avoid frequent resize 2023-12-21 15:48:42 +01:00
ptitSeb b66eccedc0 Added more wrapped function to libnss3, libnssutils3 and libnspr4 (for GridAutosport) 2023-12-21 14:38:56 +01:00
ptitSeb f79e725aa3 Removed a bridge field from librarian, it's not used anymore 2023-12-21 10:19:08 +01:00
Lily 66c4b6815f [RCFILE] Added FL64 Profile (#1149) 2023-12-20 20:16:07 +01:00
ptitSeb f073da1d27 This should fix x86_64 build 2023-12-20 18:21:07 +01:00
ptitSeb dad0d648a1 Expose max of 64 cpus core when Wine is launched (avoid buch of warning, and help Crysis Remastered) 2023-12-20 17:52:03 +01:00
ptitSeb f20262c5c8 [CMAKE] Asked minimum cmake version to be 3.13 2023-12-20 17:50:40 +01:00
ptitSeb 23b6617a3f Added 1 more syscall 2023-12-20 17:50:04 +01:00
ptitSeb ab5c02c2ae Removed old commented code 2023-12-20 17:49:47 +01:00
ptitSeb 1005cee4bc Small improvment on memory tracking 2023-12-20 17:49:29 +01:00
ptitSeb 95a1b12c07 Added syscall 316 2023-12-20 15:07:57 +01:00
ptitSeb 23542bbfee [INTERPRETER] Added 64/65 0F BA opcode (for #1146) 2023-12-18 15:56:38 +01:00
ptitSeb ec65c26b3c Merge remote-tracking branch 'refs/remotes/origin/main' 2023-12-18 14:16:04 +01:00
ptitSeb 837cc9dd93 [DYNAREC] This should avoid useless segfault on bridge creation 2023-12-18 14:15:10 +01:00
ptitSeb 88a8d1c209 [ARM64] Improved handling of unaligned access to device memory (for NVidia drivers, fixes No Man Sky) 2023-12-18 14:14:17 +01:00
Yang Liu f4b780b806 [DYNAREC_RV64] Added FILD/FISTP i64 optimization (#1145) 2023-12-18 11:38:42 +01:00
ptitSeb 3a296d237f [TRACE] Improve function name retreival in LOG=2 traces 2023-12-18 09:20:51 +01:00
ptitSeb db64c02bee [RCFILE] Fixed file leak 2023-12-18 09:20:01 +01:00
ptitSeb 97023ce1dd [VUKAN] Added 1 more extension 2023-12-18 09:19:41 +01:00
ptitSeb 3a87a2665d [RCFILE] Added Crysis Remastered profile 2023-12-18 09:18:17 +01:00
ptitSeb 6a2f4fb30d [STEAM] Improved pressure-vessel emulation 2023-12-18 09:17:41 +01:00
Yang Liu 49b9b70c29 [DYNAREC_RV64] Fixed some bugs in x87 infra (#1143) 2023-12-18 09:15:04 +01:00
ptitSeb 356340ad09 [ARM64] Added a new case of device memory unaligned write 2023-12-18 09:12:32 +01:00
ptitSeb 986bff1c22 Start of a new dev. cycle 2023-12-18 09:10:18 +01:00
1910 changed files with 274632 additions and 46613 deletions

No files matched your search

+4
View File
@@ -11,4 +11,8 @@ SortIncludes: false
MaxEmptyLinesToKeep: 2
IndentCaseLabels: true
AlignConsecutiveMacros: true
WhitespaceSensitiveMacros: ['QUOTE']
IfMacros: ['IFX', 'IFXORNAT', 'IFX2', 'IFXA', 'IFX_PENDOR0', 'IFXX', 'IFX2X', 'IFXN', 'UFLAG_IF', 'PASS2IF', 'IF_UNALIGNED', 'IF_ALIGNED']
UseTab: Never
IndentPPDirectives: None
---
+2 -2
View File
@@ -49,7 +49,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: "Checkout Box64 Repository"
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: "Environment preparation"
run: |
@@ -90,7 +90,7 @@ jobs:
make -j$(nproc) VERBOSE=1
- name: "Upload Artifact"
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: box64-${{ github.event.inputs.platform }}-${{ github.event.inputs.build_type }}
path: build/box64
+230 -35
View File
@@ -27,37 +27,79 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [X64, OTHER_ARM, RISCV, RPI4ARM64, RPI5ARM64, RK3326, RK3399, RK3588, PHYTIUM, SD845, SD888, ADLINK, ARM64, ANDROID]
type: [Release, Trace]
os: [ubuntu-latest]
include:
- platform: TEGRAX1
type: Release
os: ubuntu-20.04
- platform: TEGRAX1
type: Trace
os: ubuntu-20.04
platform: [X64, RISCV, RK3588, ARM64, ANDROID, TERMUX, LARCH64, ANDROID_GLIBC]
type: [Release, Trace, StaticBuild, Box32]
os: [ubuntu-latest, ubuntu-22.04-arm]
exclude:
- platform: ANDROID
type: StaticBuild
- platform: TERMUX
type: StaticBuild
- platform: X64
type: StaticBuild
- platform: ANDROID
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
runs-on: ${{ matrix.os }}
steps:
- name: "Checkout Box64 Repository"
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: "Environment preparation"
run: |
sudo apt-get update
if [[ ${{ matrix.platform }} != 'X64' && ${{ matrix.platform }} != 'OTHER_ARM' && ${{ matrix.platform }} != 'RISCV' ]]; then
sudo apt-get -y install git cmake make python3
if [[ ${{ matrix.platform }} == 'ANDROID' ]]; then
wget https://dl.google.com/android/repository/android-ndk-r23b-linux.zip
unzip android-ndk-r23b-linux.zip
echo "BOX64_COMPILER=$PWD/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android31-clang" >> $GITHUB_ENV
echo "BOX64_PLATFORM_MARCRO=-DANDROID=1 -DARM_DYNAREC=1 -DNOLOADADDR=1" >> $GITHUB_ENV
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
sudo apt-get -y install p7zip
wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip
unzip 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
sudo cp -rf termux-docker/system/arm /system
sudo chown -R $(whoami):$(whoami) /system
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 -DWINLATOR_GLIBC=1 -DARM_DYNAREC=1 -DBAD_SIGNAL=1" >> $GITHUB_ENV
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $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
wget https://mirrors.utermux.dev/termux/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 /
sudo chmod 755 -R /data
sudo chown -R $(whoami):$(whoami) /data
echo "CFLAGS=-L/data/data/com.termux/files/usr/lib" >> $GITHUB_ENV
echo "IS_TERMUX=1" >> $GITHUB_ENV
echo "QEMU_SET_ENV=LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib" >> $GITHUB_ENV
else
echo "IS_TERMUX=0" >> $GITHUB_ENV
fi
else
if [[ ${{ matrix.platform }} == 'X64' ]]; then
echo "BOX64_PLATFORM_MARCRO=-DLD80BITS=1 -DNOALIGN=1" >> $GITHUB_ENV
@@ -66,7 +108,22 @@ 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
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 -
sudo ln -sf /usr/local/larch/target /usr/loongarch64-linux-gnu
sudo cp -r /usr/local/larch/loongarch64-unknown-linux-gnu/lib/* /usr/loongarch64-linux-gnu/lib64/
for i in objdump objcopy strip; do
sudo ln -sf /usr/local/larch/bin/loongarch64-unknown-linux-gnu-$i /usr/bin/loongarch64-linux-gnu-$i
done
echo '/usr/local/larch/bin/loongarch64-unknown-linux-gnu-gcc -L/usr/local/larch/loongarch64-unknown-linux-gnu "$@"' | sudo tee /usr/bin/loongarch64-linux-gnu-gcc
echo '/usr/local/larch/bin/loongarch64-unknown-linux-gnu-g++ -L/usr/local/larch/loongarch64-unknown-linux-gnu "$@"' | sudo tee /usr/bin/loongarch64-linux-gnu-g++
sudo chmod 755 /usr/bin/loongarch64-linux-gnu-{gcc,g++}
echo BOX64_PLATFORM_MARCRO="-DLARCH64=ON" >> $GITHUB_ENV
echo "BOX64_COMPILER=loongarch64-linux-gnu-gcc" >> $GITHUB_ENV
sudo apt-get -y install git cmake make python3
else
echo BOX64_PLATFORM_MARCRO="-DARM_DYNAREC=ON" >> $GITHUB_ENV
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
@@ -76,57 +133,195 @@ jobs:
if [[ ${{ matrix.type }} == 'Release' ]]; then
echo BOX64_BUILD_TYPE=Release >> $GITHUB_ENV
echo BOX64_HAVE_TRACE=0 >> $GITHUB_ENV
echo BOX64_STATICBUILD=0 >> $GITHUB_ENV
echo BOX64_BOX32=0 >> $GITHUB_ENV
elif [[ ${{ matrix.type }} == 'StaticBuild' ]]; then
echo BOX64_BUILD_TYPE=Release >> $GITHUB_ENV
echo BOX64_HAVE_TRACE=0 >> $GITHUB_ENV
echo BOX64_STATICBUILD=1 >> $GITHUB_ENV
echo BOX64_BOX32=0 >> $GITHUB_ENV
elif [[ ${{ matrix.type }} == 'Box32' ]]; then
echo BOX64_BUILD_TYPE=Release >> $GITHUB_ENV
echo BOX64_HAVE_TRACE=0 >> $GITHUB_ENV
echo BOX64_STATICBUILD=0 >> $GITHUB_ENV
echo BOX64_BOX32=1 >> $GITHUB_ENV
else
echo BOX64_BUILD_TYPE=RelWithDebInfo >> $GITHUB_ENV
echo BOX64_HAVE_TRACE=1 >> $GITHUB_ENV
echo BOX64_STATICBUILD=0 >> $GITHUB_ENV
echo BOX64_BOX32=0 >> $GITHUB_ENV
fi
- name: "Get XuanTie QEMU Cache Key"
if: matrix.platform == 'RISCV'
id: get-xuantie-qemu-cache-key
run: |
echo "key=f2dfdd13014d51f957c7172acc2e791cb42dc400" >> $GITHUB_OUTPUT
- name: "Cache XuanTie QEMU"
if: matrix.platform == 'RISCV'
id: cache-xuantie-qemu
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/xuantie_qemu_install
key: ${{ runner.os }}-${{ steps.get-xuantie-qemu-cache-key.outputs.key }}-xuantie-qemu
- name: "Checkout XuanTie QEMU"
if: matrix.platform == 'RISCV' && steps.cache-xuantie-qemu.outputs.cache-hit != 'true'
uses: actions/checkout@v3
with:
repository: revyos/qemu
path: xuantie_qemu
ref: f2dfdd13014d51f957c7172acc2e791cb42dc400
- name: "Build XuanTie QEMU for XTheadVector"
if: matrix.platform == 'RISCV' && steps.cache-xuantie-qemu.outputs.cache-hit != 'true'
run: |
cd xuantie_qemu
./configure --prefix=$GITHUB_WORKSPACE/xuantie_qemu_install --target-list=riscv64-linux-user --disable-system
make -j$(nproc)
make install
- name: "Display Build info"
run: |
echo "CMake Platform Macro: ${{ env.BOX64_PLATFORM_MARCRO }}"
echo "CMake C Compiler: ${{ env.BOX64_COMPILER }}"
echo "Build type: ${{ env.BOX64_BUILD_TYPE }}"
echo "Trace Enabled: ${{ env.BOX64_HAVE_TRACE }}"
echo "StaticBuild Enabled: ${{ env.BOX64_STATICBUILD }}"
echo "Box32 Enabled: ${{ env.BOX64_BOX32 }}"
- name: "Build Box64"
run: |
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=${{ env.BOX64_COMPILER }}\
-DTERMUX=${{ env.IS_TERMUX }}\
${{ env.BOX64_PLATFORM_MARCRO }}\
-DCMAKE_BUILD_TYPE=${{ env.BOX64_BUILD_TYPE }}\
-DHAVE_TRACE=${{ env.BOX64_HAVE_TRACE }}\
-DSTATICBUILD=${{ env.BOX64_STATICBUILD }}\
-DBOX32=${{ env.BOX64_BOX32 }}\
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON\
-DCI=${{ matrix.platform != 'ANDROID' }}
make -j$(nproc) VERBOSE=1
- name: "Test Box64"
if: ${{ matrix.platform != 'TEGRAX1' }}
run: |
if [[ ${{ matrix.platform }} != 'X64' && ${{ matrix.platform }} != 'ANDROID' ]]; then
mkdir qemu8.1.0
wget -O- -q https://archive.archlinux.org/packages/q/qemu-user-static/qemu-user-static-8.1.0-2-x86_64.pkg.tar.zst | tar -I zstd -C qemu8.1.0 -xf -
sudo cp qemu8.1.0/usr/bin/* /usr/bin/
if [[ ${{ matrix.platform }} != 'X64' ]]; then
mkdir qemu9
wget -O- -q https://archive.archlinux.org/packages/q/qemu-user-static/qemu-user-static-9.0.2-1-x86_64.pkg.tar.zst | tar -I zstd -C qemu9 -xf -
sudo cp qemu9/usr/bin/* /usr/bin/
fi
cd build
export CTEST_OPTIONS="-j$(nproc) --timeout 120 --output-on-failure --repeat until-pass:20"
if [[ ${{ matrix.platform }} == 'RISCV' ]]; then
INTERPRETER=qemu-riscv64-static QEMU_LD_PREFIX=/usr/riscv64-linux-gnu/ ctest -j$(nproc) --rerun-failed --output-on-failure
INTERPRETER=qemu-riscv64-static QEMU_LD_PREFIX=/usr/riscv64-linux-gnu/ BOX64_DYNAREC=0 ctest -j$(nproc) --rerun-failed --output-on-failure
INTERPRETER=qemu-riscv64-static QEMU_LD_PREFIX=/usr/riscv64-linux-gnu/ QEMU_CPU=rv64,zba=true,zbb=true,zbc=true,zbs=true ctest -j$(nproc) --rerun-failed --output-on-failure
INTERPRETER=qemu-riscv64-static QEMU_LD_PREFIX=/usr/riscv64-linux-gnu/ QEMU_CPU=rv64,xtheadba=true,xtheadba=true,xtheadbb=true,xtheadbs=true,xtheadcondmov=true,xtheadmemidx=true,xtheadmempair=true,xtheadfmemidx=true,xtheadmac=true,xtheadfmv=true ctest -j$(nproc) --rerun-failed --output-on-failure
elif [[ ${{ matrix.platform }} != 'X64' && ${{ matrix.platform }} != 'ANDROID' ]]; then # AArch64
INTERPRETER=qemu-aarch64-static QEMU_LD_PREFIX=/usr/aarch64-linux-gnu/ BOX64_DYNAREC=0 ctest -j$(nproc) --rerun-failed --output-on-failure
INTERPRETER=qemu-aarch64-static QEMU_LD_PREFIX=/usr/aarch64-linux-gnu/ ctest -j$(nproc) --rerun-failed --output-on-failure
export INTERPRETER=qemu-riscv64-static
export QEMU_LD_PREFIX=/usr/riscv64-linux-gnu/
ctest $CTEST_OPTIONS
QEMU_CPU=rv64,v=false BOX64_DYNAREC=0 ctest $CTEST_OPTIONS
QEMU_CPU=rv64,v=false,zba=true,zbb=true,zbc=true,zbs=true ctest $CTEST_OPTIONS
QEMU_CPU=rv64,v=true,vlen=128,vext_spec=v1.0 ctest $CTEST_OPTIONS
QEMU_CPU=rv64,v=true,vlen=256,vext_spec=v1.0 ctest $CTEST_OPTIONS
QEMU_CPU=thead-c906 ctest $CTEST_OPTIONS
BOX64_DYNAREC_TEST=1 ctest $CTEST_OPTIONS -E nocosim
BOX64_DYNAREC_TEST=1 QEMU_CPU=rv64,v=false,zba=true,zbb=true,zbc=true,zbs=true ctest $CTEST_OPTIONS -E nocosim
BOX64_DYNAREC_TEST=1 QEMU_CPU=rv64,v=true,vlen=128,vext_spec=v1.0 ctest $CTEST_OPTIONS -E nocosim
BOX64_DYNAREC_TEST=1 QEMU_CPU=rv64,v=true,vlen=256,vext_spec=v1.0 ctest $CTEST_OPTIONS -E nocosim
BOX64_DYNAREC_TEST=1 QEMU_CPU=thead-c906 ctest $CTEST_OPTIONS -E nocosim
export INTERPRETER=$GITHUB_WORKSPACE/xuantie_qemu_install/bin/qemu-riscv64
QEMU_CPU=c910v ctest $CTEST_OPTIONS
BOX64_DYNAREC_TEST=1 QEMU_CPU=c910v ctest $CTEST_OPTIONS -E nocosim
elif [[ ${{ matrix.platform }} == 'LARCH64' ]]; then
export INTERPRETER=qemu-loongarch64-static
export QEMU_LD_PREFIX=/usr/loongarch64-linux-gnu/
BOX64_DYNAREC_LA64NOEXT=1 ctest $CTEST_OPTIONS -E nocosim
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS -E nocosim
BOX64_DYNAREC_TEST=1 BOX64_DYNAREC_LA64NOEXT=1 ctest $CTEST_OPTIONS -E nocosim
elif [[ ${{ matrix.platform }} == 'ANDROID' ]]; then
true
export INTERPRETER=qemu-aarch64-static
export QEMU_LD_PREFIX=/system/lib64
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS
ctest $CTEST_OPTIONS
elif [[ ${{ matrix.platform }} == 'TERMUX' ]]; then
export INTERPRETER=qemu-aarch64-static
export QEMU_SET_ENV=LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib
export QEMU_LD_PREFIX=/system/lib64:/data/data/com.termux/files/usr/lib
BOX64_DYNAREC=0 ctest $CTEST_OPTIONS
ctest $CTEST_OPTIONS
else
BOX64_DYNAREC=0 ctest -j$(nproc) --rerun-failed --output-on-failure
ctest -j$(nproc) --rerun-failed --output-on-failure
ctest -j$(nproc)
fi
- name: "Get short Git commit"
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: |
cd build
cat <<EOF > profile.json
{
"type": "Box64",
"versionName": "latest-${SHORT_COMMIT}",
"versionCode": 1,
"description": "Box64-latest-${SHORT_COMMIT}. Built from [https://github.com/ptitSeb/box64].",
"files": [
{
"source": "box64",
"target": "\${localbin}/box64"
}
]
}
EOF
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: "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 Artifact"
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: box64-${{ matrix.platform }}-${{ matrix.type }}
path: build/box64
- name: "Upload WCP file"
if: matrix.platform == 'ANDROID_GLIBC' && matrix.type != 'StaticBuild'
uses: actions/upload-artifact@v4
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
+24 -5
View File
@@ -60,11 +60,30 @@ build*/
src/git_head.h
backup/
# LLVMprivateGenerator
/LLVMprivateGenerator/*
!/LLVMprivateGenerator/Makefile
!/LLVMprivateGenerator/main.cpp
!/LLVMprivateGenerator/registered_structs.cpp
# Wrapper helper
/wrapperhelper/bin
/wrapperhelper/makedir
/wrapperhelper/obj
/wrapperhelper/sanaddress
/wrapperhelper/sanleak
/wrapperhelper/sanundefined
/wrapperhelper/src/machine.gen
/wrapperhelper/*.h
!/wrapperhelper/example-libc.h
# macOS
.DS_Store
# Archives
*.7z
*.deb
*.eopkg
*.gz
*.rar
*.rpm
*.tar*
*.xbps
*.xz
*.zip
*.zst
*.zstd
+781 -78
View File
File diff suppressed because it is too large. Load diff
-12
View File
@@ -1,12 +0,0 @@
all: dumpSigs
dumpSigs: main.o registered_structs.o
g++ -g3 -std=gnu++17 -fno-rtti main.o registered_structs.o -o dumpSigs "-L$(LLVM_install_dir)/lib" -lclang-cpp -lclangTooling -Wl,-rpath "-Wl,$(LLVM_install_dir)/lib"
main.o: main.cpp
g++ -g3 -std=gnu++17 -fno-rtti -c main.cpp -Wfatal-errors "-I$(LLVM_install_dir)/include" -o main.o
registered_structs.o: registered_structs.cpp
g++ -g3 -std=gnu++17 -fno-rtti -c registered_structs.cpp -Wfatal-errors -o registered_structs.o
clean:
$(RM) dumpSigs main.o registered_structs.o
-458
View File
@@ -1,458 +0,0 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include <numeric>
#include <unordered_map>
#include <utility>
#include <vector>
#include <llvm/Support/raw_ostream.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/AST/Decl.h>
#include <clang/AST/Mangle.h>
#include <clang/AST/PrettyPrinter.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
clang::MangleContext *mangler = nullptr;
std::unordered_map<std::string, std::pair<std::string, bool>> funMap;
std::vector<std::string> funList;
bool isTypeTrivial(const clang::QualType &q, const clang::QualType *qorig);
clang::QualType getPointedType(const clang::QualType q) {
if (const clang::PointerType *p = q->getAs<clang::PointerType>())
return getPointedType(p->getPointeeType());
else if (const clang::ReferenceType *r = q->getAs<clang::ReferenceType>())
return getPointedType(r->getPointeeType());
else
return q;
}
std::string record2name(const clang::RecordDecl &q, const clang::QualType *qorig) {
std::string s = q.getNameAsString();
if (s == "") {
if (!qorig) return "????.!";
if (const clang::TypedefType *tt = (*qorig)->getAs<clang::TypedefType>()) {
// Typedef
if (clang::TypedefNameDecl *td = tt->getDecl()) {
return td->getNameAsString();
} else {
return "<typedef with no declaration>";
}
} else {
return std::string("<unknown type ") + (*qorig)->getTypeClassName() + ">";
}
} else {
return s;
}
}
char ptr2char(const std::string &str) __attribute__((const));
const char *ptr2str(const std::string &str) __attribute__((const));
char type2char(const clang::QualType &qual /* Canonical */, const clang::QualType *qorig) {
if (qual->isBuiltinType()) {
switch (static_cast<const clang::BuiltinType&>(*qual).getKind()) {
case clang::BuiltinType::Kind::Void:
return 'v';
case clang::BuiltinType::Kind::Bool:
return 'i';
case clang::BuiltinType::Kind::Char_U:
return 'C';
case clang::BuiltinType::Kind::Char_S:
return 'c';
case clang::BuiltinType::Kind::Char8:
return 'c';
case clang::BuiltinType::Kind::UChar:
return 'C';
case clang::BuiltinType::Kind::SChar:
return 'c';
case clang::BuiltinType::Kind::WChar_U:
return 'W';
case clang::BuiltinType::Kind::UShort:
return 'W';
case clang::BuiltinType::Kind::WChar_S:
return 'w';
case clang::BuiltinType::Kind::Char16:
return 'w';
case clang::BuiltinType::Kind::Short:
return 'w';
case clang::BuiltinType::Kind::UInt:
return 'u';
case clang::BuiltinType::Kind::Char32:
return 'i';
case clang::BuiltinType::Kind::Int:
return 'i';
case clang::BuiltinType::Kind::ULong:
return 'L';
case clang::BuiltinType::Kind::Long:
return 'l';
case clang::BuiltinType::Kind::ULongLong:
return 'U';
case clang::BuiltinType::Kind::LongLong:
return 'I';
case clang::BuiltinType::Kind::UInt128:
return 'H';
case clang::BuiltinType::Kind::Int128:
return 'H';
case clang::BuiltinType::Kind::Float:
return 'f';
case clang::BuiltinType::Kind::Double:
return 'd';
case clang::BuiltinType::Kind::LongDouble:
return 'D';
case clang::BuiltinType::Kind::NullPtr:
return 'p'; // nullptr_t
case clang::BuiltinType::Kind::Half:
case clang::BuiltinType::Kind::BFloat16:
case clang::BuiltinType::Kind::ShortAccum:
case clang::BuiltinType::Kind::Accum:
case clang::BuiltinType::Kind::LongAccum:
case clang::BuiltinType::Kind::UShortAccum:
case clang::BuiltinType::Kind::UAccum:
case clang::BuiltinType::Kind::ULongAccum:
case clang::BuiltinType::Kind::ShortFract:
case clang::BuiltinType::Kind::Fract:
case clang::BuiltinType::Kind::LongFract:
case clang::BuiltinType::Kind::UShortFract:
case clang::BuiltinType::Kind::UFract:
case clang::BuiltinType::Kind::ULongFract:
case clang::BuiltinType::Kind::SatShortAccum:
case clang::BuiltinType::Kind::SatAccum:
case clang::BuiltinType::Kind::SatLongAccum:
case clang::BuiltinType::Kind::SatUShortAccum:
case clang::BuiltinType::Kind::SatUAccum:
case clang::BuiltinType::Kind::SatULongAccum:
case clang::BuiltinType::Kind::SatShortFract:
case clang::BuiltinType::Kind::SatFract:
case clang::BuiltinType::Kind::SatLongFract:
case clang::BuiltinType::Kind::SatUShortFract:
case clang::BuiltinType::Kind::SatUFract:
case clang::BuiltinType::Kind::SatULongFract:
case clang::BuiltinType::Kind::Float16:
case clang::BuiltinType::Kind::Float128:
case clang::BuiltinType::Kind::Overload:
case clang::BuiltinType::Kind::BoundMember:
case clang::BuiltinType::Kind::PseudoObject:
case clang::BuiltinType::Kind::Dependent:
case clang::BuiltinType::Kind::UnknownAny:
case clang::BuiltinType::Kind::ARCUnbridgedCast:
case clang::BuiltinType::Kind::BuiltinFn:
case clang::BuiltinType::Kind::ObjCId:
case clang::BuiltinType::Kind::ObjCClass:
case clang::BuiltinType::Kind::ObjCSel:
#define IMAGE_TYPE(it, id, si, a, s) case clang::BuiltinType::Kind::id:
#include <clang/Basic/OpenCLImageTypes.def>
#undef IMAGE_TYPE
case clang::BuiltinType::Kind::OCLSampler:
case clang::BuiltinType::Kind::OCLEvent:
case clang::BuiltinType::Kind::OCLClkEvent:
case clang::BuiltinType::Kind::OCLQueue:
case clang::BuiltinType::Kind::OCLReserveID:
case clang::BuiltinType::Kind::IncompleteMatrixIdx:
case clang::BuiltinType::Kind::OMPArraySection:
case clang::BuiltinType::Kind::OMPArrayShaping:
case clang::BuiltinType::Kind::OMPIterator:
#define EXT_OPAQUE_TYPE(et, id, e) case clang::BuiltinType::Kind::id:
#include <clang/Basic/OpenCLExtensionTypes.def>
#define SVE_TYPE(n, id, si) case clang::BuiltinType::Kind::id:
#include <clang/Basic/AArch64SVEACLETypes.def>
#define PPC_VECTOR_TYPE(n, id, s) case clang::BuiltinType::Kind::id:
#include <clang/Basic/PPCTypes.def>
#undef EXT_OPAQUE_TYPE
#undef SVE_TYPE
#undef PPC_VECTOR_TYPE
return '!';
default:
return ':';
}
} else if (qual->isEnumeralType()) {
const clang::EnumDecl *ed = qual->getAs<clang::EnumType>()->getDecl();
if (!ed) {
return 'i';
} else {
return type2char(ed->getIntegerType().getCanonicalType(), qorig);
}
} else if (qual->isFunctionPointerType()) {
return '@';
} else if (qual->isAnyPointerType() || qual->isReferenceType()) {
const clang::QualType &pointed = getPointedType(qual);
if (isTypeTrivial(pointed, qorig)) {
return 'p';
} else if (const clang::RecordType *rct = pointed->getAs<clang::RecordType>()) {
clang::RecordDecl *rc = rct->getDecl();
if (!rc) {
return '!';
} else if (!rc->isCompleteDefinition()) {
return 'p';
} else {
std::string str;
if (qorig) {
const clang::QualType qpted = getPointedType(*qorig);
str = record2name(*rc, &qpted);
} else {
str = record2name(*rc, nullptr);
}
char ret = ptr2char(str);
if (ret) return ret;
else {
return '!';
}
}
} else {
return '!';
}
} else if (const clang::RecordType *rct = qual->getAs<clang::RecordType>()) {
clang::RecordDecl *rc = rct->getDecl();
if (!rc) {
return '?';
} else if (rc->getNameAsString() == "__builtin_va_list") {
// va_list
return 'A';
} else {
return '?';
}
} else {
return '?';
}
}
bool isTypeTrivial(const clang::QualType &q, const clang::QualType *qorig) {
const char c = type2char(q, qorig);
#define GO(chr) || (c == chr)
return (c == 'v')
GO('i') GO('u')
GO('I') GO('U')
GO('l') GO('L')
GO('f') GO('d')
GO('D') GO('K')
GO('0') GO('1')
GO('C') GO('c')
GO('W') GO('w')
GO('H')
GO('p');
#undef GO
}
bool isTypeValid(const clang::QualType &q, const clang::QualType *qorig) {
const char c = type2char(q, qorig);
if (c == 'A') return false;
if (c == 'V') return false;
return ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'));
}
const std::string type2string(const clang::QualType &qual, const clang::QualType *qorig) {
if (qual->isBuiltinType()) {
return std::string("(builtin) ") + static_cast<const clang::BuiltinType&>(*qual).getName(clang::PrintingPolicy{{}}).data();
} else if (qual->isFunctionPointerType()) {
return "Callback (function pointer)";
} else if (qual->isAnyPointerType() || qual->isReferenceType()) {
std::string prefix = qual->isAnyPointerType() ? "Pointer to " : "Reference to ";
const clang::QualType &pointed = getPointedType(qual);
if (isTypeTrivial(pointed, qorig)) {
return prefix + "trivial object " + type2string(pointed, qorig) + " (" + type2char(pointed, qorig) + ")";
} else if (const clang::RecordType *rct = pointed->getAs<clang::RecordType>()) {
clang::RecordDecl *rc = rct->getDecl();
if (!rc) {
return prefix + "unknown record";
} else if (!rc->isCompleteDefinition()) {
return prefix + "incomplete record " + rc->getNameAsString();
} else {
std::string str;
if (qorig) {
const clang::QualType qpted = getPointedType(*qorig);
str = record2name(*rc, &qpted);
} else {
str = record2name(*rc, nullptr);
}
const char *ret = ptr2str(str);
if (ret[0] != '\0') {
return prefix + ret;
} else {
if (mangler && mangler->shouldMangleDeclName(rc)) {
std::string mangled;
{
llvm::raw_string_ostream strstr{mangled};
mangler->mangleName(rc, strstr);
}
return prefix + "unknown record " + str + " (=== " + mangled + ")";
} else {
return prefix + "unknown record " + str;
}
}
}
} else {
return prefix + "non-trivial or typedef'ed object " + type2string(pointed, qorig) + " (" + type2char(pointed, qorig) + ")";
//return "Pointer (maybe to callback)";
}
} else if (qual->isEnumeralType()) {
const clang::EnumDecl *ed = qual->getAs<clang::EnumType>()->getDecl();
if (!ed) {
return "Enumeration with unknown underlying integer type (assuming int)";
} else {
return "Enumeration with underlying type " + type2string(ed->getIntegerType().getCanonicalType(), nullptr);
}
} else if (const clang::RecordType *rct = qual->getAs<clang::RecordType>()) {
clang::RecordDecl *rc = rct->getDecl();
if (!rc) {
return "Unknown record";
} else if (rc->getNameAsString() == "__builtin_va_list") {
return "va_list";
} else {
return "Unknown record " + std::string(rc->getName().data());
}
} else {
return std::string("??? ") + qual->getTypeClassName();
}
}
class Visitor : public clang::RecursiveASTVisitor<Visitor> {
public:
clang::ASTContext &context;
bool shouldVisitTemplateInstantiations() const /* override */ { return true; }
Visitor(clang::CompilerInstance &ci) : context(ci.getASTContext()) {
if (!mangler) {
mangler = clang::ItaniumMangleContext::create(context, ci.getDiagnostics());
}
}
~Visitor() {
if (mangler) {
delete mangler;
mangler = nullptr;
}
}
bool VisitDecl(clang::Decl *decl) /* override */ {
std::cerr << std::flush;
if (!decl) return true;
if ((decl->getKind() >= clang::Decl::Kind::firstFunction) && (decl->getKind() <= clang::Decl::Kind::lastFunction)) {
clang::DeclaratorDecl *ddecl = static_cast<clang::DeclaratorDecl*>(decl);
std::cout << "Function detected!\n";
std::string funName{ddecl->getName()};
auto niceprint = [](const std::string &infotype, const auto &dat){ std::cout << " " << infotype << ": " << dat << "\n"; };
niceprint("Function name", funName);
if (mangler && mangler->shouldMangleDeclName(ddecl)) {
std::string mangled;
{
llvm::raw_string_ostream strstr{mangled};
mangler->mangleName(ddecl, strstr);
}
niceprint("Function mangled name", mangled);
funName = std::move(mangled);
}
bool valid;
std::string funTypeStr{""};
if (ddecl->getFunctionType()->isFunctionNoProtoType()) {
const clang::FunctionNoProtoType *funType = static_cast<const clang::FunctionNoProtoType*>(ddecl->getFunctionType());
const auto &retType = funType->getReturnType();
niceprint("Function return type", type2string(retType, &retType));
niceprint("Canonical function return type",
type2string(retType.getCanonicalType(), &retType) +
" (" + type2char(retType.getCanonicalType(), &retType) + ")");
niceprint("Is sugared", funType->isSugared());
if (funType->isSugared()) {
clang::QualType qft{funType, 0};
niceprint("Desugared", type2string(funType->desugar(), &qft));
}
funTypeStr = type2char(retType.getCanonicalType(), &retType) + std::string("Fv");
valid = isTypeValid(retType.getCanonicalType(), &retType);
} else {
const clang::FunctionProtoType *funType = static_cast<const clang::FunctionProtoType*>(ddecl->getFunctionType());
const auto &retType = funType->getReturnType();
niceprint("Function return type", type2string(retType, &retType));
niceprint("Canonical function return type",
type2string(retType.getCanonicalType(), &retType)
+ " (" + type2char(retType.getCanonicalType(), &retType) + ")");
niceprint("Parameter count", funType->getNumParams());
for (const clang::QualType &type : funType->getParamTypes()) {
niceprint(" " + type2string(type, &type),
type2string(type.getCanonicalType(), &type) + " (" + type2char(type.getCanonicalType(), &type) + ")");
}
niceprint("Variadic function", funType->isVariadic() ? "yes" : "no");
funTypeStr =
type2char(retType.getCanonicalType(), &retType) +
((funType->getNumParams() == 0)
? std::string("Fv") : std::accumulate(funType->getParamTypes().begin(), funType->getParamTypes().end(), std::string("F"),
[](const std::string &acc, const clang::QualType &qual){ return acc + type2char(qual.getCanonicalType(), &qual); }));
if (funType->isVariadic()) funTypeStr += "V";
valid = !funType->isVariadic() &&
std::accumulate(funType->getParamTypes().begin(), funType->getParamTypes().end(), isTypeValid(retType.getCanonicalType(), &retType),
[](bool acc, const clang::QualType &qual){ return acc && isTypeValid(qual.getCanonicalType(), &qual); });
}
niceprint("Conclusion", "");
niceprint("Function final name", funName);
niceprint("Function type", funTypeStr);
niceprint("Valid function type", valid ? "yes" : "no");
std::cout << "\n";
funMap[funName] = std::make_pair(funTypeStr, valid);
funList.push_back(funName);
}
return true;
}
};
class Consumer : public clang::ASTConsumer {
public:
Visitor visitor;
Consumer(clang::CompilerInstance &ci) : visitor(ci) {
}
void HandleTranslationUnit(clang::ASTContext &context) override {
visitor.TraverseDecl(context.getTranslationUnitDecl());
}
};
class Action : public clang::ASTFrontendAction {
public:
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &ci, llvm::StringRef inFile) override {
return std::make_unique<Consumer>(ci);
}
};
int main(int argc, const char **argv) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " (filenames) -- [-I...]" << std::endl;
return 2;
}
/*int fakeargc = argc + 1;
const char **fakeargv = new const char*[fakeargc];
memcpy(fakeargv, argv, argc * sizeof(char*));
fakeargv[fakeargc - 1] = "--";*/
llvm::cl::OptionCategory opcat{""};
clang::tooling::CommonOptionsParser op{argc, argv, opcat};
std::vector<std::string> paths; for (int i = 1; i < argc; ++i) paths.push_back(argv[i]);
clang::tooling::ClangTool tool{op.getCompilations(), paths};
tool.run(clang::tooling::newFrontendActionFactory<Action>().get());
std::cout << "Done, outputing output.h" << std::endl;
std::sort(funList.begin(), funList.end());
std::fstream file{"output.h", std::ios_base::out};
for (const std::string &funName : funList) {
if (!funMap[funName].second) {
file << "//";
}
file << "GO(" << funName << ", " << funMap[funName].first << ")\n";
}
return 0;
}
-267
View File
@@ -1,267 +0,0 @@
#include <string>
#define ALL START() \
/* libc */ \
STRUCT("_IO_FILE", "a FILE") \
STRUCT("_G_fpos_t", "a file position") \
STRUCT("sockaddr", "a socket address") \
STRUCT("itimerspec", "an itimerspec") \
STRUCT("timespec", "a timespec") \
STRUCT("itimerval", "an itimerval") \
STRUCT("timeval", "a timeval") \
STRUCT("timex", "a timex") \
STRUCT("timezone", "a timezone") \
STRUCT("dirent", "a dirent") \
STRUCT("dirent64", "a dirent64") \
STRUCT("__dirstream", "a dir stream") \
STRUCT("tm", "a time structure (tm)") \
STRUCT("cmsghdr", "a cmsghdr") \
STRUCT("msghdr", "a msghdr") \
STRUCT("rpcent", "an rpcent") \
STRUCT("random_data", "a random_data structure") \
STRUCT("drand48_data", "a drand48_data structure") \
STRUCT("termios", "a termios") \
STRUCT("iovec", "an iovec") \
STRUCT("file_handle", "a file handle") \
STRUCT("lconv", "an lconv") \
STRUCT("__locale_struct", "a locale structure") \
STRUCT("aliasent", "an alias") \
STRUCT("fstab", "an fstab") \
STRUCT("group", "a group") \
STRUCT("hostent", "a hostent") \
STRUCT("protoent", "a protoent") \
STRUCT("passwd", "a password") \
STRUCT("spwd", "an spwd") \
STRUCT("ttyent", "a ttyent") \
STRUCT("utmp", "an utmp structure") \
STRUCT("utmpx", "an utmpx structure") \
STRUCT("ifaddrs", "an ifaddrs structure") \
STRUCT("statfs", "a statfs structure") \
STRUCT("statfs64", "a statfs64 structure") \
STRUCT("statvfs", "a statvfs structure") \
STRUCT("statvfs64", "a statvfs64 structure") \
STRUCT("timeb", "a timeb structure") \
STRUCT("_ftsent", "an _ftsent structure") \
STRUCT("sysinfo", "a sysinfo structure") \
STRUCT("rlimit", "an rlimit structure") \
STRUCT("rlimit64", "an rlimit64 structure") \
STRUCT("rusage", "an rusage structure") \
STRUCT("entry", "an entry structure") \
STRUCT("pollfd", "a pollfd structure") \
STRUCT("re_pattern_buffer", "a re_pattern_buffer structure") \
STRUCT("sembuf", "a sembuf structure") \
STRUCT("tms", "a tms structure") \
STRUCT("utsname", "an utsname structure") \
STRUCT("utimbuf", "an utimbuf structure") \
STRUCT2("__va_list_tag", "__va_list_tag (aka, a va_list)", 'A') \
/* ncurses */ \
STRUCT("_win_st", "a _win_st structure") \
STRUCT("MEVENT", "an MEVENT structure") \
TYPEDEF("cchar_t", "a cchar_t") \
/* zlib */ \
STRUCT("gz_header_s", "a gz_header_s structure") \
STRUCT("gzFile_s", "a gzFile_s structure") \
STRUCT("z_stream_s", "a z_stream_s structure") \
\
END()
#define START()
#define STRUCT(s, ret) if (str == s) { return 'p'; } else
#define STRUCT2(s, ret, c) if (str == s) { return c; } else
#define TYPEDEF(s, ret) if (str == s) { return 'p'; } else
#define END() { return 0; }
char ptr2char(const std::string &str) {
/*if ((str == "_IO_FILE")
|| (str == "_G_fpos_t")
|| (str == "sockaddr")
|| (str == "itimerspec")
|| (str == "timespec")
|| (str == "itimerval")
|| (str == "timeval")
|| (str == "timex")
|| (str == "timezone")
|| (str == "dirent")
|| (str == "dirent64")
|| (str == "__dirstream")
|| (str == "tm")
|| (str == "cmsghdr")
|| (str == "msghdr")
|| (str == "rpcent")
|| (str == "random_data")
|| (str == "drand48_data")
|| (str == "termios")
|| (str == "iovec")
|| (str == "file_handle")
|| (str == "lconv")
|| (str == "__locale_struct")
|| (str == "aliasent")
|| (str == "fstab")
|| (str == "group")
|| (str == "hostent")
|| (str == "protoent")
|| (str == "passwd")
|| (str == "spwd")
|| (str == "ttyent")
|| (str == "utmp")
|| (str == "utmpx")
|| (str == "ifaddrs")
|| (str == "statfs")
|| (str == "statfs64")
|| (str == "statvfs")
|| (str == "timeb")
|| (str == "_ftsent")
|| (str == "sysinfo")
|| (str == "rlimit")
|| (str == "rlimit64")
|| (str == "rusage")
|| (str == "entry")
|| (str == "pollfd")
|| (str == "re_pattern_buffer")
|| (str == "sembuf")
|| (str == "tms")
|| (str == "utsname")
|| (str == "utimbuf")
// ncurses
|| (str == "_win_st")
|| (str == "cchar_t")
) {
// FILE*, fpos_t*, ...
return 'p';
} else if (str == "__va_list_tag") {
return 'A';
} else {
return 0;
}*/
ALL
}
#undef END
#undef TYPEDEF
#undef STRUCT2
#undef STRUCT
#undef START
#define START()
#define STRUCT(s, ret) if (str == s) { return ret; } else
#define STRUCT2(s, ret, c) if (str == s) { return ret; } else
#define TYPEDEF(s, ret) if (str == s) { return ret; } else
#define END() return "";
const char *ptr2str(const std::string &str) {
/*if (str == "_IO_FILE") {
return "a FILE";
} else if (str == "_G_fpos_t") {
return "a file position";
} else if (str == "sockaddr") {
return "a socket address";
} else if (str == "itimerspec") {
return "an itimerspec";
} else if (str == "timespec") {
return "a timespec";
} else if (str == "itimerval") {
return "an itimerval";
} else if (str == "timeval") {
return "a timeval";
} else if (str == "timex") {
return "a timex";
} else if (str == "timezone") {
return "a timezone";
} else if (str == "dirent") {
return "a dirent";
} else if (str == "dirent64") {
return "a dirent64";
} else if (str == "__dirstream") {
return "a dir stream";
} else if (str == "tm") {
return "a time structure (tm)";
} else if (str == "cmsghdr") {
return "a cmsghdr";
} else if (str == "msghdr") {
return "a msghdr";
} else if (str == "rpcent") {
return "an rpcent";
} else if (str == "random_data") {
return "a random_data structure";
} else if (str == "drand48_data") {
return "a drand48_data structure";
} else if (str == "termios") {
return "a termios";
} else if (str == "iovec") {
return "an iovec";
} else if (str == "file_handle") {
return "a file handle";
} else if (str == "lconv") {
return "an lconv";
} else if (str == "__locale_struct") {
return "a locale structure";
} else if (str == "aliasent") {
return "an alias";
} else if (str == "fstab") {
return "an fstab";
} else if (str == "group") {
return "a group";
} else if (str == "hostent") {
return "a hostent";
} else if (str == "protoent") {
return "a protoent";
} else if (str == "passwd") {
return "a password";
} else if (str == "spwd") {
return "an spwd";
} else if (str == "ttyent") {
return "a ttyent";
} else if (str == "utmp") {
return "an utmp structure";
} else if (str == "utmpx") {
return "an utmpx structure";
} else if (str == "ifaddrs") {
return "an ifaddrs structure";
} else if (str == "statfs") {
return "a statfs structure";
} else if (str == "statfs64") {
return "a statfs64 structure";
} else if (str == "statvfs") {
return "a statvfs structure";
} else if (str == "statvfs64") {
return "a statvfs64 structure";
} else if (str == "timeb") {
return "a timeb structure";
} else if (str == "_ftsent") {
return "an _ftsent structure";
} else if (str == "sysinfo") {
return "a sysinfo structure";
} else if (str == "rlimit") {
return "an rlimit structure";
} else if (str == "rlimit64") {
return "an rlimit64 structure";
} else if (str == "rusage") {
return "an rusage structure";
} else if (str == "entry") {
return "an entry structure";
} else if (str == "pollfd") {
return "a pollfd structure";
} else if (str == "re_pattern_buffer") {
return "a re_pattern_buffer structure";
} else if (str == "sembuf") {
return "a sembuf structure";
} else if (str == "tms") {
return "a tms structure";
} else if (str == "utsname") {
return "an utsname structure";
} else if (str == "utimbuf") {
return "an utimbuf structure";
} else if (str == "__va_list_tag") {
return "__va_list_tag (aka, a va_list)";
// ncurses
} else if (str == "_win_st") {
return "a _win_st structure";
} else if (str == "cchar_t") {
return "a cchar_t";
} else return "";*/
ALL
}
#undef END
#undef TYPEDEF
#undef STRUCT2
#undef STRUCT
#undef START
+91 -105
View File
@@ -1,123 +1,109 @@
![Official logo](docs/img/Box64Logo.png "Official Logo")
Linux Userspace x86_64 Emulator with a twist
# Box64: Linux Userspace x86-64 Emulator with a Twist
[View changelog](https://github.com/ptitSeb/box64/blob/main/docs/CHANGELOG.md) | [中文](https://github.com/ptitSeb/box64/blob/main/README_CN.md) | [Українська](https://github.com/ptitSeb/box64/blob/main/README_UK.md) | [Report an error](https://github.com/ptitSeb/box64/issues/new)
[Changelog](https://github.com/ptitSeb/box64/blob/main/docs/CHANGELOG.md) | [中文](https://github.com/ptitSeb/box64/blob/main/README_CN.md) | [Українська](https://github.com/ptitSeb/box64/blob/main/README_UK.md) | [Report an Error](https://github.com/ptitSeb/box64/issues/new)
![build](https://app.travis-ci.com/ptitSeb/box64.svg?branch=main) ![stars](https://img.shields.io/github/stars/ptitSeb/box64) ![forks](https://img.shields.io/github/forks/ptitSeb/box64) ![contributors](https://img.shields.io/github/contributors/ptitSeb/box64) ![prs](https://img.shields.io/github/issues-pr/ptitSeb/box64) ![issues](https://img.shields.io/github/issues/ptitSeb/box64)
![Build Status](https://app.travis-ci.com/ptitSeb/box64.svg?branch=main) ![Stars](https://img.shields.io/github/stars/ptitSeb/box64) ![Forks](https://img.shields.io/github/forks/ptitSeb/box64) ![Contributors](https://img.shields.io/github/contributors/ptitSeb/box64) ![Pull Requests](https://img.shields.io/github/issues-pr/ptitSeb/box64) ![Issues](https://img.shields.io/github/issues/ptitSeb/box64)
---
Box64 enables running x86_64 Linux programs, including games, on non-x86_64 Linux systems such as Arm (64-bit little-endian host system required).
Check out Box64 in action on YouTube:
- [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)
- [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)
- [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA)
Box64 leverages native system libraries (libc, libm, SDL, OpenGL), offering ease of integration and surprising performance in many applications. For performance benchmarks, check [this analysis](https://box86.org/index.php/2021/06/game-performances/).
With DynaRec for ARM64, RV64 and LA64 platforms, Box64 achieves a speed boost 5-10x faster than the interpreter alone. For a deeper look at DynaRec, see [Inner workings](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/).
<img src="docs/img/Box64Icon.png" width="96" height="96" alt="Box64 Icon">
_Logo and icon by @grayduck - Thank you!_
---
## 📖 Usage
Box64 offers environment variables to control its behavior. For details, see [Usage Documentation](docs/USAGE.md).
---
## 🚀 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)
---
## 🔄 Version History
See the [Changelog](docs/CHANGELOG.md) for version updates.
---
## 🖥️ Platform Compatibility Notes
Box64 requires 64-bit libraries on the host system, as it directly translates x86_64 function calls. For 32-bit binaries, use Box86.
**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 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`.
---
## ⚙️ Configuration
Box64 has configuration files located in `/etc/box64.box64rc` and `~/.box64rc`, both formatted as `.ini` files. If you don’t want to use the default `/etc/box64.box64rc` file, copy it to `~/.box64rc` to ensure compatibility.
Settings priority: `~/.box64rc` > `/etc/box64.box64rc` > Command line.
---
## 📄 Additional Platform-Specific Notes
### Unity Game Emulation
- Many Unity games require OpenGL 3+, which may be challenging on ARM/RISC-V SBCs.
- **Tip for Pi4 and Pi5 Users**: Set `MESA_GL_VERSION_OVERRIDE=3.2` with `BOX64_DYNAREC_STRONGMEM=1` to prevent freezes and enable strong memory mode.
- **Using Panfrost**: For better compatibility on ARM, enable `PAN_MESA_DEBUG=gl3` to force higher OpenGL profiles. This can help if a game starts but quits unexpectedly before showing any content.
### GTK Programs
Box64 wraps GTK libraries, supporting both gtk2 and gtk3.
### Steam
Steam requires Box86 due to its 32-bit client app, but uses 64-bit local server binaries. Systems with less than 6GB RAM may need a swap file for optimal performance.
### Wine
Box64 supports Wine64 and Proton. For 32-bit components, Box86 is required. Systems with both Box64 and Box86 can run 32- and 64-bit Windows programs.
**Note**: You can use Wine WOW64 build to run x86 Windows programs in Box64-only environments, this is still experimental, but it works in most cases.
### Vulkan
Box64 wraps Vulkan libraries.
----
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).
You can find many Box64 videos on the [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ), [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g) or [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA) YouTube channels.
Since 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. Take a look at thoses bench analysis for an example [here](https://box86.org/index.php/2021/06/game-performances/).
Box64 integrates with DynaRec (dynamic recompiler) for the ARM64 and RV64 platform, providing a speed boost between 5 to 10 times faster than using only the interpreter. Some high level information on how DynaRec works can be found [here](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/).
Some x64 internal opcodes use parts of "Realmode X86 Emulator Library", see [x64primop.c](src/emu/x64primop.c) for copyright details
<img src="docs/img/Box64Icon.png" width="96" height="96">
Logo and Icon made by @grayduck, thanks!
----
Usage
----
There are a few environment variables to control the behaviour of Box64.
See [here](docs/USAGE.md) for all the environment variables and what they do.
Note: Box64's Dynarec uses a mechanism with Memory Protection and a SegFault signal handler to handle JIT code. In simpler terms, if you want to use GDB to debug a running program that use JIT'd code (like mono/Unity3D), you will still have many "normal" segfaults triggering. It is suggested to use something like `handle SIGSEGV nostop` in GDB to not stop at each segfault, and maybe put a breakpoint inside `my_memprotectionhandler` in `signals.c` if you want to trap SegFaults.
----
Compiling/Installation
----
> Compilation instructions can be found [here](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md) \
> Instructions for installing Wine for Box64 can be found [here](https://github.com/ptitSeb/box64/blob/main/docs/X64WINE.md)
----
Version history/Change log
----
The change log is available [here](docs/CHANGELOG.md).
----
Notes about 32-bit platforms
----
Because Box64 works by directly translating function calls from x86_64 to host system, the host system (the one Box64 is running on) needs to have 64-bit libraries. Box64 doesn't include any 64-bit <-> 32-bit translation.
So understand that box64 will only run 64-bit linux binaries. For 32-bit binaries, you need box86 (with all the multiarch or proot trickery it implies on a 64-bit OS).
Note that many installer (mojo setup based) will fall back to "x86" when detecting ARM64 OS, and so will try to use box86 for the setup, even if an x86_64 version exist. You can hack your way around with a fake "uname" that return "x86_64" when the argument is "-m"
----
Notes about Box64 configuration
----
Box64 now have configurations files. There are 2 files loaded. `/etc/box4.box64rc` and `~/.box64rc`. Both files have the same syntax, and is basicaly an ini files. Section in square brakets define the process name, and the rest is the env. var. to set. Looke at [Usage](USAGE.md) for detail on what parameters can be put. Box64 comes with a default file that should be installed for better stability. The file in in `system/box64.box64rc` and should be installed to `/etc/box64.box64rc` If, for some reason, you don't want to install that file here, at least copy it to `~/.box64rc` or some game may not function correctly.
Note that the priority is: `~/.box64rc` > `/etc/box64.box64rc` > command line
So, your settings in `~/.box64rc` may override the setting from your command line...
----
Notes about Unity game emulation
----
Running Unity games should just work, but you should also note that many Unity3D games require OpenGL 3+ which can be tricky to provide on ARM SBC (single-board computers). Also many newer Unity3D (like KSP) games use the BC7 compressed textures, which is not supported on many ARM integrated GPU.
Hint: on Pi4, use `MESA_GL_VERSION_OVERRIDE=3.2` and with Panfrost use `PAN_MESA_DEBUG=gl3` to use higher profile if the game starts then quits before showing anything.
----
Notes about GTK programs
----
GTK libraries are now wrapped on box64, both gtk2 and gtk3.
----
Notes about Steam
----
Note that Steam is a hybrid 32-bit / 64-bit. You NEED box86 to run Steam, as the client app is a 32-bit binary. It also uses a 64-bit local server binaries, and that steamwebhelper process is now mandatory, even on the "small mode". And that process will eat lots of memory. So machine with less the 6Gb of RAM will need a swapfile to use Steam.
----
Notes about Wine
----
Wine64 is supported on box64. Proton too. Be aware that 64-bit Wine also includes 32-bit components, to be able to run 32-bit Windows programs. The 32-bit apps will need box86 and will not run without it. On a system where both box64 and box86 are present and working, a wine 64-bit setup can run both 32-bit and 64-bit Windows programs (just use `wine` and `wine64` respectively).
Note that the new 32-bit PE in 64-bit processes that the Wine team is currently implementing in Wine 7.+ is now supported, but the support is quite young so there might be some residual issues.
----
Notes about Vulkan
----
Box64 wraps Vulkan libraries, but note that it as mostly been tested with an AMD RX550 card and on the Freedreno driver, so some extensions may be missing depending on your graphics card.
----
Final word
----
I want to thank everyone who has contributed to box64 development.
There are many ways to contribute: code contribution, financial, hardware and advertisement!
So, in no particular order, I want to thank:
* For their major code contribution: rajdakin, mogery
* For their major financial contribution: FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/), [CubeCoders Limited](http://cubecoders.com/)
* For their major code contribution: rajdakin, mogery, ksco, xctan
* For their major financial contribution: [Playtron](https://playtron.one), tohodakilla, FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/), [CubeCoders Limited](http://cubecoders.com/)
* For hardware contribution and LoongArch migration: [xiaoji](https://www.linuxgame.cn/), Deepin Beijing Develop Team
* For their major code contribution on the RV64 Dynarec: ksco, xctan
* For their hardware contribution: [ADLINK](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en) with [Ampere](https://amperecomputing.com/home/edge), [Radxa](https://rockpi.org/), [StarFive](https://rvspace.org/), [Pine64](https://www.pine64.org/), [AYN](https://www.ayntec.com/)
* For their hardware contribution: [ADLINK](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en) with [Ampere](https://amperecomputing.com/home/edge), [SOPHGO](https://www.sophon.ai/), [Radxa](https://rockpi.org/), [StarFive](https://rvspace.org/), [Pine64](https://www.pine64.org/), [AYN](https://www.ayntec.com/), [AYANEO](https://ayaneo.com/), [jiangcuo](https://github.com/jiangcuo)
* For their continuous advertisements for the box64 project: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
And I also thank the many other people who participated even once in this project.
(If you use Box64 in your project, please don't forget to mention it!)
+52 -57
View File
@@ -1,97 +1,92 @@
# box64
![图标](docs/img/Box64Logo.png "图标")
![Official logo](docs/img/Box64Logo.png "Official Logo")
Linux 上用户空间的 x86_64 应用模拟器(支持运行原生库)
# Box64:Linux 用户空间 x86-64 模拟器(支持原生库)
----
![box64 build status](https://app.travis-ci.com/ptitSeb/box64.svg?branch=main)
[更新日志](https://github.com/ptitSeb/box64/blob/main/docs/CHANGELOG.md) | [English](https://github.com/ptitSeb/box64/blob/main/README.md) | [Українська](https://github.com/ptitSeb/box64/blob/main/README_UK.md) | [Report an Error](https://github.com/ptitSeb/box64/issues/new)
[English](docs/README.md) | [Українська](https://github.com/ptitSeb/box64/blob/main/README_UK.md)
![Build Status](https://app.travis-ci.com/ptitSeb/box64.svg?branch=main) ![Stars](https://img.shields.io/github/stars/ptitSeb/box64) ![Forks](https://img.shields.io/github/forks/ptitSeb/box64) ![Contributors](https://img.shields.io/github/contributors/ptitSeb/box64) ![Pull Requests](https://img.shields.io/github/issues-pr/ptitSeb/box64) ![Issues](https://img.shields.io/github/issues/ptitSeb/box64)
Box64 可以在非 x86_64 Linux 系统(比如 ARM64)上运行 x86_64 Linux 程序(比如游戏),注意主机系统需要是 64 位小端。
---
您可以在 [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)、[Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g) 和 [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA) YouTube 频道上找到许多 Box64 视频。
Box64 可以在非 x86_64 Linux 主机系统(比如 Arm)上运行 x86_64 Linux 程序(比如游戏),目前仅支持 64 位小端主机系统。
由于 Box64 使用一些“系统”库的原生版本,如 libc、libm、SDL 和 OpenGL 等,因此很容易与大多数应用程序集成和使用,并且在许多情况下性能会相当不错。可以在[这里](https://box86.org/index.php/2021/06/game-performances/)查看一些性能测试的样例。
在 YouTube 上查看 Box64 的运行效果:
- [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)
- [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)
- [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA)
Box64 集成了适用于 ARM64 和 RV64 平台的 DynaRec(动态重编译器),速度可以比纯解释模式快 5 到 10 倍。可以在[这里](https://box86.org/2021/07/inner-workings-a-high%E2%80%91level-view-of-box86-and-a-low%E2%80%91level-view-of-the-dynarec/)找到有关 DynaRec 工作原理的一些信息。
Box64 可以使用本机原生的系统库(libc、libm、SDL、OpenGL),有着易于集成的特性和令人惊讶的性能。如需性能基准测试,请查看[此分析](https://box86.org/index.php/2021/06/game-performances/)。
一些 x64 内部操作码使用 “Realmode X86 Emulator Library” 的部分内容,有关版权详细信息,请参见 [x64primop.c](../src/emu/x64primop.c)。
借助适用于 ARM64,RV64 以及 LA64 平台的 DynaRec,Box64 的速度比单独使用解释器快 5-10 倍。如需深入了解 DynaRec,请参考[此文章](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/)。
<img src="docs/img/Box64Icon.png" width="96" height="96">
<img src="docs/img/Box64Icon.png" width="96" height="96" alt="Box64 Icon">
LOGO 由 @grayduck 制作,感谢!
_Logo 由 @grayduck 制作,感谢!_
----
---
使用方法
----
## 📖 使用方法
有若干环境变量可以控制 Box64 的行为。
Box64 提供了环境变量来控制其行为。有关详细信息请参阅[使用文档](docs/USAGE.md)。
可在[这里](docs/USAGE.md)查看所有环境变量及其作用。
---
注意:Box64 的 Dynarec 使用具有内存保护和段错误信号处理的机制来执行 JIT 代码。所以,如果想使用 GDB 调试使用 JIT 代码的程序(如 Mono/Unity3D),这会触发许多“正常”的段错误。建议在 GDB 中使用类似 `handle SIGSEGV nostop` 来防止它每个段错误处停止。如果你想捕获段错误,可以在 `signals.c` 的 `my_memprotectionhandler` 中设置断点。
## 🚀 编译和安装
----
- [编译说明](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md)
- [安装 Wine](https://github.com/ptitSeb/box64/blob/main/docs/X64WINE.md)
编译/安装
----
---
编译说明可以在[这里](docs/COMPILE.md)查看。
## 🔄 版本历史
----
请参阅[变更日志](docs/CHANGELOG.md)了解版本更新说明。
版本历史
----
---
版本日志在[这里](docs/CHANGELOG.md)。
## 🖥️ 平台兼容性说明
----
Box64 直接转换 x86_64 函数调用到本机原生库,因此需要主机系统上的 64 位库。对于 32 位二进制文​​件,请使用 Box86。
32位平台的注意事项
----
**注意事项**
因为 Box64 的工作原理是直接将函数调用从 x86_64 转换为主机系统,所以主机系统(运行 Box64 的系统)需要有 64 位库。Box64 不包含任何 64 位 <-> 32 位的转换。
1. Box32 模式正在制作中,旨在支持 Box64 上运行 32 位二进制文​​件,敬请期待!
2. 某些安装程序可能会将 64 位的主机操作系统判定为 x86 导致兼容性问题。解决方法:使用假的 `uname` ,并使它在运行参数为 `-m` 时返回 `x86_64`。
所以 box64 只能运行 64 位的 Linux 二进制。对于 32 位二进制则需要使用 box86 来运行(它在 64 位操作系统上使用了 multiarch 和 proot 等技巧来实现运行)。请注意,许多(基于 mojo 的)安装程序在检测到 ARM64 操作系统时将回退到 “x86”,因此即使存在 x86_64 版本,也会尝试使用 box86。这时你可以使用一个假的 `uname` ,并使它在运行参数为 `-m` 时返回 `x86_64`。
---
----
## ⚙️ 配置
关于 Unity 游戏模拟的注意事项
----
Box64 的配置文件位于 `/etc/box64.box64rc` 和 `~/.box64rc`,均为 `.ini` 格式的文件。如果您不想使用默认的 `/etc/box64.box64rc` 文件,请将其复制到 `~/.box64rc` 以确保兼容性。
运行 Unity 游戏应该没什么问题,但还应该注意,许多 Unity3D 游戏需要 OpenGL 3+,这在 ARM SBC 上可能会比较棘手。同时许多较新的 Unity3D游戏(如 KSP)也使用 BC7 压缩纹理,很多 ARM 的集成显卡并不支持。
配置项的优先级:`~/.box64rc` > `/etc/box64.box64rc` > 命令行。
> 提示:如果游戏开始后没有显示任何东西就退出了,在 Pi4 上可以使用 `MESA_GL_VERSION_OVERRIDE=3.2`,在 Panfrost 上则可以使用 `PAN_MESA_DEBUG=gl3` 来使用更高的配置。
---
----
## 📄 特定平台的其他说明
关于GTK程序的注意事项
----
### Unity 游戏
- 许多 Unity 游戏需要 OpenGL 3+,这对 ARM/RISC-V SBC 来说可能具有挑战性。
- **对 Pi4 和 Pi5 用户的提示**:设置 `MESA_GL_VERSION_OVERRIDE=3.2` 和 `BOX64_DYNAREC_STRONGMEM=1` 以防止卡死并启用强内存模式。
- **Panfrost**:为了在 ARM 上实现更好的兼容性,启用 `PAN_MESA_DEBUG=gl3` 以强制更高的 OpenGL Profile。如果游戏可以启动但在显示任何内容之前意外退出,这个设置可能会有所帮助。
box64 封装了 GTK,包括 gtk2 和 gtk3。
### GTK 程序
----
Box64 包装了 GTK 库,支持 gtk2 和 gtk3。
关于 Steam 的注意事项
----
### Steam
请注意,Steam 是 32/64 位混合的应用,所以你需要 box86 才能运行,因为客户端应用程序是 32 位的。它还使用 64 位本地服务器,它的 steamwebhelper 无法被关闭(即使是在最小模式)而且会吃掉大量的内存。对于内存小于 6 GB 的机型,你将会需要创建 swapfile 来运行 Steam。
由于 Steam 客户端应用是 32 位的,需要使用 Box86,但其本地服务器是 64 位的二进制文件。对于内存少于 6GB 的系统,可能需要使用交换文件以获得最佳性能。
----
### Wine
关于 Wine 的注意事项
----
Box64 支持 Wine64 和 Proton。对于 32 位组件,需要 Box86。配备 Box64 和 Box86 的系统可以运行 32 位和 64 位的 Windows 程序。
box64 支持 Wine64,Proton 应该也能运行。请注意,64 位 Wine 包含有 32 位组件,以便能够运行 32 位 Windows 程序。32 位应用程序需要 box86,否则无法运行。在 box64 和 box86 都存在并工作的系统上,64 位的 Wine 可以同时运行 32 位和 64 位 Windows 程序(分别使用 `wine` 和 `wine64`)。请注意,目前在 Wine 7.+ 中实现的 Wine 时间在 64 位进程中的新 32bit PE 尚不支持。我测试了 Wine 7.5 64 位可以正常工作,但是更新的版本可能还不行。
**提示**:您可以使用 Wine WOW64 版本在仅限 Box64 的环境中运行 x86 Windows 程序,这项支持仍处于实验阶段,但在大多数情况下都可以工作。
----
### Vulkan
关于 Vulkan 注意事项
----
Box64 封装了 Vulkan 库,但请注意,它仅在 RX550 显卡上进行过测试,因此根据您的显卡,某些扩展可能会丢失。
Box64 包装了 Vulkan 库。
----
@@ -102,10 +97,10 @@ Box64 封装了 Vulkan 库,但请注意,它仅在 RX550 显卡上进行过
贡献方式有很多种:代码贡献、财务帮助、捐赠捐赠和广告合作!
以下感谢不分先后:
* 代码贡献:rajdakin, mogery
* 财务帮助:FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
* 代码贡献:rajdakin, mogery, ksco, xctan
* 财务支持:[Playtron](https://playtron.one), tohodakilla, FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/), [CubeCoders Limited](http://cubecoders.com/)
* 硬件捐赠和 LoongArch 迁移:[xiaoji](https://www.linuxgame.cn/), Deepin Beijing Develop Team
* 硬件捐赠:[ADLink](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en), [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [StarFive](https://rvspace.org/)
* 硬件捐赠:[ADLINK](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en) with [Ampere](https://amperecomputing.com/home/edge), [SOPHGO](https://www.sophon.ai/), [Radxa](https://rockpi.org/), [StarFive](https://rvspace.org/), [Pine64](https://www.pine64.org/), [AYN](https://www.ayntec.com/), [AYANEO](https://ayaneo.com/), [jiangcuo](https://github.com/jiangcuo)
* 为本项目持续的宣传:salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
我还要感谢很多人,即使他们只参与了一次本项目。
+5 -7
View File
@@ -2,7 +2,7 @@
Емулятор простіра користувача x86_64 із родзинкою
[Дивитись журнал змін](https://github.com/ptitSeb/box64/blob/main/docs/CHANGELOG.md) | [中文](https://github.com/ptitSeb/box64/blob/main/README_CN.md) | [Українська](https://github.com/ptitSeb/box64/blob/main/README_UK.md) | [Повідомити про помилку](https://github.com/ptitSeb/box64/issues/new)
[Дивитись журнал змін](https://github.com/ptitSeb/box64/blob/main/docs/CHANGELOG.md) | [中文](https://github.com/ptitSeb/box64/blob/main/README_CN.md) | [English](https://github.com/ptitSeb/box64/blob/main/README.md) | [Повідомити про помилку](https://github.com/ptitSeb/box64/issues/new)
![build](https://app.travis-ci.com/ptitSeb/box64.svg?branch=main) ![stars](https://img.shields.io/github/stars/ptitSeb/box64) ![forks](https://img.shields.io/github/forks/ptitSeb/box64) ![contributors](https://img.shields.io/github/contributors/ptitSeb/box64) ![prs](https://img.shields.io/github/issues-pr/ptitSeb/box64) ![issues](https://img.shields.io/github/issues/ptitSeb/box64)
@@ -40,7 +40,6 @@ Box64 інтегрується з DynaRec (динамічний рекомпіл
> Інструкцію з встановлення Wine для Box64 можна знайти [тут](docs/X64WINE.md).
----
Історія версій/Журнал змін
----
@@ -68,7 +67,7 @@ Box64 інтегрується з DynaRec (динамічний рекомпіл
----
Запуск ігор Unity має працювати, але ви також повинні зауважити, що для багатьох ігор Unity3D потрібен OpenGL 3+, який може бути складно забезпечити на ARM SBC (одноплатних комп’ютерах). Крім того, багато нових ігор Unity3D (наприклад, KSP) використовують стиснуті текстури BC7, які не підтримуються багатьма інтегрованими GPU ARM.
Підказка: в Pi4 використовуйте `MESA_GL_VERSION_OVERRIDE=3.2`, а в Panfrost — `PAN_MESA_DEBUG=gl3`, щоб використовувати вищий профіль, якщо гра запускається, а потім завершується, перш ніж щось показує.
Підказка: на Pi4 і Pi5 використовуйте `MESA_GL_VERSION_OVERRIDE=3.2` з `BOX64_DYNAREC_STRONGMEM=1`, щоб запобігти зависанням і ввімкнути режим сильної пам’яті, і використовуйте Panfrost `PAN_MESA_DEBUG=gl3`, щоб використовувати вищий профіль, якщо гра починається, а потім завершується, перш ніж щось показати.
----
@@ -107,11 +106,10 @@ Box64 використовує бібліотеки Vulkan, але зауваж
Я хочу подякувати всім, хто зробив внесок у розвиток box64.
Є багато способів зробити внесок: внесок коду, фінансовий внесок, апаратне забезпечення та реклама!
Отже, без особливого порядку, я хочу подякувати:
* За основний внесок у код: rajdakin, mogery
* За великий фінансовий внесок: FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
* За основний внесок у код: rajdakin, mogery, ksco, xctan
* За великий фінансовий внесок: [Playtron](https://playtron.one), tohodakilla, FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
* За апаратне забезпечення та міграцію LoongArch: [xiaoji](https://www.linuxgame.cn/), команда розробників Deepin Beijing
* За основний внесок у код RV64 Dynarec: ksco, xctan
* За внесок у апаратне забезпечення: [ADLink](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en), [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [StarFive](https://rvspace.org/)
* За внесок у апаратне забезпечення: [ADLINK](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en) with [Ampere](https://amperecomputing.com/home/edge), [SOPHGO](https://www.sophon.ai/), [Radxa](https://rockpi.org/), [StarFive](https://rvspace.org/), [Pine64](https://www.pine64.org/), [AYN](https://www.ayntec.com/), [AYANEO](https://ayaneo.com/), [jiangcuo](https://github.com/jiangcuo)
* За безперервну рекламу Box64: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/Команда [TwisterOS](https://twisteros.com/), [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
І я також дякую багатьом іншим людям, які хоч раз брали участь у цьому проекті.
+38
View File
@@ -0,0 +1,38 @@
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://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/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/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/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/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://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/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
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://archive.debian.org/debian/pool/main/c/curl/libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_amd64.deb d5ae55e3a9838d12358530cd03218cc0d18127a84e9cfc73bdf79dacd40b25e4
10 https://archive.debian.org/debian/pool/main/c/curl/libcurl3-gnutls_7.74.0-1.3+deb11u7~bpo11+1_i386.deb 625e5189304d4d3bfb27cb821e257816c5ce761b1696b5da5ca4fa1035c48463
11 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgomp-11.5.0-2.el9.alma.1.i686.rpm 686ac26afe2073a3607f26fd1592a8ccd9b78f6eec6e872528634b43c4e04dd7
12 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libgomp-11.5.0-2.el9.alma.1.x86_64.rpm 9a2bdc6807b22ffb6294b30dcc13e20198abe5facaeefcf1bfacec3e1013e3c2
13 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libICE-1.0.10-8.el9.i686.rpm d9c44bb34c990fdcc6987feefacfc9e1e7997ca25f1e0a59c9adc9c16f2266d1
14 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libICE-1.0.10-8.el9.x86_64.rpm d0b867203384942985c3c4ad6fc9ec0000fcc9965408451a6cdef8df06a3833c
15 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libidn2-2.3.0-7.el9.i686.rpm 4458e2d416b5e6714ec664c4f88791eee7d1e707026a5854d948a6159911465b
16 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libidn2-2.3.0-7.el9.x86_64.rpm c3ff43237c05258ee0dd77c28540fc8d0d824f1567b115ddfd555b78d2ee0e7a
17 https://cdn.getsol.us/repo/shannon/libj/libjpeg-turbo/libjpeg-turbo-32bit-3.0.3-21-1-x86_64.eopkg 5624990281f6520026aa2252c711f02d4916099aeac63accc83bd2135b9d3220
18 https://cdn.getsol.us/repo/shannon/libj/libjpeg-turbo/libjpeg-turbo-3.0.3-21-1-x86_64.eopkg c92f19d446b4c2450306f13b1a908f2552400da09301996fe349fee243d964d2
19 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libogg-1.3.4-6.el9.i686.rpm 9e4ff6fa0251c5357ae8f648b3e396d0043d5b3f2fb28d23325f5bd592c67aee
20 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libogg-1.3.4-6.el9.x86_64.rpm 83b4b333e335654674032d1cda4d7deb328b5a409f95e3952c3dc482b684fd8f
21 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libpng-1.6.37-12.el9.i686.rpm 66bf967e84f0d8e7a0059f2b7dda33482ff5e4fe088d0e3bc86dc54e6c7c97be
22 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libpng-1.6.37-12.el9.x86_64.rpm ebb3e927dfafa0b199e00e2bef4c10c85fc82a70c359faf9aeb599eda70bfa5e
23 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libSM-1.2.3-10.el9.i686.rpm ec68b3def828ba442248f3cff495f42c4af3dd58f38c8daad07dfddc109d999a
24 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libSM-1.2.3-10.el9.x86_64.rpm d00318843a50138829b470a97b8db1a00723b10bca23c16a8386d9ab670e4c64
25 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libtasn1-4.16.0-8.el9_1.i686.rpm 9cbd11277e89bd0d4a80900bee01ca71b0c582c9cb5744f5035135b2ed907c85
26 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libtasn1-4.16.0-8.el9_1.x86_64.rpm 2dd3a1ad2785df642cb03dfed6dfbeec929ff8b14e52e61272ca7e89f86ba3cd
27 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libtheora-1.1.1-31.el9.i686.rpm 2155c688b516ab359d0c47be6d73e51d3c65f199ed5591f7bb7ce6d5d9799977
28 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libtheora-1.1.1-31.el9.x86_64.rpm 25ab4a8ad997b450b4a34a777f5a0678eea72ca1665944a7a461ac63de4b25bf
29 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libunistring-0.9.10-15.el9.i686.rpm 792600a879fbd94ce4bf249713b0cb3a166c147cfad397e8a15e6b4f01c75997
30 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/libunistring-0.9.10-15.el9.x86_64.rpm d2f86fbee729a4900a433a6c52a3cb95d9b52b1d79c9e719ee3ef509813eb6d9
31 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libvorbis-1.3.7-5.el9.i686.rpm e38c5185fea611330ea253db020315dd564507bf95c48a81dbe7db186ce4214b
32 https://repo.almalinux.org/almalinux/9.5/AppStream/x86_64/os/Packages/libvorbis-1.3.7-5.el9.x86_64.rpm 3c340337a073975636d198a282503f32a54bf85fb5345522a2c22e530b8d6c9e
33 https://repo.almalinux.org/almalinux/8.10/BaseOS/x86_64/os/Packages/nettle-3.4.1-7.el8.i686.rpm 13bc8758355c3ec885f414e0e86efad29a7fe82c0999cdb3754d666949c06cc5
34 https://repo.almalinux.org/almalinux/8.10/BaseOS/x86_64/os/Packages/nettle-3.4.1-7.el8.x86_64.rpm fb4aaa22b2e2f2fc0c451b87ac464e8746d240397d64e79f6bfd38f4e9128a5a
35 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/nettle-3.9.1-1.el9.i686.rpm e5610fe3b25cfca1616440e1a8a7489fd37b0852f182fdda87ab8e196d981970
36 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/nettle-3.9.1-1.el9.x86_64.rpm 9786b6610d17aa495fb640ba6d046bf73704915b82d12e6d8339090ff4891de5
37 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/p11-kit-0.25.3-3.el9_5.i686.rpm abe4ab924b405c236eaf3fa067fed50ac66d15d0ef42c782a745788c1a9c5b91
38 https://repo.almalinux.org/almalinux/9.5/BaseOS/x86_64/os/Packages/p11-kit-0.25.3-3.el9_5.x86_64.rpm 0e1bd97e697a9fa3b4e508b945cf352b73b06e4e8218c14ac5fb912b0022c646
+93
View File
@@ -0,0 +1,93 @@
#!/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 "Unknown package."
echo "Unsupported package type."
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"
# 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/"
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}"
+93
View File
@@ -1,3 +1,96 @@
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
* => Box32 is a build option for Box64, and is disabled by default
* => Optionnal binfmt integration available for Box32
* => Wrapped some basics libs, including graphics and sounds so a few games already works
* => Work In Progress, many issues remain to be fixed, but some Linux games are playable
* Introduced Native Flags. Can be controled with BOX64_DYNAREC_NATIVEFLAGS, but enabled by default
* => Available on the 3 Dynarec backend, with different implementations
* => ARM64 Dynarec build have all AVX/AVX2 extensions enabled by default
* +> Can lead to large speedup on certain cases
* Improved Strong Memory Model emulation, with better default options and a more efficiant emulation
* Dynarec: RV64: using RVV (and XThreadVector) to implement SSEx opcodes, with some massive speedup when used!
* Some bugfix and improvment in the Signal handler and internal memory tracking
* Improvment to TRAP signal generation and Handling
* Improved CPUID opcodes again, and the various virtual file in /proc that represent those data
* Improved some x87 operations, like long double handling and infinity comparisons...
* Dynarec: ARM64 fixes to a few opcodes
* Dynarec: RV64 fixes to many opcodes
* Dynarec: LA64 fixes to a few opcodes
* Dynarec: RV64 fixes and improvments on LOCK prefixes opcodes
* Dynarec: Many optimisation on some individual opcodes, an all 3 backends
* WRAPPING: More libs and functions wrapped. Some wrapping fixes too
* WREPPING: New wrapperhelper to help coding new wrapping & fixing/enhancing existing one
* ElfLoader: Improved object fetching
* New build profile for SD865 and ORYON
* Changed the installation folder of x86 libs to avoid conflict with linux distro
* Added a few syscalls
* Some more Vulkan extensions wrapped
* More work on build system, and github CI (generating WCP archive), with some fixes on the Android version (still not 100% operational)
-- Sebastien Chevalier <[email protected]> Thu, 6 Dec 2024 10:30:33 -0100
box64 (0.3.0) unstable; urgency=low
* AVX and AVX2 implemented, along with BMI1, BMI2, ADX, FMA, F16C and RDANDR extension!
* Introduced BOX64_AVX env. var. to enable/disable AVX extension:
* => BOX64_AVX=1 enable AVX, BMI1, F16C and VAES extension
* => BOX64_AVX=2 also enable AVX2, BMI2, FMA, ADX,VPCLMULQDQ and RDRAND
* Dynarec: Implemented most AVX/AVX2 and friends in ARM64 Dynarec (using only NEON, so available on all ARM64 CPU)
* => ARM64 Dynarec build have all AVX/AVX2 extensions enabled by default
* Improved CPUID opcodes, adding a few leaf, fixing same. Returnning an Haswell type of CPU now (was Pentium IV before)
* Dynarec: Small optim in the emit_pf helper, on all 3 backends
* Dynarec: ARM64 some fixes to a few opcodes
* Dynarec: LA64 many new opcodes added, and fixes.
* Dynarec: RV64 some new opcodes added, many fixes.
* Dynarec: RV64 Adding some infrastructure to use RVV (if available) for SIMD emulation.
* Dynarec: Many small changes and fixes around handling of x87, registers and internal jump.
* WRAPPING: Added a workaround on SDL_GetThreadID to fix a race condition that was happening mostly on LA64 and broke many SDL games
* WRAPPING: More libs and functions wrapped. Some wrapping fixes too (including a nasty error on some rare libGL functions)
* WRAPPING: Wayland is now supported. Wine-wayland at least works now
* Dynarec: LA64 improved LOCK CMPXCHG handling, and better 16Byte LOCK handling too (fixes many Unity3D games)
* Dynarec: RV64 improved LOCK CMPXCHG handling
* COSIM: Many fixes and improvment, to make BOX64_DYNAREC_TEST more usable
* Detect when a Wine program use UnityPlayer.dll to atumaticaly use BOX64_DYNAREC_STRONGMEM=1 (unless it's already set), so more games just work
* ElfLoader: Added a new type of relocation
-- Sebastien Chevalier <[email protected]> Thu, 9 Jul 2024 10:30:33 -0100
box64 (0.2.8) unstable; urgency=low
* Wrapping: More libs and function wrapping (gtk3, vulkan...)
* Reworked X11 Callback handling, for better stability
* Reworked exit and the load/unload of libs and symbol resolution
* Some more profiles in box64rc
* Better way to rename executable (including wine ones) so driver like mesa can apply the correct profile
* Reworked memory managment in the Dynarec, limiting amount of dynamic allocation
* Improved memory tracking and managment. Also introduce BOX64_MMAP32 to force 32bits compatible mmap for external libs (like mesa)
* => Allow Vulkan drvier on Wine/WOW64 games to allocate 32bits compatible memory, allowing dxvk on 32bits.
* Reworked memory managment in the Dynarec, limiting amount of dynamic allocation
* Lots of improvments in x87 handling (virtual stack, rounding, ffree, etc.)
* => should improve games stability
* Dynarec: ARM64 some opcodes optimisation, especialy shift and rotation ones
* Dynarec: RV64 lots of opcoded added.
* => Some games on linux now have a good speed. Game on Wine are still a bit slow, and dxvk still have issues
* Dynarec: Added Loogarch backend! Note that Loongarch are 16K pagesize platform by default.
* => Linux games are running, and with good speed, especialy on 3A6000 platforms. Games on Wine are not working yet due to 16k pagesize limitation
* Dynarec: Better handling of large block in the dynarec
* Dynarec: Lots of improvments and fixes to BOX86_DYNAREC_CALLRET optimisation.
* => It can be used on more software now, and combine with BOX64_DYNAREC_BOGBLOCKS 2 or 3 can gives some good speed boosts.
-- Sebastien Chevalier <[email protected]> Thu, 31 May 2024 17:30:33 -0100
box64 (0.2.6) unstable; urgency=low
* X64Libs: Updated libstdc++ & libgcc_s
+13 -1
View File
@@ -10,4 +10,16 @@ override_dh_auto_configure:
-DNOGIT=1
override_dh_shlibdeps:
dh_shlibdeps --exclude=libgcc_s.so.1 --exclude=libpng12.so.0 --exclude=libstdc++.so.5 --exclude=libstdc++.so.6
dh_shlibdeps --exclude=libgcc_s.so.1 \
--exclude=libpng12.so.0 \
--exclude=libstdc++.so.5 \
--exclude=libstdc++.so.6 \
--exclude=libmbedcrypto.so.7 \
--exclude=libssl.so.1.1 \
--exclude=libunwind.so.8 \
--exclude=libmbedtls.so.14 \
--exclude=libcrypto.so.1.1 \
--exclude=libmbedx509.so.1 \
--exclude=libcrypto.so.1.0.0 \
--exclude=libssl.so.1.0.0 \
--exclude=box64-bash
+66
View File
@@ -0,0 +1,66 @@
# 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
```
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)
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/
- 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 Arch Linux, 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.
+113
View File
@@ -1,3 +1,116 @@
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
=> Box32 is a build option for Box64, and is disabled by default
=> Optionnal binfmt integration available for Box32
=> Wrapped some basics libs, including graphics and sounds so a few games already works
=> Work In Progress, many issues remain to be fixed, but some Linux games are playable
* Introduced Native Flags. Can be controled with BOX64_DYNAREC_NATIVEFLAGS, but enabled by default
=> Available on the 3 Dynarec backend, with different implementations
=> ARM64 Dynarec build have all AVX/AVX2 extensions enabled by default
+> Can lead to large speedup on certain cases
* Improved Strong Memory Model emulation, with better default options and a more efficiant emulation
* Dynarec: RV64: using RVV (and XThreadVector) to implement SSEx opcodes, with some massive speedup when used!
* Some bugfix and improvment in the Signal handler and internal memory tracking
* Improvment to TRAP signal generation and Handling
* Improved CPUID opcodes again, and the various virtual file in /proc that represent those data
* Improved some x87 operations, like long double handling and infinity comparisons...
* Dynarec: ARM64 fixes to a few opcodes
* Dynarec: RV64 fixes to many opcodes
* Dynarec: LA64 fixes to a few opcodes
* Dynarec: RV64 fixes and improvments on LOCK prefixes opcodes
* Dynarec: Many optimisation on some individual opcodes, an all 3 backends
* WRAPPING: More libs and functions wrapped. Some wrapping fixes too
* WREPPING: New wrapperhelper to help coding new wrapping & fixing/enhancing existing one
* ElfLoader: Improved object fetching
* New build profile for SD865 and ORYON
* Changed the installation folder of x86 libs to avoid conflict with linux distro
* Added a few syscalls
* Some more Vulkan extensions wrapped
* More work on build system, and github CI (generating WCP archive), with some fixes on the Android version (still not 100% operational)
v0.3.0
======
* AVX and AVX2 implemented, along with BMI1, BMI2, ADX, FMA, F16C and RDANDR extension!
* Introduced BOX64_AVX env. var. to enable/disable AVX extension:
=> BOX64_AVX=1 enable AVX, BMI1, F16C and VAES extension
=> BOX64_AVX=2 also enable AVX2, BMI2, FMA, ADX,VPCLMULQDQ and RDRAND
* Dynarec: Implemented most AVX/AVX2 and friends in ARM64 Dynarec (using only NEON, so available on all ARM64 CPU)
=> ARM64 Dynarec build have all AVX/AVX2 extensions enabled by default
* Improved CPUID opcodes, adding a few leaf, fixing same. Returnning an Haswell type of CPU now (was Pentium IV before)
* Dynarec: Small optim in the emit_pf helper, on all 3 backends
* Dynarec: ARM64 some fixes to a few opcodes
* Dynarec: LA64 many new opcodes added, and fixes.
* Dynarec: RV64 some new opcodes added, many fixes.
* Dynarec: RV64 Adding some infrastructure to use RVV (if available) for SIMD emulation.
* Dynarec: Many small changes and fixes around handling of x87, registers and internal jump.
* WRAPPING: Added a workaround on SDL_GetThreadID to fix a race condition that was happening mostly on LA64 and broke many SDL games
* WRAPPING: More libs and functions wrapped. Some wrapping fixes too (including a nasty error on some rare libGL functions)
* WRAPPING: Wayland is now supported. Wine-wayland at least works now
* Dynarec: LA64 improved LOCK CMPXCHG handling, and better 16Byte LOCK handling too (fixes many Unity3D games)
* Dynarec: RV64 improved LOCK CMPXCHG handling
* COSIM: Many fixes and improvment, to make BOX64_DYNAREC_TEST more usable
* Detect when a Wine program use UnityPlayer.dll to atumaticaly use BOX64_DYNAREC_STRONGMEM=1 (unless it's already set), so more games just work
* ElfLoader: Added a new type of relocation
v0.2.8
======
* Wrapping: More libs and function wrapping (gtk3, vulkan...)
* Reworked X11 Callback handling, for better stability
* Reworked exit and the load/unload of libs and symbol resolution
* Some more profiles in box64rc
* Better way to rename executable (including wine ones) so driver like mesa can apply the correct profile
* Reworked memory managment in the Dynarec, limiting amount of dynamic allocation
* Improved memory tracking and managment. Also introduce BOX64_MMAP32 to force 32bits compatible mmap for external libs (like mesa)
=> Allow Vulkan drvier on Wine/WOW64 games to allocate 32bits compatible memory, allowing dxvk on 32bits.
* Reworked memory managment in the Dynarec, limiting amount of dynamic allocation
* Lots of improvments in x87 handling (virtual stack, rounding, ffree, etc.)
=> should improve games stability
* Dynarec: ARM64 some opcodes optimisation, especialy shift and rotation ones
* Dynarec: RV64 lots of opcoded added.
=> Some games on linux now have a good speed. Game on Wine are still a bit slow, and dxvk still have issues
* Dynarec: Added Loogarch backend! Note that Loongarch are 16K pagesize platform by default.
=> Linux games are running, and with good speed, especialy on 3A6000 platforms. Games on Wine are not working yet due to 16k pagesize limitation
* Dynarec: Better handling of large block in the dynarec
* Dynarec: Lots of improvments and fixes to BOX86_DYNAREC_CALLRET optimisation.
=> It can be used on more software now, and combine with BOX64_DYNAREC_BOGBLOCKS 2 or 3 can gives some good speed boosts.
v0.2.6
======
* X64Libs: Updated libstdc++ & libgcc_s
+134 -52
View File
@@ -1,20 +1,16 @@
Compiling/Installing
----
### Debian-based Linux
You can use [@ryanfortner](https://github.com/ryanfortner)'s apt repository to install precompiled box64 debs, updated every 24 hours.
If you don't want to compile box64 yourself and prefer to use third-party pre-build version, go to the [end of the document](#pre-build-packages) for alternatives.
```
sudo wget https://ryanfortner.github.io/box64-debs/box64.list -O /etc/apt/sources.list.d/box64.list
wget -qO- https://ryanfortner.github.io/box64-debs/KEY.gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/box64-debs-archive-keyring.gpg
sudo apt update && sudo apt install box64-arm64 -y
```
You can also generate your own package using the [instructions below](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md#debian-packaging).
Alternatively, you can 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
@@ -26,10 +22,11 @@ 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.
#### 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
@@ -42,21 +39,21 @@ 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`
@@ -72,7 +69,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,23 +77,38 @@ Warning, you need a 64bit OS:
#### for Raspberry Pi 5
If your Raspberry Pi OS use 16K pages use `RPI5ARM64PS16K` instead of `RPI5ARM64`:
```
-D RPI5ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for TEGRA X1
Using a 64bit OS:
On a 64bit OS:
```
-D TEGRAX1=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for Jetson Xavier/T194
On a 64bit OS:
```
-D TEGRA_T194=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for Jetson Orin/T234
On a 64bit OS:
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
@@ -104,7 +116,7 @@ Using a 64bit OS:
#### for Snapdragon
Using a 64bit OS:
On a 64bit OS:
```
-D SD845=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -116,25 +128,25 @@ 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
```
#### for M1
Only test on Asahi for now, using the default "16K page" kernel
Only test on Asahi with Fedora, using the default "16K page" kernel
```
-D M1=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -142,7 +154,7 @@ Only test on Asahi for now, using the default "16K page" kernel
#### for LoongArch
Using a 64bit OS:
On a 64bit OS:
```
-D LARCH64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -150,7 +162,7 @@ Using a 64bit OS:
#### for RISC-V
Using a 64bit OS:
On a 64bit OS:
```
-D RV64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -158,7 +170,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
@@ -166,7 +178,7 @@ Using a 64bit OS:
#### for LX2160A
Using a 64bit OS:
On a 64bit OS:
```
-D LX2160A=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -174,7 +186,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
@@ -184,15 +196,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 -D -DCMAKE_C_COMPILER=clang CMAKE_BUILD_TYPE=RelWithDebInfo
-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
```
@@ -202,50 +215,119 @@ If you encounter some linking errors, try using `NOLOADADDR=ON` (`cmake -D NOLOA
### Use ccmake
Alternatively, you can **use the curses-bases ccmake (or any other gui frontend for cmake)** to select wich platform to use interactively.
Alternatively, you can **use the curses-based ccmake (or any other gui frontend for cmake)** to select which platform to use interactively.
### 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 ARM DynaRec
Dynarec is only available on ARM (for the meantime), Activate it by using `-DARM_DYNAREC=1`.
Add `-DARM_DYNAREC=1` option to enable DynaRec on ARM 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` 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
----
## 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
## 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 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.
```
# check if .list file already exists
if [ -f /etc/apt/sources.list.d/box64.list ]; then
sudo rm -f /etc/apt/sources.list.d/box64.list || exit 1
fi
# check if .sources file already exists
if [ -f /etc/apt/sources.list.d/box64.sources ]; then
sudo rm -f /etc/apt/sources.list.d/box64.sources || exit 1
fi
# download gpg key from specified url
if [ -f /usr/share/keyrings/box64-archive-keyring.gpg ]; then
sudo rm -f /usr/share/keyrings/box64-archive-keyring.gpg
fi
sudo mkdir -p /usr/share/keyrings
wget -qO- "https://pi-apps-coders.github.io/box64-debs/KEY.gpg" | sudo gpg --dearmor -o /usr/share/keyrings/box64-archive-keyring.gpg
# create .sources file
echo "Types: deb
URIs: https://Pi-Apps-Coders.github.io/box64-debs/debian
Suites: ./
Signed-By: /usr/share/keyrings/box64-archive-keyring.gpg" | sudo tee /etc/apt/sources.list.d/box64.sources >/dev/null
sudo apt update
sudo apt install box64-generic-arm -y
```
## Cross-compiling
----
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`.
### 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)
+695 -356
View File
File diff suppressed because it is too large. Load diff
+732 -432
View File
File diff suppressed because it is too large. Load diff
+134
View File
@@ -0,0 +1,134 @@
# Usage: python gen.py
import json
import os
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.
### Configuration files
In addition to environment variables, by default, Box64 also looks for 2 places for rcfile: the system-wide `/etc/box64.box64rc` and user-specific `~/.box64rc`.
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
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']}\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']}\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
""")
+1605
View File
File diff suppressed because it is too large. Load diff
+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."
+1 -1
View File
@@ -1,6 +1,6 @@
# Maintainer: Jai-JAP <[email protected]>
# Author: Sebastien Chevalier <[email protected]>
pkgname=box86-rk3xxx-git
pkgname=box64-rk3xxx-git
pkgver=r2431.60c6858
pkgrel=1
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
+507 -156
View File
@@ -150,14 +150,18 @@ class FunctionConvention(object):
self.ident = ident
self.name = convname
self.values = valid_chars
# Free letters: B FG J QR T XYZab e gh jk mno qrst xyz
# Free letters: B FG JK QR T YZa e gh jk mno qrst yz
conventions = {
'F': FunctionConvention('F', "System V", ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X']),
'W': FunctionConvention('W', "Windows", ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'P', 'A'])
'F': FunctionConvention('F', "System V", ['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']),
'W': FunctionConvention('W', "Windows", ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'P', 'A'])
}
sortedvalues = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X', '0', '1']
sortedvalues = ['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', '0', '1']
assert(all(all(c not in conv.values[:i] and c in sortedvalues for i, c in enumerate(conv.values)) for conv in conventions.values()))
# Some type depend on HAVE_LD80BITS; define this here so we can use it in readFiles and main
depends_on_ld: str = "DY"
assert(all(c in sortedvalues for c in depends_on_ld))
class FunctionType(str):
@staticmethod
def validate(s: str, post: str) -> bool:
@@ -197,7 +201,7 @@ class FunctionType(str):
except ValueError as e:
raise ValueError("Value is " + self) from e
def __getitem__(self, i: Union[int, slice]) -> 'FunctionType':
def __getitem__(self, i: Union[int, slice]) -> 'FunctionType': # type: ignore [override]
return FunctionType(super().__getitem__(i))
RedirectType = NewType('RedirectType', FunctionType)
@@ -359,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
@@ -369,7 +373,7 @@ def readFiles(files: Iterable[Filename]) -> Tuple[JumbledGlobals, JumbledRedirec
# typedefs is a list of all "*FE*" types for the current file
# mystructs is a map of all char -> (structure C name, replacement) for structures
typedefs : JumbledTypedefs = {}
typedefs : JumbledTypedefs = {}
mystructs : JumbledStructures = {}
mystructuses: JumbledStructUses = {}
filespec[filename[:-10]] = (typedefs, mystructs, mystructuses)
@@ -399,10 +403,14 @@ def readFiles(files: Iterable[Filename]) -> Tuple[JumbledGlobals, JumbledRedirec
or match("sdl1mixer", "sdl2mixer") \
or match("sdl1net", "sdl2net") \
or match("sdl1ttf", "sdl2ttf") \
or match("libGL", "libEGL") \
or match("libgl", "libegl") \
or match("libgl", "glesv2") \
or match("libegl", "glesv2") \
or match("softokn3", "p11kit") \
or match("libc", "tcmallocminimal") \
or match("libc", "tbbmallocproxy") \
or match("libc", "androidshmem") \
or match("crypto", "libssl3") \
or match("tcmallocminimal", "tbbmallocproxy"):
continue
@@ -528,9 +536,22 @@ def readFiles(files: Iterable[Filename]) -> Tuple[JumbledGlobals, JumbledRedirec
if ln not in gbl[str(dependants)]:
gbl[str(dependants)].append(FunctionType(ln))
if any(c in origLine for c in depends_on_ld):
if (gotype != "GOM") and (gotype != "GOWM") and (gotype != "GOD") and (gotype != "GOWD"):
print("\033[91mError:\033[m type depends on HAVE_LD80BITS but the GO type doesn't support that ({0}:{1})"
.format(filename, line[:-1]))
halt_required = True
if (gotype == "GO2") or (gotype == "GOW2") or (gotype == "GOD") or (gotype == "GODW"):
altfun = line.split(',')[2].split(')')[0].strip()
if altfun == "":
print("\033[91mError:\033[m empty alt function ({0}:{1})".format(filename, line[:-1]))
halt_required = True
elif altfun == funname:
print("\033[91mError:\033[m alt function is the original function ({0}:{1})".format(filename, line[:-1]))
halt_required = True
if origLine[2] == "E":
if (gotype != "GOM") and (gotype != "GOWM"):
if (gotype != "GO2") or not (line.split(',')[2].split(')')[0].strip().startswith('my_')):
if ((gotype != "GO2") and (gotype != "GOW2")) or not (line.split(',')[2].split(')')[0].strip().startswith('my_')):
print("\033[91mThis is probably not what you meant!\033[m ({0}:{1})".format(filename, line[:-1]))
halt_required = True
if len(origLine) > 3:
@@ -816,62 +837,82 @@ def main(root: str, files: Iterable[Filename], ver: str):
return 0
# Detect simple wrappings
simple_wraps: Dict[ClausesStr, List[Tuple[FunctionType, int]]] = {}
allowed_conv_ident = "F"
allowed_conv = conventions[allowed_conv_ident]
# H could be allowed maybe?
allowed_simply: str = "v"
allowed_regs : str = "cCwWiuIUlLp"
allowed_fpr : str = "fd"
allowed_simply: Dict[str, str] = {"ARM64": "v", "RV64": "v"}
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 = "DK"
return_x87: str = "D"
# Sanity checks
forbidden_simple: str = "EDKVOSNMHPAxX"
assert(len(allowed_simply) + len(allowed_regs) + len(allowed_fpr) + len(forbidden_simple) == len(allowed_conv.values))
assert(all(c not in allowed_regs for c in allowed_simply))
assert(all(c not in allowed_simply + allowed_regs for c in allowed_fpr))
assert(all(c not in allowed_simply + allowed_regs + allowed_fpr for c in forbidden_simple))
assert(all(c in allowed_simply + allowed_regs + allowed_fpr + forbidden_simple for c in allowed_conv.values))
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(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] + 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))
def check_simple(v: FunctionType) -> Optional[int]:
regs_count: int = 0
fpr_count : int = 0
if v.get_convention() is not allowed_conv:
return None
if v[0] in forbidden_simple:
return None
for c in v[2:]:
if c in allowed_regs:
regs_count = regs_count + 1
elif c in allowed_fpr:
fpr_count = fpr_count + 1
elif c in allowed_simply:
simple_wraps: Dict[str, Dict[ClausesStr, List[Tuple[FunctionType, int]]]] = {
k1: {} for k1 in forbidden_simple
}
def check_simple(v: FunctionType) -> Dict[str, int]:
ret: Dict[str, int] = {}
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
if v[0] in forbidden_simple[k]:
continue
for c in v[2:]:
if c in allowed_regs[k]:
regs_count = regs_count + 1
elif c in allowed_fpr[k]:
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:
return None
# No character in forbidden_simply
if (regs_count <= 6) and (fpr_count <= 8):
# All checks passed!
ret_val = 1 + fpr_count
if v[0] in allowed_fpr:
ret_val = -ret_val
return ret_val
else:
# Too many arguments...
return None
# No character in forbidden_simply
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
# Else, too many arguments
return ret
# Only search in real wrappers (mapped ones are nearly always not simple)
for k in gbls:
tmp = [ (v, ret_val) for v, ret_val in map(lambda v: (v, check_simple(v)), gbls[k]) if ret_val is not None ]
if tmp:
simple_wraps[k] = tmp
simple_idxs = sorted(simple_wraps.keys(), key=lambda x: Clauses(x).splitdef())
for v in gbls[k]:
simples = check_simple(v)
for k1, i in simples.items():
if k in simple_wraps[k1]:
simple_wraps[k1][k].append((v, i))
else:
simple_wraps[k1][k] = [(v, i)]
simple_idxs = { k1: sorted(v1.keys(), key=lambda x: Clauses(x).splitdef()) for k1, v1 in simple_wraps.items() }
def check_return_x87(v: FunctionType) -> bool:
return v[0] in return_x87
@@ -915,9 +956,24 @@ def main(root: str, files: Iterable[Filename], ver: str):
return v;
{rbr}
static void* io_convert_back(void* v)
{lbr}
if(!v)
return v;
if(v == stdin)
return my__IO_2_1_stdin_;
if(v == stdout)
return my__IO_2_1_stdout_;
if(v == stderr)
return my__IO_2_1_stderr_;
return v;
{rbr}
#define ST0val ST0.d
int of_convert(int);
void* align_xcb_connection(void* src);
void unalign_xcb_connection(void* src, void* dst);
""",
"wrapper.h": """
@@ -949,11 +1005,11 @@ def main(root: str, files: Iterable[Filename], ver: str):
// o = stdout
// S = _IO_2_1_stdXXX_ pointer (or FILE*)
// N = ... automatically sending 1 arg
// M = ... automatically sending 2 args
// A = va_list
// 0 = constant 0, 1 = constant 1
// x = float complex
// X = double complex
// b = xcb_connection_t*
""",
"fntypes.h": """
@@ -977,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 = {
@@ -999,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}
"""
}
@@ -1015,20 +1099,59 @@ def main(root: str, files: Iterable[Filename], ver: str):
# Rewrite the wrapper.c file:
# i and u should only be 32 bits
td_types = {
# E v c w i I C W u U f d D K l L p V O S N M H P A x X
'F': ["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*", "void*", "int32_t", "void*", "...", "...", "unsigned __int128", "void*", "void*", "complexf_t", "complex_t"],
# E v c w i I C W u U f d K l L p V O S N M P A
'W': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "...", "void*", "void*"]
# 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
'F': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "unsigned __int128", "void*", "void*", "complexf_t", "complex_t", "complexl_t", "void*"],
# E v c w i I C W u U f d l L p V O S N P A
'W': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "void*", "void*"]
}
td_types_nold = {
'F': {'D': "double", 'Y': "complex_t"},
'W': {}
}
td_types_ld = {
k: {t: td_types[k][conventions[k].values.index(t)] for t in td_types_nold[k]} for k in td_types_nold
}
assert(all(k in conventions for k in td_types))
assert(all(k in conventions for k in td_types_nold))
assert(all(t in depends_on_ld for k in td_types_nold for t in td_types_nold[k]))
for k in conventions:
if len(conventions[k].values) != len(td_types[k]):
raise NotImplementedError("len(values) = {lenval} != len(td_types) = {lentypes}".format(lenval=len(conventions[k].values), lentypes=len(td_types[k])))
def generate_typedefs(arr: Iterable[FunctionType], file) -> None:
any_depends_on_ld = False
for v in arr:
file.write("typedef " + td_types[v.get_convention().ident][v.get_convention().values.index(v[0])] + " (*" + v + "_t)"
if any(c in v for c in depends_on_ld):
any_depends_on_ld = True
continue
name = v + "_t"
v = v[:-1] if v.endswith('NN') else v # FIXME
file.write("typedef " + td_types[v.get_convention().ident][v.get_convention().values.index(v[0])] + " (*" + name + ")"
+ "(" + ', '.join(td_types[v.get_convention().ident][v.get_convention().values.index(t)] for t in v[2:]) + ");\n")
if any_depends_on_ld:
file.write("\n#if defined(HAVE_LD80BITS) || defined(ANDROID)\n")
for v in arr:
if all(c not in v for c in depends_on_ld):
continue
name = v + "_t"
v = v[:-1] if v.endswith('NN') else v # FIXME
file.write("typedef " + td_types[v.get_convention().ident][v.get_convention().values.index(v[0])] + " (*" + name + ")"
+ "(" + ', '.join(td_types[v.get_convention().ident][v.get_convention().values.index(t)] for t in v[2:]) + ");\n")
file.write("#else // !HAVE_LD80BITS && !ANDROID\n")
for k in td_types_nold:
for t in td_types_nold[k]:
td_types[k][conventions[k].values.index(t)] = td_types_nold[k][t]
for v in arr:
if all(c not in v for c in depends_on_ld):
continue
name = v + "_t"
v = v[:-1] if v.endswith('NN') else v # FIXME
file.write("typedef " + td_types[v.get_convention().ident][v.get_convention().values.index(v[0])] + " (*" + name + ")"
+ "(" + ', '.join(td_types[v.get_convention().ident][v.get_convention().values.index(t)] for t in v[2:]) + ");\n")
for k in td_types_nold:
for t in td_types_ld[k]:
td_types[k][conventions[k].values.index(t)] = td_types_ld[k][t]
file.write("#endif\n")
with open(os.path.join(root, "src", "wrapped", "generated", "wrapper.c"), 'w') as file:
file.write(files_header["wrapper.c"].format(lbr="{", rbr="}", version=ver))
@@ -1051,10 +1174,10 @@ def main(root: str, files: Iterable[Filename], ver: str):
conventions['F']: [
"\n#error Invalid return type: emulator\n", # E
"fn({0});", # v
"R_RAX=fn({0});", # c
"R_RAX=fn({0});", # w
"R_RAX=(int32_t)fn({0});", # i
"R_RAX=(int64_t)fn({0});", # I
"R_RAX=(uint8_t)fn({0});", # c
"R_RAX=(uint16_t)fn({0});", # w
"R_RAX=(uint32_t)fn({0});", # i
"S_RAX=(int64_t)fn({0});", # I
"R_RAX=(unsigned char)fn({0});", # C
"R_RAX=(unsigned short)fn({0});", # W
"R_RAX=(uint32_t)fn({0});", # u
@@ -1062,20 +1185,20 @@ def main(root: str, files: Iterable[Filename], ver: str):
"emu->xmm[0].f[0]=fn({0});", # f
"emu->xmm[0].d[0]=fn({0});", # d
"long double ld=fn({0}); fpu_do_push(emu); ST0val = ld;", # D
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # K
"R_RAX=(intptr_t)fn({0});", # l
"R_RAX=(uintptr_t)fn({0});", # L
"R_RAX=(uintptr_t)fn({0});", # p
"\n#error Invalid return type: va_list\n", # V
"\n#error Invalid return type: at_flags\n", # O
"\n#error Invalid return type: _io_file*\n", # S
"R_RAX=(uintptr_t)io_convert_back(fn({0}));", # S
"\n#error Invalid return type: ... with 1 arg\n", # N
"\n#error Invalid return type: ... with 2 args\n", # M
"unsigned __int128 u128 = fn({0}); R_RAX=(u128&0xFFFFFFFFFFFFFFFFL); R_RDX=(u128>>64)&0xFFFFFFFFFFFFFFFFL;", # H
"\n#error Invalid return type: pointer in the stack\n", # P
"\n#error Invalid return type: va_list\n", # A
'from_complexf(emu, fn({0})));', # x
'from_complex(emu, fn({0})));' # X
"from_complexf(emu, fn({0}));", # x
"from_complex(emu, fn({0}));", # X
"from_complexl(emu, fn({0}));", # Y
"\n#error Invalid return type: xcb_connection_t*\n", # b
],
conventions['W']: [
"\n#error Invalid return type: emulator\n", # E
@@ -1090,32 +1213,47 @@ def main(root: str, files: Iterable[Filename], ver: str):
"R_RAX=fn({0});", # U
"emu->xmm[0].f[0]=fn({0});", # f
"emu->xmm[0].d[0]=fn({0});", # d
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # K
"R_RAX=(intptr_t)fn({0});", # l
"R_RAX=(uintptr_t)fn({0});", # L
"R_RAX=(uintptr_t)fn({0});", # p
"\n#error Invalid return type: va_list\n", # V
"\n#error Invalid return type: at_flags\n", # O
"\n#error Invalid return type: _io_file*\n", # S
"R_RAX=io_convert_back(fn({0}));", # S
"\n#error Invalid return type: ... with 1 arg\n", # N
"\n#error Invalid return type: ... with 2 args\n", # M
"\n#error Invalid return type: pointer in the stack\n", # P
"\n#error Invalid return type: va_list\n", # A
]
}
vals_nold = {
conventions['F']: {
'D': "double db=fn({0}); fpu_do_push(emu); ST0val = db;",
'Y': "from_complexk(emu, fn({0}));",
},
conventions['W']: {}
}
vals_android = {
conventions['F']: {
"D": "long double ld=fn({0}); emu->xmm[0].u128=*(__uint128_t*)&ld;",
"Y": "from_complexl(emu, fn({0}));",
},
conventions['W']: {}
}
vals_ld = {
k: {t: vals[k][k.values.index(t)] for t in vals_nold[k]} for k in vals_nold
}
# vreg: value is in a general register
# E v c w i I C W u U f d D K l L p V O S N M H P A x X
vreg = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 2, 2, 0, 1, 0, 0]
# 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
vreg = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 2, 0, 1, 0, 0, 0, 1]
# vxmm: value is in a XMM register
# E v c w i I C W u U f d D K l L p V O S N M H P A x X
vxmm = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2]
# 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
vxmm = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]
# vother: value is elsewere
# E v c w i I C W u U f d D K l L p V O S N M H P A x X
vother = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# 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
vother = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# vstack: value is on the stack (or out of register)
# E v c w i I C W u U f d D K l L p V O S N M H P A x X
vstack = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 2]
# 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
vstack = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, 1, 1, 1, 2, 1, 1, 1, 2, 4, 1]
arg_r = [
"", # E
"", # v
@@ -1130,7 +1268,6 @@ def main(root: str, files: Iterable[Filename], ver: str):
"", # f
"", # d
"", # D
"", # K
"(intptr_t){p}, ", # l
"(uintptr_t){p}, ", # L
"(void*){p}, ", # p
@@ -1138,70 +1275,71 @@ def main(root: str, files: Iterable[Filename], ver: str):
"of_convert((int32_t){p}), ", # O
"io_convert((void*){p}), ", # S
"(void*){p}, ", # N
"(void*){p}, ", # M
"\n#error Use pp instead\n", # H
"(unsigned __int128){p} + ((unsigned __int128){p2} << 64), ", # H
"", # P
"(void*){p}, ", # A
"", # x
"", # x
"", # X
"", # Y
"aligned_xcb, ", # b
]
arg_x = [
"", # E
"", # v
"", # c
"", # w
"", # i
"", # I
"", # C
"", # W
"", # u
"", # U
"emu->xmm[{p}].f[0], ", # f
"emu->xmm[{p}].d[0], ", # d
"", # D
"", # K
"", # l
"", # L
"", # p
"", # V
"", # O
"", # S
"", # N
"", # M
"", # H
"", # P
"", # A
"to_complexf(emu, {p}),",# x
"to_complex(emu, {p})," # X
"", # E
"", # v
"", # c
"", # w
"", # i
"", # I
"", # C
"", # W
"", # u
"", # U
"emu->xmm[{p}].f[0], ", # f
"emu->xmm[{p}].d[0], ", # d
"", # D
"", # l
"", # L
"", # p
"", # V
"", # O
"", # S
"", # N
"", # H
"", # P
"", # A
"to_complexf(emu, {p}), ", # x
"to_complex(emu, {p}), ", # X
"", # Y
"", # b
]
arg_o = [
"emu, ", # E
"", # v
"", # c
"", # w
"", # i
"", # I
"", # C
"", # W
"", # u
"", # U
"", # f
"", # d
"", # D
"", # K
"", # l
"", # L
"", # p
"(void*)(R_RSP + {p}), ", # V
"", # O
"", # S
"", # N
"", # M
"", # H
"", # P
"", # A
"", # x
"", # X
"emu, ", # E
"", # v
"", # c
"", # w
"", # i
"", # I
"", # C
"", # W
"", # u
"", # U
"", # f
"", # d
"", # D
"", # l
"", # L
"", # p
"(void*)(R_RSP + {p}), ", # V
"", # O
"", # S
"", # N
"", # H
"", # P
"", # A
"", # x
"", # X
"", # Y
"", # b
]
arg_s = [
"", # E
@@ -1217,7 +1355,6 @@ def main(root: str, files: Iterable[Filename], ver: str):
"*(float*)(R_RSP + {p}), ", # f
"*(double*)(R_RSP + {p}), ", # d
"LD2localLD((void*)(R_RSP + {p})), ", # D
"FromLD((void*)(R_RSP + {p})), ", # K
"*(intptr_t*)(R_RSP + {p}), ", # l
"*(uintptr_t*)(R_RSP + {p}), ", # L
"*(void**)(R_RSP + {p}), ", # p
@@ -1225,13 +1362,36 @@ def main(root: str, files: Iterable[Filename], ver: str):
"of_convert(*(int32_t*)(R_RSP + {p})), ", # O
"io_convert(*(void**)(R_RSP + {p})), ", # S
"*(void**)(R_RSP + {p}), ", # N
"*(void**)(R_RSP + {p}),*(void**)(R_RSP + {p} + 8), ", # M
"*(unsigned __int128)(R_RSP + {p}), ", # H
"*(unsigned __int128*)(R_RSP + {p}), ", # H
"*(void**)(R_RSP + {p}), ", # P
"*(void**)(R_RSP + {p}), ", # A
"*(complexf_t*)(R_RSP + {p}), ", # x
"*(complex_t*)(R_RSP + {p}), ", # X
"to_complexl(emu, R_RSP + {p}), ", # Y
"aligned_xcb, ", # b
]
arg_s_nold = {
'D': "FromLD((void*)(R_RSP + {p})), ", # K
'Y': "to_complexk(emu, R_RSP + {p}), ", # y
}
arg_s_android = {
'D': "*(long double*)(R_RSP + {p})], ",
'Y': "to_complexl(emu, R_RSP + {p}), ",
}
arg_s_ld = {
t: arg_s[conventions['F'].values.index(t)] for t in arg_s_nold
}
vxmm_noandroid = vxmm[:]
vxmm_android = vxmm[:]
vxmm_android[conventions['F'].values.index('D')] = 1
vxmm_android[conventions['F'].values.index('Y')] = 1
arg_x_android = {
'D': "*(long double*)&emu->xmm[{p}], ",
'Y': "to_complexl(emu, (uintptr_t)&emu->xmm[{p}]), ",
}
arg_x_ld = {
t: arg_x[conventions['F'].values.index(t)] for t in arg_x_android
}
# Asserts
for k in conventions:
@@ -1258,7 +1418,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
for k in conventions:
c = conventions[k]
if c not in vals:
raise NotImplementedError("[{k}]values not in vals".format(k=k, lenval=len(c.values), lenvals=len(vals[c])))
raise NotImplementedError("convention {k} not in vals".format(k=k))
if len(c.values) != len(vals[c]):
raise NotImplementedError("len([{k}]values) = {lenval} != len(vals[...]) = {lenvals}".format(k=k, lenval=len(c.values), lenvals=len(vals[c])))
# When arg_* is not empty, v* should not be 0
@@ -1282,6 +1442,50 @@ def main(root: str, files: Iterable[Filename], ver: str):
# Helper functions to write the function definitions
systemVconv = conventions['F']
def function_pre_systemV(args: FunctionType, d: int = 8, r: int = 0, x: int = 0) -> Tuple[Optional[str], str]:
# args: string of argument types
# d: delta (in the stack)
# r: general register no
# x: XMM register no
if len(args) == 0:
return None, ""
# Redirections
if args[0] == "0":
return function_pre_systemV(args[1:], d, r, x)
elif args[0] == "1":
return function_pre_systemV(args[1:], d, r, x)
idx = systemVconv.values.index(args[0])
# Name of the registers
reg_arg = ["R_RDI", "R_RSI", "R_RDX", "R_RCX", "R_R8", "R_R9"]
if args[0] == "b":
if 'b' in args[1:]:
raise NotImplementedError("Multiple XCB connections unsupported")
content = ""
if r < len(reg_arg):
content = reg_arg[r]
else:
content = "(R_RSP + " + str(d) + ")"
return "(void*)" + content, f"void *aligned_xcb = align_xcb_connection((void*){content}); "
elif (r < len(reg_arg)) and (vreg[idx] > 0):
for _ in range(vreg[idx]):
if r < len(reg_arg):
r = r + 1
else:
d = d + 8
return function_pre_systemV(args[1:], d, r, x)
elif (x < 8) and (vxmm[idx] > 0):
return function_pre_systemV(args[1:], d, r, x+1)
elif vstack[idx] > 0:
return function_pre_systemV(args[1:], d+8*vstack[idx], r, x)
else:
return function_pre_systemV(args[1:], d, r, x)
def function_post_systemV(content: Optional[str]) -> str:
if content is not None:
return f" unalign_xcb_connection(aligned_xcb, {content});"
else:
return ""
def function_args_systemV(args: FunctionType, d: int = 8, r: int = 0, x: int = 0) -> str:
# args: string of argument types
# d: delta (in the stack)
@@ -1301,20 +1505,30 @@ def main(root: str, files: Iterable[Filename], ver: str):
reg_arg = ["R_RDI", "R_RSI", "R_RDX", "R_RCX", "R_R8", "R_R9"]
if (r < len(reg_arg)) and (vreg[idx] > 0):
ret = ""
for _ in range(vreg[idx]):
# There may be values in multiple registers
if (vreg[idx] == 2) and ("{p2}" in arg_r[idx]):
if r < len(reg_arg):
# Value is in a general register
ret = ret + arg_r[idx].format(p=reg_arg[r])
r = r + 1
ret = ret + arg_r[idx].format(p=reg_arg[r], p2=reg_arg[r+1])
r = r + 2
else:
# Remaining is in the stack
ret = ret + arg_s[idx].format(p=d)
d = d + 8
else:
for _ in range(vreg[idx]):
# There may be values in multiple registers
if r < len(reg_arg):
# Value is in a general register
ret = ret + arg_r[idx].format(p=reg_arg[r])
r = r + 1
else:
# Remaining is in the stack
ret = ret + arg_s[idx].format(p=d)
d = d + 8
return ret + function_args_systemV(args[1:], d, r, x)
elif (x < 8) and (vxmm[idx] > 0):
# Value is in an XMM register
return arg_x[idx].format(p=x) + function_args_systemV(args[1:], d, r, x+1)
return arg_x[idx].format(p=x) + function_args_systemV(args[1:], d, r, x+vxmm[idx])
elif vstack[idx] > 0:
# Value is in the stack
return arg_s[idx].format(p=d) + function_args_systemV(args[1:], d+8*vstack[idx], r, x)
@@ -1361,42 +1575,156 @@ def main(root: str, files: Iterable[Filename], ver: str):
# Generic function
conv = N.get_convention()
if conv is systemVconv:
f.write(vals[conv][conv.values.index(N[0])].format(function_args_systemV(N[2:])[:-2]) + " }\n")
prepost, pre = function_pre_systemV(N[2:])
f.write(pre + vals[conv][conv.values.index(N[0])].format(function_args_systemV(N[2:])[:-2]) + function_post_systemV(prepost))
else:
f.write(vals[conv][conv.values.index(N[0])].format(function_args_windows(N[2:])[:-2]) + " }\n")
f.write(vals[conv][conv.values.index(N[0])].format(function_args_windows(N[2:])[:-2]))
f.write(" }\n")
for k in gbls:
any_depends_on_ld = False
if k != str(Clauses()):
file.write("\n#if " + k + "\n")
for v in gbls[k]:
if any(c in v for c in depends_on_ld):
any_depends_on_ld = True
continue
if v == FunctionType("vFv"):
# Suppress all warnings...
file.write("void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); (void)emu; }\n")
else:
function_writer(file, v, v + "_t")
if any_depends_on_ld:
file.write("\n#if defined(ANDROID)\n")
for c in vals_android:
for t in vals_android[c]:
vals[c][c.values.index(t)] = vals_android[c][t]
for t in arg_s_android:
arg_s[conventions['F'].values.index(t)] = arg_s_android[t]
for t in arg_x_android:
arg_x[conventions['F'].values.index(t)] = arg_x_android[t]
vxmm = vxmm_android
for v in gbls[k]:
if all(c not in v for c in depends_on_ld):
continue
if v == FunctionType("vFv"):
# Suppress all warnings...
file.write("void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); (void)emu; }\n")
else:
function_writer(file, v, v + "_t")
file.write("#elif !defined(HAVE_LD80BITS)\n")
for c in vals_android:
for t in vals_ld[c]:
vals[c][c.values.index(t)] = vals_ld[c][t]
for c in vals_nold:
for t in vals_nold[c]:
vals[c][c.values.index(t)] = vals_nold[c][t]
for t in arg_s_android:
arg_s[conventions['F'].values.index(t)] = arg_s_ld[t]
for t in arg_s_nold:
arg_s[conventions['F'].values.index(t)] = arg_s_nold[t]
for t in arg_x_android:
arg_x[conventions['F'].values.index(t)] = arg_x_ld[t]
vxmm = vxmm_noandroid
for v in gbls[k]:
if all(c not in v for c in depends_on_ld):
continue
if v == FunctionType("vFv"):
# Suppress all warnings...
file.write("void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); (void)emu; }\n")
else:
function_writer(file, v, v + "_t")
for c in vals_nold:
for t in vals_nold[c]:
vals[c][c.values.index(t)] = vals_ld[c][t]
for t in arg_s_nold:
arg_s[conventions['F'].values.index(t)] = arg_s_ld[t]
file.write("#else // defined(HAVE_LD80BITS) && !defined(ANDROID)\n")
for v in gbls[k]:
if all(c not in v for c in depends_on_ld):
continue
if v == FunctionType("vFv"):
# Suppress all warnings...
file.write("void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); (void)emu; }\n")
else:
function_writer(file, v, v + "_t")
file.write("#endif\n")
if k != str(Clauses()):
file.write("#endif\n")
file.write("\n")
for k in redirects:
any_depends_on_ld = False
if k != str(Clauses()):
file.write("\n#if " + k + "\n")
for vr, vf in redirects[k]:
if any(c in vr for c in depends_on_ld):
any_depends_on_ld = True
continue
function_writer(file, vr, vf + "_t")
if any_depends_on_ld:
file.write("\n#if defined(ANDROID)\n")
for c in vals_android:
for t in vals_android[c]:
vals[c][c.values.index(t)] = vals_android[c][t]
for t in arg_s_android:
arg_s[conventions['F'].values.index(t)] = arg_s_android[t]
for t in arg_x_android:
arg_x[conventions['F'].values.index(t)] = arg_x_android[t]
vxmm = vxmm_android
for vr, vf in redirects[k]:
if all(c not in vr for c in depends_on_ld):
continue
function_writer(file, vr, vf + "_t")
file.write("#elif !defined(HAVE_LD80BITS)\n")
for c in vals_android:
for t in vals_ld[c]:
vals[c][c.values.index(t)] = vals_ld[c][t]
for c in vals_nold:
for t in vals_nold[c]:
vals[c][c.values.index(t)] = vals_nold[c][t]
for t in arg_s_android:
arg_s[conventions['F'].values.index(t)] = arg_s_ld[t]
for t in arg_s_nold:
arg_s[conventions['F'].values.index(t)] = arg_s_nold[t]
for t in arg_x_android:
arg_x[conventions['F'].values.index(t)] = arg_x_ld[t]
vxmm = vxmm_noandroid
for vr, vf in redirects[k]:
if all(c not in vr for c in depends_on_ld):
continue
function_writer(file, vr, vf + "_t")
for c in vals_nold:
for t in vals_nold[c]:
vals[c][c.values.index(t)] = vals_ld[c][t]
for t in arg_s_nold:
arg_s[conventions['F'].values.index(t)] = arg_s_ld[t]
file.write("#else // defined(HAVE_LD80BITS) && !defined(ANDROID)\n")
for vr, vf in redirects[k]:
if all(c not in vr for c in depends_on_ld):
continue
function_writer(file, vr, vf + "_t")
file.write("#endif\n")
if k != str(Clauses()):
file.write("#endif\n")
# Write the isSimpleWrapper function
file.write("\nint isSimpleWrapper(wrapper_t fun) {\n")
for k in simple_idxs:
if k != str(Clauses()):
file.write("#if " + k + "\n")
for vf, val in simple_wraps[k]:
file.write("\tif (fun == &" + vf + ") return " + str(val) + ";\n")
if k != str(Clauses()):
file.write("#endif\n")
file.write("\treturn 0;\n}\n")
inttext = ""
file.write("\n")
for k1 in simple_idxs:
file.write("#{inttext}if defined({k1})\nint isSimpleWrapper(wrapper_t fun) {{\n\tif (box64_is32bits) return 0;\n".format(inttext=inttext, k1=k1))
inttext = "el"
for k in simple_idxs[k1]:
if k != str(Clauses()):
file.write("#if " + k + "\n")
for vf, val in simple_wraps[k1][k]:
file.write("\tif (fun == &" + vf + ") return " + str(val) + ";\n")
if k != str(Clauses()):
file.write("#endif\n")
file.write("\treturn 0;\n}\n")
file.write("#else\nint isSimpleWrapper(wrapper_t fun) {\n\treturn 0;\n}\n#endif\n")
# Write the isRetX87Wrapper function
file.write("\nint isRetX87Wrapper32(wrapper_t fun)\n#ifndef BOX32\n{ return 0; }\n#else\n ;\n#endif\n")
file.write("\nint isRetX87Wrapper(wrapper_t fun) {\n")
for k in retx87_idxs:
if k != str(Clauses()):
@@ -1430,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 "OSNxXYb") or signature.endswith('FE'):
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"
@@ -1475,11 +1826,11 @@ def main(root: str, files: Iterable[Filename], ver: str):
return 0
if __name__ == '__main__':
limit = []
limit: List[int] = []
for i, v in enumerate(sys.argv):
if v == "--":
limit.append(i)
Define.defines = list(map(DefineType, sys.argv[2:limit[0]]))
if main(sys.argv[1], sys.argv[limit[0]+1:], "2.2.0.18") != 0:
if main(sys.argv[1], sys.argv[limit[0]+1:], "2.5.0.24") != 0:
exit(2)
exit(0)
+1655
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -19,10 +19,10 @@ set(ENV{BOX64_LOG} 0)
set(ENV{BOX64_NOBANNER} 1)
if( EXISTS ${CMAKE_SOURCE_DIR}/x64lib )
# we are inside box64 folder
set(ENV{LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/x64lib)
set(ENV{BOX64_LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/x64lib)
else()
# we are inside build folder
set(ENV{LD_LIBRARY_PATH} ${CMAKE_SOURCE_DIR}/../x64lib)
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
+342
View File
@@ -0,0 +1,342 @@
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include "debug.h"
#include "box32.h"
#include "custommem.h"
#include "converter32.h"
#include "khash.h"
KHASH_MAP_INIT_INT64(to, ulong_t);
KHASH_MAP_INIT_INT(from, uintptr_t);
KHASH_MAP_INIT_STR(strings, ptr_t);
static kh_from_t* hash_from = NULL;
static kh_to_t* hash_to = NULL;
#define HASH_MSK 0xf000000f
#define HASH_VAL 0x00ffffff
#define HASH_SHIFT 4
static uint32_t hash_cnt = 1;
static pthread_rwlock_t hash_lock = {0};
static int hash_running = 0;
// locale
static kh_from_t* locale_from = NULL;
static kh_to_t* locale_to = NULL;
static kh_strings_t* const_strings = NULL;
void init_hash_helper() {
hash_from = kh_init(from);
hash_to = kh_init(to);
locale_from = kh_init(from);
locale_to = kh_init(to);
const_strings = kh_init(strings);
pthread_rwlock_init(&hash_lock, NULL);
hash_running = 1;
}
void fini_hash_helper() {
if(!hash_running)
return;
hash_running = 0;
kh_destroy(from, hash_from);
hash_from = NULL;
kh_destroy(to, hash_to);
hash_to = NULL;
hash_cnt = 1;
kh_destroy(from, locale_from);
locale_from = NULL;
kh_destroy(to, locale_to);
locale_to = NULL;
kh_destroy(strings, const_strings); //TODO: does not free memory correctly
const_strings = NULL;
pthread_rwlock_destroy(&hash_lock);
}
// Convert from hash key to original 64bits value
uintptr_t from_hash(ulong_t l) {
// easy case first
if((l&HASH_MSK)!=HASH_MSK) {
return (uintptr_t)l;
}
if(l==0xffffffff) {
return 0xffffffffffffffffll;
}
// get value from hash table second
uintptr_t ret = 0;
if(!hash_running) {
//printf_log(LOG_INFO, "Warning, from_hash used but hash not running\n");
return ret;
}
pthread_rwlock_rdlock(&hash_lock);
khint_t k = kh_get(from, hash_from, l);
if (k==kh_end(hash_from)) {
ret = (uintptr_t)l;
} else {
ret = kh_value(hash_from, k);
}
pthread_rwlock_unlock(&hash_lock);
return ret;
}
// same as from_hash
uintptr_t from_hash_d(ulong_t l) {
return from_hash(l);
}
// Convert from 64bits to hash key, creating it if needed
ulong_t to_hash(uintptr_t p) {
if((p<0x100000000LL) && ((p&HASH_MSK)!=HASH_MSK))
return (ulong_t)p;
if(p==0xffffffffffffffffll) {
return 0xffffffff;
}
ulong_t ret = 0;
if(!hash_running) {
//printf_log(LOG_INFO, "Warning, to_hash used but hash not running\n");
return ret;
}
khint_t k;
pthread_rwlock_rdlock(&hash_lock);
k = kh_get(to, hash_to, p);
if(k==kh_end(hash_to)) {
// create a new key, but need write lock!
pthread_rwlock_unlock(&hash_lock);
pthread_rwlock_wrlock(&hash_lock);
ret = HASH_MSK | (((hash_cnt++)&HASH_VAL)<<HASH_SHIFT);
int r;
k = kh_put(to, hash_to, p, &r);
kh_value(hash_to, k) = ret;
k = kh_put(from, hash_from, ret, &r);
kh_value(hash_from, k) = p;
} else {
ret = kh_value(hash_to, k);
}
pthread_rwlock_unlock(&hash_lock);
return ret;
}
// Convert from 64bits to hash key and delete the entry from both hash table
ulong_t to_hash_d(uintptr_t p) {
if((p<0x100000000LL) && ((p&HASH_MSK)!=HASH_MSK))
return (ulong_t)p;
if(p==0xffffffffffffffffll)
return 0xffffffff;
ulong_t ret = 0;
if(!hash_running) {
//printf_log(LOG_INFO, "Warning, to_hash_d used but hash not running\n");
return ret;
}
khint_t k;
pthread_rwlock_wrlock(&hash_lock);
k = kh_get(to, hash_to, p);
if(k==kh_end(hash_to)) {
/// should this be an assert?
} else {
ret = kh_value(hash_to, k);
// delete both entries
//k = kh_get(to, hash_to, p);
kh_del(to, hash_to, k);
k = kh_get(from, hash_from, ret);
kh_del(from, hash_from, k);
}
pthread_rwlock_unlock(&hash_lock);
return ret;
}
typedef struct struct_locale_s {
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]; //const char*
} struct_locale_t;
// not a real structure
#define LOCALE_SIGN 0x54abcd845412LL
typedef struct struct_locale_32_s {
ptr_t p0[13];
ptr_t p1;
ptr_t p2;
ptr_t p3;
ptr_t p4[13];
uint64_t sign;
struct_locale_t* org; // save the orginal locale
// copy of the array, in case some apps use them
unsigned short int type_b[384];
int tolower[384];
int tohigher[384];
} struct_locale_32_t;
void to_struct_locale(ptr_t d, const struct_locale_t *src) {
if (!src) return;
struct_locale_32_t* dest = from_ptrv(d);
// save the original locale
dest->sign = LOCALE_SIGN;
dest->org = (void*)src;
//copy the 2 arrays
for(int i=0; i<13; ++i) {
dest->p0[i] = to_hashv(src->p0[i]);
}
for(int i=0; i<13; ++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));
memcpy(dest->tolower, src->p2-128*sizeof(int), 384*sizeof(int));
memcpy(dest->tohigher, src->p3-128*sizeof(int), 384*sizeof(int));
dest->p1 = to_ptrv(dest->type_b)+128*sizeof(short);
dest->p2 = to_ptrv(dest->tolower)+128*sizeof(int);
dest->p3 = to_ptrv(dest->tohigher)+128*sizeof(int);
}
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) {
to_hash_d((uintptr_t)src->p4[i]);
}*/
}
// Convert from locale key to original 64bits value
void* from_locale(ptr_t l) {
// easy case first
if(l < 0x100) {
return from_ptrv(l);
}
if(l == 0xffffffff) {
return (void*)-1;
}
// get value from hash table second
void* ret = 0;
if(!hash_running) {
//printf_log(LOG_INFO, "Warning, from_locale used but hash not running\n");
return ret;
}
struct_locale_32_t* loc = from_ptrv(l);
if(loc->sign==LOCALE_SIGN)
return loc->org;
pthread_rwlock_rdlock(&hash_lock);
khint_t k = kh_get(from, locale_from, l);
if (k==kh_end(locale_from)) {
ret = from_ptrv(l);
} else {
ret = (void*)kh_value(locale_from, k);
}
pthread_rwlock_unlock(&hash_lock);
//from_struct_locale((struct_locale_t*)ret, l);
return ret;
}
// same as from_locale
void* from_locale_d(ptr_t l) {
return from_locale(l);
}
// Convert from 64bits to locale key, creating it if needed
ptr_t to_locale(void* p) {
if((uintptr_t)p < 0x100) {
return to_ptrv(p);
}
if(p == (void*)-1) {
return 0xffffffff;
}
ptr_t ret = 0;
if(!hash_running) {
//printf_log(LOG_INFO, "Warning, to_locale used but hash not running\n");
return ret;
}
khint_t k;
pthread_rwlock_rdlock(&hash_lock);
k = kh_get(to, locale_to, (uintptr_t)p);
int conv = 0;
if(k==kh_end(locale_to)) {
// create a new key, but need write lock!
pthread_rwlock_unlock(&hash_lock);
pthread_rwlock_wrlock(&hash_lock);
// a locale_t is 5 pointer!
void* m = calloc(1, sizeof(struct_locale_32_t)); // the 3 ctype value are also inside the locale struct
ret = to_ptrv(m);
// add to hash maps
int r;
k = kh_put(to, locale_to, (uintptr_t)p, &r);
kh_value(locale_to, k) = ret;
k = kh_put(from, locale_from, ret, &r);
kh_value(locale_from, k) = (uintptr_t)p;
conv = 1;
} else {
ret = kh_value(locale_to, k);
}
pthread_rwlock_unlock(&hash_lock);
if(conv)
to_struct_locale(ret, (struct_locale_t*)p);
return ret;
}
// Convert from 64bits to hash key and delete the entry from both hash table
ptr_t to_locale_d(void* p) {
if((uintptr_t)p < 0x100)
return to_ptrv(p);
ptr_t ret = 0;
if(!hash_running)
return ret;
khint_t k;
pthread_rwlock_wrlock(&hash_lock);
k = kh_get(to, locale_to, (uintptr_t)p);
if(k==kh_end(locale_to)) {
/// should this be an assert?
} else {
ret = kh_value(locale_to, k);
// free the memory
free_struct_locale(p);
free(from_ptrv(ret));
// delete both entries
k = kh_get(to, locale_to, (uintptr_t)p);
kh_del(to, locale_to, k);
k = kh_get(from, locale_from, ret);
kh_del(from, locale_from, k);
}
pthread_rwlock_unlock(&hash_lock);
return ret;
}
char* from_cstring(ptr_t p) {
return (char*)from_ptrv(p);
}
ptr_t to_cstring(char* p) {
if((uintptr_t)p<0x100000000LL)
return to_ptrv(p);
ptr_t ret = 0;
pthread_rwlock_rdlock(&hash_lock);
khint_t k = kh_get(strings, const_strings, p);
if(k==kh_end(const_strings)) {
// create a new key, but need write lock!
pthread_rwlock_unlock(&hash_lock);
pthread_rwlock_wrlock(&hash_lock);
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;
} else
ret = kh_value(const_strings, k);
pthread_rwlock_unlock(&hash_lock);
return ret;
}
ptr_t to_cstring_d(char* p) {
if((uintptr_t)p<0x100000000LL)
return to_ptrv(p);
ptr_t ret = 0;
pthread_rwlock_wrlock(&hash_lock);
khint_t k = kh_get(strings, const_strings, p);
if(k==kh_end(const_strings)) {
// assert?
} else {
ret = kh_value(const_strings, k);
kh_del(strings, const_strings, k);
box32_free(from_ptrv(ret));
}
pthread_rwlock_unlock(&hash_lock);
return ret;
}
+55 -22
View File
@@ -19,8 +19,12 @@
#include "wrapper.h"
#include "x64emu.h"
#include "signals.h"
#include "rcfile.h"
#include "gltools.h"
#include "rbtree.h"
#include "dynarec.h"
#ifdef BOX32
#include "box32.h"
#endif
EXPORTDYN
void initAllHelpers(box64context_t* context)
@@ -29,6 +33,9 @@ void initAllHelpers(box64context_t* context)
if(inited)
return;
my_context = context;
#ifdef BOX32
init_hash_helper();
#endif
init_pthread_helper();
init_bridge_helper();
init_signal_helper(context);
@@ -41,10 +48,12 @@ void finiAllHelpers(box64context_t* context)
static int finied = 0;
if(finied)
return;
DeleteParams();
fini_pthread_helper(context);
fini_signal_helper();
fini_bridge_helper();
#ifdef BOX32
fini_hash_helper();
#endif
fini_custommem_helper(context);
finied = 1;
}
@@ -66,13 +75,14 @@ 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);
}
void x64Syscall(x64emu_t *emu);
void x86Syscall(x64emu_t *emu);
int unlockMutex()
{
@@ -126,7 +136,7 @@ void relockMutex(int locks)
#undef GO
}
static void init_mutexes(box64context_t* context)
void init_mutexes(box64context_t* context)
{
#ifndef DYNAREC
pthread_mutexattr_t attr;
@@ -169,8 +179,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]);
}
@@ -182,10 +192,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(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);
}
@@ -211,25 +221,33 @@ box64context_t *NewBox64Context(int argc)
init_custommem_helper(context);
context->maplib = NewLibrarian(context, 1);
context->local_maplib = NewLibrarian(context, 1);
context->maplib = NewLibrarian(context);
context->local_maplib = NewLibrarian(context);
context->versym = NewDictionnary();
context->system = NewBridge();
// Cannot use Bridge name as the map is not initialized yet
// create vsyscall
context->vsyscall = AddBridge(context->system, vFEv, x64Syscall, 0, NULL);
context->vsyscall = AddBridge(context->system, vFEv, box64_is32bits?x86Syscall:x64Syscall, 0, NULL);
// create the vsyscalls
context->vsyscalls[0] = AddVSyscall(context->system, 96);
context->vsyscalls[1] = AddVSyscall(context->system, 201);
context->vsyscalls[2] = AddVSyscall(context->system, 309);
// create the alternate to map at address
addAlternate((void*)0xffffffffff600000, (void*)context->vsyscalls[0]);
addAlternate((void*)0xffffffffff600400, (void*)context->vsyscalls[1]);
addAlternate((void*)0xffffffffff600800, (void*)context->vsyscalls[2]);
if(box64_is32bits) {
#ifdef BOX32
addAlternate((void*)0xffffe400, from_ptrv(context->vsyscall));
#endif
} else {
context->vsyscalls[0] = AddVSyscall(context->system, 96);
context->vsyscalls[1] = AddVSyscall(context->system, 201);
context->vsyscalls[2] = AddVSyscall(context->system, 309);
// create the alternate to map at address
addAlternate((void*)0xffffffffff600000, (void*)context->vsyscalls[0]);
addAlternate((void*)0xffffffffff600400, (void*)context->vsyscalls[1]);
addAlternate((void*)0xffffffffff600800, (void*)context->vsyscalls[2]);
}
// create exit bridge
context->exit_bridge = AddBridge(context->system, NULL, NULL, 0, NULL);
// get handle to box64 itself
#ifndef STATICBUILD
context->box64lib = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
#endif
context->dlprivate = NewDLPrivate();
context->argc = argc;
@@ -262,8 +280,13 @@ box64context_t *NewBox64Context(int argc)
context->segtls[4].is32bits = 1;
context->globdata = NewMapSymbols();
context->uniques = NewMapSymbols();
initAllHelpers(context);
#ifdef DYNAREC
context->db_sizes = rbtree_init("db_sizes");
#endif
return context;
}
@@ -278,7 +301,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)
@@ -335,8 +358,12 @@ void FreeBox64Context(box64context_t** context)
FreeBridge(&ctx->system);
#ifndef STATICBUILD
freeGLProcWrapper(ctx);
freeALProcWrapper(ctx);
#ifdef BOX32
#endif
#endif
if(ctx->stack_clone)
box_free(ctx->stack_clone);
@@ -358,6 +385,12 @@ void FreeBox64Context(box64context_t** context)
FreeX64Emu(&ctx->emu_sig);
FreeMapSymbols(&ctx->globdata);
FreeMapSymbols(&ctx->uniques);
#ifdef DYNAREC
//dynarec_log(LOG_INFO, "BOX64 Dynarec at exit: Max DB=%d, righter=%d\n", ctx->max_db_size, rb_get_righter(ctx->db_sizes));
rbtree_delete(ctx->db_sizes);
#endif
finiAllHelpers(ctx);
+2 -2
View File
@@ -2,7 +2,7 @@
#define __BOX64_VERSION_H_
#define BOX64_MAJOR 0
#define BOX64_MINOR 2
#define BOX64_REVISION 6
#define BOX64_MINOR 3
#define BOX64_REVISION 4
#endif //__BOX64_VERSION_H_
+1 -1
View File
@@ -9,7 +9,7 @@
void PrintBox64Version()
{
printf("Box64%s%s v%d.%d.%d %s built on %s %s\n",
printf_ftrace(1, "Box64%s%s v%d.%d.%d %s built on %s %s\n",
#ifdef HAVE_TRACE
" with trace",
#else
+15
View File
@@ -1,6 +1,21 @@
#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);
#define BOX64_BUILD_INFO_STR_HELPER(x) #x
#define BOX64_BUILD_INFO_STR(x) BOX64_BUILD_INFO_STR_HELPER(x)
#define BOX64_BUILD_INFO_STRING \
"Box64" \
" v" BOX64_BUILD_INFO_STR(BOX64_MAJOR) "." BOX64_BUILD_INFO_STR(BOX64_MINOR) "." BOX64_BUILD_INFO_STR(BOX64_REVISION) \
" " GITREV
#endif //__BUILD_INFO_H__
+1577
View File
File diff suppressed because it is too large. Load diff
+1184 -848
View File
File diff suppressed because it is too large. Load diff
+56
View File
@@ -0,0 +1,56 @@
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <unistd.h>
#include <stdint.h>
#include "env.h"
#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif
#define EXPORT __attribute__((visibility("default")))
#ifdef BUILD_DYNAMIC
#define EXPORTDYN __attribute__((visibility("default")))
#else
#define EXPORTDYN
#endif
#ifndef MAP_32BIT
#define MAP_32BIT 0x40
#endif
typedef void x64emu_t;
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* 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 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 && 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);
if(ret!=MAP_FAILED && mapallmem)
setProtection((uintptr_t)ret, length, prot);
return ret;
}
EXPORT void* mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) __attribute__((alias("mmap64")));
EXPORT int munmap(void* addr, unsigned long length)
{
int ret = internal_munmap(addr, length);
if(!ret && mapallmem) {
freeProtection((uintptr_t)addr, length);
}
return ret;
}
+322 -71
View File
@@ -5,6 +5,41 @@
*/
/*
ARM64 Linux Call Convention
SP The Stack Pointer.
r30 LR The Link Register.
r29 FP The Frame Pointer
r19…r28 Callee-saved registers
r18 The Platform Register, if needed; otherwise a temporary register. See notes.
r17 IP1 The second intra-procedure-call temporary register (can be used by call veneers and PLT code); at other times may be used as a temporary register.
r16 IP0 The first intra-procedure-call scratch register (can be used by call veneers and PLT code); at other times may be used as a temporary register.
r9…r15 Temporary registers
r8 Indirect result location register
r0…r7 Parameter/result registers
For SIMD:
The first eight registers, v0-v7, are used to pass argument values into a subroutine and to return result values from a function.
They may also be used to hold intermediate values within a routine (but, in general, only between subroutine calls).
Registers v8-v15 must be preserved by a callee across subroutine calls;
the remaining registers (v0-v7, v16-v31) do not need to be preserved (or should be preserved by the caller).
Additionally, only the bottom 64 bits of each value stored in v8-v15 need to be preserved [8];
it is the responsibility of the caller to preserve larger values.
For SVE:
z0-z7 are used to pass scalable vector arguments to a subroutine, and to return scalable vector results from a function.
If a subroutine takes at least one argument in scalable vector registers or scalable predicate registers,
or returns results in such regisers, the subroutine must ensure that the entire contents of z8-z23 are preserved across the call.
In other cases it need only preserve the low 64 bits of z8-z15, as described in SIMD and Floating-Point registers.
p0-p3 are used to pass scalable predicate arguments to a subroutine and to return scalable predicate results from a function.
If a subroutine takes at least one argument in scalable vector registers or scalable predicate registers,
or returns results in such registers, the subroutine must ensure that p4-p15 are preserved across the call.
In other cases it need not preserve any scalable predicate register contents.
*/
// x86 Register mapping
#define xRAX 10
#define xRCX 11
@@ -25,6 +60,10 @@
#define xFlags 26
#define xRIP 27
#define xSavedSP 28
// convert a x86 register to native according to the register mapping
#define TO_NAT(A) (xRAX + (A))
// 32bits version
#define wEAX xRAX
#define wECX xRCX
@@ -70,24 +109,49 @@
#define wZR xZR
// conditions
// Z == 1
#define cEQ 0b0000
// Z != 1
#define cNE 0b0001
// C == 1
#define cCS 0b0010
// C == 1
#define cHS cCS
// C != 1
#define cCC 0b0011
// C != 1
#define cLO cCC
// N == 1
#define cMI 0b0100
// N != 1
#define cPL 0b0101
// V == 1
#define cVS 0b0110
// V != 1
#define cVC 0b0111
// C == 1 && Z == 0
#define cHI 0b1000
// C !=1 || Z == 1
#define cLS 0b1001
// N == V
#define cGE 0b1010
// N != V
#define cLT 0b1011
// N == V && Z == 0
#define cGT 0b1100
// N != V || Z == 1
#define cLE 0b1101
// 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)
#define convert_bitmask_xw(A) convert_bitmask(rex.w?((uint64_t)(A)):(((uint64_t)(A) << 32) + (uint32_t)(A)))
#define invCond(cond) ((cond)^0b0001)
// MOVZ
@@ -111,23 +175,8 @@
#define MOVKw(Rd, imm16) EMIT(MOVK_gen(0, 0, ((uint16_t)(imm16))&0xffff, Rd))
#define MOVKw_LSL(Rd, imm16, shift) EMIT(MOVK_gen(0, (shift)/16, ((uint16_t)(imm16))&0xffff, Rd))
// This macro will give a -Wsign-compare warning, probably bug #38341
#define MOV32w(Rd, imm32) \
if(~((uint32_t)(imm32))<0xffffu) { \
MOVNw(Rd, (~(uint32_t)(imm32))&0xffff); \
} else { \
MOVZw(Rd, (imm32)&0xffff); \
if((imm32)&0xffff0000) {MOVKw_LSL(Rd, ((imm32)>>16)&0xffff, 16);} \
}
#define MOV64x(Rd, imm64) \
if(~((uint64_t)(imm64))<0xffff) { \
MOVNx(Rd, (~(uint64_t)(imm64))&0xffff); \
} else { \
MOVZx(Rd, ((uint64_t)(imm64))&0xffff); \
if(((uint64_t)(imm64))&0xffff0000) {MOVKx_LSL(Rd, (((uint64_t)(imm64))>>16)&0xffff, 16);} \
if(((uint64_t)(imm64))&0xffff00000000LL) {MOVKx_LSL(Rd, (((uint64_t)(imm64))>>32)&0xffff, 32);} \
if(((uint64_t)(imm64))&0xffff000000000000LL) {MOVKx_LSL(Rd, (((uint64_t)(imm64))>>48)&0xffff, 48);} \
}
#define MOV32w(Rd, imm32) arm64_move32(dyn, ninst, Rd, imm32)
#define MOV64x(Rd, imm64) arm64_move64(dyn, ninst, Rd, imm64)
#define MOV64xw(Rd, imm64) if(rex.w) {MOV64x(Rd, imm64);} else {MOV32w(Rd, imm64);}
#define MOV64z(Rd, imm64) if(rex.is32bits) {MOV32w(Rd, imm64);} else {MOV64x(Rd, imm64);}
@@ -136,38 +185,49 @@
// ADD / SUB
#define ADDSUB_REG_gen(sf, op, S, shift, Rm, imm6, Rn, Rd) ((sf)<<31 | (op)<<30 | (S)<<29 | 0b01011<<24 | (shift)<<22 | (Rm)<<16 | (imm6)<<10 | (Rn)<<5 | (Rd))
#define ADDx_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(1, 0, 0, 0b00, Rm, 0, Rn, Rd))
#define ADDSx_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(1, 0, 1, 0b00, Rm, 0, Rn, Rd))
#define ADDSx_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(1, 0, 1, 0b00, Rm, 0, Rn, Rd))
#define ADDx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(1, 0, 0, 0b00, Rm, lsl, Rn, Rd))
#define ADDz_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(rex.is32bits?0:1, 0, 0, 0b00, Rm, lsl, Rn, Rd))
#define ADDw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(0, 0, 0, 0b00, Rm, 0, Rn, Rd))
#define ADDSw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(0, 0, 1, 0b00, Rm, 0, Rn, Rd))
#define ADDSw_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(0, 0, 1, 0b00, Rm, 0, Rn, Rd))
#define ADDw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(0, 0, 0, 0b00, Rm, lsl, Rn, Rd))
#define ADDSw_REG_LSL(Rd, Rn, Rm, lsl) FEMIT(ADDSUB_REG_gen(0, 0, 1, 0b00, Rm, lsl, Rn, Rd))
#define ADDxw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(rex.w, 0, 0, 0b00, Rm, 0, Rn, Rd))
#define ADDz_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(rex.is32bits?0:1, 0, 0, 0b00, Rm, 0, Rn, Rd))
#define ADDSxw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(rex.w, 0, 1, 0b00, Rm, 0, Rn, Rd))
#define ADDSxw_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(rex.w, 0, 1, 0b00, Rm, 0, Rn, Rd))
#define ADDxw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(ADDSUB_REG_gen(rex.w, 0, 0, 0b01, Rm, lsr, Rn, Rd))
#define ADDSUB_IMM_gen(sf, op, S, shift, imm12, Rn, Rd) ((sf)<<31 | (op)<<30 | (S)<<29 | 0b10001<<24 | (shift)<<22 | (imm12)<<10 | (Rn)<<5 | (Rd))
#define ADDx_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(1, 0, 0, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDSx_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(1, 0, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDSx_U12(Rd, Rn, imm12) FEMIT(ADDSUB_IMM_gen(1, 0, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDw_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(0, 0, 0, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDSw_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(0, 0, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDSw_U12(Rd, Rn, imm12) FEMIT(ADDSUB_IMM_gen(0, 0, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDxw_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(rex.w, 0, 0, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDSxw_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(rex.w, 0, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDSxw_U12(Rd, Rn, imm12) FEMIT(ADDSUB_IMM_gen(rex.w, 0, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define ADDz_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(rex.is32bits?0:1, 0, 0, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBx_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(1, 1, 0, 0b00, Rm, 0, Rn, Rd))
#define SUBSx_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(1, 1, 1, 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 SUBSw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(0, 1, 1, 0b00, Rm, 0, Rn, Rd))
#define SUBSw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(0, 1, 1, 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) EMIT(ADDSUB_REG_gen(rex.w, 1, 1, 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);
@@ -176,12 +236,12 @@
#define NEGSxw_REG(Rd, Rm) SUBSxw_REG(Rd, xZR, Rm);
#define SUBx_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(1, 1, 0, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBSx_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(1, 1, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBSx_U12(Rd, Rn, imm12) FEMIT(ADDSUB_IMM_gen(1, 1, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBw_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(0, 1, 0, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBSw_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(0, 1, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBSw_U12(Rd, Rn, imm12) FEMIT(ADDSUB_IMM_gen(0, 1, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBxw_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(rex.w, 1, 0, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBz_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(rex.is32bits?0:1, 1, 0, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBSxw_U12(Rd, Rn, imm12) EMIT(ADDSUB_IMM_gen(rex.w, 1, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define SUBSxw_U12(Rd, Rn, imm12) FEMIT(ADDSUB_IMM_gen(rex.w, 1, 1, 0b00, (imm12)&0xfff, Rn, Rd))
#define CMPSx_U12(Rn, imm12) SUBSx_U12(xZR, Rn, imm12)
#define CMPSw_U12(Rn, imm12) SUBSw_U12(wZR, Rn, imm12)
#define CMPSxw_U12(Rn, imm12) SUBSxw_U12(xZR, Rn, imm12)
@@ -193,18 +253,22 @@
#define SBCx_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(1, 1, 0, Rm, Rn, Rd))
#define SBCw_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(0, 1, 0, Rm, Rn, Rd))
#define SBCxw_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(rex.w, 1, 0, Rm, Rn, Rd))
#define ADCSx_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(1, 0, 1, Rm, Rn, Rd))
#define ADCSw_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(0, 0, 1, Rm, Rn, Rd))
#define ADCSxw_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(rex.w, 0, 1, Rm, Rn, Rd))
#define SBCSx_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(1, 1, 1, Rm, Rn, Rd))
#define SBCSw_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(0, 1, 1, Rm, Rn, Rd))
#define SBCSxw_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(rex.w, 1, 1, Rm, Rn, Rd))
#define ADCSx_REG(Rd, Rn, Rm) FEMIT(ADDSUBC_gen(1, 0, 1, Rm, Rn, Rd))
#define ADCSw_REG(Rd, Rn, Rm) FEMIT(ADDSUBC_gen(0, 0, 1, Rm, Rn, Rd))
#define ADCSxw_REG(Rd, Rn, Rm) FEMIT(ADDSUBC_gen(rex.w, 0, 1, Rm, Rn, Rd))
#define SBCSx_REG(Rd, Rn, Rm) FEMIT(ADDSUBC_gen(1, 1, 1, Rm, Rn, Rd))
#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) EMIT(CCMP_reg(0, Wm, cond, Wn, nzcv))
#define CCMPx(Xn, Xm, nzcv, cond) EMIT(CCMP_reg(1, Xm, cond, Xn, nzcv))
#define CCMPxw(Xn, Xm, nzcv, cond) EMIT(CCMP_reg(rex.w, Xm, cond, Xn, nzcv))
#define CCMPw(Wn, Wm, nzcv, cond) FEMIT(CCMP_reg(0, Wm, cond, Wn, nzcv))
#define CCMPx(Xn, Xm, nzcv, cond) FEMIT(CCMP_reg(1, Xm, cond, Xn, nzcv))
#define CCMPxw(Xn, Xm, nzcv, cond) FEMIT(CCMP_reg(rex.w, Xm, cond, Xn, nzcv))
// ADR
#define ADR_gen(immlo, immhi, Rd) ((immlo)<<29 | 0b10000<<24 | (immhi)<<5 | (Rd))
@@ -241,13 +305,25 @@
#define LDRx_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b11, Rm, 0b011, 0, Rn, Rt))
#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))
@@ -259,6 +335,8 @@
#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))
@@ -329,12 +407,21 @@
#define STRx_REG(Rt, Rn, Rm) EMIT(STR_REG_gen(0b11, Rm, 0b011, 0, Rn, Rt))
#define STRx_REG_LSL3(Rt, Rn, Rm) EMIT(STR_REG_gen(0b11, Rm, 0b011, 1, Rn, Rt))
#define STRx_REG_UXTW(Rt, Rn, Rm) EMIT(STR_REG_gen(0b11, Rm, 0b010, 0, Rn, Rt))
#define STRx_REG_SXTW(Rt, Rn, Rm) EMIT(STR_REG_gen(0b11, Rm, 0b110, 0, Rn, Rt))
#define STRw_REG(Rt, Rn, Rm) EMIT(STR_REG_gen(0b10, Rm, 0b011, 0, Rn, Rt))
#define STRw_REG_LSL2(Rt, Rn, Rm) EMIT(STR_REG_gen(0b10, Rm, 0b011, 1, Rn, Rt))
#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))
@@ -434,12 +521,19 @@
// Data Memory Barrier
#define DMB_gen(CRm) (0b1101010100<<22 | 0b011<<16 | 0b0011<<12 | (CRm)<<8 | 1<<7 | 0b01<<5 | 0b11111)
#define DMB_ISH() EMIT(DMB_gen(0b1011))
#define DMB_ISHLD() EMIT(DMB_gen(0b1001))
#define DMB_ISHST() EMIT(DMB_gen(0b1010))
#define DMB_LD() EMIT(DMB_gen(0b1101))
#define DMB_ST() EMIT(DMB_gen(0b1110))
#define DMB_SY() EMIT(DMB_gen(0b1111))
// Data Synchronization Barrier
#define DSB_gen(CRm) (0b1101010100<<22 | 0b011<<16 | 0b0011<<12 | (CRm)<<8 | 1<<7 | 0b00<<5 | 0b11111)
#define DSB_ISH() EMIT(DSB_gen(0b1011))
#define DSB_ISHLD() EMIT(DSB_gen(0b1001))
#define DSB_ISHST() EMIT(DSB_gen(0b1010))
#define DSB_LD() EMIT(DSB_gen(0b1101))
#define DSB_ST() EMIT(DSB_gen(0b1110))
#define DSB_SY() EMIT(DSB_gen(0b1111))
// Break
@@ -450,6 +544,7 @@
#define BR_gen(Z, op, A, M, Rn, Rm) (0b1101011<<25 | (Z)<<24 | (op)<<21 | 0b11111<<16 | (A)<<11 | (M)<<10 | (Rn)<<5 | (Rm))
#define BR(Rn) EMIT(BR_gen(0, 0b00, 0, 0, Rn, 0))
#define BLR(Rn) EMIT(BR_gen(0, 0b01, 0, 0, Rn, 0))
#define RET(Rn) EMIT(BR_gen(0, 0b10, 0, 0, Rn, 0))
#define CB_gen(sf, op, imm19, Rt) ((sf)<<31 | 0b011010<<25 | (op)<<24 | (imm19)<<5 | (Rt))
#define CBNZx(Rt, imm19) EMIT(CB_gen(1, 1, ((imm19)>>2)&0x7FFFF, Rt))
@@ -475,6 +570,10 @@
#define BL(imm26) EMIT(BL_gen(((imm26)>>2)&0x3ffffff))
#define NOP EMIT(0b11010101000000110010000000011111)
#define WFE EMIT(0b11010101000000110010000001011111)
#define WFI EMIT(0b11010101000000110010000001111111)
#define YIELD EMIT(0b11010101000000110010000000111111)
#define SEVL EMIT(0b11010101000000110010000010111111)
#define CSINC_gen(sf, Rm, cond, Rn, Rd) ((sf)<<31 | 0b11010100<<21 | (Rm)<<16 | (cond)<<12 | 1<<10 | (Rn)<<5 | (Rd))
#define CSINCx(Rd, Rn, Rm, cond) EMIT(CSINC_gen(1, Rm, cond, Rn, Rd))
@@ -487,7 +586,7 @@
#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))
@@ -513,22 +612,29 @@
// logic to get the mask is ... convoluted... list of possible value there: https://gist.github.com/dinfuehr/51a01ac58c0b23e4de9aac313ed6a06a
#define ANDx_mask(Rd, Rn, N, immr, imms) EMIT(LOGIC_gen(1, 0b00, N, immr, imms, Rn, Rd))
#define ANDw_mask(Rd, Rn, immr, imms) EMIT(LOGIC_gen(0, 0b00, 0, immr, imms, Rn, Rd))
#define ANDSx_mask(Rd, Rn, N, immr, imms) EMIT(LOGIC_gen(1, 0b11, N, immr, imms, Rn, Rd))
#define ANDSw_mask(Rd, Rn, immr, imms) EMIT(LOGIC_gen(0, 0b11, 0, immr, imms, Rn, Rd))
#define ANDxw_mask(Rd, Rn, N, immr, imms) EMIT(LOGIC_gen(rex.w, 0b00, rex.w?(N):0, immr, imms, Rn, Rd))
#define ANDSx_mask(Rd, Rn, N, immr, imms) FEMIT(LOGIC_gen(1, 0b11, N, immr, imms, Rn, Rd))
#define ANDSw_mask(Rd, Rn, immr, imms) FEMIT(LOGIC_gen(0, 0b11, 0, immr, imms, Rn, Rd))
#define ANDSxw_mask(Rd, Rn, N, immr, imms) FEMIT(LOGIC_gen(rex.w, 0b11, rex.w?(N):0, immr, imms, Rn, Rd))
#define ORRx_mask(Rd, Rn, N, immr, imms) EMIT(LOGIC_gen(1, 0b01, N, immr, imms, Rn, Rd))
#define ORRw_mask(Rd, Rn, immr, imms) EMIT(LOGIC_gen(0, 0b01, 0, immr, imms, Rn, Rd))
#define ORRxw_mask(Rd, Rn, N, immr, imms) EMIT(LOGIC_gen(rex.w, 0b01, rex.w?(N):0, immr, imms, Rn, Rd))
#define EORx_mask(Rd, Rn, N, immr, imms) EMIT(LOGIC_gen(1, 0b10, N, immr, imms, Rn, Rd))
#define EORw_mask(Rd, Rn, immr, imms) EMIT(LOGIC_gen(0, 0b10, 0, immr, imms, Rn, Rd))
#define EORxw_mask(Rd, Rn, N, immr, imms) EMIT(LOGIC_gen(rex.w, 0b10, rex.w?(N):0, immr, imms, Rn, Rd))
#define TSTx_mask(Rn, N, immr, imms) ANDSx_mask(xZR, Rn, N, immr, imms)
#define TSTw_mask(Rn, immr, imms) ANDSw_mask(wZR, Rn, immr, imms)
#define TSTxw_mask(Rn, N, immr, imms) ANDSxw_mask(xZR, Rn, N, immr, imms)
#define LOGIC_REG_gen(sf, opc, shift, N, Rm, imm6, Rn, Rd) ((sf)<<31 | (opc)<<29 | 0b01010<<24 | (shift)<<22 | (N)<<21 | (Rm)<<16 | (imm6)<<10 | (Rn)<<5 | (Rd))
#define ANDx_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDw_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(0, 0b00, 0b01, 0, Rm, lsr, Rn, Rd))
#define ANDxw_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDSx_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b11, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDSw_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(0, 0b11, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDSxw_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(rex.w, 0b11, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDSx_REG(Rd, Rn, Rm) FEMIT(LOGIC_REG_gen(1, 0b11, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDSw_REG(Rd, Rn, Rm) FEMIT(LOGIC_REG_gen(0, 0b11, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDSxw_REG(Rd, Rn, Rm) FEMIT(LOGIC_REG_gen(rex.w, 0b11, 0b00, 0, Rm, 0, Rn, Rd))
#define ANDSw_REG_LSL(Rd, Rn, Rm, lsl) FEMIT(LOGIC_REG_gen(0, 0b11, 0b00, 0, Rm, lsl, Rn, Rd))
#define ORRx_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b01, 0b00, 0, Rm, 0, Rn, Rd))
#define ORRx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(1, 0b01, 0b00, 0, Rm, lsl, Rn, Rd))
#define ORRw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b01, 0b00, 0, Rm, lsl, Rn, Rd))
@@ -579,10 +685,10 @@
#define BICx(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 1, Rm, 0, Rn, Rd))
#define BICw(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, 0, Rn, Rd))
#define BICw_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, lsl, Rn, Rd))
#define BICSx(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 1, Rm, 0, Rn, Rd))
#define BICSw(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, 0, Rn, Rd))
#define BICxw(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b00, 1, Rm, 0, Rn, Rd))
#define BICSxw(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b00, 1, Rm, 0, Rn, Rd))
#define BICSx(Rd, Rn, Rm) FEMIT(LOGIC_REG_gen(1, 0b11, 0b00, 1, Rm, 0, Rn, Rd))
#define BICSw(Rd, Rn, Rm) FEMIT(LOGIC_REG_gen(0, 0b11, 0b00, 1, Rm, 0, Rn, Rd))
#define BICxw(Rd, Rn, Rm) FEMIT(LOGIC_REG_gen(rex.w, 0b00, 0b00, 1, Rm, 0, Rn, Rd))
#define BICSxw(Rd, Rn, Rm) FEMIT(LOGIC_REG_gen(rex.w, 0b11, 0b00, 1, Rm, 0, Rn, Rd))
#define BICx_REG BICx
#define BICw_REG BICw
#define BICxw_REG BICxw
@@ -610,9 +716,11 @@
#define BFIx(Rd, Rn, lsb, width) BFMx(Rd, Rn, ((-(lsb))%64)&0x3f, (width)-1)
#define BFIw(Rd, Rn, lsb, width) BFMw(Rd, Rn, ((-(lsb))%32)&0x1f, (width)-1)
#define BFIxw(Rd, Rn, lsb, width) if(rex.w) {BFIx(Rd, Rn, lsb, width);} else {BFIw(Rd, Rn, lsb, width);}
#define BFIz(Rd, Rn, lsb, width) if(rex.is32bits) {BFIw(Rd, Rn, lsb, width);} else {BFIx(Rd, Rn, lsb, width);}
#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)
@@ -757,15 +865,21 @@
#define MRS_gen(L, o0, op1, CRn, CRm, op2, Rt) (0b1101010100<<22 | (L)<<21 | 1<<20 | (o0)<<19 | (op1)<<16 | (CRn)<<12 | (CRm)<<8 | (op2)<<5 | (Rt))
// mrs x0, nzcv : 1101010100 1 1 1 011 0100 0010 000 00000 o0=1(op0=3), op1=0b011(3) CRn=0b0100(4) CRm=0b0010(2) op2=0
// MRS : from System register
#define MRS_nzvc(Rt) EMIT(MRS_gen(1, 1, 3, 4, 2, 0, Rt))
#define MRS_nzcv(Rt) EMIT(MRS_gen(1, 1, 3, 4, 2, 0, Rt))
// MSR : to System register
#define MSR_nzvc(Rt) EMIT(MRS_gen(0, 1, 3, 4, 2, 0, Rt))
#define MSR_nzcv(Rt) FEMIT(MRS_gen(0, 1, 3, 4, 2, 0, Rt))
// mrs x0, fpcr : 1101010100 1 1 1 011 0100 0100 000 00000 o0=1(op0=3), op1=0b011(3) CRn=0b0100(4) CRm=0b0100(4) op2=0
#define MRS_fpcr(Rt) EMIT(MRS_gen(1, 1, 3, 4, 4, 0, Rt))
#define MSR_fpcr(Rt) EMIT(MRS_gen(0, 1, 3, 4, 4, 0, Rt))
// mrs x0, fpsr : 1101010100 1 1 1 011 0100 0100 001 00000 o0=1(op0=3), op1=0b011(3) CRn=0b0100(4) CRm=0b0100(4) op2=1
#define MRS_fpsr(Rt) EMIT(MRS_gen(1, 1, 3, 4, 4, 1, Rt))
#define MSR_fpsr(Rt) EMIT(MRS_gen(0, 1, 3, 4, 4, 1, Rt))
// mrs x0, cntvct_el0 op0=0b11 op1=0b011 CRn=0b1110 CRm=0b0000 op2=0b010
#define MRS_cntvct_el0(Rt) EMIT(MRS_gen(1, 1, 0b011, 0b1110, 0b0000, 0b010, Rt))
// mrs x0, cntpctss_el0 op0=0b11 op1=0b011 CRn=0b1110 CRm=0b0000 op2=0b101
#define MRS_cntpctss_el0(Rt) EMIT(MRS_gen(1, 1, 0b011, 0b1110, 0b0000, 0b101, Rt))
// mrs rt, rndr op0=0b11 op1=0b011 CRn=0b0010 CRm=0b0100 op2=0b000
#define MRS_rndr(Rt) EMIT(MRS_gen(1, 1, 0b011, 0b0010, 0b0100, 0b000, Rt))
// NEON Saturation Bit
#define FPSR_QC 27
// NEON Input Denormal Cumulative
@@ -780,6 +894,14 @@
#define FPSR_DZC 1
// NEON Invalid Operation Cumulative
#define FPSR_IOC 0
// NZCV N
#define NZCV_N 31
// NZCV Z
#define NZCV_Z 30
// NZCV C
#define NZCV_C 29
// NZCV V
#define NZCV_V 28
// FCSEL
#define FCSEL_scalar(type, Rm, cond, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | (Rm)<<16 | (cond)<<12 | 0b11<<10 | (Rn)<<5 | (Rd))
@@ -823,10 +945,12 @@
#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))
@@ -841,18 +965,24 @@
#define VMEM_REG_gen(size, opc, Rm, option, S, Rn, Rt) ((size)<<30 | 0b111<<27 | 1<<26 | (opc)<<22 | 1<<21 | (Rm)<<16 | (option)<<13 | (S)<<12 | 0b10<<10 | (Rn)<<5 | (Rt))
#define VLDR32_REG(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b10, 0b01, Rm, 0b011, 0, Rn, Dt))
#define VLDR32_REG_SXTW(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b10, 0b01, Rm, 0b110, 0, Rn, Dt))
#define VLDR32_REG_LSL2(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b10, 0b01, Rm, 0b011, 1, Rn, Dt))
#define VLDR64_REG(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b11, 0b01, Rm, 0b011, 0, Rn, Dt))
#define VLDR64_REG_SXTW(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b11, 0b01, Rm, 0b110, 0, Rn, Dt))
#define VLDR64_REG_LSL3(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b11, 0b01, Rm, 0b011, 1, Rn, Dt))
#define VLDR128_REG(Qt, Rn, Rm) EMIT(VMEM_REG_gen(0b00, 0b11, Rm, 0b011, 0, Rn, Qt))
#define VLDR128_REG_LSL4(Qt, Rn, Rm) EMIT(VMEM_REG_gen(0b00, 0b11, Rm, 0b011, 1, Rn, Qt))
#define VLDR128_REG_SXTW(Qt, Rn, Rm) EMIT(VMEM_REG_gen(0b00, 0b11, Rm, 0b110, 0, Rn, Qt))
#define VSTR32_REG(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b10, 0b00, Rm, 0b011, 0, Rn, Dt))
#define VSTR32_REG_LSL2(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b10, 0b00, Rm, 0b011, 1, Rn, Dt))
#define VSTR32_REG_SXTW(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b10, 0b00, Rm, 0b110, 0, Rn, Dt))
#define VSTR64_REG(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b11, 0b00, Rm, 0b011, 0, Rn, Dt))
#define VSTR64_REG_LSL3(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b11, 0b00, Rm, 0b011, 1, Rn, Dt))
#define VSTR64_REG_SXTW(Dt, Rn, Rm) EMIT(VMEM_REG_gen(0b11, 0b00, Rm, 0b110, 0, Rn, Dt))
#define VSTR128_REG(Qt, Rn, Rm) EMIT(VMEM_REG_gen(0b00, 0b10, Rm, 0b011, 0, Rn, Qt))
#define VSTR128_REG_LSL4(Qt, Rn, Rm) EMIT(VMEM_REG_gen(0b00, 0b10, Rm, 0b011, 1, Rn, Qt))
#define VSTR128_REG_SXTW(Qt, Rn, Rm) EMIT(VMEM_REG_gen(0b00, 0b10, Rm, 0b110, 0, Rn, Qt))
#define VLDR_PC_gen(opc, imm19, Rt) ((opc)<<30 | 0b011<<27 | 1<<26 | (imm19)<<5 | (Rt))
#define VLDR32_literal(Vt, imm19) EMIT(VLDR_PC_gen(0b00, ((imm19)>>2)&0x7FFFF, Vt))
@@ -1040,7 +1170,9 @@
#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
@@ -1062,6 +1194,12 @@
#define VMOVHto(Wd, Vn, index) EMIT(UMOV_gen(0, ((index)<<2) | 2, Vn, Wd))
#define VMOVSto(Wd, Vn, index) EMIT(UMOV_gen(0, ((index)<<3) | 4, Vn, Wd))
#define SMOV_gen(Q, imm5, Rn, Rd) ((Q)<<30 | 0b01110000<<21 | (imm5)<<16 | 0b01<<13 | 0<<12 | 1<<11 | 1<<10 | (Rn)<<5 | (Rd))
#define SMOVQDto(Xd, Vn, index) EMIT(SMOV_gen(1, ((index)<<4) | 8, Vn, Xd))
#define SMOVQBto(Xd, Vn, index) EMIT(SMOV_gen(1, ((index)<<1) | 1, Vn, Xd))
#define SMOVQHto(Xd, Vn, index) EMIT(SMOV_gen(1, ((index)<<2) | 2, Vn, Xd))
#define SMOVQSto(Xd, Vn, index) EMIT(SMOV_gen(1, ((index)<<3) | 4, Vn, Xd))
#define MVN_vector(Q, Rn, Rd) ((Q)<<30 | 1<<29 | 0b01110<<24 | 0b10000<<17 | 0b00101<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
#define VMVNQ(Rd, Rn) EMIT(MVN_vector(1, Rn, Rd))
@@ -1132,6 +1270,13 @@
#define FABSS(Sd, Sn) EMIT(FNEGABS_scalar(0b00, 0b01, Sn, Sd))
#define FABSD(Dd, Dn) EMIT(FNEGABS_scalar(0b01, 0b01, Dn, Dd))
#define FNEGABS_vector(Q, U, sz, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | 1<<23 | (sz)<<22 | 0b10000<<17 | 0b01111<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
#define VFNEGS(Vd, Vn) EMIT(FNEGABS_vector(0, 1, 0, Vn, Vd))
#define VFNEGQS(Vd, Vn) EMIT(FNEGABS_vector(1, 1, 0, Vn, Vd))
#define VFNEGQD(Vd, Vn) EMIT(FNEGABS_vector(1, 1, 1, Vn, Vd))
#define VFABSS(Vd, Vn) EMIT(FNEGABS_vector(0, 0, 0, Vn, Vd))
#define VFABSQS(Vd, Vn) EMIT(FNEGABS_vector(1, 0, 0, Vn, Vd))
#define VFABSQD(Vd, Vn) EMIT(FNEGABS_vector(1, 0, 1, Vn, Vd))
// MUL
#define FMUL_vector(Q, sz, Rm, Rn, Rd) ((Q)<<30 | 1<<29 | 0b01110<<24 | (sz)<<22 | 1<<21 | (Rm)<<16 | 0b11011<<11 | 1<<10 | (Rn)<<5 | (Rd))
@@ -1143,11 +1288,6 @@
#define FMULS(Sd, Sn, Sm) EMIT(FMUL_scalar(0b00, Sm, Sn, Sd))
#define FMULD(Dd, Dn, Dm) EMIT(FMUL_scalar(0b01, Dm, Dn, Dd))
#define FMLA_vector(Q, op, sz, Rm, Rn, Rd) ((Q)<<30 | 0b01110<<24 | (op)<<23 | (sz)<<22 | 1<<21 | (Rm)<<16 | 0b11001<<11 | 1<<10 | (Rn)<<5 | (Rd))
#define VFMLAS(Sd, Sn, Sm) EMIT(FMLA_vector(0, 0, 0, Sm, Sn, Sd))
#define VFMLAQS(Sd, Sn, Sm) EMIT(FMLA_vector(1, 0, 0, Sm, Sn, Sd))
#define VFMLAQD(Dd, Dn, Dm) EMIT(FMLA_vector(1, 0, 1, Dm, Dn, Dd))
// DIV
#define FDIV_vector(Q, sz, Rm, Rn, Rd) ((Q)<<30 | 1<<29 | 0b01110<<24 | (sz)<<22 | 1<<21 | (Rm)<<16 | 0b11111<<11 | 1<<10 | (Rn)<<5 | (Rd))
#define VFDIVS(Sd, Sn, Sm) EMIT(FDIV_vector(0, 0, Sm, Sn, Sd))
@@ -1188,12 +1328,12 @@
#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) EMIT(FCMP_scalar(0b00, Sn, Sm, 0b00))
#define FCMPD(Dn, Dm) EMIT(FCMP_scalar(0b01, Dn, Dm, 0b00))
#define FCMPS_0(Sn) EMIT(FCMP_scalar(0b00, 0, Sn, 0b01))
#define FCMPD_0(Dn) EMIT(FCMP_scalar(0b01, 0, Dn, 0b01))
#define FCMPS(Sn, Sm) FEMIT(FCMP_scalar(0b00, Sn, Sm, 0b00))
#define FCMPD(Dn, Dm) FEMIT(FCMP_scalar(0b01, Dn, Dm, 0b00))
#define FCMPS_0(Sn) FEMIT(FCMP_scalar(0b00, Sn, 0, 0b01))
#define FCMPD_0(Dn) FEMIT(FCMP_scalar(0b01, Dn, 0, 0b01))
// CVT
#define FCVT_scalar(sf, type, rmode, opcode, Rn, Rd) ((sf)<<31 | 0b11110<<24 | (type)<<22 | 1<<21 | (rmode)<<19 | (opcode)<<16 | (Rn)<<5 | (Rd))
@@ -1349,18 +1489,30 @@
#define FCVTN(Vd, Vn) EMIT(FCVTN_vector(0, 1, Vn, Vd))
// Convert Vn from 2*Double to higher Vd as 2*float, use FPCR rounding
#define FCVTN2(Vd, Vn) EMIT(FCVTN_vector(1, 1, Vn, Vd))
// Convert Vn from 2*Float to lower Vd as 2*float16 and clears the upper half, use FPCR rounding
#define FCVTN16(Vd, Vn) EMIT(FCVTN_vector(0, 0, Vn, Vd))
// Convert Vn from 2*Float to higher Vd as 2*float16, use FPCR rounding
#define FCVTN162(Vd, Vn) EMIT(FCVTN_vector(1, 0, Vn, Vd))
#define FCVTXN_vector(Q, sz, Rn, Rd) ((Q)<<30 | 1<<29 | 0b01110<<24 | (sz)<<22 | 0b10000<<17 | 0b10110<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
// Convert Vn from 2*Double to lower Vd as 2*float and clears the upper half
#define FCVTXN(Vd, Vn) EMIT(FCVTXN_vector(0, 1, Vn, Vd))
// Convert Vn from 2*Double to higher Vd as 2*float
#define FCVTXN2(Vd, Vn) EMIT(FCVTXN_vector(1, 1, Vn, Vd))
// Convert Vn from 2*Float to lower Vd as 2*float16 and clears the upper half
#define FCVTXN16(Vd, Vn) EMIT(FCVTXN_vector(0, 0, Vn, Vd))
// Convert Vn from 2*Float to higher Vd as 2*float16
#define FCVTXN162(Vd, Vn) EMIT(FCVTXN_vector(1, 0, Vn, Vd))
#define FCVTL_vector(Q, sz, Rn, Rd) ((Q)<<30 | 0<<29 | 0b01110<<24 | (sz)<<22 | 0b10000<<17 | 0b10111<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
// Convert lower Vn from 2*float to Vd as 2*double
#define FCVTL(Vd, Vn) EMIT(FCVTL_vector(0, 1, Vn, Vd))
// Convert higher Vn from 2*float to Vd as 2*double
#define FCVTL2(Vd, Vn) EMIT(FCVTL_vector(1, 1, Vn, Vd))
// Convert lower Vn from 2*float16 to Vd as 2*float
#define FCVTL16(Vd, Vn) EMIT(FCVTL_vector(0, 0, Vn, Vd))
// Convert higher Vn from 2*float16 to Vd as 2*float
#define FCVTL162(Vd, Vn) EMIT(FCVTL_vector(1, 0, Vn, Vd))
#define SCVTF_scalar(sf, type, rmode, opcode, Rn, Rd) ((sf)<<31 | 0b11110<<24 | (type)<<22 | 1<<21 | (rmode)<<19 | (opcode)<<16 | (Rn)<<5 | (Rd))
#define SCVTFSw(Sd, Wn) EMIT(SCVTF_scalar(0, 0b00, 0b00, 0b010, Wn, Sd))
@@ -1432,6 +1584,37 @@
// FMAXNM NaN vs Number: number is picked
#define FMAXNMD(Dd, Dn, Dm) EMIT(FMINMAX_scalar(0b01, Dm, 0b10, Dn, Dd))
// Fused Add Multiply
#define FMADD_gen(type, o1, Rm, o0, Ra, Rn, Rd) (0b11111<<24 | (type)<<22 | (o1)<<21 | (Rm)<<16 | (o0)<<15 | (Ra)<<10 | (Rn)<<5 | (Rd))
// scalar Rd = Ra + Rn*Rm
#define FMADD_32(Sd, Sa, Sn, Sm) EMIT(FMADD_gen(0b00, 0, Sm, 0, Sa, Sn, Sd))
// scalar Rd = Ra + Rn*Rm
#define FMADD_64(Dd, Da, Dn, Dm) EMIT(FMADD_gen(0b01, 0, Dm, 0, Da, Dn, Dd))
// scalar Rd = -Ra - Rn*Rm
#define FNMADD_32(Sd, Sa, Sn, Sm) EMIT(FMADD_gen(0b00, 1, Sm, 0, Sa, Sn, Sd))
// scalar Rd = -Ra - Rn*Rm
#define FNMADD_64(Dd, Da, Dn, Dm) EMIT(FMADD_gen(0b01, 1, Dm, 0, Da, Dn, Dd))
// scalar Rd = Ra - Rn*Rm
#define FMSUB_32(Sd, Sa, Sn, Sm) EMIT(FMADD_gen(0b00, 0, Sm, 1, Sa, Sn, Sd))
// scalar Rd = Ra - Rn*Rm
#define FMSUB_64(Dd, Da, Dn, Dm) EMIT(FMADD_gen(0b01, 0, Dm, 1, Da, Dn, Dd))
// scalar Rd = -Ra + Rn*Rm
#define FNMSUB_32(Sd, Sa, Sn, Sm) EMIT(FMADD_gen(0b00, 1, Sm, 1, Sa, Sn, Sd))
// scalar Rd = -Ra + Rn*Rm
#define FNMSUB_64(Dd, Da, Dn, Dm) EMIT(FMADD_gen(0b01, 1, Dm, 1, Da, Dn, Dd))
#define FMLA_vector(Q, op, sz, Rm, Rn, Rd) ((Q)<<30 | 0b01110<<24 | (op)<<23 | (sz)<<22 | 1<<21 | (Rm)<<16 | 0b11001<<11 | 1<<10 | (Rn)<<5 | (Rd))
// Vd += Vn*Vm
#define VFMLAS(Vd, Vn, Vm) EMIT(FMLA_vector(0, 0, 0, Vm, Vn, Vd))
// Vd += Vn*Vm
#define VFMLAQS(Vd, Vn, Vm) EMIT(FMLA_vector(1, 0, 0, Vm, Vn, Vd))
// Vd += Vn*Vm
#define VFMLAQD(Vd, Vn, Vm) EMIT(FMLA_vector(1, 0, 1, Vm, Vn, Vd))
// Vd -= Vn*Vm
#define VFMLSQS(Vd, Vn, Vm) EMIT(FMLA_vector(1, 1, 0, Vm, Vn, Vd))
// Vd -= Vn*Vm
#define VFMLSQD(Vd, Vn, Vm) EMIT(FMLA_vector(1, 1, 1, Vm, Vn, Vd))
// ZIP / UZP
#define ZIP_gen(Q, size, Rm, op, Rn, Rd) ((Q)<<30 | 0b001110<<24 | (size)<<22 | (Rm)<<16 | (op)<<14 | 0b11<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
#define VZIP1Q_8(Rt, Rn, Rm) EMIT(ZIP_gen(1, 0b00, Rm, 0, Rn, Rt))
@@ -1465,6 +1648,16 @@
#define VUZP1Q_64(Rt, Rn, Rm) EMIT(UZP_gen(1, 0b11, Rm, 0, Rn, Rt))
#define VUZP2Q_64(Rt, Rn, Rm) EMIT(UZP_gen(1, 0b11, Rm, 1, Rn, Rt))
#define BITBIF_gen(Q, opc2, Rm, Rn, Rd) ((Q)<<30 | 0b101110<<24 | (opc2)<<22 | 1<<21 | (Rm)<<16 | 0b000111<<10 | (Rn)<<5 | (Rd))
// Bitwise insert Vn in Vd if Vm is "0"
#define VBIF(Vd, Vn,Vm) EMIT(BITBIF_gen(0, 0b11, Vm, Vn, Vd))
// Bitwise insert Vn in Vd if Vm is "0"
#define VBIFQ(Vd, Vn,Vm) EMIT(BITBIF_gen(1, 0b11, Vm, Vn, Vd))
// Bitwise insert Vn in Vd if Vm is "1"
#define VBIT(Vd, Vn,Vm) EMIT(BITBIF_gen(0, 0b10, Vm, Vn, Vd))
// Bitwise insert Vn in Vd if Vm is "1"
#define VBITQ(Vd, Vn,Vm) EMIT(BITBIF_gen(1, 0b10, Vm, Vn, Vd))
#define DUP_element(Q, imm5, Rn, Rd) ((Q)<<30 | 0b01110000<<21 | (imm5)<<16 | 1<<10 | (Rn)<<5 | (Rd))
#define VDUP_8(Vd, Vn, idx) EMIT(DUP_element(0, ((idx)<<1|1), Vn, Vd))
#define VDUPQ_8(Vd, Vn, idx) EMIT(DUP_element(1, ((idx)<<1|1), Vn, Vd))
@@ -1563,6 +1756,15 @@
// Signed saturating extract Unsigned Narrow, takes Rn element and reduce 16->8 with Unsigned saturation and fit higher part of Rd
#define SQXTUN2_8(Rd, Rn) EMIT(QXTUN_vector(1, 1, 0b00, Rn, Rd))
#define XTN_vector(Q, size, Rn, Rd) ((Q)<<30 | 0b01110<<24 | (size)<<22 | 0b10000<<17 | 0b10010<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
// Xtract narrow to X bits
#define XTN_8(Vd, Vn) EMIT(XTN_vector(0, 0b00, Vn, Vd))
#define XTN_16(Vd, Vn) EMIT(XTN_vector(0, 0b01, Vn, Vd))
#define XTN_32(Vd, Vn) EMIT(XTN_vector(0, 0b10, Vn, Vd))
#define XTN2_8(Vd, Vn) EMIT(XTN_vector(1, 0b00, Vn, Vd))
#define XTN2_16(Vd, Vn) EMIT(XTN_vector(1, 0b01, Vn, Vd))
#define XTN2_32(Vd, Vn) EMIT(XTN_vector(1, 0b10, Vn, Vd))
// Integer CMP
// EQual
#define CMEQ_vector(Q, U, size, Rm, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b10001<<11 | 1<<10 | (Rn)<<5 | (Rd))
@@ -1600,8 +1802,8 @@
#define VCHIQQ_64(Rd, Rn, Rm) EMIT(CMG_vector(1, 1, 0b11, 0, Rm, Rn, Rd))
// Less Than 0
#define CMLT_0_vector(Q, size, Rn, Rd) ((Q)<<30 | 0b01110<<24 | (size)<<22 | 0b10000<<17 | 0b01010<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
#define CMLT_0_8(Rd, Rn) EMIT(CMLT_0_vector(0, 0b00, Rn, Rd))
#define CMLT_0_vector(Q, size, Rn, Rd) ((Q)<<30 | 0b01110<<24 | (size)<<22 | 0b10000<<17 | 0b01010<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
#define CMLT_0_8(Rd, Rn) EMIT(CMLT_0_vector(0, 0b00, Rn, Rd))
#define CMLT_0_16(Rd, Rn) EMIT(CMLT_0_vector(0, 0b01, Rn, Rd))
#define CMLT_0_32(Rd, Rn) EMIT(CMLT_0_vector(0, 0b10, Rn, Rd))
#define CMLTQ_0_8(Rd, Rn) EMIT(CMLT_0_vector(1, 0b00, Rn, Rd))
@@ -1655,7 +1857,7 @@
#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)))
@@ -1785,8 +1987,12 @@
#define MOVI_vector(Q, op, abc, cmode, defgh, Rd) ((Q)<<30 | (op)<<29 | 0b0111100000<<19 | (abc)<<16 | (cmode)<<12 | 1<<10 | (defgh)<<5 | (Rd))
#define MOVIQ_8(Rd, imm8) EMIT(MOVI_vector(1, 0, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
#define MOVIQ_16(Rd, imm8, lsl8) EMIT(MOVI_vector(1, 0, (((imm8)>>5)&0b111), 0b1000|((lsl8)?0b10:0), ((imm8)&0b11111), Rd))
#define MOVIQ_32(Rd, imm8) EMIT(MOVI_vector(1, 0, (((imm8)>>5)&0b111), 0b0000, ((imm8)&0b11111), Rd))
#define MOVIQ_32_lsl(Rd, imm8, lsl8) EMIT(MOVI_vector(1, 0, (((imm8)>>5)&0b111), (lsl8<<1), ((imm8)&0b11111), Rd))
#define MOVIQ_64(Rd, imm8) EMIT(MOVI_vector(1, 1, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
#define MOVI_8(Rd, imm8) EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
#define MOVI_16(Rd, imm8, lsl8) EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), 0b1000|((lsl8)?0b10:0), ((imm8)&0b11111), Rd))
#define MOVI_32_lsl(Rd, imm8, lsl8) EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), (lsl8<<1), ((imm8)&0b11111), Rd))
#define MOVI_32(Rd, imm8) EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), 0b0000, ((imm8)&0b11111), Rd))
#define MOVI_64(Rd, imm8) EMIT(MOVI_vector(0, 1, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
@@ -1888,6 +2094,33 @@
#define UMINQ_32(Vd, Vn, Vm) EMIT(MINMAX_vector(1, 1, 0b10, Vm, 1, Vn, Vd))
//#define UMINQ_64(Vd, Vn, Vm) EMIT(MINMAX_vector(1, 1, 0b11, Vm, 1, Vn, Vd))
// MIN or MAX accros vector
#define MAXMINV_vector(Q, U, size, op, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 0b11000<<17 | (op)<<16 | 0b1010<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
#define SMAXV_8(Vd, Vn) EMIT(MAXMINV_vector(0, 0, 0b00, 0, Vn, Vd))
#define SMINV_8(Vd, Vn) EMIT(MAXMINV_vector(0, 0, 0b00, 1, Vn, Vd))
#define UMAXV_8(Vd, Vn) EMIT(MAXMINV_vector(0, 1, 0b00, 0, Vn, Vd))
#define UMINV_8(Vd, Vn) EMIT(MAXMINV_vector(0, 1, 0b00, 1, Vn, Vd))
#define SMAXV_16(Vd, Vn) EMIT(MAXMINV_vector(0, 0, 0b01, 0, Vn, Vd))
#define SMINV_16(Vd, Vn) EMIT(MAXMINV_vector(0, 0, 0b01, 1, Vn, Vd))
#define UMAXV_16(Vd, Vn) EMIT(MAXMINV_vector(0, 1, 0b01, 0, Vn, Vd))
#define UMINV_16(Vd, Vn) EMIT(MAXMINV_vector(0, 1, 0b01, 1, Vn, Vd))
#define SMAXV_32(Vd, Vn) EMIT(MAXMINV_vector(0, 0, 0b10, 0, Vn, Vd))
#define SMINV_32(Vd, Vn) EMIT(MAXMINV_vector(0, 0, 0b10, 1, Vn, Vd))
#define UMAXV_32(Vd, Vn) EMIT(MAXMINV_vector(0, 1, 0b10, 0, Vn, Vd))
#define UMINV_32(Vd, Vn) EMIT(MAXMINV_vector(0, 1, 0b10, 1, Vn, Vd))
#define SMAXVQ_8(Vd, Vn) EMIT(MAXMINV_vector(1, 0, 0b00, 0, Vn, Vd))
#define SMINVQ_8(Vd, Vn) EMIT(MAXMINV_vector(1, 0, 0b00, 1, Vn, Vd))
#define UMAXVQ_8(Vd, Vn) EMIT(MAXMINV_vector(1, 1, 0b00, 0, Vn, Vd))
#define UMINVQ_8(Vd, Vn) EMIT(MAXMINV_vector(1, 1, 0b00, 1, Vn, Vd))
#define SMAXVQ_16(Vd, Vn) EMIT(MAXMINV_vector(1, 0, 0b01, 0, Vn, Vd))
#define SMINVQ_16(Vd, Vn) EMIT(MAXMINV_vector(1, 0, 0b01, 1, Vn, Vd))
#define UMAXVQ_16(Vd, Vn) EMIT(MAXMINV_vector(1, 1, 0b01, 0, Vn, Vd))
#define UMINVQ_16(Vd, Vn) EMIT(MAXMINV_vector(1, 1, 0b01, 1, Vn, Vd))
#define SMAXVQ_32(Vd, Vn) EMIT(MAXMINV_vector(1, 0, 0b10, 0, Vn, Vd))
#define SMINVQ_32(Vd, Vn) EMIT(MAXMINV_vector(1, 0, 0b10, 1, Vn, Vd))
#define UMAXVQ_32(Vd, Vn) EMIT(MAXMINV_vector(1, 1, 0b10, 0, Vn, Vd))
#define UMINVQ_32(Vd, Vn) EMIT(MAXMINV_vector(1, 1, 0b10, 1, Vn, Vd))
// HADD vector
#define HADD_vector(Q, U, size, Rm, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 1<<10 | (Rn)<<5 | (Rd))
#define SHADD_8(Vd, Vn, Vm) EMIT(HADD_vector(0, 0, 0b00, Vm, Vn, Vd))
@@ -2026,7 +2259,7 @@
#define LDSETLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b011, Rn, Rt))
#define STSETH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b011, Rn, 0b11111))
#define STSETLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b011, Rn, 0b11111))
// Atomic Signel Max
// Atomic Signed Max
#define LDSMAXxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b100, Rn, Rt))
#define LDSMAXAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b100, Rn, Rt))
#define LDSMAXALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b100, Rn, Rt))
@@ -2142,23 +2375,23 @@
// FLAGM extension
// Invert Carry Flag
#define CFINV() EMIT(0b1101010100<<22 | 0b0100<<12 | 0b000<<5 | 0b11111)
#define CFINV() FEMIT(0b1101010100<<22 | 0b0100<<12 | 0b000<<5 | 0b11111)
#define RMIF_gen(imm6, Rn, mask) (0b10111010000<<21 | (imm6)<<15 | 0b00001<<10 | (Rn)<<5 | (mask))
// Rotate right reg and use as NZCV
#define RMIF(Xn, shift, mask) EMIT(RMIF_gen(shift, Xn, mask))
#define RMIF(Xn, shift, mask) FEMIT(RMIF_gen(shift, Xn, mask))
#define SETF_gen(sz, Rn) (0b00111010000<<21 | (sz)<<14 | 0b0010<<10 | (Rn)<<5 | 0b1101)
// Set NZVc with 8bit value of reg: N=bit7, Z=[0..7]==0, V=bit8 eor bit7, C unchanged
#define SETF8(Wn) EMIT(SETF_gen(0, Wn))
#define SETF8(Wn) FEMIT(SETF_gen(0, Wn))
// Set NZVc with 16bit value of reg: N=bit15, Z=[0..15]==0, V=bit16 eor bit15, C unchanged
#define SETF16(Wn) EMIT(SETF_gen(1, Wn))
#define SETF16(Wn) FEMIT(SETF_gen(1, Wn))
// FLAGM2 extension
// NZCV -> N=0 Z=C|V C=C&!V V=0
#define AXFLAG() EMIT(0b1101010100<<22 | 0b0100<<12 | 0b010<<5 | 0b11111)
#define AXFLAG() FEMIT(0b1101010100<<22 | 0b0100<<12 | 0b010<<5 | 0b11111)
// NZCV -> N=!C&!Z Z=Z&C C=C|Z V=!C&Z
#define XAFLAG() EMIT(0b1101010100<<22 | 0b0100<<12 | 0b001<<5 | 0b11111)
#define XAFLAG() FEMIT(0b1101010100<<22 | 0b0100<<12 | 0b001<<5 | 0b11111)
// FRINTTS extension
#define FRINTxx_scalar(type, op, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | 0b0100<<17 | (op)<<15 | 0b10000<<10 | (Rn)<<5 | (Rd))
@@ -2171,6 +2404,24 @@
#define FRINT64XS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b11, Sn, Sd))
#define FRINT64XD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b11, Dn, Dd))
#define FRINTxx_vector(Q, U, sz, op, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (sz)<<22 | 0b10000<<17 | 0b1111<<13 | (op)<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
#define VFRINT32ZS(Vd, Vn) EMIT(FRINTxx_vector(0, 0, 0, 0, Vn, Vd))
#define VFRINT32ZSQ(Vd, Vn) EMIT(FRINTxx_vector(1, 0, 0, 0, Vn, Vd))
#define VFRINT32XS(Vd, Vn) EMIT(FRINTxx_vector(0, 1, 0, 0, Vn, Vd))
#define VFRINT32XSQ(Vd, Vn) EMIT(FRINTxx_vector(1, 1, 0, 0, Vn, Vd))
#define VFRINT32ZD(Vd, Vn) EMIT(FRINTxx_vector(0, 0, 1, 0, Vn, Vd))
#define VFRINT32ZDQ(Vd, Vn) EMIT(FRINTxx_vector(1, 0, 1, 0, Vn, Vd))
#define VFRINT32XD(Vd, Vn) EMIT(FRINTxx_vector(0, 1, 1, 0, Vn, Vd))
#define VFRINT32XDQ(Vd, Vn) EMIT(FRINTxx_vector(1, 1, 1, 0, Vn, Vd))
#define VFRINT64ZS(Vd, Vn) EMIT(FRINTxx_vector(0, 0, 0, 1, Vn, Vd))
#define VFRINT64ZSQ(Vd, Vn) EMIT(FRINTxx_vector(1, 0, 0, 1, Vn, Vd))
#define VFRINT64XS(Vd, Vn) EMIT(FRINTxx_vector(0, 1, 0, 1, Vn, Vd))
#define VFRINT64XSQ(Vd, Vn) EMIT(FRINTxx_vector(1, 1, 0, 1, Vn, Vd))
#define VFRINT64ZD(Vd, Vn) EMIT(FRINTxx_vector(0, 0, 1, 1, Vn, Vd))
#define VFRINT64ZDQ(Vd, Vn) EMIT(FRINTxx_vector(1, 0, 1, 1, Vn, Vd))
#define VFRINT64XD(Vd, Vn) EMIT(FRINTxx_vector(0, 1, 1, 1, Vn, Vd))
#define VFRINT64XDQ(Vd, Vn) EMIT(FRINTxx_vector(1, 1, 1, 1, Vn, Vd))
// CRC32 extension
#define CRC32C_gen(sf, Rm, sz, Rn, Rd) ((sf)<<31 | 0b11010110<<21 | (Rm)<<16 | 0b010<<13 | 1<<12 | (sz)<<10 | (Rn)<<5 | (Rd))
#define CRC32CB(Wd, Wn, Wm) EMIT(CRC32C_gen(0, Wm, 0b00, Wn, Wd))
-20
View File
@@ -34,23 +34,3 @@ arm64_epilog:
ldp x30, x29, [sp], 16 // saved lr
//end, return...
ret
.global arm64_epilog_fast
arm64_epilog_fast:
//restore all used register
add sp, x28, 0
//vpop {d8-d15}
ldp x19, x20, [sp, (8 * 0)]
ldp x21, x22, [sp, (8 * 2)]
ldp x23, x24, [sp, (8 * 4)]
ldp x25, x26, [sp, (8 * 6)]
ldp x27, x28, [sp, (8 * 8)]
ldp d8, d9, [sp, (8 *10)]
ldp d10, d11, [sp, (8 *12)]
ldp d12, d13, [sp, (8 *14)]
ldp d14, d15, [sp, (8 *16)]
add sp, sp, (8 * 18)
ldp x30, x29, [sp], 16 // saved lr
//end, return...
ret
+88
View File
@@ -0,0 +1,88 @@
#include <stdint.h>
#include "arm64_immenc.h"
#define one (uint64_t)1
// Returns the packed valid-N-imms-immr (1-1-6-6 bits); returns 0 if bitmask is not encodable
int convert_bitmask(uint64_t bitmask) {
if (bitmask == 0 || bitmask == ~0ULL) return 0;
uint64_t size, mask, pat;
for (size = 6; size > 1; --size) {
mask = (one << (1 << (size - 1))) - 1;
pat = bitmask & mask;
if (pat != ((bitmask >> (1 << (size - 1))) & mask)) {
break;
}
}
mask = (size >= 6) ? ~0ULL : ((one << (1 << size)) - 1);
pat = bitmask & mask;
for (uint64_t i = 1; i < 7 - size; ++i) {
uint64_t boff = i * (1 << size);
if (((bitmask >> boff) & mask) != pat) {
return 0;
}
}
int immr = 0;
uint64_t last_bit = one << ((1 << size) - 1);
if (pat & 1) {
while (pat & last_bit) {
pat = ((pat - last_bit) << 1) | 1;
++immr;
}
} else {
immr = 1 << size;
while (!(pat & 1)) {
pat >>= 1;
--immr;
}
}
if (pat & (pat + 1)) return 0;
int to = 1;
while (pat & (one << to)) ++to;
return 0x2000 + ((size == 6) << 12) + ((((0x1E << size) & 0x3F) + (to - 1)) << 6) + immr;
}
#if 0
#include <unordered_set>
int main() {
std::unordered_set<uint64_t> okvals;
uint64_t val;
for (int n = 1; n < 7; ++n) {
int imms0 = ((n == 6) ? 0xC0 : 0x80) + ((0x1E << n) & 0x3F);
for (int nones = 0; nones < (1 << n) - 1; ++nones) {
val = (one << (nones + 1)) - 1;
for (int j = 0; j < 6 - n; ++j) {
val += val << (1 << (n + j));
}
for (int immr = 0; immr < (1 << n); ++immr) {
int exp = ((imms0 + nones) << 6) + immr;
int got = convert_bitmask(val);
if (exp != got) {
printf("0x%016lX: expected %04X, got %04X\n", val, exp, got);
}
okvals.emplace(val);
val = (val >> 1) | ((val & 1) << 63);
}
}
}
#pragma omp parallel for
for (uint64_t i = 1; i < 0xFFFFFFFFFFFFFFFFu; ++i) {
int got = convert_bitmask(i);
if (!!got != (okvals.find(i) != okvals.cend())) {
printf("0x%016lX: expected %s, got %04X\n", i, (!!got ? "non0" : "0000"), got);
}
}
}
#endif
+8
View File
@@ -0,0 +1,8 @@
#ifndef __ARM64_IMMENC_H__
#define __ARM64_IMMENC_H__
#include <stdint.h>
int convert_bitmask(uint64_t bitmask);
#endif // __ARM64_IMMENC_H__
+166 -25
View File
@@ -34,10 +34,12 @@ uint64_t DecodeBitMasks(int N, int imms, int immr)
if(s==levels) return 0;
uint64_t mask = (1LL<<(s+1))-1;
if(r) { // rotate
mask=(mask>>r)|(mask<<(e-r));
mask&=((1LL<<e)-1);
mask=(mask>>r)|(mask<<(e-r));
if(e<64) {
mask&=((1LL<<e)-1);
}
}
while (e<64) { // replicate
while(e<64) { // replicate
mask|=(mask<<e);
e<<=1;
}
@@ -122,6 +124,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "NOP");
return buff;
}
if(isMask(opcode, "11010101000000110010000001011111", &a)) {
snprintf(buff, sizeof(buff), "WFE");
return buff;
}
if(isMask(opcode, "11010101000000110010000001111111", &a)) {
snprintf(buff, sizeof(buff), "WFI");
return buff;
}
if(isMask(opcode, "11010101000000110010000000111111", &a)) {
snprintf(buff, sizeof(buff), "YIELD");
return buff;
}
if(isMask(opcode, "11010101000000110010000010111111", &a)) {
snprintf(buff, sizeof(buff), "SEVL");
return buff;
}
// --- LDR / STR
if(isMask(opcode, "f010100011iiiiiii22222nnnnnttttt", &a)) {
int offset = signExtend(imm, 7)<<(2+sf);
@@ -387,13 +405,13 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
}
if(isMask(opcode, "f00100101wwiiiiiiiiiiiiiiiiddddd", &a)) {
if(sf) {
uint64_t noti=~(uint64_t)imm;
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);
else
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x LSL %d\t; 0x%lx", Xt[Rd], imm, 16*hw, noti);
} else {
uint32_t noti=~(uint32_t)imm;
uint32_t noti=~(((uint32_t)imm)<<(hw*16));
if(!hw)
snprintf(buff, sizeof(buff), "MOVN %s, 0x%x\t; 0x%x", Wt[Rd], imm, noti);
else
@@ -536,6 +554,16 @@ 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);
@@ -571,6 +599,14 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "BIC %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, "f1101010hh1mmmmmiiiiiinnnnnddddd", &a)) {
const char* shifts[] = { "LSL", "LSR", "ASR", "ROR" };
if(shift==0 && imm==0)
snprintf(buff, sizeof(buff), "BICS %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm]);
else
snprintf(buff, sizeof(buff), "BICS %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, "f01100100Nrrrrrrssssssnnnnnddddd", &a)) {
uint64_t i = DecodeBitMasks(a.N, imms, immr);
if(!sf) i&=0xffffffff;
@@ -717,8 +753,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
@@ -742,17 +782,12 @@ 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)) {
@@ -914,7 +949,6 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
}
// UMOV
if(isMask(opcode, "0Q001110000rrrrr001111nnnnnddddd", &a)) {
char q = a.Q?'Q':'D';
char s = '?';
int sz=0;
if(a.Q==0 && immr&1) {s='B'; sz=0; }
@@ -923,9 +957,24 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
else if(a.Q==1 && (immr&15)==8) {s='D'; sz=3; }
int index = (immr)>>(sz+1);
if(sz>2)
snprintf(buff, sizeof(buff), "MOV %s, %c%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], q, Rn, s, index);
snprintf(buff, sizeof(buff), "MOV %s, V%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], Rn, s, index);
else
snprintf(buff, sizeof(buff), "UMOV %s, %c%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], q, Rn, s, index);
snprintf(buff, sizeof(buff), "UMOV %s, V%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], Rn, s, index);
return buff;
}
// SMOV
if(isMask(opcode, "0Q001110000rrrrr001011nnnnnddddd", &a)) {
char s = '?';
int sz=0;
if(a.Q==0 && immr&1) {s='B'; sz=0; }
else if(/*a.Q==0 &&*/ (immr&3)==2) {s='H'; sz=1; }
else if(/*a.Q==0 &&*/ (immr&7)==4) {s='S'; sz=2; }
else if(a.Q==1 && (immr&15)==8) {s='D'; sz=3; }
int index = (immr)>>(sz+1);
if(sz>2)
snprintf(buff, sizeof(buff), "MOV %s, V%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], Rn, s, index);
else
snprintf(buff, sizeof(buff), "SMOV %s, V%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], Rn, s, index);
return buff;
}
// VEOR
@@ -950,6 +999,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "VMUL V%d.%s, V%d.%s, V%d.%s", Rd, Vd, Rn, Vd, Rm, Vd);
return buff;
}
// VBIT / VBIF
if(isMask(opcode, "0Q1011101o1mmmmm000111nnnnnddddd", &a)) {
char q = a.Q?'Q':'D';
snprintf(buff, sizeof(buff), "VBI%c %c%d, %c%d, %c%d", a.o?'F':'T', q, Rd, q, Rn, q, Rm);
return buff;
}
// CMP
if(isMask(opcode, "0Q101110ff1mmmmm100011nnnnnddddd", &a)) {
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
@@ -1005,6 +1060,19 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm<<8);
return buff;
}
// MOV immediate 64bits
if(isMask(opcode, "0Q10111100000iii111001iiiiiddddd", &a)) {
uint64_t tmp64u = 0;
for(int i=0; i<8; ++i)
if((imm)&(1<<i))
tmp64u |= 0xffLL<<(i*8);
if(a.Q)
snprintf(buff, sizeof(buff), "MOVI V%d.2D, #0x%016lx", Rd, tmp64u);
else
snprintf(buff, sizeof(buff), "MOVI D%d, #0x%016lx", Rd, tmp64u);
return buff;
}
// Shift
if(isMask(opcode, "0QU011110hhhhrrr000001nnnnnddddd", &a)) {
@@ -1265,6 +1333,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, "000111100f1mmmmm111001nnnnnddddd", &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':'?');
@@ -1295,6 +1369,28 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
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);
return buff;
}
// FMADD
if(isMask(opcode, "00011111tt0mmmmmoaaaaannnnnddddd", &a)) {
char s = (a.t==0b00)?'S':((a.t==0b01)?'D':'?');
int n = (a.t==0)?1:2;
snprintf(buff, sizeof(buff), "FM%s V%d.%d%c, V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"SUB":"ADD", Rd, n, s, Ra, n, s, Rn, n, s, Rm, n, s);
return buff;
}
// FNMADD
if(isMask(opcode, "00011111tt1mmmmmoaaaaannnnnddddd", &a)) {
char s = (a.t==0b00)?'S':((a.t==0b01)?'D':'?');
int n = (a.t==0)?1:2;
snprintf(buff, sizeof(buff), "FNM%s V%d.%d%c, V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"SUB":"ADD", Rd, n, s, Ra, n, s, Rn, n, s, Rm, n, s);
return buff;
}
// FMLA
if(isMask(opcode, "0Q001110of1mmmmm110011nnnnnddddd", &a)) {
char s = (sf==0)?'S':((sf==1)?'D':'?');
int n = (sf==0)?2:1;
n *= a.Q?2:1;
snprintf(buff, sizeof(buff), "FML%s%s V%d.%d%c, V%d.%d%c, V%d.%d%c", option?"S":"A", a.Q?"Q":"", Rd, n, s, Rn, n, s, Rm, n, s);
return buff;
}
// NEG
if(isMask(opcode, "0Q101110ff100000101110nnnnnddddd", &a)) {
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
@@ -1493,12 +1589,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))
@@ -1509,7 +1605,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
@@ -1556,6 +1655,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)) {
@@ -1574,6 +1678,26 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "%cSHLL%s V%d.%s, V%d.%s, #%d", a.U?'U':'S', a.Q?"2":"", Rd, Va, Rn, Vd, sh);
return buff;
}
if(isMask(opcode, "0Q0011110hhhhiii010101nnnnnddddd", &a) && (a.h != 0b1000)) {
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
int sz = 3;
if((a.h&0b1111)==0b0001) sz=0;
else if((a.h&0b1110)==0b0010) sz=1;
else if((a.h&0b1100)==0b0100) sz=2;
int sh=(((a.h)<<3)|(imm)) - (8<<sz);
const char* Vd = Y[(sz<<1)|a.Q];
snprintf(buff, sizeof(buff), "SHL%s V%d.%s, V%d.%s, #%d", a.Q?"Q":"", Rd, Vd, Rn, Vd, sh);
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)) {
@@ -1583,7 +1707,7 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
if((imm&0b0001)==0b0001) sz=0;
else if((imm&0b0011)==0b0010) sz=1;
else if((imm&0b0111)==0b0100) sz=2;
int sh=imm - (1<<sz);
int sh=(imm>>sz) - 1;
const char* Vd = Y[(sz<<1)|a.Q];
const char* Vn = Z[sz];
snprintf(buff, sizeof(buff), "DUP V%d.%s, V%d.%s[%d]", Rd, Vd, Rn, Vn, sh);
@@ -1621,14 +1745,26 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
return buff;
}
// DMB ISH
// DMB
if(isMask(opcode, "11010101000000110011nnnn10111111", &a)) {
snprintf(buff, sizeof(buff), "DMB %s", (Rn==0b1011)?"ISH":"???");
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 ISH/ISHST
// 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;
}
@@ -1759,6 +1895,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "SHA256H2 Q%d, Q%d, V%d.4S", Rd, Rn, Rm);
return buff;
}
// UDF
if(isMask(opcode, "0000000000000000iiiiiiiiiiiiiiii", &a)) {
snprintf(buff, sizeof(buff), "UDF 0x%x", a.i);
return buff;
}
snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode));
return buff;
+1 -4
View File
@@ -6,8 +6,6 @@
.text
.align 4
.extern arm64_next
.global arm64_prolog
arm64_prolog:
//save all 18 used register
@@ -34,8 +32,7 @@ arm64_prolog:
ldp x24, x25, [x0, (8 * 14)]
ldp x26, x27, [x0, (8 * 16)]
// Push a jump next on the stack
adr x28, arm64_next
stp x28, xzr, [sp, -16]!
stp xzr, xzr, [sp, -16]!
// Save old xSP in x28
add x28, sp, 16
//jump to function
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
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+164 -32
View File
@@ -18,7 +18,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog)
@@ -27,8 +27,9 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
uint8_t opcode = F8;
uint8_t nextop;
uint8_t gd, ed;
uint8_t gd, ed, wb1, wback;
int64_t j64;
int16_t i16;
int v0, v1;
int64_t fixedaddress;
int unscaled;
@@ -57,42 +58,169 @@ 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);
v1 = fpu_get_scratch(dyn);
VLDR64_REG(v1, ed, x4);
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);
VLD64(v1, ed, fixedaddress);
}
FCMPD(v0, v1);
FCOMI(x1, x2);
break;
case 0xD6:
INST_NAME("MOVQ Ex, Gx");
nextop = F8;
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));
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);
VSTR64_REG(v0, ed, x4);
SMWRITE();
}
break;
case 0x6F:
INST_NAME("MOVDQA Gx,Ex");
nextop = F8;
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
GETGX_empty(v0);
VMOVQ(v0, v1);
} else {
GETGX_empty(v0);
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();
ADDz_REG(x4, x4, ed);
ed = x4;
VLD128(v0, ed, fixedaddress);
}
break;
case 0x7F:
INST_NAME("MOVDQA Ex,Gx");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);
VMOVQ(v1, v0);
} else {
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);
ed = x4;
VST128(v0, ed, fixedaddress);
SMWRITE2();
}
break;
case 0xD6:
INST_NAME("MOVQ Ex, Gx");
nextop = F8;
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));
FMOVD(v1, v0);
} else {
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);
ed = x4;
VST64(v0, ed, fixedaddress);
SMWRITE();
}
break;
default:
DEFAULT;
}
break;
case 0x83:
nextop = F8;
switch((nextop>>3)&7) {
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, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
emit_add16(dyn, ninst, ed, x5, x2, x4);
EWBACK;
break;
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, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_or16c(dyn, ninst, x1, i16, x2, x4);
EWBACK;
break;
case 2: //ADC
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, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
emit_adc16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
case 3: //SBB
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, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
emit_sbb16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
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, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_and16c(dyn, ninst, x1, i16, x2, x4);
EWBACK;
break;
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, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
emit_sub16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
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, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_xor16c(dyn, ninst, x1, i16, x2, x4);
EWBACK;
break;
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, (MODREG));
GETEWO(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
if(i16) {
MOVZw(x2, i16);
emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5);
} else
emit_cmp16_0(dyn, ninst, x1, x3, x4);
break;
}
break;
case 0x89:
INST_NAME("MOV FS:Ew, Gw");
nextop = F8;
GETGD; // don't need GETGW here
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
if(rex.w) {
MOVx_REG(ed, gd);
} else {
@@ -101,23 +229,25 @@ 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 {
STRH_REG(gd, ed, x4);
STH(gd, ed, fixedaddress);
}
SMWRITE();
}
break;
case 0x8B:
INST_NAME("MOV Gd, FS:Ed");
INST_NAME("MOV Gw, FS:Ew");
nextop=F8;
GETGD;
if(MODREG) { // reg <= reg
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
if(rex.w) {
MOVx_REG(gd, ed);
} else {
@@ -126,13 +256,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 {
LDRH_REG(x1, ed, x4);
LDH(x1, ed, fixedaddress);
BFIx(gd, x1, 0, 16);
}
}
+193 -83
View File
@@ -18,7 +18,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -30,7 +30,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
uint8_t nextop;
uint8_t gd, ed, u8;
uint8_t wback, wb1, wb2, gb1, gb2;
int32_t i32;
int16_t i16;
int64_t i64, j64;
int64_t fixedaddress;
int unscaled;
@@ -48,13 +48,44 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETREX();
switch(opcode) {
case 0x01:
INST_NAME("LOCK ADD Ew, Gw");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGW(x5);
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_add16(dyn, ninst, x6, x5, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
if(arm64_atomics) {
UFLAG_IF {
LDADDALH(x5, x1, wback);
emit_add16(dyn, ninst, x1, x5, x3, x4);
} else {
STADDLH(x5, wback);
}
} else {
MARKLOCK;
LDAXRH(x1, wback);
emit_add16(dyn, ninst, x1, x5, x3, x4);
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
SMDMB();
}
break;
case 0x09:
INST_NAME("LOCK OR Ew, Gw");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGW(x5);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_or16(dyn, ninst, x6, x5, x3, x4);
BFIx(ed, x6, 0, 16);
@@ -89,7 +120,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETGD;
UXTHw(x6, xRAX);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
wback = 0;
UXTHw(x1, ed);
CMPSxw_REG(x6, x1);
@@ -98,8 +129,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
if(!ALIGNED_ATOMICH) {
TSTx_mask(wback, 1, 0, 0); // mask=1
B_MARK3(cNE);
if(arm64_uscat) {
ANDx_mask(x1, wback, 1, 0, 3); // mask = F
CMPSw_U12(x1, 0xF);
B_MARK3(cGE);
} else {
TSTx_mask(wback, 1, 0, 0); // mask=1
B_MARK3(cNE);
}
}
// Aligned version
if(arm64_atomics) {
@@ -121,6 +158,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
@@ -129,8 +168,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);
@@ -140,10 +179,10 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
INST_NAME("LOCK XADD Gw, Ew");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);
gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3));
UXTHx(x5, gd);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
BFIx(gd, ed, 0, 16);
emit_add16(dyn, ninst, x5, gd, x3, x4);
BFIx(ed, x5, 0, 16);
@@ -171,6 +210,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
DEFAULT;
}
break;
case 0x11:
INST_NAME("LOCK ADC Ew, Gw");
READFLAGS(X_CF);
@@ -178,7 +218,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGW(x5);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_adc16(dyn, ninst, x6, x5, x3, x4);
BFIx(ed, x6, 0, 16);
@@ -192,6 +232,38 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
SMDMB();
}
break;
case 0x21:
INST_NAME("LOCK AND Ew, Gw");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGW(x5);
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_and16(dyn, ninst, x6, gd, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
if(arm64_atomics) {
MVNw_REG(x3, gd);
UFLAG_IF {
LDCLRALH(x3, x1, wback);
emit_and16(dyn, ninst, x1, gd, x3, x4);
} else {
STCLRLH(x3, wback);
}
} else {
MARKLOCK;
LDAXRH(x1, wback);
emit_and16(dyn, ninst, x1, gd, x3, x4);
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
SMDMB();
}
break;
case 0x81:
case 0x83:
nextop = F8;
@@ -204,72 +276,89 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
SETFLAGS(X_ALL, SF_SET_PENDING);
if(MODREG) {
if(opcode==0x81) i32 = F16S; else i32 = F8S;
ed = xRAX+(nextop&7)+(rex.b<<3);
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
ed = TO_NAT((nextop & 7) + (rex.b << 3));
MOV32w(x5, i16);
UXTHw(x6, ed);
emit_add16(dyn, ninst, x6, x5, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
if(!ALIGNED_ATOMICH) {
TSTx_mask(wback, 1, 0, 0); // mask=1
B_MARK(cNE);
if(arm64_uscat) {
ANDx_mask(x1, wback, 1, 0, 3); // mask = F
CMPSw_U12(x1, 0xF);
B_MARK(cGE);
} else {
TSTx_mask(wback, 1, 0, 0); // mask=1
B_MARK(cNE);
}
}
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
if(opcode==0x81) {INST_NAME("LOCK OR Ew, Iw");} else {INST_NAME("LOCK OR Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
if(MODREG) {
if(opcode==0x81) i32 = F16S; else i32 = F8S;
ed = xRAX+(nextop&7)+(rex.b<<3);
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_or16(dyn, ninst, x6, x5, x3, x4);
emit_or16c(dyn, ninst, x6, i16, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
if(!i64) {MOV32w(x5, i16);}
if(arm64_atomics) {
UFLAG_IF {
LDSETALH(x5, x1, wback);
emit_or16(dyn, ninst, x1, x5, x3, x4);
emit_or16c(dyn, ninst, x1, i16, x3, x4);
} else {
STSETLH(x5, wback);
}
} else {
i64 = convert_bitmask_w(i16);
if(!i64) {MOV32w(x5, i16);}
MARKLOCK;
LDAXRH(x1, wback);
emit_or16(dyn, ninst, x1, x5, x3, x4);
if(i64) {
emit_or16c(dyn, ninst, x1, i16, x3, x4);
} else {
emit_or16(dyn, ninst, x1, x5, x3, x4);
}
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
@@ -281,16 +370,16 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
if(MODREG) {
if(opcode==0x81) i32 = F16S; else i32 = F8S;
ed = xRAX+(nextop&7)+(rex.b<<3);
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
ed = TO_NAT((nextop & 7) + (rex.b << 3));
MOV32w(x5, i16);
UXTHw(x6, ed);
emit_adc16(dyn, ninst, x6, x5, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MARKLOCK;
LDAXRH(x1, wback);
emit_adc16(dyn, ninst, x1, x5, x3, x4);
@@ -304,16 +393,16 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
if(MODREG) {
if(opcode==0x81) i32 = F16S; else i32 = F8S;
ed = xRAX+(nextop&7)+(rex.b<<3);
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
ed = TO_NAT((nextop & 7) + (rex.b << 3));
MOV32w(x5, i16);
UXTHw(x6, ed);
emit_sbb16(dyn, ninst, x6, x5, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MARKLOCK;
LDAXRH(x1, wback);
emit_sbb16(dyn, ninst, x1, x5, x3, x4);
@@ -326,29 +415,37 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
if(opcode==0x81) {INST_NAME("LOCK AND Ew, Iw");} else {INST_NAME("LOCK AND Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
if(MODREG) {
if(opcode==0x81) i32 = F16S; else i32 = F8S;
ed = xRAX+(nextop&7)+(rex.b<<3);
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_and16(dyn, ninst, x6, x5, x3, x4);
emit_and16c(dyn, ninst, x6, i16, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
if(opcode==0x81) i16 = F16S; else i16 = F8S;
i64 = convert_bitmask_w(i16);
if(arm64_atomics) {
MOV32w(x5, ~i32);
MOV32w(x5, ~i16);
UFLAG_IF {
LDCLRALH(x5, x1, wback);
MVNw_REG(x5, x5);
emit_and16(dyn, ninst, x1, x5, x3, x4);
if(i64) {
emit_and16c(dyn, ninst, x1, i16, x3, x4);
} else {
MVNw_REG(x5, x5);
emit_and16(dyn, ninst, x1, x5, x3, x4);
}
} else {
STCLRLH(x5, wback);
}
} else {
MOV32w(x5, i32);
if(!i64) {MOV32w(x5, i16);}
MARKLOCK;
LDAXRH(x1, wback);
emit_and16(dyn, ninst, x1, x5, x3, x4);
if(i64) {
emit_and16c(dyn, ninst, x1, i16, x3, x4);
} else {
emit_and16(dyn, ninst, x1, x5, x3, x4);
}
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
SMDMB();
@@ -359,75 +456,88 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
if(opcode==0x81) {INST_NAME("LOCK SUB Ew, Iw");} else {INST_NAME("LOCK SUB Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
if(MODREG) {
if(opcode==0x81) i32 = F16S; else i32 = F8S;
ed = xRAX+(nextop&7)+(rex.b<<3);
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
ed = TO_NAT((nextop & 7) + (rex.b << 3));
MOV32w(x5, i16);
UXTHw(x6, ed);
emit_sub16(dyn, ninst, x6, x5, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
if(!ALIGNED_ATOMICH) {
TSTx_mask(wback, 1, 0, 0); // mask=1
B_MARK(cNE);
if(arm64_uscat) {
ANDx_mask(x1, wback, 1, 0, 3); // mask = F
CMPSw_U12(x1, 0xF);
B_MARK(cGE);
} else {
TSTx_mask(wback, 1, 0, 0); // mask=1
B_MARK(cNE);
}
}
if(arm64_atomics) {
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
if(opcode==0x81) {INST_NAME("LOCK XOR Ew, Iw");} else {INST_NAME("LOCK XOR Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
if(MODREG) {
if(opcode==0x81) i32 = F16S; else i32 = F8S;
ed = xRAX+(nextop&7)+(rex.b<<3);
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_xor16(dyn, ninst, x6, x5, x3, x4);
emit_xor16c(dyn, ninst, x6, i16, x3, x4);
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
i64 = convert_bitmask_w(i16);
if(arm64_atomics) {
UFLAG_IF {
LDEORALH(x5, x1, wback);
emit_xor16(dyn, ninst, x1, x5, x3, x4);
emit_xor16c(dyn, ninst, x1, i16, x3, x4);
} else {
STEORLH(x5, wback);
}
} else {
if(!i64) {MOV32w(x5, i16);}
MARKLOCK;
LDAXRH(x1, wback);
emit_xor16(dyn, ninst, x1, x5, x3, x4);
if(i64)
emit_xor16c(dyn, ninst, x1, i16, x3, x4);
else
emit_xor16(dyn, ninst, x1, x5, x3, x4);
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
SMDMB();
@@ -440,9 +550,9 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEW(x6, (opcode==0x81)?2:1);
(void)wb1;
// No need to LOCK, this is readonly
if(opcode==0x81) i32 = F16S; else i32 = F8S;
if(i32) {
MOV32w(x5, i32);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
if(i16) {
MOV32w(x5, i16);
emit_cmp16(dyn, ninst, x6, x5, x3, x4, x6);
} else {
emit_cmp16_0(dyn, ninst, ed, x3, x4);
@@ -457,9 +567,9 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
{
case 0: // INC Ew
INST_NAME("LOCK INC Ew");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_inc16(dyn, ninst, x6, x5, x3);
BFIx(ed, x6, 0, 16);
@@ -485,9 +595,9 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
break;
case 1: //DEC Ew
INST_NAME("LOCK DEC Ew");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UXTHw(x6, ed);
emit_dec16(dyn, ninst, x6, x5, x3);
BFIx(ed, x6, 0, 16);
+1 -1
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "emu/x64compstrings.h"
uintptr_t dynarec64_66F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
+75 -1
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "emu/x64compstrings.h"
uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
@@ -55,7 +55,81 @@ 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");
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
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?
}
GWBACK;
break;
case 0xBD:
INST_NAME("LZCNT Gw, Ew");
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
SET_DFNONE();
nextop = F8;
GETEW(x1, 0);
GETGW(x2);
IFX(X_CF) {
TSTxw_REG(ed, ed);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
}
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?
}
GWBACK;
break;
default:
DEFAULT;
+616 -70
View File
@@ -15,10 +15,11 @@
#include "emu/x64run_private.h"
#include "x64trace.h"
#include "dynarec_native.h"
#include "custommem.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
#define GETGm gd = ((nextop&0x38)>>3)
@@ -36,6 +37,8 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
uint8_t u8;
int32_t i32;
int64_t j64, i64;
int16_t i16;
uint64_t u64;
int cacheupd = 0;
int lock;
int v0, v1, s0;
@@ -53,11 +56,18 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
return addr;
}
while(opcode==0x67) opcode = F8;
// reset rex after 67
GETREX();
rep = 0;
while((opcode==0xF2) || (opcode==0xF3)) {
rep = opcode-0xF1;
while((opcode==0xF2) || (opcode==0xF3) || (opcode>=0x40 && opcode<=0x4F)) {
if((opcode==0xF2) || (opcode==0xF3))
rep = opcode-0xF1;
if(opcode>=0x40 && opcode<=0x4F)
rex.rex = opcode;
opcode = F8;
}
@@ -200,7 +210,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if(MODREG) {
s0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 0);
} else {
s0 = fpu_get_scratch(dyn);
s0 = fpu_get_scratch(dyn, ninst);
SMREAD();
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
@@ -213,6 +223,39 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0x38: /* MAP 0F38 */
opcode = F8;
switch(opcode) {
case 0xF6:
switch(rep) {
case 2:
INST_NAME("ADOX Gd, Ed");
nextop = F8;
READFLAGS(X_OF);
SETFLAGS(X_OF, SF_SUBSET);
GETED32(0);
GETGD;
MRS_nzcv(x3);
LSRw(x4, xFlags, F_OF);
BFIx(x3, x4, 29, 1); // set C
MSR_nzcv(x3); // load CC into ARM CF
IFX(X_OF) {
ADCSxw_REG(gd, gd, ed);
CSETw(x3, cCS);
BFIw(xFlags, x3, F_OF, 1);
} else {
ADCxw_REG(gd, gd, ed);
}
break;
default:
DEFAULT;
}
break;
default:
DEFAULT;
}
break;
case 0x6F:
switch(rep) {
case 0:
@@ -264,6 +307,19 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SMWRITE();
}
break;
case 2:
INST_NAME("MOVDQU Ex, Gx");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
v1 = sse_get_reg_empty(dyn, ninst, x1, nextop&7);
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);
SMWRITE();
}
break;
default:
DEFAULT;
}
@@ -275,11 +331,11 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
GETGD;
if(MODREG) {
if(rex.rex) {
eb1 = xRAX+(nextop&7)+(rex.b<<3);
eb1 = TO_NAT((nextop & 7) + (rex.b << 3));
eb2 = 0;
} else {
ed = (nextop&7);
eb1 = xRAX+(ed&3); // Ax, Cx, Dx or Bx
eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx
eb2 = (ed&4)>>2; // L or H
}
UBFXxw(gd, eb1, eb2*8, 8);
@@ -294,7 +350,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
nextop = F8;
GETGD;
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
UBFXxw(gd, ed, 0, 16);
} else {
SMREAD();
@@ -627,13 +683,32 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4);
break;
case 0x50:
case 0x51:
case 0x52:
case 0x53:
case 0x54:
case 0x55:
case 0x56:
case 0x57:
case 0x58:
case 0x59:
case 0x5A:
case 0x5B:
case 0x5C:
case 0x5D:
case 0x5E:
case 0x5F:
// just use regular conditional jump
return dynarec64_00(dyn, addr-1, ip, ninst, rex, rep, ok, need_epilog);
case 0x63:
INST_NAME("MOVSXD Gd, Ed");
nextop = F8;
GETGD;
if(rex.w) {
if(MODREG) { // reg <= reg
SXTWx(gd, xRAX+(nextop&7)+(rex.b<<3));
SXTWx(gd, TO_NAT((nextop & 7) + (rex.b << 3)));
} else { // mem <= reg
SMREAD();
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
@@ -641,7 +716,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
} else {
if(MODREG) { // reg <= reg
MOVw_REG(gd, xRAX+(nextop&7)+(rex.b<<3));
MOVw_REG(gd, TO_NAT((nextop & 7) + (rex.b << 3)));
} else { // mem <= reg
SMREAD();
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
@@ -652,29 +727,274 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x66:
opcode=F8;
GETREX();
switch(opcode) {
case 0x0F:
nextop = F8;
switch(nextop) {
case 0x6F:
INST_NAME("MOVDQA Gx,Ex");
nextop = F8;
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
GETGX_empty(v0);
VMOVQ(v0, v1);
} else {
GETGX_empty(v0);
SMREAD();
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VLD128(v0, ed, fixedaddress);
}
break;
case 0x7E:
INST_NAME("MOVD Ed,Gx");
nextop = F8;
GETGX(v0, 0);
if(rex.w) {
if(MODREG) {
ed = TO_NAT((nextop & 0x07) + (rex.b << 3));
VMOVQDto(ed, v0, 0);
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v0, ed, fixedaddress);
SMWRITE2();
}
} else {
if(MODREG) {
ed = TO_NAT((nextop & 0x07) + (rex.b << 3));
VMOVSto(ed, v0, 0);
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VST32(v0, ed, fixedaddress);
SMWRITE2();
}
}
break;
case 0xD6:
INST_NAME("MOVQ Ex, Gx");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3));
FMOVD(v1, v0);
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v0, ed, fixedaddress);
SMWRITE2();
}
break;
case 0xFE:
INST_NAME("PADDD Gx,Ex");
nextop = F8;
GETGX(v0, 1);
GETEX32(v1, 0, 0);
VADDQ_32(v0, v0, v1);
break;
default:
DEFAULT;
}
break;
case 0x81:
case 0x83:
nextop = F8;
switch((nextop>>3)&7) {
case 0: //ADD
if(opcode==0x81) {INST_NAME("ADD Ew, Iw");} else {INST_NAME("ADD Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW32(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
emit_add16(dyn, ninst, ed, x5, x2, x4);
EWBACK;
break;
case 1: //OR
if(opcode==0x81) {INST_NAME("OR Ew, Iw");} else {INST_NAME("OR Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW32(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_or16c(dyn, ninst, x1, i16, x2, x4);
EWBACK;
break;
case 2: //ADC
if(opcode==0x81) {INST_NAME("ADC Ew, Iw");} else {INST_NAME("ADC Ew, Ib");}
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW32(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
emit_adc16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
case 3: //SBB
if(opcode==0x81) {INST_NAME("SBB Ew, Iw");} else {INST_NAME("SBB Ew, Ib");}
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW32(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
emit_sbb16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
case 4: //AND
if(opcode==0x81) {INST_NAME("AND Ew, Iw");} else {INST_NAME("AND Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW32(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_and16c(dyn, ninst, x1, i16, x2, x4);
EWBACK;
break;
case 5: //SUB
if(opcode==0x81) {INST_NAME("SUB Ew, Iw");} else {INST_NAME("SUB Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW32(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOVZw(x5, i16);
emit_sub16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
case 6: //XOR
if(opcode==0x81) {INST_NAME("XOR Ew, Iw");} else {INST_NAME("XOR Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW32(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
emit_xor16c(dyn, ninst, x1, i16, x2, x4);
EWBACK;
break;
case 7: //CMP
if(opcode==0x81) {INST_NAME("CMP Ew, Iw");} else {INST_NAME("CMP Ew, Ib");}
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW32(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
if(i16) {
MOVZw(x2, i16);
emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5);
} else
emit_cmp16_0(dyn, ninst, x1, x3, x4);
break;
}
break;
case 0x89:
INST_NAME("MOV Ew, Gw");
nextop = F8;
GETGD; // don't need GETGW here
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
if(ed!=gd) {
BFIx(ed, gd, 0, 16);
}
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, &lock, 0, 0);
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff << 1, 1, rex, &lock, 0, 0);
STH(gd, ed, fixedaddress);
SMWRITELOCK(lock);
}
break;
case 0x8D:
INST_NAME("LEA Gw, Ed");
nextop=F8;
//GETGW(x1);
gd = x1; // no need to read
if(MODREG) { // reg <= reg? that's an invalid operation
DEFAULT;
} else { // mem <= reg
addr = geted32(dyn, addr, ninst, nextop, &ed, gd, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=gd)
gd = ed;
}
GWBACK;
break;
default:
DEFAULT;
}
break;
case 0x6B:
INST_NAME("IMUL Gd, Ed, Ib");
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);
i64 = F8S;
MOV64xw(x4, i64);
if(rex.w) {
// 64bits imul
UFLAG_IF {
SMULH(x3, ed, x4);
MULx(gd, ed, x4);
SET_DFNONE();
IFX(X_CF | X_OF) {
CMPSx_REG_ASR(x3, gd, 63);
CSETw(x1, cNE);
IFX(X_CF) {
BFIw(xFlags, x1, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x1, F_OF, 1);
}
}
} else {
MULxw(gd, ed, x4);
}
} else {
// 32bits imul
UFLAG_IF {
SMULL(gd, ed, x4);
LSRx(x3, gd, 32);
MOVw_REG(gd, gd);
SET_DFNONE();
IFX(X_CF | X_OF) {
CMPSw_REG_ASR(x3, gd, 31);
CSETw(x1, cNE);
IFX(X_CF) {
BFIw(xFlags, x1, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x1, F_OF, 1);
}
}
} else {
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:
case 0x71:
case 0x72:
case 0x73:
case 0x74:
case 0x75:
case 0x76:
case 0x77:
case 0x78:
case 0x79:
case 0x7A:
case 0x7B:
case 0x7C:
case 0x7D:
case 0x7E:
case 0x7F:
// just use regular conditional jump
return dynarec64_00(dyn, addr-1, ip, ninst, rex, rep, ok, need_epilog);
case 0x81:
case 0x83:
nextop = F8;
@@ -759,10 +1079,10 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
gd = ((nextop&0x38)>>3)+(rex.r<<3);
if(rex.rex) {
gb2 = 0;
gb1 = xRAX + gd;
gb1 = TO_NAT(gd);
} else {
gb2 = ((gd&4)<<1);
gb1 = xRAX+(gd&3);
gb1 = TO_NAT(gd & 3);
}
if(gb2) {
gd = x4;
@@ -773,10 +1093,10 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if(MODREG) {
ed = (nextop&7) + (rex.b<<3);
if(rex.rex) {
eb1 = xRAX+ed;
eb1 = TO_NAT(ed);
eb2 = 0;
} else {
eb1 = xRAX+(ed&3); // Ax, Cx, Dx or Bx
eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx
eb2 = ((ed&4)>>2); // L or H
}
BFIx(eb1, gd, eb2*8, 8);
@@ -791,9 +1111,9 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
nextop=F8;
GETGD;
if(MODREG) { // reg <= reg
MOVxw_REG(xRAX+(nextop&7)+(rex.b<<3), gd);
MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), gd);
} else { // mem <= reg
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 0);
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff << (2 + rex.w), (1 << (2 + rex.w)) - 1, rex, &lock, 0, 0);
STxw(gd, ed, fixedaddress);
SMWRITELOCK(lock);
}
@@ -802,21 +1122,21 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("MOV Gb, Eb");
nextop = F8;
if(rex.rex) {
gb1 = gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);
gb1 = gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3));
gb2=0;
} else {
gd = (nextop&0x38)>>3;
gb1 = xRAX+(gd&3);
gb1 = TO_NAT(gd & 3);
gb2 = ((gd&4)<<1);
}
if(MODREG) {
if(rex.rex) {
wback = xRAX+(nextop&7)+(rex.b<<3);
wback = TO_NAT((nextop & 7) + (rex.b << 3));
wb2 = 0;
} else {
wback = (nextop&7);
wb2 = (wback>>2);
wback = xRAX+(wback&3);
wback = TO_NAT(wback & 3);
}
if(wb2) {
UBFXw(x4, wback, wb2*8, 8);
@@ -837,7 +1157,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
nextop=F8;
GETGD;
if(MODREG) {
MOVxw_REG(gd, xRAX+(nextop&7)+(rex.b<<3));
MOVxw_REG(gd, TO_NAT((nextop & 7) + (rex.b << 3)));
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 0);
SMREADLOCK(lock);
@@ -853,18 +1173,51 @@ 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;
case 0x90:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
case 0x95:
case 0x96:
case 0x97:
gd = TO_NAT((opcode & 0x07) + (rex.b << 3));
if(gd==xRAX) {
INST_NAME("NOP");
} else {
INST_NAME("XCHG EAX, Reg");
MOVxw_REG(x2, xRAX);
MOVxw_REG(xRAX, gd);
MOVxw_REG(gd, x2);
}
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);
i64 = F32S;
emit_test32c(dyn, ninst, rex, xRAX, i64, x3, x4, x5);
break;
case 0xC1:
nextop = F8;
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, Ib");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -872,7 +1225,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 1:
INST_NAME("ROR Ed, Ib");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -880,34 +1233,32 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 2:
INST_NAME("RCL Ed, Ib");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
GETED32W(x4, x1, 1);
u8 = F8;
MOV32w(x2, u8);
CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4);
WBACK;
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_rcl32c(dyn, ninst, rex, ed, u8, x3, x4);
if(u8) { WBACK; }
break;
case 3:
INST_NAME("RCR Ed, Ib");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
GETED32W(x4, x1, 1);
u8 = F8;
MOV32w(x2, u8);
CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);
WBACK;
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_rcr32c(dyn, ninst, rex, ed, u8, x3, x4);
if(u8) { WBACK; }
break;
case 4:
case 6:
INST_NAME("SHL Ed, Ib");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);
WBACK;
if(u8) { //should create the geted32_ib utility function for that
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);
WBACK;
}
break;
case 5:
INST_NAME("SHR Ed, Ib");
@@ -932,12 +1283,86 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0xC4:
nextop = F8;
if(rex.is32bits && !(MODREG)) {
DEFAULT;
} else {
if(rex.is32bits) {
DEFAULT;
return addr;
}
vex_t vex = {0};
vex.rex = rex;
u8 = nextop;
vex.m = u8&0b00011111;
vex.rex.b = (u8&0b00100000)?0:1;
vex.rex.x = (u8&0b01000000)?0:1;
vex.rex.r = (u8&0b10000000)?0:1;
u8 = F8;
vex.p = u8&0b00000011;
vex.l = (u8>>2)&1;
vex.v = ((~u8)>>3)&0b1111;
vex.rex.w = (u8>>7)&1;
addr = dynarec64_67_AVX(dyn, addr, ip, ninst, vex, ok, need_epilog);
}
break;
case 0xC5:
nextop = F8;
if(rex.is32bits && !(MODREG)) {
DEFAULT;
} else {
if(rex.is32bits) {
DEFAULT;
return addr;
}
vex_t vex = {0};
vex.rex = rex;
u8 = nextop;
vex.p = u8&0b00000011;
vex.l = (u8>>2)&1;
vex.v = ((~u8)>>3)&0b1111;
vex.rex.r = (u8&0b10000000)?0:1;
vex.rex.b = 0;
vex.rex.x = 0;
vex.rex.w = 0;
vex.m = VEX_M_0F;
addr = dynarec64_67_AVX(dyn, addr, ip, ninst, vex, ok, need_epilog);
}
break;
case 0xC6:
INST_NAME("MOV Eb, Ib");
nextop=F8;
if(MODREG) { // reg <= u8
u8 = F8;
if(!rex.rex) {
ed = (nextop&7);
eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx
eb2 = (ed&4)>>2; // L or H
} else {
eb1 = TO_NAT((nextop & 7) + (rex.b << 3));
eb2 = 0;
}
MOV32w(x3, u8);
BFIx(eb1, x3, eb2*8, 8);
} else { // mem <= u8
addr = geted32(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1);
u8 = F8;
if(u8) {
MOV32w(x3, u8);
ed = x3;
} else
ed = xZR;
STB(ed, wback, fixedaddress);
SMWRITELOCK(lock);
}
break;
case 0xC7:
INST_NAME("MOV Ed, Id");
nextop=F8;
if(MODREG) { // reg <= i32
i64 = F32S;
ed = xRAX+(nextop&7)+(rex.b<<3);
ed = TO_NAT((nextop & 7) + (rex.b << 3));
MOV64xw(ed, i64);
} else { // mem <= i32
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4);
@@ -960,25 +1385,27 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
if(!(dyn->insts[ninst].x64.barrier&BARRIER_FLOAT)) \
fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \
jump_to_next(dyn, addr+i8, 0, ninst); \
jump_to_next(dyn, addr+i8, 0, ninst, rex.is32bits); \
} else { \
CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size);\
SKIP_SEVL(i32); \
B(i32); \
} \
} else { \
/* inside the block */ \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \
Bcond(YES, i32); \
SKIP_SEVL(i32); \
Bcond(YES, i32); \
}
case 0xE0:
INST_NAME("LOOPNZ (32bits)");
READFLAGS(X_ZF);
i8 = F8S;
MOVw_REG(x1, xRCX);
SUBSw_U12(x1, x1, 1);
SUBw_U12(x1, x1, 1);
BFIx(xRCX, x1, 0, 32);
B_NEXT(cEQ); // ECX is 0, no LOOP
CBZw_NEXT(x1); // ECX is 0, no LOOP
TSTw_mask(xFlags, 0b011010, 0); //mask=0x40
GO(cNE, cEQ);
break;
@@ -987,9 +1414,9 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
READFLAGS(X_ZF);
i8 = F8S;
MOVw_REG(x1, xRCX);
SUBSw_U12(x1, x1, 1);
SUBw_U12(x1, x1, 1);
BFIx(xRCX, x1, 0, 32);
B_NEXT(cEQ); // ECX is 0, no LOOP
CBZw_NEXT(x1); // ECX is 0, no LOOP
TSTw_mask(xFlags, 0b011010, 0); //mask=0x40
GO(cEQ, cNE);
break;
@@ -1022,8 +1449,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
GETED32H(x1, 4);
i64 = F32S;
MOV64xw(x2, i64);
emit_test32(dyn, ninst, rex, ed, x2, x3, x4, x5);
emit_test32c(dyn, ninst, rex, ed, i64, x3, x4, x5);
break;
case 2:
INST_NAME("NOT Ed");
@@ -1040,7 +1466,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_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;
@@ -1052,13 +1482,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_RES(xRAX);
UFLAG_OP1(xRDX);
UFLAG_DF(x2, rex.w?d_mul64:d_mul32);
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);
}
}
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;
@@ -1070,15 +1519,29 @@ 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");
SETFLAGS(X_ALL, SF_SET);
if(!rex.w) {
SET_DFNONE(x2);
GETED32(0);
MOVw_REG(x3, xRAX);
ORRx_REG_LSL(x3, x3, xRDX, 32);
@@ -1095,7 +1558,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
&& dyn->insts[ninst-1].x64.addr
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) {
SET_DFNONE(x2);
GETED32(0);
UDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
@@ -1110,16 +1572,28 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVx_REG(xRAX, x2);
SET_DFNONE(x2);
}
}
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) {
SET_DFNONE(x2)
GETSED32w(0);
MOVw_REG(x3, xRAX);
ORRx_REG_LSL(x3, x3, xRDX, 32);
@@ -1132,7 +1606,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
&& dyn->insts[ninst-1].x64.addr
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x48
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) {
SET_DFNONE(x2)
GETED32(0);
SDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
@@ -1149,12 +1622,85 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVx_REG(xRAX, x2);
SET_DFNONE(x2)
}
}
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 0xFF:
nextop = F8;
switch((nextop>>3)&7) {
case 0: // INC Ed
INST_NAME("INC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETED32(0);
emit_inc32(dyn, ninst, rex, ed, x3, x4);
WBACK;
break;
case 1: //DEC Ed
INST_NAME("DEC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETED32(0);
emit_dec32(dyn, ninst, rex, ed, x3, x4);
WBACK;
break;
case 2: // CALL Ed
INST_NAME("CALL Ed");
PASS2IF((BOX64DRENV(dynarec_safeflags)>1) ||
((ninst && dyn->insts[ninst-1].x64.set_flags)
|| ((ninst>1) && dyn->insts[ninst-2].x64.set_flags)), 1)
{
READFLAGS(X_PEND); // that's suspicious
} else {
SETFLAGS(X_ALL, SF_SET_NODF); //Hack to put flag in "don't care" state
}
GETED32(0);
if(BOX64DRENV(dynarec_callret) && BOX64DRENV(dynarec_bigblock)>1) {
BARRIER(BARRIER_FULL);
} else {
BARRIER(BARRIER_FLOAT);
*need_epilog = 0;
*ok = 0;
}
GETIP_(addr);
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;
ADR_S20(x4, j64);
MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2);
} else {
j64 = (dyn->insts)?(GETMARK-(dyn->native_size)):0;
ADR_S20(x4, j64);
MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2);
}
STPx_S7_preindex(x4, xRIP, xSP, -16);
}
PUSH1z(xRIP);
jump_to_next(dyn, 0, ed, ninst, rex.is32bits);
if(BOX64DRENV(dynarec_callret) && addr >= (dyn->start + dyn->isize)) {
// jumps out of current dynablock...
MARK;
j64 = getJumpTableAddress64(addr);
TABLE64(x4, j64);
LDRx_U12(x4, x4, 0);
BR(x4);
}
break;
default:
DEFAULT;
return addr;
}
break;
default:
DEFAULT;
+65 -7
View File
@@ -18,7 +18,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
#define GETGm gd = ((nextop&0x38)>>3)
@@ -61,10 +61,67 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
switch(opcode) {
case 0x89:
INST_NAME("MOV Seg:Ed, Gd");
nextop=F8;
GETGD;
if(MODREG) { // reg <= reg
MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), gd);
} else { // mem <= reg
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;
case 0x8B:
INST_NAME("MOV Gd, Seg:Ed");
nextop=F8;
GETGD;
if(MODREG) { // reg => reg
MOVxw_REG(gd, TO_NAT((nextop & 7) + (rex.b << 3)));
} else { // mem => reg
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;
case 0x8F:
INST_NAME("POP Seg:Ed");
nextop=F8;
if(MODREG) { // reg <= reg
POP1_32(x1);
MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), x1);
} else { // mem <= reg
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
POP1_32(x1);
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, 0);
if(i32<4096 && !(i32&3)) {
LDRw_U12(xRAX, x4, i32);
} else if(i32<256) {
LDURw_I9(xRAX, x4, i32);
} else {
MOV32w(x1, i32);
LDRw_REG(xRAX, x4, x1);
}
break;
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) {
@@ -77,16 +134,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;
+63 -1
View File
@@ -18,7 +18,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
#define GETGm gd = ((nextop&0x38)>>3)
@@ -65,6 +65,68 @@ uintptr_t dynarec64_67_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int
addr = dynarec64_6764_32(dyn, addr, ip, ninst, rex, rep, _FS, ok, need_epilog);
break;
#define GO(NO, YES) \
BARRIER(BARRIER_MAYBE); \
JUMP(addr+i8, 1); \
if(dyn->insts[ninst].x64.jmp_insts==-1 || \
CHECK_CACHE()) { \
/* out of the block */ \
i32 = dyn->insts[ninst].epilog-(dyn->native_size); \
Bcond(NO, i32); \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
if(!(dyn->insts[ninst].x64.barrier&BARRIER_FLOAT)) \
fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \
jump_to_next(dyn, addr+i8, 0, ninst, rex.is32bits); \
} else { \
CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size);\
SKIP_SEVL(i32); \
B(i32); \
} \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \
SKIP_SEVL(i32); \
Bcond(YES, i32); \
}
case 0xE0:
INST_NAME("LOOPNZ (16bits)");
READFLAGS(X_ZF);
i8 = F8S;
UXTHw(x1, xRCX);
SUBw_U12(x1, x1, 1);
BFIx(xRCX, x1, 0, 16);
CBZw_NEXT(x1); // ECX is 0, no LOOP
TSTw_mask(xFlags, 0b011010, 0); //mask=0x40
GO(cNE, cEQ);
break;
case 0xE1:
INST_NAME("LOOPZ (16bits)");
READFLAGS(X_ZF);
i8 = F8S;
UXTHw(x1, xRCX);
SUBw_U12(x1, x1, 1);
BFIx(xRCX, x1, 0, 16);
CBZw_NEXT(x1); // ECX is 0, no LOOP
TSTw_mask(xFlags, 0b011010, 0); //mask=0x40
GO(cEQ, cNE);
break;
case 0xE2:
INST_NAME("LOOP (16bits)");
i8 = F8S;
UXTHw(x1, xRCX);
SUBSw_U12(x1, x1, 1);
BFIx(xRCX, x1, 0, 16);
GO(cEQ, cNE);
break;
case 0xE3:
INST_NAME("JCXZ");
i8 = F8S;
TSTw_mask(xRCX, 0, 15); //mask=0xffff
GO(cNE, cEQ);
break;
#undef GO
default:
DEFAULT;
}
+154
View File
@@ -0,0 +1,154 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
static const char* avx_prefix_string(uint16_t p)
{
switch(p) {
case VEX_P_NONE: return "0";
case VEX_P_66: return "66";
case VEX_P_F2: return "F2";
case VEX_P_F3: return "F3";
default: return "??";
}
}
static const char* avx_map_string(uint16_t m)
{
switch(m) {
case VEX_M_NONE: return "0";
case VEX_M_0F: return "0F";
case VEX_M_0F38: return "0F38";
case VEX_M_0F3A: return "0F3A";
default: return "??";
}
}
uintptr_t dynarec64_67_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed, vd;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
uint64_t tmp64u;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
rex_t rex = vex.rex;
if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2)) {
switch(opcode) {
case 0xF6:
INST_NAME("MULX Gd, Vd, Ed (,RDX)");
nextop = F8;
GETGD;
GETED32(0);
GETVD;
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);
if(gd!=vd) {MOVw_REG(vd, x3);}
LSRx(gd, x3, 32);
}
break;
default:
DEFAULT;
}
}
else if((vex.m==VEX_M_0F) && (vex.p==VEX_P_66)) {
switch(opcode) {
case 0xD6:
INST_NAME("VMOVQ Ex, Gx");
nextop = F8;
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));
VMOV(v1, v0);
YMM0((nextop&7)+(rex.b<<3));
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xfff<<3, 7, rex, NULL, 0, 0);
VSTR64_U12(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) && (BOX64ENV(dynarec_log)>=LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing)==1))
if(!dyn->size || BOX64ENV(dynarec_log)>LOG_INFO || BOX64DRENV(dynarec_dump)) {
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);
}
return addr;
}
+418
View File
@@ -0,0 +1,418 @@
#include <stddef.h>
#include <stdio.h>
#include <signal.h>
#include <ucontext.h>
#include <string.h>
#include "debug.h"
#include "dynablock.h"
#include "x64emu.h"
#include "emu/x64emu_private.h"
#include "x64run.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
seq++;
arch->seq = seq;
} else {
int sz = sizeof_arch_build(build);
if(total+sz>tot_sz) {
printf_log(LOG_INFO, "Warning: populate_arch oversized\n");
return NULL;
}
arch = next;
build_next(arch, build);
seq = 0;
previous = build;
total += sz;
next = (arch_arch_t*)((uintptr_t)arch+sz);
}
}
return p;
}
int getX64AddressInst(dynablock_t* db, uintptr_t x64pc); // define is signal.c
// NZCV N
#define NZCV_N 31
// NZCV Z
#define NZCV_Z 30
// NZCV C
#define NZCV_C 29
// NZCV V
#define NZCV_V 28
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, 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");
}
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;
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef __DYNAREC_ARM_ARCH_H__
#define __DYNAREC_ARM_ARCH_H__
#include <stddef.h>
#include <ucontext.h>
#include "x64emu.h"
#include "box64context.h"
#include "dynarec.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);
//adjust flags and more
void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t x64pc);
// get if instruction can be regenerated for unaligned access
int arch_unaligned(dynablock_t* db, uintptr_t x64pc);
#endif // __DYNAREC_ARM_ARCH_H__
+79
View File
@@ -0,0 +1,79 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
static const char* avx_prefix_string(uint16_t p)
{
switch(p) {
case VEX_P_NONE: return "0";
case VEX_P_66: return "66";
case VEX_P_F2: return "F2";
case VEX_P_F3: return "F3";
default: return "??";
}
}
static const char* avx_map_string(uint16_t m)
{
switch(m) {
case VEX_M_NONE: return "0";
case VEX_M_0F: return "0F";
case VEX_M_0F38: return "0F38";
case VEX_M_0F3A: return "0F3A";
default: return "??";
}
}
uintptr_t dynarec64_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = PK(0);
rex_t rex = vex.rex;
if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_NONE))
addr = dynarec64_AVX_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_NONE))
addr = dynarec64_AVX_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_66))
addr = dynarec64_AVX_66_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F2))
addr = dynarec64_AVX_F2_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F3))
addr = dynarec64_AVX_F3_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_66))
addr = dynarec64_AVX_66_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_66))
addr = dynarec64_AVX_66_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2))
addr = dynarec64_AVX_F2_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_F2))
addr = dynarec64_AVX_F2_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog);
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F3))
addr = dynarec64_AVX_F3_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
else {DEFAULT;}
if((*ok==-1) && (BOX64ENV(dynarec_log)>=LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing)==1))
if(!dyn->size || BOX64ENV(dynarec_log)>LOG_INFO || BOX64DRENV(dynarec_dump)) {
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);
}
return addr;
}
+813
View File
@@ -0,0 +1,813 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "my_cpuid.h"
#include "emu/x87emu_private.h"
#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
uint64_t tmp64u;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
#if STEP > 1
static const int8_t mask_shift8[] = { -7, -6, -5, -4, -3, -2, -1, 0 };
#endif
rex_t rex = vex.rex;
switch(opcode) {
case 0x10:
INST_NAME("VMOVUPS Gx,Ex");
nextop = F8;
GETG;
if(MODREG) {
ed = (nextop&7)+(rex.b<<3);
v1 = sse_get_reg(dyn, ninst, x1, ed, 0);
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
if(v0!=v1) VMOVQ(v0, v1);
if(vex.l) {
v1 = ymm_get_reg(dyn, ninst, x1, ed, 0, gd, -1, -1);
v0 = ymm_get_reg_empty(dyn, ninst, x1, gd, ed, -1, -1);
if(v0!=v1) VMOVQ(v0, v1);
}
} 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);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x11:
INST_NAME("VMOVUPS 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);
if(vex.l) {
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 {
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);
}
SMWRITE2();
}
break;
case 0x12:
nextop = F8;
GETVX(v2, 0);
if(MODREG) {
INST_NAME("VMOVHLPS Gx, Vx, Ex");
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
GETGX_empty(v0);
if((v0!=v2) && (v0!=v1))
VMOVQ(v0, v2);
VMOVeD(v0, 0, v1, 1);
if((v0!=v2) && (v0==v1))
VMOVeD(v0, 1, v2, 1);
} else {
INST_NAME("VMOVLPS Gx, Vx, Ex");
GETGX_empty(v0);
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(v0!=v2)
VMOVQ(v0, v2);
VLD1_64(v0, 0, ed);
}
YMM0(gd);
break;
case 0x13:
nextop = F8;
INST_NAME("VMOVLPS Ex, Vx, 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);
} 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
SMWRITE2();
}
break;
case 0x14:
INST_NAME("VUNPCKLPS Gx, Vx, Ex");
nextop = F8;
SMREAD();
GETGX_empty_VXEX(v0, v2, v1, 0);
VZIP1Q_32(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
VZIP1Q_32(v0, v2, v1);
} else YMM0(gd);
break;
case 0x15:
INST_NAME("VUNPCKHPS Gx, Vx, Ex");
nextop = F8;
SMREAD();
GETGX_empty_VXEX(v0, v2, v1, 0);
VZIP2Q_32(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
VZIP2Q_32(v0, v2, v1);
} else YMM0(gd);
break;
case 0x16:
nextop = F8;
if(MODREG) {
INST_NAME("VMOVLHPS Gx, Vx, Ex");
GETGX(v0, 1);
GETVX(v2, 0);
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
if(v0!=v2 && v0!=v1) VMOVQ(v0, v2);
VMOVeD(v0, 1, v1, 0);
if(v0!=v2 && v0==v1) VMOVeD(v0, 0, v2, 0);
} else {
INST_NAME("VMOVHPS Gx, Vx, Ex");
SMREAD();
GETGX(v0, 1);
GETVX(v2, 0);
if(v0!=v2) VMOVQ(v0, v2);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
VLD1_64(v0, 1, ed);
}
YMM0(gd);
break;
case 0x17:
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);
VMOVeD(v1, 0, v0, 1);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
VST1_64(v0, 1, ed);
}
break;
case 0x28:
INST_NAME("VMOVAPS Gx, Ex");
nextop = F8;
GETG;
if(MODREG) {
ed = (nextop&7)+(rex.b<<3);
v1 = sse_get_reg(dyn, ninst, x1, ed, 0);
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VMOVQ(v0, v1);
if(vex.l) {
GETGY_empty_EY(v0, v1);
VMOVQ(v0, v1);
}
} 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);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x29:
INST_NAME("VMOVAPS 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);
if(vex.l) {
GETGYEY_empty(v0, v1);
VMOVQ(v1, v0);
}
} 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);
}
SMWRITE2();
}
break;
case 0x2B:
INST_NAME("VMOVNTPS 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);
if(vex.l) {
GETGYEY_empty(v0, v1);
VMOVQ(v1, v0);
}
} 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);
}
}
break;
case 0x2E:
// no special check...
case 0x2F:
if(opcode==0x2F) {INST_NAME("VCOMISS Gx, Ex");} else {INST_NAME("VUCOMISS Gx, Ex");}
SETFLAGS(X_ALL, SF_SET_NODF);
nextop = F8;
GETGX(v0, 0);
GETEXSS(s0, 0, 0);
FCMPS(v0, s0);
FCOMI(x1, x2);
break;
case 0x50:
INST_NAME("VMOVMSPKPS Gd, Ex");
nextop = F8;
GETGD;
MOV32w(gd, 0);
if(MODREG) {
// EX is an xmm reg
q0 = fpu_get_scratch(dyn, ninst);
for(int l=0; l<1+vex.l; ++l) {
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);
BFIx(gd, x1, 0+(l*4), 1);
LSRx(x1, x1, 16);
BFIx(gd, x1, 1+(l*4), 1);
LSRx(x1, x1, 16);
BFIx(gd, x1, 2+(l*4), 1);
LSRx(x1, x1, 16);
BFIx(gd, x1, 3+(l*4), 1);
}
} else {
// EX is memory
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, (0xfff<<3)-24, 7, rex, NULL, 0, 0);
for(int l=0; l<1+vex.l; ++l) {
LDRx_U12(x1, 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);
BFIx(gd, x1, 2+(l*4), 1);
LSRx(x1, x1, 32);
BFIx(gd, x1, 3+(l*4), 1);
}
}
break;
case 0x51:
INST_NAME("VSQRTPS Gx, Ex");
nextop = F8;
SKIPTEST(x1);
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(!vex.l) YMM0(gd);
break;
case 0x52:
INST_NAME("VRSQRTPS Gx, Ex");
nextop = F8;
SKIPTEST(x1);
v0 = fpu_get_scratch(dyn, ninst);
VFMOVSQ_8(v0, 0b01110000); //1.0f
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_EX(q0, q1, 0); } else { GETGY_empty_EY(q0, q1); }
#if 0
// the aproximation doesn't not work on Death Stranding. code around 0x1419c9100 fail...
if(!l) {
if(q1==q0)
v1 = fpu_get_scratch(dyn, ninst);
else
v1 = q1;
}
// more precise
VFRSQRTEQS(v0, q1);
VFMULQS(v1, v0, q1);
VFRSQRTSQS(v1, v1, v0);
VFMULQS(q0, v1, v0);
#else
VFSQRTQS(q0, q1);
VFDIVQS(q0, v0, q0);
#endif
}
if(!vex.l) YMM0(gd);
break;
case 0x53:
INST_NAME("VRCPPS Gx, Ex");
nextop = F8;
SKIPTEST(x1);
q0 = fpu_get_scratch(dyn, ninst);
VFMOVSQ_8(q0, 0b01110000); //1.0f
for(int l=0; l<1+vex.l; ++l) {
if(!l) {
GETGX_empty_EX(v0, v1, 0);
#if 0
if(v0==v1)
q1 = fpu_get_scratch(dyn, ninst);
#endif
} else {
GETGY_empty_EY(v0, v1);
}
#if 0
if(v0!=v1) q1 = v0;
VFRECPEQS(q0, v1);
VFRECPSQS(q1, q0, v1);
VFMULQS(v0, q0, q1);
#else
VFDIVQS(v0, q0, v1);
#endif
}
if(!vex.l) YMM0(gd);
break;
case 0x54:
INST_NAME("VANDPS Gx, Vx, Ex");
nextop = F8;
GETGX_empty_VXEX(v0, v2, v1, 0);
VANDQ(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
VANDQ(v0, v2, v1);
} else YMM0(gd)
break;
case 0x55:
INST_NAME("VANDNPS Gx, Vx, Ex");
nextop = F8;
GETGX_empty_VXEX(v0, v2, v1, 0);
VBICQ(v0, v1, v2);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
VBICQ(v0, v1, v2);
} else YMM0(gd)
break;
case 0x56:
INST_NAME("VORPS Gx, Vx, Ex");
nextop = F8;
GETGX_empty_VXEX(v0, v2, v1, 0);
VORRQ(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
VORRQ(v0, v2, v1);
} else YMM0(gd)
break;
case 0x57:
INST_NAME("VXORPS Gx, Vx, Ex");
nextop = F8;
GETGX_empty_VXEX(v0, v2, v1, 0);
VEORQ(v0, v2, v1);
if(vex.l) {
GETGY_empty_VYEY(v0, v2, v1);
VEORQ(v0, v2, v1);
} else YMM0(gd)
break;
case 0x58:
INST_NAME("VADDPS 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
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFADDQS(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 0x59:
INST_NAME("VMULPS 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
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFMULQS(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 0x5A:
INST_NAME("VCVTPS2PD Gx, Ex");
nextop = F8;
GETGX_empty_EX(v0, v1, 0);
if(vex.l) {
GETGY_empty(q0, -1, -1, -1);
FCVTL2(q0, v1);
} else YMM0(gd)
FCVTL(v0, v1);
break;
case 0x5B:
INST_NAME("VCVTDQ2PS Gx, Ex");
nextop = F8;
GETGX_empty_EX(v0, v1, 0);
SCVTQFS(v0, v1);
if(vex.l) {
GETGY_empty_EY(v0, v1);
SCVTQFS(v0, v1);
} else YMM0(gd)
break;
case 0x5C:
INST_NAME("VSUBPS 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
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFSUBQS(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 0x5D:
INST_NAME("VMINPS Gx, Vx, Ex");
nextop = F8;
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(!BOX64ENV(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(!vex.l) YMM0(gd);
break;
case 0x5E:
INST_NAME("VDIVPS 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
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(q0, q0, q0); // 0 if NAN, 1 if not NAN
}
VFDIVQS(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 0x5F:
INST_NAME("VMAXPS Gx, Vx, Ex");
nextop = F8;
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(!BOX64ENV(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(!vex.l) YMM0(gd);
break;
case 0x77:
if(!vex.l) {
INST_NAME("VZEROUPPER");
if(vex.v!=0) {
UDF(0);
} else {
for(int i=0; i<(rex.is32bits?8:16); ++i) {
YMM0(i);
}
}
} else {
INST_NAME("VZEROALL");
if(vex.v!=0) {
UDF(0);
} else {
for(int i=0; i<(rex.is32bits?8:16); ++i) {
v0 = sse_get_reg_empty(dyn, ninst, x1, i);
VEORQ(v0, v0, v0);
YMM0(i);
}
}
}
break;
case 0xAE:
nextop = F8;
if(MODREG) {
DEFAULT;
} else
switch((nextop>>3)&7) {
case 2:
INST_NAME("VLDMXCSR Md");
GETED(0);
STRw_U12(ed, xEmu, offsetof(x64emu_t, mxcsr));
if(BOX64ENV(sse_flushto0)) {
MRS_fpcr(x2); // get fpscr
LSRw_IMM(x3, ed, 15); // get FZ bit
BFIw(x2, x3, 24, 1); // inject FZ bit
EORw_REG_LSR(x3, x3, ed, 1); // FZ xor DAZ
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:
INST_NAME("VSTMXCSR Md");
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));
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
}
STW(x4, ed, fixedaddress);
break;
default:
DEFAULT;
}
break;
case 0xC2:
INST_NAME("VCMPPS Gx, Vx, Ex, Ib");
nextop = F8;
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)) {
VFMAXQS(q0, v2, v1); // propagate NAN
VFCMEQQS(((u8&15)==7)?v0:q0, q0, q0); // 0 if NAN, 1 if not NAN
}
switch(u8&0xf) {
// the inversion of the params in the comparison is there to handle NaN the same way SSE does
case 0x00: VFCMEQQS(v0, v2, v1); break; // Equal, not unordered
case 0x01: VFCMGTQS(v0, v1, v2); break; // Less than
case 0x02: VFCMGEQS(v0, v1, v2); break; // Less or equal
case 0x03: VMVNQ(v0, q0); break; // unordered
case 0x04: VFCMEQQS(v0, v2, v1); VMVNQ(v0, v0); break; // Not Equal (or unordered on ARM, not on X86...)
case 0x05: VFCMGTQS(v0, v1, v2); VMVNQ(v0, v0); break; // Greater or equal or unordered
case 0x06: VFCMGEQS(v0, v1, v2); VMVNQ(v0, v0); break; // Greater or unordered
case 0x07: break; // ordered
case 0x08: VFCMEQQS(v0, v2, v1); VORNQ(v0, v0, q0); break; // Equal, or unordered
case 0x09: VFCMGTQS(v0, v1, v2); VORNQ(v0, v0, q0); break; // Less than or unordered
case 0x0a: VFCMGEQS(v0, v1, v2); VORNQ(v0, v0, q0); break; // Less or equal or unordered
case 0x0b: VEORQ(v0, v0, v0); break; // false
case 0x0c: VFCMEQQS(v0, v2, v1); VBICQ(v0, q0, v0); break;
case 0x0d: VFCMGEQS(v0, v2, v1); break;
case 0x0e: VFCMGTQS(v0, v2, v1); break;
case 0x0f: MOVIQ_64(v0, 0xff); break; //true
}
}
if(!vex.l) YMM0(gd);
break;
case 0xC6:
INST_NAME("VSHUFPS Gx, Vx, Ex, Ib");
nextop = F8;
GETVX(v2, 0);
if(!MODREG) {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
v1 = -1; // to avoid a warning
} else
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
GETGX_empty(v0);
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)) { // elements 3 2 0 0
VMOVQ(v0, v2);
VMOVeS(v0, 1, v0, 0);
} else if(v2==v1 && (u8==0xe5)) { // elements 3 2 1 1
VMOVQ(v0, v2);
VMOVeS(v0, 0, v0, 1);
} 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) { // elements 3 1 3 1
VUZP2Q_32(v0, v2, v1);
} else {
if((v0==v1) || (v0==v2)) {
d0 = fpu_get_scratch(dyn, ninst); s0 = 0;
} else {
d0 = v0; s0 = 1;
}
// first two elements from Vx
for(int i=0; i<2; ++i) {
VMOVeS(d0, i, v2, (u8>>(i*2))&3);
}
// second two from Ex
if(MODREG) {
for(int i=2; i<4; ++i) {
VMOVeS(d0, i, v1, (u8>>(i*2))&3);
}
} else {
SMREAD();
for(int i=2; i<4; ++i) {
ADDx_U12(x2, ed, ((u8>>(i*2))&3)*4);
VLD1_32(d0, i, x2);
}
}
if(v0!=d0) VMOVQ(v0, d0);
}
if(vex.l) {
if(MODREG)
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0, gd, vex.v, -1);
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)) { // elements 3 2 0 0
VMOVQ(v0, v2);
VMOVeS(v0, 1, v0, 0);
} else if(v2==v1 && (u8==0xe5)) { // elements 3 2 1 1
VMOVQ(v0, v2);
VMOVeS(v0, 0, v0, 1);
} 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) { // elements 3 1 3 1
VUZP2Q_32(v0, v2, v1);
} else {
if(s0) d0 = v0;
for(int i=0; i<2; ++i) {
VMOVeS(d0, i, v2, (u8>>(i*2))&3);
}
if(MODREG) {
for(int i=2; i<4; ++i) {
VMOVeS(d0, i, v1, (u8>>(i*2))&3);
}
} else {
SMREAD();
for(int i=2; i<4; ++i) {
ADDx_U12(x2, ed, 16+((u8>>(i*2))&3)*4);
VLD1_32(d0, i, x2);
}
}
VMOVQ(v0, d0);
}
} else YMM0(gd);
break;
default:
DEFAULT;
}
return addr;
}
+302
View File
@@ -0,0 +1,302 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "my_cpuid.h"
#include "emu/x87emu_private.h"
#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed, vd;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
int need_tst;
uint64_t tmp64u;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
rex_t rex = vex.rex;
switch(opcode) {
case 0xF2:
INST_NAME("ANDN Gd, Vd, Ed");
nextop = F8;
SETFLAGS(X_ALL, SF_SET);
GETGD;
GETED(0);
GETVD;
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) {
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_SF) {
IFNATIVE(NF_SF) {} else {
LSRxw_IMM(x1, gd, rex.w?63:31);
BFIw(xFlags, x1, F_SF, 1);
}
}
break;
case 0xF3:
nextop = F8;
switch((nextop>>3)&7) {
case 1:
INST_NAME("BLSR 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;
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;
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;
}
break;
case 0xF5:
INST_NAME("BZHI Gd, Ed, Vd");
nextop = F8;
SETFLAGS(X_ALL, SF_SET);
GETGD;
GETED(0);
GETVD;
UXTBw(x1, vd);
CMPSw_U12(x1, rex.w?64:32);
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;
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);
} else
BICxw(gd, ed, x2);
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1);
}
}
IFX(X_SF) {
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) 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:
DEFAULT;
}
return addr;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,835 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "my_cpuid.h"
#include "emu/x87emu_private.h"
#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
uint64_t tmp64u;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
#if STEP > 1
static const int8_t round_round[] = { 0, 2, 1, 3};
#endif
rex_t rex = vex.rex;
switch(opcode) {
case 0x00:
case 0x01:
if(opcode) {INST_NAME("VPERMPD Gx, Ex, Imm8");} else {INST_NAME("VPERMQ Gx, Ex, Imm8");}
nextop = F8;
GETGX_empty_EX(v0, q0, 1);
u8 = F8;
if(v0==q0) d0 = fpu_get_scratch(dyn, ninst);
if(v0==q0 || !MODREG) d1 = fpu_get_scratch(dyn, ninst);
q1 = d1;
GETGY_empty_EY(v1, q1);
if(v0==q0) { VMOVQ(d0, q0); VMOVQ(d1, q1); } else {d1 = q1; d0 = q0;}
VMOVeD(v0, 0, ((u8>>1)&1)?d1:d0, (u8>>0)&1);
VMOVeD(v0, 1, ((u8>>3)&1)?d1:d0, (u8>>2)&1);
VMOVeD(v1, 0, ((u8>>5)&1)?d1:d0, (u8>>4)&1);
VMOVeD(v1, 1, ((u8>>7)&1)?d1:d0, (u8>>6)&1);
break;
case 0x02:
INST_NAME("VPBLENDD Gx, Vx, Ex, u8");
nextop = F8;
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); u8 >>=4;}
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(v0==v1) {
VBIFQ(v0, v2, q0);
} else {
if(v0!=v2) VMOVQ(v0, v2);
VBITQ(v0, v1, q0);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x04:
INST_NAME("VPERMILPS Gx, Ex, Imm8");
nextop = F8;
for(int l=0; l<1+vex.l; ++l) {
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==0x00 || u8==0x55 || u8==0xAA || u8==0xFF)
VDUPQ_32(v0, (v0==v1)?q1:v1, u8&3);
else if(u8==0x50)
VZIP1Q_32(v0, v1, v1);
else if(u8==0xFA)
VZIP2Q_32(v0, v1, v1);
else if(u8==0xA0)
VTRNQ1_32(v0, v1, v1);
else if(u8==0xF5)
VTRNQ2_32(v0, v1, v1);
else for(int i=0; i<4; ++i)
VMOVeS(v0, i, (v0==v1)?q1:v1, (u8>>(i*2))&3);
}
if(!vex.l) YMM0(gd);
break;
case 0x05:
INST_NAME("VPERMILD Gx, Ex, Imm8");
nextop = F8;
for(int l=0; l<1+vex.l; ++l) {
if(!l) {
GETGX_empty_EX(v0, v1, 1);
u8 = F8;
} else {
GETGY_empty_EY(v0, v1);
}
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;
case 0x06:
case 0x46:
if(opcode==0x06) { INST_NAME("VPERM2F128 Gx, Vx, Ex, Imm8"); } else { INST_NAME("VPERM2I128 Gx, Vx, Ex, Imm8"); }
nextop = F8;
if(!vex.l) UDF(0);
if(MODREG) {
s0 = (nextop&7)+(rex.b<<3);
v1 = sse_get_reg(dyn, ninst, x1, s0, 0);
} else {
s0 = -1;
v1 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
}
u8 = F8;
GETVX(v2, 0);
GETGX_empty(v0);
if((v0==v2) && ((u8&0xf0)==0)) {
q0 = fpu_get_scratch(dyn, ninst);
VMOVQ(q0, v2);
v2 = q0;
}
if((v0==v1) && ((u8&0xf0)==0x20)) {
q1 = fpu_get_scratch(dyn, ninst);
VMOVQ(q1, v1);
v1 = q1;
}
switch(u8&0x0f) {
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;
case 3: if(MODREG) { d1 = ymm_get_reg(dyn, ninst, x1, s0, 0, gd, vex.v, -1); VMOVQ(v0, d1); } else { VLDR128_U12(v0, ed, fixedaddress+16); } break;
default: VEORQ(v0, v0, v0);
}
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) {
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;
case 3: if(MODREG) { if(v0!=d1) VMOVQ(v0, d1); } else { VLDR128_U12(v0, ed, fixedaddress+16); } break;
default: VEORQ(v0, v0, v0);
}
break;
case 0x08:
INST_NAME("VROUNDPS Gx, Ex, Ib");
nextop = F8;
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_EX(v0, v1, 1); u8 = F8; } else { GETGY_empty_EY(v0, v1); }
if(u8&4) {
if(!l) wb1 = sse_setround(dyn, ninst, x1, x2, x4);
VFRINTISQ(v0, v1);
if(l || !vex.l) x87_restoreround(dyn, ninst, wb1);
} else {
VFRINTRSQ(v0, v1, round_round[u8&3]);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x09:
INST_NAME("VROUNDPD Gx, Ex, Ib");
nextop = F8;
for(int l=0; l<1+vex.l; ++l) {
if(!l) { GETGX_empty_EX(v0, v1, 1); u8 = F8; } else { GETGY_empty_EY(v0, v1); }
if(u8&4) {
if(!l) wb1 = sse_setround(dyn, ninst, x1, x2, x4);
VFRINTIDQ(v0, v1);
if(l || !vex.l) x87_restoreround(dyn, ninst, wb1);
} else {
VFRINTRDQ(v0, v1, round_round[u8&3]);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x0A:
INST_NAME("VROUNDSS Gx, Vx, Ex, Ib");
nextop = F8;
GETEXSS(v1, 0, 1);
GETGX_empty_VX(v0, v2);
u8 = F8;
d1 = fpu_get_scratch(dyn, ninst);
if(u8&4) {
u8 = sse_setround(dyn, ninst, x1, x2, x3);
FRINTXS(d1, v1);
x87_restoreround(dyn, ninst, u8);
} else {
FRINTRRS(d1, v1, round_round[u8&3]);
}
if(v0!=v2) VMOVQ(v0, v2);
VMOVeS(v0, 0, d1, 0);
YMM0(gd);
break;
case 0x0B:
INST_NAME("VROUNDSD Gx, Vx, Ex, Ib");
nextop = F8;
GETEXSD(v1, 0, 1);
GETGX_empty_VX(v0, v2);
u8 = F8;
d1 = fpu_get_scratch(dyn, ninst);
if(u8&4) {
u8 = sse_setround(dyn, ninst, x1, x2, x3);
FRINTXD(d1, v1);
x87_restoreround(dyn, ninst, u8);
} else {
FRINTRRD(d1, v1, round_round[u8&3]);
}
if(v0!=v2) VMOVQ(v0, v2);
VMOVeD(v0, 0, d1, 0);
YMM0(gd);
break;
case 0x0C:
INST_NAME("VBLENDPS Gx, Vx, Ex, Ib");
nextop = F8;
GETGX_empty_VXEX(q0, q2, q1, 1);
u8 = F8;
if((u8&0xf)==0xf) {
if(q0!=q1) VMOVQ(q0, q1);
} else if(q0==q1) {
for(int i=0; i<4; ++i)
if(u8&(1<<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) {
VMOVeD(q0, 0, q1, 0);
} else if((u8&15)==0b1100) {
VMOVeD(q0, 1, q1, 1);
} else for(int i=0; i<4; ++i)
if(u8&(1<<i)) {
VMOVeS(q0, i, q1, i);
}
}
if(vex.l) {
GETGY_empty_VYEY(q0, q2, q1);
if((u8&0xf0)==0xf0) {
if(q0!=q1) VMOVQ(q0, q1);
} else if(q0==q1) {
for(int i=0; i<4; ++i)
if(u8&(1<<(i+4))) {
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) {
VMOVeD(q0, 0, q1, 0);
} else if((u8>>4)==0b1100) {
VMOVeD(q0, 1, q1, 1);
} else for(int i=0; i<4; ++i)
if(u8&(1<<(i+4))) {
VMOVeS(q0, i, q1, i);
}
}
} else YMM0(gd);
break;
case 0x0D:
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) {
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]
case 0b11: if(q0!=q1) VMOVQ(q0, q1); break; // ExEx
}
}
if(!vex.l) YMM0(gd);
break;
case 0x0E:
INST_NAME("VPBLENDW Gx, Vx, Ex, u8");
nextop = F8;
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(!l) {
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(!vex.l) YMM0(gd);
break;
case 0x0F:
INST_NAME("VPALIGNR Gx, Vx, Ex, Ib");
nextop = F8;
d0 = 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>31) {
VEORQ(v0, v0, v0);
} else if(u8>15) {
if(!l) VEORQ(d0, d0, d0);
VEXTQ_8(v0, v2, d0, u8-16);
} else {
VEXTQ_8(v0, v1, v2, u8);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x14:
INST_NAME("VPEXTRB Ed, Gx, imm8");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff, 0, rex, NULL, 0, 1);
ed = x1;
}
u8 = F8;
VMOVBto(ed, v0, u8&0x0f);
if(!MODREG) {
STB(ed, wback, fixedaddress);
}
break;
case 0x15:
INST_NAME("VPEXTRW Ed, Gx, imm8");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 1);
ed = x1;
}
u8 = F8;
VMOVHto(ed, v0, u8&7);
if(!MODREG) {
STH(ed, wback, fixedaddress);
}
break;
case 0x16:
INST_NAME("VPEXTRD/Q Ed, Gx, imm8");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 1);
ed = x1;
}
u8 = F8;
if(rex.w) {
VMOVQDto(ed, v0, u8&1);
} else {
VMOVSto(ed, v0, u8&3);
}
if(!MODREG) {
STxw(ed, wback, fixedaddress);
}
break;
case 0x17:
INST_NAME("VEXTRACTPS Ed, Gx, imm8");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 1);
ed = x1;
}
u8 = F8;
VMOVSto(ed, v0, u8&3);
if(!MODREG) {
STW(ed, wback, fixedaddress);
}
break;
case 0x18:
case 0x38:
if(opcode==0x18) {INST_NAME("VINSERTF128 Gx, Vx, Ex, imm8");} else {INST_NAME("VINSERTI128 Gx, Vx, Ex, imm8");}
nextop = F8;
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 1);
v1 = -1; // to avoid a warning
}
u8 = F8;
GETVX(v2, 0);
GETGX_empty(v0);
if(v0==v2 && u8==1) {
GETGY_empty(q0, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);
q2 = q0;
} else {
GETGY_empty_VY(q0, q2, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);
}
if(MODREG)
VMOVQ((u8&1)?q0:v0, v1);
else
VLD128((u8&1)?q0:v0, ed, fixedaddress);
if(v0!=v2)
VMOVQ((u8&1)?v0:q0, (u8&1)?v2:q2);
break;
case 0x19:
case 0x39:
if(opcode==0x19) {INST_NAME("VEXTRACTF128 Ex, Gx, imm8");} else {INST_NAME("VEXTRACTI128 Ex, Gx, imm8");}
nextop = F8;
u8 = geted_ib(dyn, addr, ninst, nextop);
GETGX(v0, 0);
if(u8&1) {GETGY(v0, ((nextop&7)+(rex.b<<3)==gd && MODREG)?1:0, -1, -1, -1);}
if(MODREG) {
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7)+(rex.b<<3));
VMOVQ(v1, v0);
if((nextop&7)+(rex.b<<3)==gd && (u8&1))
VEORQ(v0, v0, v0); // special case like vextractf128 xmm3, ymm3, 0x01
else
YMM0((nextop&7)+(rex.b<<3));
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 1);
VST128(v0, ed, fixedaddress);
}
F8; // read u8, but it's been already handled
break;
case 0x1D:
INST_NAME("VCVTPS2PH Ex, Gx");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
v1 = sse_get_reg_empty(dyn, ninst, x3, (nextop&7)+(rex.b<<3));
} else {
v1 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<(3+vex.l), vex.l?15:7, rex, NULL, 0, 1);
}
if(vex.l && v0==v1) {
q0 = fpu_get_scratch(dyn, ninst);
VMOVQ(q0, v0);
v0 = q0;
}
u8 = F8;
if(u8&4) {
s0 = sse_setround(dyn, ninst, x1, x2, x6);
} else {
u8&=3;
if(u8==1) u8=2;
else if(u8==2) u8=1;
MRS_fpcr(x1); // get fpscr
MOV32w(x2, u8);
MOVx_REG(x6, x1);
BFIx(x1, x2, 22, 2); // inject new round
MSR_fpcr(x1); // put new fpscr
s0 = x6;
}
FCVTN16(v1, v0);
if(vex.l) {
GETGY(v0, 0, MODREG?((nextop&7)+(rex.b<<3)):-1, -1,-1);
FCVTN162(v1, v0);
}
x87_restoreround(dyn, ninst, s0);
if(MODREG) {
YMM0((nextop&7)+(rex.b<<3));
} else {
if(vex.l) {
VST128(v1, ed, fixedaddress);
} else {
VST64(v1, ed, fixedaddress);
}
SMWRITE2();
}
break;
case 0x20:
INST_NAME("VINSERTD Gx, Vx, Ex, Ib");
nextop = F8;
GETGX_empty_VX(v0, v2);
GETED(1);
u8 = F8;
if(v0!=v2) VMOVQ(v0, v2);
VMOVQBfrom(v0, u8&0xf, ed);
YMM0(gd);
break;
case 0x21:
INST_NAME("VINSERTPS Gx, Vx, Ex, Ib");
nextop = F8;
if (MODREG) {
GETGX_empty_VXEX(v0, v2, v1, 1);
u8 = F8;
if(v0==v1) {
d0 = fpu_get_scratch(dyn, ninst);
VMOVQ(d0, v1);
if(v0!=v2) VMOVQ(v0, v2);
VMOVeS(v0, (u8>>4)&3, d0, (u8>>6)&3);
} else {
if(v0!=v2) VMOVQ(v0, v2);
VMOVeS(v0, (u8>>4)&3, v1, (u8>>6)&3);
}
} else {
GETGX_empty_VX(v0, v2);
if(v0!=v2) VMOVQ(v0, v2);
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 1);
u8 = F8;
LDW(x2, wback, fixedaddress);
VMOVQSfrom(v0, (u8>>4)&3, x2);
}
uint8_t zmask = u8 & 0xf;
for (uint8_t i=0; i<4; i++) {
if (zmask & (1<<i)) {
VMOVQSfrom(v0, i, wZR);
}
}
YMM0(gd);
break;
case 0x22:
INST_NAME("VINSERTD Gx, Vx, Ex, Ib");
nextop = F8;
GETGX_empty_VX(v0, v2);
GETED(1);
u8 = F8;
if(v0!=v2) VMOVQ(v0, v2);
if(rex.w)
VMOVQDfrom(v0, u8&1, ed);
else
VMOVQSfrom(v0, u8&3, ed);
YMM0(gd);
break;
case 0x40:
INST_NAME("VDPPS Gx, Vx, Ex, Ib");
nextop = F8;
u8 = geted_ib(dyn, addr, ninst, nextop);
q0 = fpu_get_scratch(dyn, ninst);
// first mask
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);
if((u8&0xf0)!=0xf0) {
VANDQ(v0, v0, q1); // second mask
}
VFADDPQS(v0, v0, v0);
FADDPS(v0, v0);
VDUPQ_32(v0, v0, 0);
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);
}
if(!vex.l) YMM0(gd);
break;
case 0x44:
INST_NAME("PCLMULQDQ Gx, Vx, Ex, Ib");
nextop = F8;
if(arm64_pmull) {
d0 = 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);
}
switch (u8&0b00010001) {
case 0b00000000:
PMULL_128(v0, v2, v1);
break;
case 0b00010001:
PMULL2_128(v0, v2, v1);
break;
case 0b00000001:
VEXTQ_8(d0, v2, v2, 8); // Swap Up/Lower 64bits parts
PMULL_128(v0, d0, v1);
break;
case 0b00010000:
VEXTQ_8(d0, v2, v2, 8); // Swap Up/Lower 64bits parts
PMULL2_128(v0, d0, v1);
break;
}
}
} 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);
}
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);
}
}
if(!vex.l) YMM0(gd);
break;
//case 0x46: // see 0x06
case 0x4A:
INST_NAME("VBLENDVPS Gx, Vx, Ex, XMMImm8");
nextop = F8;
q0 = fpu_get_scratch(dyn, ninst);
u8 = geted_ib(dyn, addr, ninst, nextop)>>4;
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);
if(MODREG)
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 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);
}
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(!vex.l) YMM0(gd);
break;
case 0x4B:
INST_NAME("VBLENDVPD Gx, Vx, Ex, XMMImm8");
nextop = F8;
q0 = fpu_get_scratch(dyn, ninst);
u8 = geted_ib(dyn, addr, ninst, nextop)>>4;
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);
if(MODREG)
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 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);
}
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(!vex.l) YMM0(gd);
break;
case 0x4C:
INST_NAME("VBLENDPVB Gx, Vx, Ex, XMMImm8");
nextop = F8;
q0 = fpu_get_scratch(dyn, ninst);
u8 = geted_ib(dyn, addr, ninst, nextop)>>4;
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);
if(MODREG)
v1 = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 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);
}
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(!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);
if(!vex.l) YMM0(gd);
break;
default:
DEFAULT;
}
return addr;
}
+554
View File
@@ -0,0 +1,554 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "my_cpuid.h"
#include "emu/x87emu_private.h"
#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed, vd;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
uint64_t tmp64u, u64;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
rex_t rex = vex.rex;
switch(opcode) {
case 0x10:
INST_NAME("VMOVSD Gx, [Vx,] Ex");
nextop = F8;
GETG;
if(MODREG) {
GETGX_empty_VXEX(v0, v2, v1, 0);
if(v0!=v1) VMOVeD(v0, 0, v1, 0);
if(v0!=v2) VMOVeD(v0, 1, v2, 1);
} else {
SMREAD();
GETGX_empty(v0);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v0, ed, fixedaddress); // upper part reseted
}
YMM0(gd);
break;
case 0x11:
INST_NAME("VMOVSD Ex, Vx, Gx");
nextop = F8;
GETG;
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
if(MODREG) {
GETVXEX(v2, 0, v1, 1, 0);
if(v0!=v1) VMOVeD(v1, 0, v0, 0);
if(v1!=v2) VMOVeD(v1, 1, v2, 1);
YMM0((nextop&7)+(rex.b<<3));
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v0, ed, fixedaddress);
SMWRITE2();
}
break;
case 0x12:
INST_NAME("VMOVDDUP Gx, Ex");
nextop = F8;
GETG;
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
GETGX_empty(v0);
VDUPQ_64(v0, v1, 0);
if(vex.l) {
GETGY_empty_EY(v0, v1);
VDUPQ_64(v0, v1, 0);
}
} else {
SMREAD();
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
VLDQ1R_64(v0, ed);
if(vex.l) {
GETGY_empty(v0, -1, -1, -1);
ADDx_U12(x3, ed, 16);
VLDQ1R_64(v0, x3);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x2A:
INST_NAME("VCVTSI2SD Gx, Vx, Ed");
nextop = F8;
GETGX_empty_VX(v0, v1);
GETED(0);
d1 = fpu_get_scratch(dyn, ninst);
if(rex.w) {
SCVTFDx(d1, ed);
} else {
SCVTFDw(d1, ed);
}
if(v0!=v1) VMOVQ(v0, v1);
VMOVeD(v0, 0, d1, 0);
YMM0(gd);
break;
case 0x2C:
INST_NAME("VCVTTSD2SI Gd, Ex");
nextop = F8;
GETGD;
GETEXSD(q0, 0, 0);
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
}
FCVTZSxwD(gd, q0);
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
ORRx_mask(gd, xZR, 1, 1, 0); //0x8000000000000000
} else {
MOV32w(gd, 0x80000000);
}
}
break;
case 0x2D:
INST_NAME("VCVTSD2SI Gd, Ex");
nextop = F8;
GETGD;
GETEXSD(q0, 0, 0);
if(!BOX64ENV(dynarec_fastround)) {
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);
x87_restoreround(dyn, ninst, u8);
FCVTZSxwD(gd, d1);
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
ORRx_mask(gd, xZR, 1, 1, 0); //0x8000000000000000
} else {
MOV32w(gd, 0x80000000);
}
}
break;
case 0x51:
INST_NAME("VSQRTSD Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
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(!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
VORR(d1, d1, q1); // NAN -> -NAN
}
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeD(v0, 0, d1, 0);
YMM0(gd)
break;
case 0x58:
INST_NAME("VADDSD Gx, Vx, Ex");
nextop = F8;
q2 = fpu_get_scratch(dyn, ninst);
GETEXSD(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
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, q2, 0);
YMM0(gd)
break;
case 0x59:
INST_NAME("VMULSD Gx, Vx, Ex");
nextop = F8;
q2 = fpu_get_scratch(dyn, ninst);
GETEXSD(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
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, q2, 0);
YMM0(gd);
break;
case 0x5A:
INST_NAME("VCVTSD2SS Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
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);
}
VMOVeS(v0, 0, d1, 0);
YMM0(gd)
break;
case 0x5C:
INST_NAME("VSUBSD Gx, Vx, Ex");
nextop = F8;
q2 = fpu_get_scratch(dyn, ninst);
GETEXSD(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
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, q2, 0);
YMM0(gd)
break;
case 0x5D:
INST_NAME("VMINSD Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
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);
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeD(v0, 0, d1, 0); // to not erase uper part
YMM0(gd)
break;
case 0x5E:
INST_NAME("VDIVSD Gx, Vx, Ex");
nextop = F8;
q2 = fpu_get_scratch(dyn, ninst);
GETEXSD(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
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, q2, 0);
YMM0(gd)
break;
case 0x5F:
INST_NAME("VMAXSD Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FCMPD(v1, v2);
FCSELD(d1, v1, v2, cCS);
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeD(v0, 0, d1, 0); // to not erase uper part
YMM0(gd)
break;
case 0x70:
INST_NAME("VPSHUFLW Gx, Ex, Ib");
nextop = F8;
d0 = fpu_get_scratch(dyn, ninst);
for(int l=0; l<1+vex.l; ++l) {
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);
}
VDUP_16(v0, v1, u8&3);
if(v0==v1)
v1 = d0;
} else {
// only low part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
if(!l) {
u64 = 0;
for (int i=0; i<4; ++i) {
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+0)<<(i*16+0);
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+1)<<(i*16+8);
}
MOV64x(x2, u64);
}
VMOVQDfrom(d0, 0, x2);
VTBL1_8(d0, v1, d0);
VMOVeD(v0, 0, d0, 0);
}
if(v0!=v1) {
VMOVeD(v0, 1, v1, 1);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x7C:
INST_NAME("VHADDPS Gx, Vx, Ex");
nextop = F8;
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); }
VFADDPQS(v0, v2, v1);
}
if(!vex.l) YMM0(gd);
break;
case 0x7D:
INST_NAME("VHSUBPS Gx, Vx, Ex");
nextop = F8;
q0 = fpu_get_scratch(dyn, ninst);
if(MODREG || (v1==v2)) {
q1 = fpu_get_scratch(dyn, ninst);
} else
q1 = v1;
if(vex.l)
q2 = fpu_get_scratch(dyn, ninst);
else
q2 = q0;
// q0 will contains -1 / 0 / -1 / 0
MOVIQ_64(q0, 0xf0);
VSHLQ_32(q0, q0, 31); // keep sign bit
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); }
VEORQ(q1, v1, q0);
VEORQ(q2, v2, q0);
VFADDPQS(v0, q2, q1);
}
if(!vex.l) YMM0(gd);
break;
case 0xC2:
INST_NAME("CMPSD Gx, Ex, Ib");
nextop = F8;
GETEXSD(v1, 0, 1);
GETGX_empty_VX(v0, v2);
u8 = F8;
FCMPD(v2, v1);
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
}
VMOVQDfrom(v0, 0, x2);
YMM0(gd);
break;
case 0xD0:
INST_NAME("VADDSUBPS Gx, Vx, Ex");
nextop = F8;
q0 = fpu_get_scratch(dyn, ninst);
static float addsubps[4] = {-1.f, 1.f, -1.f, 1.f};
MAYUSE(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); } else { GETGY_empty_VYEY(v0, v2, v1); }
if(v0==v1) {
//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);
}
}
if(!vex.l) YMM0(gd);
break;
case 0xE6:
INST_NAME("VCVTPD2DQ Gx, Ex");
nextop = F8;
u8 = sse_setround(dyn, ninst, x1, x2, x6);
for(int l=0; l<1+vex.l; ++l) {
if(!l) {
GETEX_Y(v1, 0, 0);
GETGX_empty(v0);
if(!BOX64ENV(dynarec_fastround) || vex.l)
d0 = fpu_get_scratch(dyn, ninst);
} else {
GETEY(v1);
}
if(BOX64ENV(dynarec_fastround)) {
VFRINTIDQ(l?d0:v0, v1);
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);
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);
}
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);
}
}
x87_restoreround(dyn, ninst, u8);
YMM0(gd);
break;
case 0xF0:
INST_NAME("LDDQU Gx,Ex");
nextop = F8;
GETG;
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VMOVQ(v0, v1);
if(vex.l) {
GETGY_empty_EY(v0, v1);
VMOVQ(v0, v1);
}
} else {
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
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);
}
if(!vex.l) YMM0(gd);
break;
default:
DEFAULT;
}
return addr;
}
@@ -0,0 +1,131 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "my_cpuid.h"
#include "emu/x87emu_private.h"
#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_AVX_F2_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed, vd;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
uint64_t tmp64u;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
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;
GETGD;
GETED(0);
GETVD;
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);
if(gd!=vd) {MOVw_REG(vd, x3);}
LSRx(gd, x3, 32);
}
break;
case 0xF7:
INST_NAME("SHRX Gd, Ed, Vd");
nextop = F8;
GETGD;
GETED(0);
GETVD;
ANDx_mask(x3, vd, 1, 0, rex.w?5:4); // mask 0x3f/0x1f
LSRxw_REG(gd, ed, x3);
break;
default:
DEFAULT;
}
return addr;
}
@@ -0,0 +1,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "my_cpuid.h"
#include "emu/x87emu_private.h"
#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_AVX_F2_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed, vd;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
uint64_t tmp64u;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
rex_t rex = vex.rex;
switch(opcode) {
case 0xF0:
INST_NAME("RORX Gd, Ed, Ib");
nextop = F8;
GETGD;
GETED(1);
u8 = F8;
u8&=rex.w?0x3f:0x1f;
RORxw(gd, ed, u8);
break;
default:
DEFAULT;
}
return addr;
}
+582
View File
@@ -0,0 +1,582 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "my_cpuid.h"
#include "emu/x87emu_private.h"
#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed, vd;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
uint64_t tmp64u, u64;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
rex_t rex = vex.rex;
switch(opcode) {
case 0x10:
INST_NAME("VMOVSS Gx, Ex [,Vx]");
nextop = F8;
GETG;
if(MODREG) {
GETGX_empty_VXEX(v0, v2, v1, 0);
if((v0!=v2) && (v0!=v1)) VMOVQ(v0, v2);
if(v0!=v1) VMOVeS(v0, 0, v1, 0);
if((v0!=v2) && (v0==v1)) { VMOVeS(v0, 1, v2, 1); VMOVeD(v0, 1, v2, 1);}
} else {
GETGX_empty(v0);
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v0, ed, fixedaddress);
}
YMM0(gd);
break;
case 0x11:
INST_NAME("VMOVSS Ex, Gx [,Vx]");
nextop = F8;
GETG;
if(MODREG) {
GETGXVXEX_empty(v0, v2, v1, 0);
if((v2!=v1) && (v2!=v0)) VMOVQ(v2, v1);
if(v2!=v0) VMOVeS(v2, 0, v0, 0);
if((v2!=v1) && (v2==v0)) { VMOVeS(v2, 1, v0, 1); VMOVeD(v2, 1, v0, 1);}
YMM0((nextop&7)+(rex.b<<3));
} else {
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VST32(v0, ed, fixedaddress);
SMWRITE2();
}
break;
case 0x12:
INST_NAME("VMOVSLDUP Gx, Ex");
nextop = F8;
GETEX_Y(q1, 0, 0);
GETGX_empty(q0);
VTRNQ1_32(q0, q1, q1);
if(vex.l) {
GETGY_empty_EY(q0, q1);
VTRNQ1_32(q0, q1, q1);
} else YMM0(gd);
break;
case 0x16:
INST_NAME("MOVSHDUP Gx, Ex");
nextop = F8;
GETEX_Y(q1, 0, 0);
GETGX_empty(q0);
VTRNQ2_32(q0, q1, q1);
if(vex.l) {
GETGY_empty_EY(q0, q1);
VTRNQ2_32(q0, q1, q1);
} else YMM0(gd);
break;
case 0x2A:
INST_NAME("VCVTSI2SS Gx, Vx, Ed");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
GETGX_empty_VX(v0, v1);
GETED(0);
if(rex.w) {
SCVTFSx(d1, ed);
} else {
SCVTFSw(d1, ed);
}
if(v0!=v1) VMOVQ(v0, v1);
VMOVeS(v0, 0, d1, 0);
YMM0(gd);
break;
case 0x2C:
INST_NAME("VCVTTSS2SI Gd, Ex");
nextop = F8;
GETGD;
GETEXSS(d0, 0, 0);
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
}
FCVTZSxwS(gd, d0);
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
ORRx_mask(gd, xZR, 1, 1, 0); //0x8000000000000000
} else {
ORRw_mask(gd, xZR, 1, 0); //0x80000000
}
}
break;
case 0x2D:
INST_NAME("VCVTSS2SI Gd, Ex");
nextop = F8;
GETGD;
GETEXSS(q0, 0, 0);
if(!BOX64ENV(dynarec_fastround)) {
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);
x87_restoreround(dyn, ninst, u8);
FCVTZSxwS(gd, d1);
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
ORRx_mask(gd, xZR, 1, 1, 0); //0x8000000000000000
} else {
ORRw_mask(gd, xZR, 1, 0); //0x80000000
}
}
break;
case 0x51:
INST_NAME("SQRTSS Gx, Ex");
nextop = F8;
GETEXSS(d0, 0, 0);
GETGX_empty_VX(v0, v2);
d1 = fpu_get_scratch(dyn, ninst);
FSQRTS(d1, d0);
if(v0!=v2) VMOVQ(v0, v2);
VMOVeS(v0, 0, d1, 0);
YMM0(gd);
break;
case 0x52:
INST_NAME("VRSQRTSS Gx, Vx Ex");
nextop = F8;
GETGX(v0, 1);
GETVX(v2, 0);
GETEXSS(v1, 0, 0);
d0 = fpu_get_scratch(dyn, ninst);
d1 = fpu_get_scratch(dyn, ninst);
// so here: F32: Imm8 = abcd efgh that gives => aBbbbbbc defgh000 00000000 00000000
// and want 1.0f = 0x3f800000
// so 00111111 10000000 00000000 00000000
// a = 0, b = 1, c = 1, d = 1, efgh=0
// 0b01110000
FMOVS_8(d0, 0b01110000);
FSQRTS(d1, v1);
FDIVS(d0, d0, d1);
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeS(v0, 0, d0, 0);
YMM0(gd);
break;
case 0x53:
INST_NAME("VRCPSS Gx, Vx, Ex");
nextop = F8;
GETGX(v0, 1);
GETVX(v2, 0);
GETEXSS(v1, 0, 0);
d0 = fpu_get_scratch(dyn, ninst);
FMOVS_8(d0, 0b01110000); //1.0f
FDIVS(d0, d0, v1);
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeS(v0, 0, d0, 0);
YMM0(gd);
break;
case 0x58:
INST_NAME("VADDSS Gx, Vx, Ex");
nextop = F8;
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) {
VMOVQ(v0, v2);
}
VMOVeS(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x59:
INST_NAME("VMULSS Gx, Vx, Ex");
nextop = F8;
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) {
VMOVQ(v0, v2);
}
VMOVeS(v0, 0, q2, 0);
YMM0(gd)
break;
case 0x5A:
INST_NAME("VCVTSS2SD Gx, Vx, Ex");
nextop = F8;
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);
YMM0(gd);
break;
case 0x5B:
INST_NAME("VCVTTPS2DQ Gx, Ex");
nextop = F8;
d0 = fpu_get_scratch(dyn, ninst);
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(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(!vex.l) YMM0(gd);
break;
case 0x5C:
INST_NAME("VSUBSS Gx, Vx, Ex");
nextop = F8;
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
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, q2, 0);
YMM0(gd)
break;
case 0x5D:
INST_NAME("VMINSS Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FCMPS(v2, v1);
FCSELS(d1, v1, v2, cCS);
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeS(v0, 0, d1, 0); // to not erase uper part
YMM0(gd)
break;
case 0x5E:
INST_NAME("VDIVSS Gx, Vx, Ex");
nextop = F8;
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
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, q2, 0);
YMM0(gd)
break;
case 0x5F:
INST_NAME("VMAXSS Gx, Vx, Ex");
nextop = F8;
d1 = fpu_get_scratch(dyn, ninst);
GETEXSS(v1, 0, 0);
GETGX_empty_VX(v0, v2);
FCMPS(v1, v2);
FCSELS(d1, v1, v2, cCS);
if(v0!=v2) {
VMOVQ(v0, v2);
}
VMOVeS(v0, 0, d1, 0); // to not erase uper part
YMM0(gd)
break;
case 0x6F:
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);
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);
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);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x70:
INST_NAME("VPSHUFHW Gx, Ex, Ib");
nextop = F8;
d0 = fpu_get_scratch(dyn, ninst);
for(int l=0; l<1+vex.l; ++l) {
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 {
// only high part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
if(!l) {
u64 = 0;
for (int i=0; i<4; ++i) {
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+8)<<(i*16+0);
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+9)<<(i*16+8);
}
MOV64x(x2, u64);
}
VMOVQDfrom(d0, 0, x2);
VTBL1_8(d0, v1, d0);
}
VMOVeD(v0, 1, d0, 0);
if(v0!=v1) {
VMOVeD(v0, 0, v1, 0);
}
}
if(!vex.l) YMM0(gd);
break;
case 0x7E:
INST_NAME("MOVQ Gx, Ex");
nextop = F8;
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 0);
GETGX_empty(v0);
FMOVD(v0, v1);
} else {
GETGX_empty(v0);
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v0, ed, fixedaddress);
}
YMM0(gd);
break;
case 0x7F:
INST_NAME("VMOVDQU Ex, Gx");
nextop = F8;
GETGX(v0, 0);
if(MODREG) {
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3));
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);
VMOVQ(v1, v0);
} // no ymm raz here it seems
} else {
IF_UNALIGNED(ip) {
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(wback!=x1) {
MOVx_REG(x1, wback);
wback = x1;
}
for(int i=0; i<16; ++i) {
VST1_8(v0, i, wback);
ADDx_U12(wback, wback, 1);
}
if(vex.l) {
GETGY(v0, 0, -1, -1, -1);
for(int i=0; i<16; ++i) {
VST1_8(v0, i, wback);
ADDx_U12(wback, wback, 1);
}
}
} 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);
}
}
SMWRITE2();
}
break;
case 0xC2:
INST_NAME("VCMPSS Gx, Vx, Ex, Ib");
nextop = F8;
GETEXSS(v1, 0, 1);
GETGX_empty_VX(v0, v2);
u8 = F8;
if(((u8&15)!=11) && ((u8&15)!=15)) {
if((u8&15)>7)
FCMPS(v1, v2);
else
FCMPS(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&15) {
case 0x00: CSETMw(x2, cEQ); break; // Equal
case 0x01: CSETMw(x2, cCC); break; // Less than
case 0x02: CSETMw(x2, cLS); break; // Less or equal
case 0x03: CSETMw(x2, cVS); break; // NaN
case 0x04: CSETMw(x2, cNE); break; // Not Equal or unordered
case 0x05: CSETMw(x2, cCS); break; // Greater or equal or unordered
case 0x06: CSETMw(x2, cHI); break; // Greater or unordered
case 0x07: CSETMw(x2, cVC); break; // not NaN
case 0x08: CSETMw(x2, cEQ); CSETMw(x3, cVS); ORRw_REG(x2, x2, x3); break; // Equal or unordered
case 0x09: CSETMw(x2, cHI); break; // Less than or unordered
case 0x0a: CSETMw(x2, cCS); break; // Less or equal or unordered
case 0x0b: MOV32w(x2, 0); break; // false
case 0x0c: CSETMw(x2, cNE); CSETMw(x3, cVS); BICw(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: MOV32w(x2, 0xffffffff); break; // true
}
VMOVQSfrom(v0, 0, x2);
YMM0(gd);
break;
case 0xE6:
INST_NAME("VCVTDQ2PD Gx, Ex");
nextop = F8;
if(vex.l) {
GETEX_Y(v1, 0, 0);
} else {
GETEXSD(v1, 0, 0);
}
GETGX_empty(v0);
d0 = fpu_get_scratch(dyn, ninst);
if(vex.l) {
q0 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1, -1);
SXTL2_32(q0, v1);
SCVTQFD(q0, q0);
} else YMM0(gd);
SXTL_32(v0, v1);
SCVTQFD(v0, v0);
break;
default:
DEFAULT;
}
return addr;
}
@@ -0,0 +1,107 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include "debug.h"
#include "box64context.h"
#include "dynarec.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 "my_cpuid.h"
#include "emu/x87emu_private.h"
#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_AVX_F3_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
uint8_t gd, ed, vd;
uint8_t wback, wb1, wb2;
uint8_t eb1, eb2, gb1, gb2;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1, v2;
int q0, q1, q2;
int d0, d1, d2;
int s0;
uint64_t tmp64u;
int64_t j64;
int64_t fixedaddress;
int unscaled;
MAYUSE(wb1);
MAYUSE(wb2);
MAYUSE(eb1);
MAYUSE(eb2);
MAYUSE(gb1);
MAYUSE(gb2);
MAYUSE(q0);
MAYUSE(q1);
MAYUSE(d0);
MAYUSE(d1);
MAYUSE(s0);
MAYUSE(j64);
MAYUSE(cacheupd);
rex_t rex = vex.rex;
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;
GETGD;
GETED(0);
GETVD;
ANDx_mask(x3, vd, 1, 0, rex.w?5:4); // mask 0x3f/0x1f
ASRxw_REG(gd, ed, x3);
break;
default:
DEFAULT;
}
return addr;
}
+165 -114
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -29,6 +29,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;
@@ -38,6 +39,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(v2);
MAYUSE(v1);
if(MODREG)
switch(nextop) {
case 0xC0:
case 0xC1:
@@ -50,11 +52,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xC8:
case 0xC9:
@@ -67,11 +73,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xD0:
case 0xD1:
@@ -121,11 +131,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xE8:
case 0xE9:
@@ -138,11 +152,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xF0:
case 0xF1:
@@ -155,11 +173,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xF8:
case 0xF9:
@@ -172,125 +194,154 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FADD ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
s0 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(ST_IS_F(0)) {
FADDS(v1, v1, s0);
} else {
FCVT_D_S(s0, s0);
FADDD(v1, v1, s0);
}
break;
case 1:
INST_NAME("FMUL ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
s0 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(ST_IS_F(0)) {
FMULS(v1, v1, s0);
} else {
FCVT_D_S(s0, s0);
FMULD(v1, v1, s0);
}
break;
case 2:
INST_NAME("FCOM ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
s0 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(ST_IS_F(0)) {
FCMPS(v1, s0);
} else {
FCVT_D_S(s0, s0);
FCMPD(v1, s0);
}
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FCOMP ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
s0 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(ST_IS_F(0)) {
FCMPS(v1, s0);
} else {
FCVT_D_S(s0, s0);
FCMPD(v1, s0);
}
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FSUB ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
s0 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(ST_IS_F(0)) {
FSUBS(v1, v1, s0);
} else {
FCVT_D_S(s0, s0);
FSUBD(v1, v1, s0);
}
break;
case 5:
INST_NAME("FSUBR ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
s0 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(ST_IS_F(0)) {
FSUBS(v1, s0, v1);
} else {
FCVT_D_S(s0, s0);
FSUBD(v1, s0, v1);
}
break;
case 6:
INST_NAME("FDIV ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
s0 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(ST_IS_F(0)) {
FDIVS(v1, v1, s0);
} else {
FCVT_D_S(s0, s0);
FDIVD(v1, v1, s0);
}
break;
case 7:
INST_NAME("FDIVR ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
s0 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(s0, ed, fixedaddress);
if(ST_IS_F(0)) {
FDIVS(v1, s0, v1);
} else {
FCVT_D_S(s0, s0);
FDIVD(v1, s0, v1);
}
break;
default:
DEFAULT;
}
}
DEFAULT;
break;
} else
switch((nextop>>3)&7) {
case 0:
INST_NAME("FADD ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 1:
INST_NAME("FMUL ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 2:
INST_NAME("FCOM ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
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(ST_IS_F(0)) {
FCMPS(v1, s0);
} else {
FCVT_D_S(s0, s0);
FCMPD(v1, s0);
}
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FCOMP ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
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(ST_IS_F(0)) {
FCMPS(v1, s0);
} else {
FCVT_D_S(s0, s0);
FCMPD(v1, s0);
}
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FSUB ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 5:
INST_NAME("FSUBR ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 6:
INST_NAME("FDIV ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 7:
INST_NAME("FDIVR ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
default:
DEFAULT;
}
return addr;
}
+227 -112
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -31,7 +31,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
uint8_t ed;
uint8_t wback, wb1;
uint8_t u8;
int64_t fixedaddress;
int64_t fixedaddress, j64;
int unscaled;
int v1, v2;
int s0;
@@ -41,6 +41,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(v2);
MAYUSE(v1);
if(MODREG)
switch(nextop) {
case 0xC0:
case 0xC1:
@@ -131,18 +132,109 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xE5:
INST_NAME("FXAM");
#if 1
i1 = x87_get_current_cache(dyn, ninst, 0, NEON_CACHE_ST_D);
// value put in x14
if(i1==-1) {
if(fpu_is_st_freed(dyn, ninst, 0)) {
MOV32w(x4, 0b100000100000000);
B_MARK3_nocond;
} else {
// not in cache, so check Empty status and load it
i2 = -dyn->n.x87stack;
LDRw_U12(x3, xEmu, offsetof(x64emu_t, fpu_stack));
if(i2) {
if(i2<0) {
ADDw_U12(x3, x3, -i2);
} else {
SUBw_U12(x3, x3, i2);
}
}
CMPSw_U12(x3, 0);
MOV32w(x4, 0b100000100000000); // empty: C3,C2,C0 = 101
B_MARK3(cLE);
// x5 will be the actual top
LDRw_U12(x5, xEmu, offsetof(x64emu_t, top));
if(i2) {
if(i2<0) {
SUBw_U12(x5, x5, -i2);
} else {
ADDw_U12(x5, x5, i2);
}
ANDw_mask(x5, x5, 0, 2); // (emu->top + i)&7
}
// load x2 with ST0 anyway, for sign extraction
ADDx_REG_LSL(x1, xEmu, x5, 3);
LDRx_U12(x2, x1, offsetof(x64emu_t, x87));
// load tag
if(i2>=0) {
LDRH_U12(x3, xEmu, offsetof(x64emu_t, fpu_tags));
if(i2>0) {
ORRw_mask(x3, x3, 0b010000, 0b001111); // 0xffff0000
LSRw_IMM(x3, x3, i2*2);
}
TSTw_mask(x3, 0, 1); // 0b11
B_MARK3(cNE); // empty: C3,C2,C0 = 101
}
}
} else {
// simply move from cache reg to x2
v1 = dyn->n.x87reg[i1];
VMOVQDto(x2, v1, 0);
}
// get exponant in x1
LSRx_IMM(x1, x2, 20+32);
ANDSx_mask(x1, x1, 1, 0b00000, 0b001010); // 0x7ff
B_MARK(cNE); // not zero or denormal
ANDSx_mask(x1, x2, 1, 0, 0b111110); // 0x7fffffffffffffff
MOV32w(x4, 0b100000000000000); // Zero: C3,C2,C0 = 100
MOV32w(x5, 0b100010000000000); // Denormal: C3,C2,C0 = 110
CSELx(x4, x4, x5, cEQ);
B_MARK3(c__);
MARK;
CMPSx_U12(x1, 0x7ff); // infinite/NaN?
MOV32w(x5, 0b000010000000000); // normal: C3,C2,C0 = 010
CSELx(x4, x5, x4, cNE);
B_MARK3(cNE);
TSTx_mask(x2, 1, 0b000000, 0b110011); // 0x000fffffffffffff
MOV32w(x4, 0b000010100000000); // infinity: C3,C2,C0 = 011
MOV32w(x3, 0b000000100000000); // NaN: C3,C2,C0 = 001
CSELx(x4, x4, x3, cEQ);
MARK3;
// Extract signa & Update SW
LSRx_IMM(x1, x2, 63);
BFIx(x4, x1, 9, 1); //C1
LDRH_U12(x1, xEmu, offsetof(x64emu_t, sw));
MOV32w(x2, 0b01000111);
BICw_REG_LSL(x1, x1, x2, 8);
ORRw_REG(x4, x4, x1);
STRH_U12(x4, xEmu, offsetof(x64emu_t, sw));
#else
MESSAGE(LOG_DUMP, "Need Optimization\n");
x87_refresh(dyn, ninst, x1, x2, 0);
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(fpu_fxam, -1); // should be possible inline, but is it worth it?
x87_unstackcount(dyn, ninst, x1, i1);
#endif
break;
case 0xE8:
INST_NAME("FLD1");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
if(ST_IS_F(0)) {
FMOVS_8(v1, 0b01110000);
if(ninst<dyn->size+2 && (dyn->insts[ninst+1].pred_sz==1) && (dyn->insts[ninst+2].pred_sz==1)
&& PK(0)==0xD9 && PK(1)==0xE8
&& PK(2)==0xD9 && PK(3)==0xF3
) {
MESSAGE(LOG_DUMP, "Hack for FLD1 FLD1 FPATAN");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
FTABLE64(v1, PI/4.0);
addr+=4;
} else {
FMOVD_8(v1, 0b01110000);
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
if(ST_IS_F(0)) {
FMOVS_8(v1, 0b01110000);
} else {
FMOVD_8(v1, 0b01110000);
}
}
break;
case 0xE9:
@@ -178,7 +270,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);
@@ -186,7 +278,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);
@@ -196,13 +288,17 @@ 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 emiting 1\n");
MESSAGE(LOG_DUMP, "Optimized next DD D8 fstp st0, st0, not emitting 1\n");
u8 = F8;
u8 = F8;
} else {
@@ -216,17 +312,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);
@@ -235,8 +335,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);
@@ -245,7 +345,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
#else
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
s0 = fpu_get_scratch(dyn);
s0 = fpu_get_scratch(dyn, ninst);
FDIVD(s0, v1, v2);
FRINTRRD(s0, s0, 0b00); // Nearest == TieToEven?
FCVTZSxD(x4, s0);
@@ -293,7 +393,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
#else
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
s0 = fpu_get_scratch(dyn);
s0 = fpu_get_scratch(dyn, ninst);
FDIVD(s0, v1, v2);
FRINTZD(s0, s0);
FCVTZSxD(x4, s0);
@@ -315,7 +415,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);
@@ -326,19 +426,27 @@ 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);
}
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:
@@ -361,115 +469,122 @@ 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;
case 0xD1:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD7:
case 0xE2:
case 0xE3:
case 0xE6:
case 0xE7:
case 0xEF:
default:
DEFAULT;
break;
default:
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);
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)) {
FCVT_D_S(v1, v1);
}
break;
case 2:
INST_NAME("FST float[ED], ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
if(ST_IS_F(0))
s0 = v1;
else {
s0 = fpu_get_scratch(dyn);
FCVT_S_D(s0, v1);
}
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VST32(s0, ed, fixedaddress);
break;
case 3:
INST_NAME("FSTP float[ED], ST0");
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)) {
FCVT_S_D(v1, v1);
}
VST32(v1, ed, fixedaddress);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FLDENV Ed");
MESSAGE(LOG_DUMP, "Need Optimization\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);
}
MOV32w(x2, 0);
CALL(fpu_loadenv, -1);
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
break;
case 6:
INST_NAME("FNSTENV Ed");
MESSAGE(LOG_DUMP, "Need Optimization\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);
}
MOV32w(x2, 0);
CALL(fpu_savenv, -1);
break;
case 7:
INST_NAME("FNSTCW Ew");
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
ed = x1;
wb1 = 1;
LDRH_U12(x1, xEmu, offsetof(x64emu_t, cw));
EWBACK;
break;
default:
DEFAULT;
}
}
} else
switch((nextop>>3)&7) {
case 0:
INST_NAME("FLD ST0, float[ED]");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, BOX64ENV(dynarec_x87double)?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)) {
FCVT_D_S(v1, v1);
}
break;
case 2:
INST_NAME("FST float[ED], ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
if(ST_IS_F(0))
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);
break;
case 3:
INST_NAME("FSTP float[ED], ST0");
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 (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) {
MOVx_REG(x1, ed);
}
MOV32w(x2, 0);
CALL(fpu_loadenv, -1);
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
break;
case 6:
INST_NAME("FNSTENV Ed");
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) {
MOVx_REG(x1, ed);
}
MOV32w(x2, 0);
CALL(fpu_savenv, -1);
break;
case 7:
INST_NAME("FNSTCW Ew");
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
ed = x1;
wb1 = 1;
LDRH_U12(x1, xEmu, offsetof(x64emu_t, cw));
EWBACK;
break;
default:
DEFAULT;
}
return addr;
}
+114 -99
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -29,6 +29,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;
@@ -42,6 +43,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(ed);
MAYUSE(j64);
if(MODREG)
switch(nextop) {
case 0xC0:
case 0xC1:
@@ -134,106 +136,119 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE4:
case 0xF0:
case 0xF1:
case 0xF4:
case 0xF5:
case 0xF6:
case 0xF7:
case 0xF8:
case 0xF9:
case 0xFD:
default:
DEFAULT;
break;
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FIADD ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FADDD(v1, v1, v2);
break;
case 1:
INST_NAME("FIMUL ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FMULD(v1, v1, v2);
break;
case 2:
INST_NAME("FICOM ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FCMPD(v1, v2);
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FICOMP ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FCMPD(v1, v2);
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FISUB ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FSUBD(v1, v1, v2);
break;
case 5:
INST_NAME("FISUBR ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FSUBD(v1, v2, v1);
break;
case 6:
INST_NAME("FIDIV ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FDIVD(v1, v1, v2);
break;
case 7:
INST_NAME("FIDIVR ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FDIVD(v1, v2, v1);
break;
}
}
} else
switch((nextop>>3)&7) {
case 0:
INST_NAME("FIADD ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 1:
INST_NAME("FIMUL ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 2:
INST_NAME("FICOM ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FCMPD(v1, v2);
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FICOMP ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v2, ed, fixedaddress);
SXTL_32(v2, v2); // i32 -> i64
SCVTFDD(v2, v2); // i64 -> double
FCMPD(v1, v2);
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FISUB ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 5:
INST_NAME("FISUBR ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 6:
INST_NAME("FIDIV ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 7:
INST_NAME("FIDIVR ST0, Ed");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
}
return addr;
}
+127 -123
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -42,6 +42,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(v1);
MAYUSE(j64);
if(MODREG)
switch(nextop) {
case 0xC0:
case 0xC1:
@@ -126,14 +127,13 @@ 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);
break;
@@ -176,152 +176,161 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCOMI(x1, x2);
break;
case 0xE0:
case 0xE4:
case 0xE5:
case 0xE6:
case 0xE7:
default:
DEFAULT;
break;
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FILD ST0, Ed");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v1, ed, fixedaddress);
SXTL_32(v1, v1); // i32 -> i64
SCVTFDD(v1, v1); // i64 -> double
break;
case 1:
INST_NAME("FISTTP Ed, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
s0 = fpu_get_scratch(dyn);
#if 0
ed = x1;
} else
switch((nextop>>3)&7) {
case 0:
INST_NAME("FILD ST0, Ed");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v1, ed, fixedaddress);
SXTL_32(v1, v1); // i32 -> i64
SCVTFDD(v1, v1); // i64 -> double
break;
case 1:
INST_NAME("FISTTP Ed, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
s0 = fpu_get_scratch(dyn, ninst);
if(arm64_frintts) {
FRINT32ZD(s0, v1);
FCVTZSwD(ed, s0);
WBACK;
#else
FCVTZSwD(x5, s0);
STW(x5, wback, fixedaddress);
} 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;
#endif
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FIST Ed, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
u8 = x87_setround(dyn, ninst, x1, x2, x4); // x1 have the modified RPSCR reg
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
s0 = fpu_get_scratch(dyn);
#if 0
ed = x1;
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FIST Ed, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
u8 = x87_setround(dyn, ninst, x1, x2, x4); // x1 have the modified RPSCR reg
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
s0 = fpu_get_scratch(dyn, ninst);
if(arm64_frintts) {
FRINT32XD(s0, v1);
FCVTZSwD(ed, s0);
WBACK;
#else
FCVTZSwD(x5, s0);
STW(x5, wback, fixedaddress);
} 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;
#endif
x87_restoreround(dyn, ninst, u8);
break;
case 3:
INST_NAME("FISTP Ed, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
u8 = x87_setround(dyn, ninst, x1, x2, x4); // x1 have the modified RPSCR reg
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
s0 = fpu_get_scratch(dyn);
#if 0
ed = x1;
}
x87_restoreround(dyn, ninst, u8);
break;
case 3:
INST_NAME("FISTP Ed, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
u8 = x87_setround(dyn, ninst, x1, x2, x4); // x1 have the modified RPSCR reg
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
s0 = fpu_get_scratch(dyn, ninst);
if(arm64_frintts) {
FRINT32XD(s0, v1);
FCVTZSwD(ed, s0);
WBACK;
#else
FCVTZSwD(x5, s0);
STW(x5, wback, fixedaddress);
} 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;
#endif
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 5:
INST_NAME("FLD tbyte");
}
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 5:
INST_NAME("FLD tbyte");
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if((PK(0)==0xDB && ((PK(1)>>3)&7)==7) || (!rex.is32bits && PK(0)>=0x40 && PK(0)<=0x4f && PK(1)==0xDB && ((PK(2)>>3)&7)==7)) {
NOTEST(x5);
// the FLD is immediatly followed by an FSTP
LDRx_U12(x5, ed, 0);
LDRH_U12(x6, ed, 8);
// no persistant scratch register, so unrool both instruction here...
MESSAGE(LOG_DUMP, "\tHack: FSTP tbyte\n");
nextop = F8; // 0xDB or rex
if(!rex.is32bits && nextop>=0x40 && nextop<=0x4f) {
rex.rex = nextop;
nextop = F8; //0xDB
} else
rex.rex = 0;
nextop = F8; //modrm
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if((PK(0)==0xDB && ((PK(1)>>3)&7)==7) || (PK(0)>=0x40 && PK(0)<=0x4f && PK(1)==0xDB && ((PK(2)>>3)&7)==7)) {
// the FLD is immediatly followed by an FSTP
LDRx_U12(x5, ed, 0);
LDRH_U12(x6, ed, 8);
// no persistant scratch register, so unrool both instruction here...
MESSAGE(LOG_DUMP, "\tHack: FSTP tbyte\n");
nextop = F8; // 0xDB or rex
if(nextop>=0x40 && nextop<=0x4f) {
rex.rex = nextop;
nextop = F8; //0xDB
} else
rex.rex = 0;
nextop = F8; //modrm
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
STRx_U12(x5, ed, 0);
STRH_U12(x6, ed, 8);
STRx_U12(x5, ed, 0);
STRH_U12(x6, ed, 8);
} else {
if(BOX64ENV(x87_no80bits)) {
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
VLDR64_U12(v1, ed, fixedaddress);
} else {
if(box64_x87_no80bits) {
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
VLDR64_U12(v1, ed, fixedaddress);
} else {
if(ed!=x1) {
MOVx_REG(x1, ed);
}
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3);
CALL(native_fld, -1);
}
}
break;
case 7:
INST_NAME("FSTP tbyte");
if(box64_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);
}
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
// sync top
x87_reflectcount(dyn, ninst, x3, x4);
CALL(native_fld, -1);
// go back with the top & stack counter
x87_unreflectcount(dyn, ninst, x3, x4);
}
}
break;
case 7:
INST_NAME("FSTP tbyte");
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(!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);
#else
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);
@@ -340,22 +349,18 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
// get exp
LSRx(x3, x1, 52); // x3 = exp11
ANDw_mask(x3, x3, 0, 0b1010); //0x7ff
MOV32w(x4, 0x7ff);
CMPSw_REG(x3, x4);
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
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
ORRx_mask(x5, x1, 1, 1, 0); //0x8000000000000000
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?
CBZw(x3, 4+4*4); // exp11 == 0?
// normals
ADDw_REG(x3, x3, x4); // x3 = exp16
ORRw_REG(x3, x3, x5); // x3 = sign | exp
@@ -370,13 +375,12 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MARK3;
STRx_U12(x5, wback, 0);
STRH_U12(x3, wback, 8);
#endif
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
DEFAULT;
}
}
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
DEFAULT;
}
return addr;
}
+123 -71
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -29,6 +29,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;
@@ -36,6 +37,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(v2);
MAYUSE(v1);
if(MODREG)
switch(nextop) {
case 0xC0:
case 0xC1:
@@ -48,11 +50,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xC8:
case 0xC9:
@@ -65,11 +71,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xD0:
case 0xD1:
@@ -119,11 +129,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xE8:
case 0xE9:
@@ -136,11 +150,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xF0:
case 0xF1:
@@ -153,11 +171,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 0xF8:
case 0xF9:
@@ -170,82 +192,112 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FADD ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
FADDD(v1, v1, v2);
break;
case 1:
INST_NAME("FMUL ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
FMULD(v1, v1, v2);
break;
case 2:
INST_NAME("FCOM ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
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);
break;
case 3:
INST_NAME("FCOMP ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
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);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FSUB ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
FSUBD(v1, v1, v2);
break;
case 5:
INST_NAME("FSUBR ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
FSUBD(v1, v2, v1);
break;
case 6:
INST_NAME("FDIV ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
FDIVD(v1, v1, v2);
break;
case 7:
INST_NAME("FDIVR ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v2, wback, fixedaddress);
FDIVD(v1, v2, v1);
break;
}
}
DEFAULT;
break;
} else
switch((nextop>>3)&7) {
case 0:
INST_NAME("FADD ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 1:
INST_NAME("FMUL ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 2:
INST_NAME("FCOM ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
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);
FCMPD(v1, v2);
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FCOMP ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
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);
FCMPD(v1, v2);
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FSUB ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 5:
INST_NAME("FSUBR ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 6:
INST_NAME("FDIV ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
case 7:
INST_NAME("FDIVR ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
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);
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
break;
}
return addr;
}
+91 -105
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -40,6 +40,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(v1);
MAYUSE(j64);
if(MODREG)
switch(nextop) {
case 0xC0:
case 0xC1:
@@ -50,10 +51,20 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xC6:
case 0xC7:
INST_NAME("FFREE STx");
#if 1
if((nextop&7)==0 && PK(0)==0xD9 && PK(1)==0xF7) {
MESSAGE(LOG_DUMP, "Hack for FFREE ST0 / FINCSTP\n");
x87_do_pop(dyn, ninst, x1);
addr+=2;
SKIPTEST(x1);
} else
x87_free(dyn, ninst, x1, x2, x3, nextop&7);
#else
MESSAGE(LOG_DUMP, "Need Optimization\n");
x87_purgecache(dyn, ninst, 0, x1, x2, x3);
MOV32w(x1, nextop&7);
CALL(fpu_do_free, -1);
#endif
break;
case 0xD0:
case 0xD1:
@@ -129,121 +140,96 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
case 0xC9:
case 0xCA:
case 0xCB:
case 0xCC:
case 0xCD:
case 0xCE:
case 0xCF:
case 0xF0:
case 0xF1:
case 0xF2:
case 0xF3:
case 0xF4:
case 0xF5:
case 0xF6:
case 0xF7:
case 0xF8:
case 0xF9:
case 0xFA:
case 0xFB:
case 0xFC:
case 0xFD:
case 0xFE:
case 0xFF:
default:
DEFAULT;
break;
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FLD double");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x3, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v1, ed, fixedaddress);
break;
case 1:
INST_NAME("FISTTP i64, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_I64);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
if(ST_IS_I64(0)) {
VST64(v1, ed, fixedaddress);
} else {
s0 = fpu_get_scratch(dyn);
#if 0
// those are ARM 8.5 opcode!
} else
switch((nextop>>3)&7) {
case 0:
INST_NAME("FLD double");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x3, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v1, ed, fixedaddress);
break;
case 1:
INST_NAME("FISTTP i64, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_I64);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
if(ST_IS_I64(0)) {
VST64(v1, ed, fixedaddress);
} else {
s0 = fpu_get_scratch(dyn, ninst);
if(arm64_frintts) {
FRINT64ZD(s0, v1);
FCVTZSxD(x2, s0);
STRx_U12(x2, ed, fixedaddress);
#else
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);
STx(x2, ed, fixedaddress);
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(x5, xZR, 1, 1, 0); //0x8000000000000000
STx(x5, ed, fixedaddress);
ORRx_mask(x2, xZR, 1, 1, 0); //0x8000000000000000
STx(x2, ed, fixedaddress);
MARK3;
#endif
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FST double");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v1, ed, fixedaddress);
break;
case 3:
INST_NAME("FSTP double");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v1, ed, fixedaddress);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FRSTOR m108byte");
MESSAGE(LOG_DUMP, "Need Optimization\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_frstor, -1);
break;
case 6:
INST_NAME("FSAVE m108byte");
MESSAGE(LOG_DUMP, "Need Optimization\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);
break;
case 7:
INST_NAME("FNSTSW m2byte");
//fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
addr = geted(dyn, addr, ninst, nextop, &ed, x4, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
LDRw_U12(x2, xEmu, offsetof(x64emu_t, top));
LDRH_U12(x3, xEmu, offsetof(x64emu_t, sw));
if(dyn->n.x87stack) {
// update top
if(dyn->n.x87stack>0) {
SUBw_U12(x2, x2, dyn->n.x87stack);
} else {
ADDw_U12(x2, x2, -dyn->n.x87stack);
}
ANDw_mask(x2, x2, 0, 2);
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FST double");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v1, ed, fixedaddress);
break;
case 3:
INST_NAME("FSTP double");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v1, ed, fixedaddress);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FRSTOR m108byte");
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);}
CALL(native_frstor, -1);
break;
case 6:
INST_NAME("FNSAVE m108byte");
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);
break;
case 7:
INST_NAME("FNSTSW m2byte");
//fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
addr = geted(dyn, addr, ninst, nextop, &ed, x4, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
LDRw_U12(x2, xEmu, offsetof(x64emu_t, top));
LDRH_U12(x3, xEmu, offsetof(x64emu_t, sw));
if(dyn->n.x87stack) {
// update top
if(dyn->n.x87stack>0) {
SUBw_U12(x2, x2, dyn->n.x87stack);
} else {
ADDw_U12(x2, x2, -dyn->n.x87stack);
}
BFIw(x3, x2, 11, 3); // inject TOP at bit 11 (3 bits)
STRH_U12(x3, xEmu, offsetof(x64emu_t, sw));
STH(x3, ed, fixedaddress); // store whole sw flags
break;
default:
DEFAULT;
}
}
ANDw_mask(x2, x2, 0, 2);
}
BFIw(x3, x2, 11, 3); // inject TOP at bit 11 (3 bits)
STRH_U12(x3, xEmu, offsetof(x64emu_t, sw));
STH(x3, ed, fixedaddress); // store whole sw flags
break;
default:
DEFAULT;
}
return addr;
}
+122 -103
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -29,6 +29,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;
@@ -36,6 +37,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(v2);
MAYUSE(v1);
if(MODREG)
switch(nextop) {
case 0xC0:
case 0xC1:
@@ -48,11 +50,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
@@ -66,11 +72,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD0:
@@ -116,11 +126,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE8:
@@ -134,11 +148,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF0:
@@ -152,11 +170,15 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF8:
@@ -170,116 +192,113 @@ 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);
}
if(!BOX64ENV(dynarec_fastround))
x87_restoreround(dyn, ninst, u8);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD8:
case 0xDA:
case 0xDB:
case 0xDC:
case 0xDD:
case 0xDE:
case 0xDF:
default:
DEFAULT;
break;
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FIADD ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FADDD(v1, v1, v2);
break;
case 1:
INST_NAME("FIMUL ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FMULD(v1, v1, v2);
break;
case 2:
INST_NAME("FICOM ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FCMPD(v1, v2);
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FICOMP ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FCMPD(v1, v2);
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FISUB ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FSUBD(v1, v1, v2);
break;
case 5:
INST_NAME("FISUBR ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FSUBD(v1, v2, v1);
break;
case 6:
INST_NAME("FIDIV ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FDIVD(v1, v1, v2);
break;
case 7:
INST_NAME("FIDIVR ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FDIVD(v1, v2, v1);
break;
}
}
} else
switch((nextop>>3)&7) {
case 0:
INST_NAME("FIADD ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FADDD(v1, v1, v2);
break;
case 1:
INST_NAME("FIMUL ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FMULD(v1, v1, v2);
break;
case 2:
INST_NAME("FICOM ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FCMPD(v1, v2);
FCOM(x1, x2, x3);
break;
case 3:
INST_NAME("FICOMP ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FCMPD(v1, v2);
FCOM(x1, x2, x3);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FISUB ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FSUBD(v1, v1, v2);
break;
case 5:
INST_NAME("FISUBR ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FSUBD(v1, v2, v1);
break;
case 6:
INST_NAME("FIDIV ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FDIVD(v1, v1, v2);
break;
case 7:
INST_NAME("FIDIVR ST0, word[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
v2 = fpu_get_scratch(dyn, ninst);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
VLD16(v2, wback, fixedaddress);
SXTL_16(v2, v2);
SXTL_32(v2, v2);
SCVTFDD(v2, v2);
FDIVD(v1, v2, v1);
break;
}
return addr;
}
+245 -256
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
#include "dynarec_arm64_functions.h"
@@ -41,6 +41,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(v1);
MAYUSE(j64);
if(MODREG)
switch(nextop) {
case 0xC0:
case 0xC1:
@@ -55,6 +56,25 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD0:
case 0xD1:
case 0xD2:
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD7:
INST_NAME("FSTP STx, ST0");
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(ST_IS_F(0)) {
FMOVS(v2, v1);
} else {
FMOVD(v2, v1);
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
INST_NAME("FNSTSW AX");
LDRw_U12(x2, xEmu, offsetof(x64emu_t, top));
@@ -114,264 +134,233 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
case 0xC9:
case 0xCA:
case 0xCB:
case 0xCC:
case 0xCD:
case 0xCE:
case 0xCF:
case 0xD0:
case 0xD1:
case 0xD2:
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD7:
case 0xD8:
case 0xD9:
case 0xDA:
case 0xDB:
case 0xDC:
case 0xDD:
case 0xDE:
case 0xDF:
case 0xE1:
case 0xE2:
case 0xE3:
case 0xE4:
case 0xE5:
case 0xE6:
case 0xE7:
case 0xF8:
case 0xF9:
case 0xFA:
case 0xFB:
case 0xFC:
case 0xFD:
case 0xFE:
case 0xFF:
default:
DEFAULT;
break;
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FILD ST0, Ew");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
LDSHw(x1, wback, fixedaddress);
if(ST_IS_F(0)) {
SCVTFSw(v1, x1);
} else {
SCVTFDw(v1, x1);
}
break;
case 1:
INST_NAME("FISTTP Ew, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
ed = x1;
s0 = fpu_get_scratch(dyn);
#if 0
// this version needs ARM v8.5, //TODO: add detection of this extension to use it
FRINT32ZD(s0, v1);
// no saturation instruction on Arm, so using NEON
} else
switch((nextop>>3)&7) {
case 0:
INST_NAME("FILD ST0, Ew");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
LDSHw(x1, wback, fixedaddress);
if(ST_IS_F(0)) {
SCVTFSw(v1, x1);
} else {
SCVTFDw(v1, x1);
}
break;
case 1:
INST_NAME("FISTTP Ew, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
ed = x1;
s0 = fpu_get_scratch(dyn, ninst);
#if 0
// this version needs ARM v8.5, and doesn't handle saturation for 32bits integer not fitting 16bits
FRINT32ZD(s0, v1);
// no saturation instruction on Arm, so using NEON
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
SQXTN_H_S(s0, s0);
VST16(s0, wback, fixedaddress);
#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)) {
VFCVTZSs(s0, v1);
} else {
VFCVTZSd(s0, v1);
SQXTN_S_D(s0, s0);
}
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);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x3, 0x8000);
MARK3;
STH(x3, wback, fixedaddress);
#endif
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FIST Ew, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
u8 = x87_setround(dyn, ninst, x1, x2, x4);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
ed = x1;
s0 = fpu_get_scratch(dyn, ninst);
#if 0
FRINT32XD(s0, v1);
// no saturation instruction on Arm, so using NEON
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
SQXTN_H_S(s0, s0);
VST16(s0, wback, fixedaddress);
#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);
VFCVTZSs(s0, s0);
} else {
FRINTXD(s0, v1);
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
SQXTN_H_S(s0, s0);
VST16(s0, wback, fixedaddress);
#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)) {
VFCVTZSs(s0, v1);
} else {
VFCVTZSd(s0, v1);
SQXTN_S_D(s0, s0);
}
VMOVSto(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);
MARK2;
MOV32w(x3, 0x8000);
MARK3;
STH(x3, wback, fixedaddress);
#endif
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FIST Ew, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
u8 = x87_setround(dyn, ninst, x1, x2, x4);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
ed = x1;
s0 = fpu_get_scratch(dyn);
#if 0
FRINT32XD(s0, v1);
// no saturation instruction on Arm, so using NEON
}
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);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x3, 0x8000);
MARK3;
STH(x3, wback, fixedaddress);
#endif
x87_restoreround(dyn, ninst, u8);
break;
case 3:
INST_NAME("FISTP Ew, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
u8 = x87_setround(dyn, ninst, x1, x2, x4);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
ed = x1;
s0 = fpu_get_scratch(dyn, ninst);
#if 0
FRINT32XD(s0, v1);
// no saturation instruction on Arm, so using NEON
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
SQXTN_H_S(s0, s0);
VST16(s0, wback, fixedaddress);
#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);
VFCVTZSs(s0, s0);
} else {
FRINTXD(s0, v1);
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
SQXTN_H_S(s0, s0);
VST16(s0, wback, fixedaddress);
#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);
VFCVTZSs(s0, s0);
} else {
FRINTXD(s0, v1);
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
}
VMOVSto(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);
MARK2;
MOV32w(x3, 0x8000);
MARK3;
STH(x3, wback, fixedaddress);
#endif
x87_restoreround(dyn, ninst, u8);
break;
case 3:
INST_NAME("FISTP Ew, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_F);
u8 = x87_setround(dyn, ninst, x1, x2, x4);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
ed = x1;
s0 = fpu_get_scratch(dyn);
#if 0
FRINT32XD(s0, v1);
// no saturation instruction on Arm, so using NEON
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
SQXTN_H_S(s0, s0);
VST16(s0, wback, fixedaddress);
#else
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
if(ST_IS_F(0)) {
FRINTXS(s0, v1);
VFCVTZSs(s0, s0);
} else {
FRINTXD(s0, v1);
VFCVTZSd(s0, s0);
SQXTN_S_D(s0, s0);
}
VMOVSto(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);
MARK2;
MOV32w(x3, 0x8000);
MARK3;
STH(x3, wback, fixedaddress);
#endif
X87_POP_OR_FAIL(dyn, ninst, x3);
x87_restoreround(dyn, ninst, u8);
break;
case 4:
INST_NAME("FBLD ST0, tbytes");
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(fpu_fbld, -1);
break;
case 5:
INST_NAME("FILD ST0, i64");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_I64);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v1, wback, fixedaddress);
if(!ST_IS_I64(0)) {
if(rex.is32bits) {
// need to also feed the STll stuff...
ADDx_U12(x4, xEmu, offsetof(x64emu_t, fpu_ll));
LDRw_U12(x1, xEmu, offsetof(x64emu_t, top));
int a = 0 - dyn->n.x87stack;
if(a) {
if(a<0) {
SUBw_U12(x1, x1, -a);
} else {
ADDw_U12(x1, x1, a);
}
ANDw_mask(x1, x1, 0, 2); //mask=7
}
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);
TBNZ_MARK2(x5, FPSR_QC);
B_MARK3_nocond;
MARK2;
MOV32w(x3, 0x8000);
MARK3;
STH(x3, wback, fixedaddress);
#endif
X87_POP_OR_FAIL(dyn, ninst, x3);
x87_restoreround(dyn, ninst, u8);
break;
case 4:
INST_NAME("FBLD ST0, tbytes");
X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
s0 = x87_stackcount(dyn, ninst, x3);
CALL(fpu_fbld, -1);
x87_unstackcount(dyn, ninst, x3, s0);
break;
case 5:
INST_NAME("FILD ST0, i64");
X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_I64);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v1, wback, fixedaddress);
if(!ST_IS_I64(0)) {
if(rex.is32bits) {
// need to also feed the STll stuff...
ADDx_U12(x4, xEmu, offsetof(x64emu_t, fpu_ll));
LDRw_U12(x1, xEmu, offsetof(x64emu_t, top));
int a = 0 - dyn->n.x87stack;
if(a) {
if(a<0) {
SUBw_U12(x1, x1, -a);
} else {
ADDw_U12(x1, x1, a);
}
ADDx_REG_LSL(x1, x4, x1, 4); // fpu_ll is 2 i64
VSTR64_U12(v1, x1, 8); // ll
ANDw_mask(x1, x1, 0, 2); //mask=7
}
SCVTFDD(v1, v1);
if(rex.is32bits) {
VSTR64_U12(v1, x1, 0); // ref
ADDx_REG_LSL(x1, x4, x1, 4); // fpu_ll is 2 i64
VSTR64_U12(v1, x1, 8); // ll
}
SCVTFDD(v1, v1);
if(rex.is32bits) {
VSTR64_U12(v1, x1, 0); // ref
}
}
break;
case 6:
INST_NAME("FBSTP tbytes, ST0");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(fpu_fbst, -1);
x87_unstackcount(dyn, ninst, x1, i1);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 7:
INST_NAME("FISTP i64, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_I64);
if(!ST_IS_I64(0)) {
u8 = x87_setround(dyn, ninst, x1, x2, x4);
}
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
ed = x1;
s0 = fpu_get_scratch(dyn, ninst);
if(ST_IS_I64(0)) {
VST64(v1, wback, fixedaddress);
} else {
#if 0
FRINT64XD(s0, v1);
VFCVTZSd(s0, s0);
VSTR64_U12(s0, wback, fixedaddress);
#else
if(rex.is32bits) {
// need to check STll first...
ADDx_U12(x5, xEmu, offsetof(x64emu_t, fpu_ll));
LDRw_U12(x1, xEmu, offsetof(x64emu_t, top));
VMOVQDto(x3, v1, 0);
int a = 0 - dyn->n.x87stack;
if(a) {
if(a<0) {
SUBw_U12(x1, x1, -a);
} else {
ADDw_U12(x1, x1, a);
}
ANDw_mask(x1, x1, 0, 2); //mask=7
}
ADDx_REG_LSL(x1, x5, x1, 4); // fpu_ll is 2 i64
LDRx_U12(x5, x1, 0); // ref
SUBx_REG(x5, x5, x3);
CBNZx_MARK2(x5);
LDRx_U12(x5, x1, 8); // ll
STx(x5, wback, fixedaddress);
B_MARK3(c__);
MARK2;
}
break;
case 6:
INST_NAME("FBSTP tbytes, ST0");
i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(fpu_fbst, -1);
x87_unstackcount(dyn, ninst, x1, i1);
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 7:
INST_NAME("FISTP i64, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_I64);
if(!ST_IS_I64(0)) {
u8 = x87_setround(dyn, ninst, x1, x2, x4);
}
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
ed = x1;
s0 = fpu_get_scratch(dyn);
if(ST_IS_I64(0)) {
VST64(v1, wback, fixedaddress);
} else {
#if 0
if(arm64_frintts) {
FRINT64XD(s0, v1);
VFCVTZSd(s0, s0);
VSTR64_U12(s0, wback, fixedaddress);
#else
if(rex.is32bits) {
// need to check STll first...
ADDx_U12(x5, xEmu, offsetof(x64emu_t, fpu_ll));
LDRw_U12(x1, xEmu, offsetof(x64emu_t, top));
VMOVQDto(x3, v1, 0);
int a = 0 - dyn->n.x87stack;
if(a) {
if(a<0) {
SUBw_U12(x1, x1, -a);
} else {
ADDw_U12(x1, x1, a);
}
ANDw_mask(x1, x1, 0, 2); //mask=7
}
ADDx_REG_LSL(x1, x5, x1, 4); // fpu_ll is 2 i64
LDRx_U12(x5, x1, 0); // ref
SUBx_REG(x5, x5, x3);
CBNZx_MARK2(x5);
LDRx_U12(x5, x1, 8); // ll
STx(x5, wback, fixedaddress);
B_MARK3(c__);
MARK2;
}
VST64(s0, wback, fixedaddress);
} else {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
@@ -382,15 +371,15 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
TBZ_MARK3(x5, FPSR_IOC);
ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000
STx(x5, wback, fixedaddress);
MARK3;
#endif
x87_restoreround(dyn, ninst, u8);
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
DEFAULT;
}
}
MARK3;
#endif
x87_restoreround(dyn, ninst, u8);
}
X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
DEFAULT;
}
return addr;
}
+386 -273
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
// emit OR32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch
void emit_or32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4)
@@ -27,59 +27,100 @@ 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) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
int 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) TSTxw_REG(s1, s1);
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX(X_ZF) {
TSTxw_REG(s1, s1);
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit OR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
void emit_or32c(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) {
MOV64xw(s3, c);
emit_or32(dyn, ninst, rex, s1, s3, s3, s4);
return;
}
IFX(X_PEND) {
SET_DF(s4, rex.w?d_or64:d_or32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
MOV64xw(s3, c);
ORRxw_REG(s1, s1, s3);
ORRxw_mask(s1, s1, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
int 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) TSTxw_REG(s1, s1);
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX(X_ZF) {
TSTxw_REG(s1, s1);
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
@@ -89,59 +130,104 @@ 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) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
int 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) TSTxw_REG(s1, s1);
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX(X_ZF) {
TSTxw_REG(s1, s1);
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit XOR32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
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 && !((!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);
}
MOV64xw(s3, c);
EORxw_REG(s1, s1, s3);
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
int 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) TSTxw_REG(s1, s1);
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX(X_ZF) {
TSTxw_REG(s1, s1);
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
@@ -151,10 +237,10 @@ 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) {
IFX(X_ZF|X_SF|X_CF|X_OF) {
ANDSxw_REG(s1, s1, s2);
} else {
ANDxw_REG(s1, s1, s2);
@@ -162,54 +248,85 @@ void emit_and32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX(X_ZF) {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit AND32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
void emit_and32c(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) {
MOV64xw(s3, c);
emit_and32(dyn, ninst, rex, s1, s3, s3, s4);
return;
}
IFX(X_PEND) {
SET_DF(s4, rex.w?d_and64:d_and32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
MOV64xw(s3, c);
IFX(X_ALL) {
ANDSxw_REG(s1, s1, s3);
} else {
ANDxw_REG(s1, s1, s3);
SET_DFNONE();
}
IFX(X_ZF|X_SF|X_CF|X_OF) {
ANDSxw_mask(s1, s1, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
} else {
ANDxw_mask(s1, s1, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
}
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX(X_ZF) {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
@@ -218,9 +335,9 @@ void emit_or8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
{
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s3, d_or8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
SET_DF(s4, d_or8);
} else {
SET_DFNONE();
}
ORRw_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -232,20 +349,25 @@ void emit_or8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit OR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
void emit_or8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
void emit_or8c(dynarec_arm_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4)
{
MOV32w(s3, c&0xff);
int mask = convert_bitmask_w(c);
if(!mask) {
MOV32w(s3, c);
emit_or8(dyn, ninst, s1, s3, s3, s4);
return;
}
IFX(X_PEND) {
SET_DF(s4, d_or8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
ORRw_REG(s1, s1, s3);
ORRw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
}
@@ -255,7 +377,7 @@ void emit_or8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
}
COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
@@ -264,9 +386,9 @@ void emit_xor8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
{
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s3, d_xor8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
SET_DF(s4, d_xor8);
} else {
SET_DFNONE();
}
EORx_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -278,20 +400,25 @@ void emit_xor8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit XOR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
void emit_xor8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
void emit_xor8c(dynarec_arm_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4)
{
MOV32w(s3, c&0xff);
int mask = convert_bitmask_w(c);
if(!mask) {
MOV32w(s3, c&0xff);
emit_xor8(dyn, ninst, s1, s3, s3, s4);
return;
}
IFX(X_PEND) {
SET_DF(s4, d_xor8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
} else {
SET_DFNONE();
}
EORw_REG(s1, s1, s3);
EORw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
}
@@ -301,7 +428,7 @@ void emit_xor8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4
}
COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
@@ -310,9 +437,9 @@ void emit_and8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
{
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s3, d_and8);
} else IFX(X_ALL) {
SET_DFNONE(s3);
SET_DF(s4, d_and8);
} else {
SET_DFNONE();
}
IFX(X_ZF) {
ANDSw_REG(s1, s1, s2);
@@ -326,32 +453,43 @@ void emit_and8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw_REG(xFlags, xFlags, s3);
}
IFX(X_ZF) {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
IFX(X_SF) {
LSRw(s3, s1, 7);
BFIw(xFlags, s3, F_SF, 1);
if(arm64_flagm) {
COMP_ZFSF(s1, 8)
} else {
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRw(s3, s1, 7);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit AND8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
void emit_and8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
void emit_and8c(dynarec_arm_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4)
{
MOV32w(s3, c&0xff);
int mask = convert_bitmask_w(c);
if(!mask) {
MOV32w(s3, c);
emit_and8(dyn, ninst, s1, s3, s3, s4);
return;
}
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, s3);
ANDSw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
} else {
ANDw_REG(s1, s1, s3);
ANDw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
}
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
@@ -360,28 +498,33 @@ void emit_and8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
IFX(X_ZF) {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
IFX(X_SF) {
LSRw(s3, s1, 7);
BFIw(xFlags, s3, F_SF, 1);
if(arm64_flagm) {
COMP_ZFSF(s1, 8)
} else {
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRw(s3, s1, 7);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit OR16 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
void emit_or16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
{
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s3, d_or16);
} else IFX(X_ALL) {
SET_DFNONE(s3);
SET_DF(s4, d_or16);
} else {
SET_DFNONE();
}
ORRw_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -393,64 +536,46 @@ void emit_or16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit OR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
//void emit_or16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOVW(s3, c);
// STR_IMM9(s1, xEmu, offsetof(x64emu_t, op1));
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s4, d_or16);
// } else IFX(X_ALL) {
// SET_DFNONE(s4);
// }
// if(c>=0 && c<256) {
// IFX(X_ALL) {
// ORRS_IMM8(s1, s1, c, 0);
// } else {
// ORR_IMM8(s1, s1, c, 0);
// }
// } else {
// IFX(X_PEND) {} else {MOVW(s3, c);}
// IFX(X_ALL) {
// ORRS_REG_LSL_IMM5(s1, s1, s3, 0);
// } else {
// ORR_REG_LSL_IMM5(s1, s1, s3, 0);
// }
// }
// IFX(X_PEND) {
// STR_IMM9(s1, xEmu, offsetof(x64emu_t, res));
// }
// IFX(X_CF | X_AF | X_ZF) {
// BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
// }
// IFX(X_OF) {
// BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
// }
// IFX(X_ZF) {
// ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
// }
// IFX(X_SF) {
// MOV_REG_LSR_IMM5(s3, s1, 15);
// BFI(xFlags, s3, F_SF, 1);
// }
// IFX(X_PF) {
// emit_pf(dyn, ninst, s1, s3, s4);
// }
//}
void emit_or16c(dynarec_arm_t* dyn, int ninst, int s1, int16_t c, int s3, int s4)
{
int mask = convert_bitmask_w((uint16_t)c);
if(!mask) {
MOV32w(s3, (uint16_t)c);
emit_or16(dyn, ninst, s1, s3, s3, s4);
return;
}
IFX(X_PEND) {
SET_DF(s4, d_or16);
} else {
SET_DFNONE();
}
ORRw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s4);
}
}
// emit XOR16 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
void emit_xor16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
{
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s3, d_xor16);
} else IFX(X_ALL) {
SET_DFNONE(s3);
SET_DF(s4, d_xor16);
} else {
SET_DFNONE();
}
EORw_REG(s1, s1, s2);
IFX(X_PEND) {
@@ -462,66 +587,49 @@ void emit_xor16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit XOR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
//void emit_xor16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOVW(s3, c);
// STR_IMM9(s1, xEmu, offsetof(x64emu_t, op1));
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s4, d_xor16);
// } else IFX(X_ALL) {
// SET_DFNONE(s4);
// }
// if(c>=0 && c<256) {
// IFX(X_ALL) {
// XORS_IMM8(s1, s1, c);
// } else {
// XOR_IMM8(s1, s1, c);
// }
// } else {
// IFX(X_PEND) {} else {MOVW(s3, c);}
// IFX(X_ALL) {
// XORS_REG_LSL_IMM5(s1, s1, s3, 0);
// } else {
// XOR_REG_LSL_IMM5(s1, s1, s3, 0);
// }
// }
// IFX(X_PEND) {
// STR_IMM9(s1, xEmu, offsetof(x64emu_t, res));
// }
// IFX(X_CF | X_AF | X_ZF) {
// BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
// }
// IFX(X_OF) {
// BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
// }
// IFX(X_ZF) {
// ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
// }
// IFX(X_SF) {
// MOV_REG_LSR_IMM5(s3, s1, 15);
// BFI(xFlags, s3, F_SF, 1);
// }
// IFX(X_PF) {
// emit_pf(dyn, ninst, s1, s3, s4);
// }
//}
void emit_xor16c(dynarec_arm_t* dyn, int ninst, int s1, int16_t c, int s3, int s4)
{
int mask = convert_bitmask_w((uint16_t)c);
if(!mask) {
MOV32w(s3, (uint16_t)c);
emit_xor16(dyn, ninst, s1, s3, s3, s4);
return;
}
IFX(X_PEND) {
SET_DF(s4, d_xor16);
} else {
SET_DFNONE();
}
EORw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s4);
}
}
// emit AND16 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed)
void emit_and16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
{
MAYUSE(s2);
IFX(X_PEND) {
SET_DF(s3, d_and16);
} else IFX(X_ALL) {
SET_DFNONE(s3);
SET_DF(s4, d_and16);
} else {
SET_DFNONE();
}
IFX(X_ALL) {
IFX(X_ZF) {
ANDSw_REG(s1, s1, s2);
} else {
ANDw_REG(s1, s1, s2);
@@ -533,61 +641,66 @@ void emit_and16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw_REG(xFlags, xFlags, s3);
}
IFX(X_ZF) {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
IFX(X_SF) {
LSRw(s3, s1, 15);
BFIw(xFlags, s3, F_SF, 1);
if(arm64_flagm) {
COMP_ZFSF(s1, 16)
} else {
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRw(s3, s1, 15);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit AND16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
//void emit_and16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
//{
// IFX(X_PEND) {
// MOVW(s3, c);
// STR_IMM9(s1, xEmu, offsetof(x64emu_t, op1));
// STR_IMM9(s3, xEmu, offsetof(x64emu_t, op2));
// SET_DF(s4, d_and16);
// } else IFX(X_ALL) {
// SET_DFNONE(s4);
// }
// if(c>=0 && c<256) {
// IFX(X_ALL) {
// ANDS_IMM8(s1, s1, c);
// } else {
// AND_IMM8(s1, s1, c);
// }
// } else {
// IFX(X_PEND) {} else {MOVW(s3, c);}
// IFX(X_ALL) {
// ANDS_REG_LSL_IMM5(s1, s1, s3, 0);
// } else {
// AND_REG_LSL_IMM5(s1, s1, s3, 0);
// }
// }
// IFX(X_PEND) {
// STR_IMM9(s1, xEmu, offsetof(x64emu_t, res));
// }
// IFX(X_CF | X_AF | X_ZF) {
// BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF)|(1<<F_ZF), 0);
// }
// IFX(X_OF) {
// BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
// }
// IFX(X_ZF) {
// ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
// }
// IFX(X_SF) {
// MOV_REG_LSR_IMM5(s3, s1, 15);
// BFI(xFlags, s3, F_SF, 1);
// }
// IFX(X_PF) {
// emit_pf(dyn, ninst, s1, s3, s4);
// }
//}
void emit_and16c(dynarec_arm_t* dyn, int ninst, int s1, int16_t c, int s3, int s4)
{
int mask = convert_bitmask_w((uint16_t)c);
if(!mask) {
MOV32w(s3, (uint16_t)c);
emit_and16(dyn, ninst, s1, s3, s3, s4);
return;
}
IFX(X_PEND) {
SET_DF(s4, d_and16);
} else {
SET_DFNONE();
}
IFX(X_ZF) {
ANDSw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
} else {
ANDw_mask(s1, s1, mask&0x3F, (mask>>6)&0x3F);
}
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
if(arm64_flagm) {
COMP_ZFSF(s1, 16)
} else {
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRw(s3, s1, 15);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s4);
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+411 -114
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
// emit CMP32 instruction, from cmp s1, s2, using s3 and s4 as scratch
void emit_cmp32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5)
@@ -30,7 +30,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
@@ -47,24 +47,34 @@ void emit_cmp32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
BFIx(xFlags, s4, F_AF, 1); // AF: bc & 0x08
}
IFX(X_ZF) {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_CF) {
// inverted carry
CSETw(s4, cCC);
BFIw(xFlags, s4, F_CF, 1);
IFNATIVE(NF_CF) {
GEN_INVERTED_CARRY();
} else {
CSETw(s4, cCC);
BFIw(xFlags, s4, F_CF, 1);
}
}
IFX(X_OF) {
CSETw(s4, cVS);
BFIw(xFlags, s4, F_OF, 1);
IFNATIVE(NF_VF) {} else {
CSETw(s4, cVS);
BFIw(xFlags, s4, F_OF, 1);
}
}
IFX(X_SF) {
LSRxw(s3, s5, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s3, s5, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s5, s3, s4);
emit_pf(dyn, ninst, s5, s4);
}
}
@@ -78,25 +88,40 @@ 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
// bc = (res & (~d | s)) | (~d & s) => is 0 here...
IFX(X_OF|X_AF|X_CF) {
MOV32w(s4, (1<<F_OF)|(1<<F_AF)|(1<<F_CF));
BICw(xFlags, xFlags, s4);
IFX(X_CF) {
IFNATIVE(NF_CF) {
GEN_INVERTED_CARRY();
} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX(X_ZF) {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s3, s1, (rex.w)?63:31);
BFIw(xFlags, s3, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
@@ -109,36 +134,65 @@ 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
BICw(s4, s2, s1); // s4 = ~op1 & op2
}
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 16);
SUBSw_REG_LSL(s5, s5, s2, 16);
IFX(X_AF) {
ANDw_REG_LSR(s3, s3, s5, 16); // s3 = (~op1 | op2) & res
ORRw_REG(s3, s3, s4); // s3 = (~op1 & op2) | ((~op1 | op2) & res)
LSRw(s4, s3, 3);
BFIx(xFlags, s4, F_AF, 1); // AF: bc & 0x08
}
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_CF) {
// inverted carry
IFNATIVE(NF_CF) {
GEN_INVERTED_CARRY();
} else {
CSETw(s4, cCC);
BFIw(xFlags, s4, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
CSETw(s4, cVS);
BFIw(xFlags, s4, F_OF, 1);
}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
CSETw(s4, cMI);
BFIw(xFlags, s4, F_SF, 1);
}
}
IFX(X_PF|X_PEND) {
LSRw(s5, s5, 16);
}
} else {
SUBw_REG(s5, s1, s2); // res = s1 - s2
IFX(X_AF) {
ANDw_REG(s3, s3, s5); // s3 = (~op1 | op2) & res
ORRw_REG(s3, s3, s4); // s3 = (~op1 & op2) | ((~op1 | op2) & res)
LSRw(s4, s3, 3);
BFIx(xFlags, s4, F_AF, 1); // AF: bc & 0x08
}
}
SUBw_REG(s5, s1, s2); // res = s1 - s2
IFX_PENDOR0 {
STRH_U12(s5, xEmu, offsetof(x64emu_t, res));
}
COMP_ZFSF(s5, 16)
// bc = (res & (~d | s)) | (~d & s)
IFX(X_CF|X_AF|X_OF) {
MVNw_REG(s4, s1); // s4 = ~d
ORRw_REG(s4, s4, s2); // s4 = ~d | s
ANDw_REG(s4, s4, s5); // s4 = res & (~d | s)
BICw_REG(s3, s2, s1); // s3 = s & ~d
ORRw_REG(s3, s4, s3); // s3 = (res & (~d | s)) | (s & ~d)
IFX(X_CF) {
LSRw(s4, s3, 15);
BFIw(xFlags, s4, F_CF, 1); // CF : bc & 0x8000
}
IFX(X_AF) {
LSRw(s4, s3, 3);
BFIw(xFlags, s4, F_AF, 1); // AF: bc & 0x08
}
IFX(X_OF) {
LSRw(s4, s3, 14);
EORw_REG_LSR(s4, s4, s4, 1);
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s5, s3, s4);
emit_pf(dyn, ninst, s5, s4);
}
}
@@ -152,7 +206,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) {
@@ -161,7 +215,7 @@ void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
}
COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
// emit CMP8 instruction, from cmp s1, s2, using s3 and s4 as scratch
@@ -171,37 +225,67 @@ void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, in
IFX_PENDOR0 {
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, d_cmp8);
SET_DF(s3, d_cmp8);
} else {
SET_DFNONE(s4);
SET_DFNONE();
}
IFX(X_AF) {
ORNw_REG(s3, s2, s1); // s3 = ~op1 | op2
BICw(s4, s2, s1); // s4 = ~op1 & op2
}
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 24);
SUBSw_REG_LSL(s5, s5, s2, 24);
IFX(X_AF) {
ANDw_REG_LSR(s3, s3, s5, 24); // s3 = (~op1 | op2) & res
ORRw_REG(s3, s3, s4); // s3 = (~op1 & op2) | ((~op1 | op2) & res)
LSRw(s4, s3, 3);
BFIx(xFlags, s4, F_AF, 1); // AF: bc & 0x08
}
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_CF) {
// inverted carry
IFNATIVE(NF_CF) {
GEN_INVERTED_CARRY();
} else {
CSETw(s4, cCC);
BFIw(xFlags, s4, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
CSETw(s4, cVS);
BFIw(xFlags, s4, F_OF, 1);
}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
CSETw(s4, cMI);
BFIw(xFlags, s4, F_SF, 1);
}
}
IFX(X_PF|X_PEND) {
LSRw(s5, s5, 24);
}
} else {
SUBw_REG(s5, s1, s2); // res = s1 - s2
IFX(X_AF) {
ANDw_REG(s3, s3, s5); // s3 = (~op1 | op2) & res
ORRw_REG(s3, s3, s4); // s3 = (~op1 & op2) | ((~op1 | op2) & res)
LSRw(s4, s3, 3);
BFIx(xFlags, s4, F_AF, 1); // AF: bc & 0x08
}
}
SUBw_REG(s5, s1, s2); // res = s1 - s2
IFX_PENDOR0 {
STRB_U12(s5, xEmu, offsetof(x64emu_t, res));
}
COMP_ZFSF(s5, 8)
// bc = (res & (~d | s)) | (~d & s)
IFX(X_CF|X_AF|X_OF) {
ORNw_REG(s4, s2, s1); // s4 = ~d | s
ANDw_REG(s4, s4, s5); // s4 = res & (~d | s)
BICw_REG(s3, s2, s1); // s3 = s & ~d
ORRw_REG(s3, s4, s3); // s3 = (res & (~d | s)) | (s & ~d)
IFX(X_CF) {
LSRw(s4, s3, 7);
BFIw(xFlags, s4, F_CF, 1); // CF : bc & 0x80
}
IFX(X_AF) {
LSRw(s4, s3, 3);
BFIw(xFlags, s4, F_AF, 1); // AF: bc & 0x08
}
IFX(X_OF) {
LSRw(s4, s3, 6);
EORw_REG_LSR(s4, s4, s4, 1);
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s5, s3, s4);
emit_pf(dyn, ninst, s5, s4);
}
}
// emit CMP8 instruction, from cmp s1 , 0, using s3 and s4 as scratch
@@ -214,7 +298,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) {
@@ -223,7 +307,7 @@ void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
}
COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
emit_pf(dyn, ninst, s1, s4);
}
}
@@ -234,27 +318,88 @@ 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 | X_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
ANDSxw_REG(s3, s1, s2); // res = s1 & s2
IFX_PENDOR0 {
STRxw_U12(s3, xEmu, offsetof(x64emu_t, res));
}
IFX(X_ZF) {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_SF) {
LSRxw(s4, s3, rex.w?63:31);
BFIw(xFlags, s4, F_SF, 1);
IFNATIVE(NF_SF) {} else {
LSRxw(s4, s3, rex.w?63:31);
BFIw(xFlags, s4, F_SF, 1);
}
}
// PF: (((emu->x64emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
IFX(X_PF) {
emit_pf(dyn, ninst, s3, s4, s5);
emit_pf(dyn, ninst, s3, s5);
}
}
// emit TEST32 instruction, from test s1, s2, using s3, s4 and s5 as scratch
void emit_test32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4, int s5)
{
MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
int mask = convert_bitmask_xw(c);
IFX_PENDOR0 {
SET_DF(s3, rex.w?d_tst64:d_tst32);
} else {
SET_DFNONE();
}
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {
BFCw(xFlags, F_CF, 1);
}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {
BFCw(xFlags, F_OF, 1);
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
if(mask) {
ANDSxw_mask(s3, s1, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
} else {
MOV64xw(s3, c);
ANDSxw_REG(s3, s1, s3); // res = s1 & s2
}
IFX_PENDOR0 {
STRxw_U12(s3, xEmu, offsetof(x64emu_t, res));
}
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
LSRxw(s4, s3, rex.w?63:31);
BFIw(xFlags, s4, F_SF, 1);
}
}
IFX(X_PF) {
emit_pf(dyn, ninst, s3, s5);
}
}
@@ -265,27 +410,103 @@ 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_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 16);
ANDSw_REG_LSL(s5, s5, s2, 16);
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {BFCw(xFlags, F_CF, 1);}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
CSETw(s4, cMI);
BFIw(xFlags, s4, F_SF, 1);
}
}
IFX(X_PF|X_PEND) {
LSRw(s5, s5, 16);
}
} else {
ANDw_REG(s5, s1, s2); // res = s1 & s2
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
ANDSw_REG(s5, s1, s2); // res = s1 & s2
IFX_PENDOR0 {
STRH_U12(s5, xEmu, offsetof(x64emu_t, res));
}
IFX(X_ZF) {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
IFX(X_SF) {
LSRw(s4, s5, 15);
BFIw(xFlags, s4, F_SF, 1);
}
// PF: (((emu->x64emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
IFX(X_PF) {
emit_pf(dyn, ninst, s5, s3, s4);
emit_pf(dyn, ninst, s5, s4);
}
}
// emit TEST16 instruction, from test s1, s2, using s3, s4 and s5 as scratch
void emit_test16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4, int s5)
{
MAYUSE(s1);
int mask = 0;
IFX_PENDOR0 {
SET_DF(s3, d_tst16);
} else {
SET_DFNONE();
}
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 16);
mask = convert_bitmask_w(c<<16);
if(mask) {
ANDSw_mask(s5, s5, mask&0x3F, (mask>>6)&0x3F);
} else {
MOV32w(s3, c);
ANDSw_REG_LSL(s5, s5, s3, 16);
}
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {BFCw(xFlags, F_CF, 1);}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
CSETw(s4, cMI);
BFIw(xFlags, s4, F_SF, 1);
}
}
IFX(X_PF|X_PEND) {
LSRw(s5, s5, 16);
}
} else {
mask = convert_bitmask_w(c);
if(mask) {
ANDw_mask(s5, s1, mask&0x3F, (mask>>6)&0x3F);
} else {
MOV32w(s5, c);
ANDw_REG(s5, s1, s5); // res = s1 & s2
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX_PENDOR0 {
STRH_U12(s5, xEmu, offsetof(x64emu_t, res));
}
IFX(X_PF) {
emit_pf(dyn, ninst, s5, s4);
}
}
@@ -296,26 +517,102 @@ 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_AF | X_OF) {
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 24);
ANDSw_REG_LSL(s5, s5, s2, 24);
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {BFCw(xFlags, F_CF, 1);}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
CSETw(s4, cMI);
BFIw(xFlags, s4, F_SF, 1);
}
}
IFX(X_PF|X_PEND) {
LSRw(s5, s5, 24);
}
} else {
ANDw_REG(s5, s1, s2); // res = s1 & s2
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
ANDSw_REG(s5, s1, s2); // res = s1 & s2
IFX_PENDOR0 {
STRB_U12(s5, xEmu, offsetof(x64emu_t, res));
}
IFX(X_ZF) {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
IFX(X_SF) {
LSRw(s4, s5, 7);
BFIw(xFlags, s4, F_SF, 1);
}
// PF: (((emu->x64emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
IFX(X_PF) {
emit_pf(dyn, ninst, s5, s3, s4);
emit_pf(dyn, ninst, s5, s4);
}
}
// emit TEST8 instruction, from test s1, s2, using s3, s4 and s5 as scratch
void emit_test8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4, int s5)
{
MAYUSE(s1);
int mask = 0;
IFX_PENDOR0 {
SET_DF(s3, d_tst8);
} else {
SET_DFNONE();
}
IFX(X_CF|X_ZF|X_SF|X_OF) {
LSLw(s5, s1, 24);
mask = convert_bitmask_w(c<<24);
if(mask) {
ANDSw_mask(s5, s5, mask&0x3F, (mask>>6)&0x3F);
} else {
MOV32w(s3, c);
ANDSw_REG_LSL(s5, s5, s3, 24);
}
IFX(X_ZF) {
IFNATIVE(NF_EQ) {} else {
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
}
IFX(X_CF) {
IFNATIVE(NF_CF) {} else {BFCw(xFlags, F_CF, 1);}
}
IFX(X_OF) {
IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);}
}
IFX(X_SF) {
IFNATIVE(NF_SF) {} else {
CSETw(s4, cMI);
BFIw(xFlags, s4, F_SF, 1);
}
}
IFX(X_PF|X_PEND) {
LSRw(s5, s5, 24);
}
} else {
mask = convert_bitmask_w(c);
if(mask) {
ANDw_mask(s5, s1, mask&0x3F, (mask>>6)&0x3F);
} else {
MOV32w(s5, c);
ANDw_REG(s5, s1, s5); // res = s1 & s2
}
}
IFX(X_AF) {
BFCw(xFlags, F_AF, 1);
}
IFX_PENDOR0 {
STRB_U12(s5, xEmu, offsetof(x64emu_t, res));
}
IFX(X_PF) {
emit_pf(dyn, ninst, s5, s4);
}
}
File diff suppressed because it is too large. Load diff
+133 -69
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
{
@@ -31,6 +31,8 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
uint8_t wback, wb1, wb2;
uint8_t u8;
uint64_t u64, j64;
int32_t i32, i32_;
int cacheupd = 0;
int v0, v1;
int q0;
int d0, d1;
@@ -83,14 +85,13 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
if(MODREG) {
d0 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VMOVeD(v0, 0, d0, 0);
VDUPQ_64(v0, d0, 0);
} else {
SMREAD();
v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v0, ed, fixedaddress);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
VLDQ1R_64(v0, ed);
}
VMOVeD(v0, 1, v0, 0);
break;
case 0x2A:
@@ -98,12 +99,18 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGX(v0, 1);
GETED(0);
d1 = fpu_get_scratch(dyn);
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);
}
VMOVeD(v0, 0, d1, 0);
break;
@@ -112,13 +119,13 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGD;
GETEXSD(q0, 0, 0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround)) {
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)) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
@@ -133,17 +140,17 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGD;
GETEXSD(q0, 0, 0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround)) {
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);
d1 = fpu_get_scratch(dyn, ninst);
FRINTID(d1, q0);
x87_restoreround(dyn, ninst, u8);
FCVTZSxwD(gd, d1);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
@@ -205,30 +212,34 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x51:
INST_NAME("SQRTSD Gx, Ex");
nextop = F8;
GETGX(v0, 1);
d1 = fpu_get_scratch(dyn);
GETGX(q0, 1);
d1 = fpu_get_scratch(dyn, ninst);
GETEXSD(d0, 0, 0);
if(!box64_dynarec_fastnan) {
v1 = fpu_get_scratch(dyn);
FCMLTD_0(v1, d0);
SHL_64(v1, v1, 63);
if(!BOX64ENV(dynarec_fastnan)) {
v0 = fpu_get_scratch(dyn, ninst);
v1 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FCMEQD(v0, d0, d0); // 0 if NAN, 1 if not NAN
FSQRTD(d1, d0);
VORR(d1, d1, v1);
FCMEQD(v1, d1, d1); // 0 => out is NAN
VBIC(v1, v0, v1); // forget it in any input was a NAN already
SHL_64(v1, v1, 63); // only keep the sign bit
VORR(d1, d1, v1); // NAN -> -NAN
} else {
FSQRTD(d1, d0);
}
VMOVeD(v0, 0, d1, 0);
VMOVeD(q0, 0, d1, 0);
break;
case 0x58:
INST_NAME("ADDSD Gx, Ex");
nextop = F8;
GETGX(d1, 1);
v1 = fpu_get_scratch(dyn);
v1 = fpu_get_scratch(dyn, ninst);
GETEXSD(d0, 0, 0);
if(!box64_dynarec_fastnan) {
v0 = fpu_get_scratch(dyn);
q0 = fpu_get_scratch(dyn);
if(!BOX64ENV(dynarec_fastnan)) {
v0 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXD(v0, d0, d1); // propagate NAN
FCMEQD(v0, v0, v0); // 0 if NAN, 1 if not NAN
@@ -246,11 +257,11 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
INST_NAME("MULSD Gx, Ex");
nextop = F8;
GETGX(d1, 1);
v1 = fpu_get_scratch(dyn);
v1 = fpu_get_scratch(dyn, ninst);
GETEXSD(d0, 0, 0);
if(!box64_dynarec_fastnan) {
v0 = fpu_get_scratch(dyn);
q0 = fpu_get_scratch(dyn);
if(!BOX64ENV(dynarec_fastnan)) {
v0 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXD(v0, d0, d1); // propagate NAN
FCMEQD(v0, v0, v0); // 0 if NAN, 1 if not NAN
@@ -269,8 +280,14 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGX(v0, 1);
GETEXSD(d0, 0, 0);
d1 = fpu_get_scratch(dyn);
FCVT_S_D(d1, d0);
d1 = fpu_get_scratch(dyn, ninst);
if(BOX64ENV(dynarec_fastround)>1) {
FCVT_S_D(d1, d0);
} else {
u8 = sse_setround(dyn, ninst, x1, x2, x3);
FCVT_S_D(d1, d0);
x87_restoreround(dyn, ninst, u8);
}
VMOVeS(v0, 0, d1, 0);
break;
@@ -278,11 +295,11 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
INST_NAME("SUBSD Gx, Ex");
nextop = F8;
GETGX(d1, 1);
v1 = fpu_get_scratch(dyn);
v1 = fpu_get_scratch(dyn, ninst);
GETEXSD(d0, 0, 0);
if(!box64_dynarec_fastnan) {
v0 = fpu_get_scratch(dyn);
q0 = fpu_get_scratch(dyn);
if(!BOX64ENV(dynarec_fastnan)) {
v0 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXD(v0, d0, d1); // propagate NAN
FCMEQD(v0, v0, v0); // 0 if NAN, 1 if not NAN
@@ -303,7 +320,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEXSD(v1, 0, 0);
// MINSD: if any input is NaN, or Ex[0]<Gx[0], copy Ex[0] -> Gx[0]
#if 0
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
FMINNMD(d0, v0, v1); // NaN handling may be slightly different, is that a problem?
VMOVeD(v0, 0, d0, 0); // to not erase uper part
#else
@@ -316,11 +333,11 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
INST_NAME("DIVSD Gx, Ex");
nextop = F8;
GETGX(v0, 1);
d1 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn, ninst);
GETEXSD(v1, 0, 0);
if(!box64_dynarec_fastnan) {
d0 = fpu_get_scratch(dyn);
q0 = fpu_get_scratch(dyn);
if(!BOX64ENV(dynarec_fastnan)) {
d0 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXD(d0, v0, v1); // propagate NAN
FCMEQD(d0, d0, d0); // 0 if NAN, 1 if not NAN
@@ -341,7 +358,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEXSD(v1, 0, 0);
// MAXSD: if any input is NaN, or Ex[0]>Gx[0], copy Ex[0] -> Gx[0]
#if 0
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
FMAXNMD(d0, v0, v1); // NaN handling may be slightly different, is that a problem?
VMOVeD(v0, 0, d0, 0); // to not erase uper part
#else
@@ -358,17 +375,27 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETGX(v0, 1);
u8 = F8;
// only low part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
u64 = 0;
for (int i=0; i<4; ++i) {
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+0)<<(i*16+0);
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+1)<<(i*16+8);
}
MOV64x(x2, u64);
d0 = fpu_get_scratch(dyn);
VMOVQDfrom(d0, 0, x2);
VTBL1_8(d0, v1, d0);
VMOVeD(v0, 0, d0, 0);
if(u8==0b00000000 || u8==0b01010101 || u8==0b10101010 || u8==0b11111111) {
if(v0==v1) {
d0 = fpu_get_scratch(dyn, ninst);
VMOVQ(d0, v1);
}
VDUP_16(v0, v1, u8&3);
if(v0==v1)
v1 = d0;
} else {
// only low part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
u64 = 0;
for (int i=0; i<4; ++i) {
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+0)<<(i*16+0);
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+1)<<(i*16+8);
}
MOV64x(x2, u64);
d0 = fpu_get_scratch(dyn, ninst);
VMOVQDfrom(d0, 0, x2);
VTBL1_8(d0, v1, d0);
VMOVeD(v0, 0, d0, 0);
}
if(v0!=v1) {
VMOVeD(v0, 1, v1, 1);
}
@@ -378,31 +405,68 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
INST_NAME("HADDPS Gx, Ex");
nextop = F8;
GETGX(v0, 1);
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
v1 = fpu_get_scratch(dyn);
VLD128(v1, ed, fixedaddress);
}
GETEX(v1, 0, 1);
VFADDPQS(v0, v0, v1);
break;
case 0x7D:
INST_NAME("HSUBPS Gx, Ex");
nextop = F8;
GETGX(v0, 1);
if(MODREG) {
v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
v1 = fpu_get_scratch(dyn);
VLD128(v1, ed, fixedaddress);
}
d0 = fpu_get_scratch(dyn);
GETEX(v1, 0, 1);
d0 = fpu_get_scratch(dyn, ninst);
VUZP1Q_32(d0, v0, v1);
VUZP2Q_32(v0, v0, v1);
VFSUBQS(v0, d0, v0);
break;
#define GO(GETFLAGS, NO, YES, F) \
READFLAGS(F); \
i32_ = F32S; \
if(rex.is32bits) \
j64 = (uint32_t)(addr+i32_); \
else \
j64 = addr+i32_; \
BARRIER(BARRIER_MAYBE); \
JUMP(j64, 1); \
GETFLAGS; \
if(dyn->insts[ninst].x64.jmp_insts==-1 || \
CHECK_CACHE()) { \
/* out of the block */ \
i32 = dyn->insts[ninst].epilog-(dyn->native_size); \
Bcond(NO, i32); \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
if(!(dyn->insts[ninst].x64.barrier&BARRIER_FLOAT)) \
fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \
jump_to_next(dyn, j64, 0, ninst, rex.is32bits); \
} else { \
CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \
SKIP_SEVL(i32); \
B(i32); \
} \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \
SKIP_SEVL(i32); \
Bcond(YES, i32); \
}
GOCOND(0x80, "J", "Id");
#undef GO
case 0xAE:
nextop = F8;
switch((nextop>>3)&7) {
case 6:
INST_NAME("(unsupported) UWAIT Ed");
FAKEED;
UDF(0);
break;
default:
DEFAULT;
}
break;
case 0xC2:
INST_NAME("CMPSD Gx, Ex, Ib");
nextop = F8;
@@ -428,10 +492,10 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGX(v0, 1);
GETEX(v1, 0, 0);
q0 = fpu_get_scratch(dyn);
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); // no need to use table64, as box64 is loaded in low memory
VLDR128_U12(q0, x2, 0);
VFMLAQS(v0, v1, q0);
break;
@@ -449,7 +513,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETEX(v1, 0, 0);
GETGX_empty(v0);
if(box64_dynarec_fastround) {
if(BOX64ENV(dynarec_fastround)) {
u8 = sse_setround(dyn, ninst, x1, x2, x3);
VFRINTIDQ(v0, v1);
x87_restoreround(dyn, ninst, u8);
@@ -461,7 +525,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
ORRw_mask(x4, xZR, 1, 0); //0x80000000
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
for(int i=0; i<2; ++i) {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
+216 -71
View File
@@ -19,7 +19,7 @@
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "dynarec_arm64_helper.h"
#include "../dynarec_helper.h"
uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
{
@@ -84,7 +84,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
q1 = fpu_get_scratch(dyn);
q1 = fpu_get_scratch(dyn, ninst);
VLD128(q1, ed, fixedaddress);
}
GETGX_empty(q0);
@@ -99,7 +99,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
q1 = fpu_get_scratch(dyn);
q1 = fpu_get_scratch(dyn, ninst);
VLD128(q1, ed, fixedaddress);
}
GETGX_empty(q0);
@@ -117,7 +117,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGX(v0, 1);
GETED(0);
d1 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn, ninst);
if(rex.w) {
SCVTFSx(d1, ed);
} else {
@@ -131,13 +131,13 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGD;
GETEXSS(d0, 0, 0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround)) {
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)) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
@@ -152,17 +152,17 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGD;
GETEXSS(q0, 0, 0);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround)) {
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);
d1 = fpu_get_scratch(dyn, ninst);
FRINTIS(d1, q0);
x87_restoreround(dyn, ninst, u8);
FCVTZSxwS(gd, d1);
if(!box64_dynarec_fastround) {
if(!BOX64ENV(dynarec_fastround)) {
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ_NEXT(x5, FPSR_IOC);
if(rex.w) {
@@ -172,11 +172,45 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
}
break;
case 0x38: /* MAP */
opcode = F8;
switch(opcode) {
case 0xF6:
INST_NAME("ADOX Gd, Ed");
nextop = F8;
READFLAGS(X_OF);
SETFLAGS(X_OF, SF_SUBSET);
GETED(0);
GETGD;
MRS_nzcv(x3);
IFNATIVE_BEFORE(NF_VF) {
LSRw(x4, x3, NZCV_V);
} else {
LSRw(x4, xFlags, F_OF);
}
BFIx(x3, x4, NZCV_C, 1); // set C
MSR_nzcv(x3); // load CC into ARM CF
IFX(X_OF) {
ADCSxw_REG(gd, gd, ed);
CSETw(x3, cCS);
BFIw(xFlags, x3, F_OF, 1);
} else {
ADCxw_REG(gd, gd, ed);
}
break;
default:
DEFAULT;
}
break;
case 0x51:
INST_NAME("SQRTSS Gx, Ex");
nextop = F8;
GETGX(v0, 1);
d1 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn, ninst);
GETEXSS(d0, 0, 0);
FSQRTS(d1, d0);
VMOVeS(v0, 0, d1, 0);
@@ -186,8 +220,8 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGX(v0, 1);
GETEXSS(v1, 0, 0);
d0 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
d1 = fpu_get_scratch(dyn, ninst);
// so here: F32: Imm8 = abcd efgh that gives => aBbbbbbc defgh000 00000000 00000000
// and want 1.0f = 0x3f800000
// so 00111111 10000000 00000000 00000000
@@ -203,7 +237,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETGX(v0, 1);
GETEXSS(v1, 0, 0);
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
FMOVS_8(d0, 0b01110000); //1.0f
FDIVS(d0, d0, v1);
VMOVeS(v0, 0, d0, 0);
@@ -212,27 +246,53 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x58:
INST_NAME("ADDSS Gx, Ex");
nextop = F8;
GETGX(v0, 1);
d1 = fpu_get_scratch(dyn);
GETGX(d1, 1);
v1 = fpu_get_scratch(dyn, ninst);
GETEXSS(d0, 0, 0);
FADDS(d1, v0, d0); // the high part of the vector is erased...
VMOVeS(v0, 0, d1, 0);
if(!BOX64ENV(dynarec_fastnan)) {
v0 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXS(v0, d0, d1); // propagate NAN
FCMEQS(v0, v0, v0); // 0 if NAN, 1 if not NAN
FADDS(v1, d1, d0); // the high part of the vector is erased...
FCMEQS(q0, v1, v1); // 0 => out is NAN
VBIC(q0, v0, q0); // forget it in any input was a NAN already
VSHL_32(q0, q0, 31); // only keep the sign bit
VORR(v1, v1, q0); // NAN -> -NAN
} else {
FADDS(v1, d1, d0); // the high part of the vector is erased...
}
VMOVeS(d1, 0, v1, 0);
break;
case 0x59:
INST_NAME("MULSS Gx, Ex");
nextop = F8;
GETGX(v0, 1);
d1 = fpu_get_scratch(dyn);
GETGX(d1, 1);
v1 = fpu_get_scratch(dyn, ninst);
GETEXSS(d0, 0, 0);
FMULS(d1, v0, d0);
VMOVeS(v0, 0, d1, 0);
if(!BOX64ENV(dynarec_fastnan)) {
v0 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXS(v0, d0, d1); // propagate NAN
FCMEQS(v0, v0, v0); // 0 if NAN, 1 if not NAN
FMULS(v1, d1, d0); // the high part of the vector is erased...
FCMEQS(q0, v1, v1); // 0 => out is NAN
VBIC(q0, v0, q0); // forget it in any input was a NAN already
VSHL_32(q0, q0, 31); // only keep the sign bit
VORR(v1, v1, q0); // NAN -> -NAN
} else {
FMULS(v1, d1, d0); // the high part of the vector is erased...
}
VMOVeS(d1, 0, v1, 0);
break;
case 0x5A:
INST_NAME("CVTSS2SD Gx, Ex");
nextop = F8;
GETGX(v0, 1);
GETEXSS(v1, 0, 0);
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
FCVT_D_S(d0, v1);
VMOVeD(v0, 0, d0, 0);
break;
@@ -241,14 +301,14 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETEX(v1, 0, 0) ;
GETGX_empty(v0);
if(box64_dynarec_fastround) {
if(BOX64ENV(dynarec_fastround)) {
VFCVTZSQS(v0, v1);
} else {
MRS_fpsr(x5);
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
ORRw_mask(x4, xZR, 1, 0); //0x80000000
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
for(int i=0; i<4; ++i) {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
@@ -261,15 +321,27 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
}
break;
case 0x5C:
INST_NAME("SUBSS Gx, Ex");
nextop = F8;
GETGX(v0, 1);
d1 = fpu_get_scratch(dyn);
GETGX(d1, 1);
v1 = fpu_get_scratch(dyn, ninst);
GETEXSS(d0, 0, 0);
FSUBS(d1, v0, d0);
VMOVeS(v0, 0, d1, 0);
if(!BOX64ENV(dynarec_fastnan)) {
v0 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXS(v0, d0, d1); // propagate NAN
FCMEQS(v0, v0, v0); // 0 if NAN, 1 if not NAN
FSUBS(v1, d1, d0); // the high part of the vector is erased...
FCMEQS(q0, v1, v1); // 0 => out is NAN
VBIC(q0, v0, q0); // forget it in any input was a NAN already
VSHL_32(q0, q0, 31); // only keep the sign bit
VORR(v1, v1, q0); // NAN -> -NAN
} else {
FSUBS(v1, d1, d0); // the high part of the vector is erased...
}
VMOVeS(d1, 0, v1, 0);
break;
case 0x5D:
INST_NAME("MINSS Gx, Ex");
@@ -278,23 +350,36 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEXSS(v1, 0, 0);
// MINSS: if any input is NaN, or Ex[0]<Gx[0], copy Ex[0] -> Gx[0]
#if 0
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
FMINNMS(d0, v0, v1); // NaN handling may be slightly different, is that a problem?
VMOVeS(v0, 0, d0, 0); // to not erase uper part
#else
FCMPS(v0, v1);
B_NEXT(cLS); //Less than or equal
B_NEXT(cCC); //Less than
VMOVeS(v0, 0, v1, 0); // to not erase uper part
#endif
break;
case 0x5E:
INST_NAME("DIVSS Gx, Ex");
nextop = F8;
GETGX(v0, 1);
d1 = fpu_get_scratch(dyn);
GETGX(d1, 1);
v1 = fpu_get_scratch(dyn, ninst);
GETEXSS(d0, 0, 0);
FDIVS(d1, v0, d0);
VMOVeS(v0, 0, d1, 0);
if(!BOX64ENV(dynarec_fastnan)) {
v0 = fpu_get_scratch(dyn, ninst);
q0 = fpu_get_scratch(dyn, ninst);
// check if any input value was NAN
FMAXS(v0, d0, d1); // propagate NAN
FCMEQS(v0, v0, v0); // 0 if NAN, 1 if not NAN
FDIVS(v1, d1, d0); // the high part of the vector is erased...
FCMEQS(q0, v1, v1); // 0 => out is NAN
VBIC(q0, v0, q0); // forget it in any input was a NAN already
VSHL_32(q0, q0, 31); // only keep the sign bit
VORR(v1, v1, q0); // NAN -> -NAN
} else {
FDIVS(v1, d1, d0); // the high part of the vector is erased...
}
VMOVeS(d1, 0, v1, 0);
break;
case 0x5F:
INST_NAME("MAXSS Gx, Ex");
@@ -303,16 +388,16 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEXSS(v1, 0, 0);
// MAXSS: if any input is NaN, or Ex[0]>Gx[0], copy Ex[0] -> Gx[0]
#if 0
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
FMAXNMS(d0, v0, v1); // NaN handling may be slightly different, is that a problem?
VMOVeS(v0, 0, d0, 0); // to not erase uper part
#else
FCMPS(v0, v1);
B_NEXT(cGE); //Greater than or equal
B_NEXT(cGT); //Greater than
VMOVeS(v0, 0, v1, 0); // to not erase uper part
#endif
break;
case 0x6F:
INST_NAME("MOVDQU Gx,Ex");// no alignment constraint on NEON here, so same as MOVDQA
nextop = F8;
@@ -333,16 +418,20 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEX(v1, 0, 1) ;
GETGX(v0, 1);
u8 = F8;
// only high part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
u64 = 0;
for (int i=0; i<4; ++i) {
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+8)<<(i*16+0);
u64 |= ((uint64_t)((u8>>(i*2))&3)*2+9)<<(i*16+8);
d0 = fpu_get_scratch(dyn, ninst);
if (u8 == 0b00000000 || u8 == 0b01010101 || u8 == 0b10101010 || u8 == 0b11111111) {
VDUPQ_16(d0, v1, (u8 & 3) + 4);
} else {
// only high part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
u64 = 0;
for (int i = 0; i < 4; ++i) {
u64 |= ((uint64_t)((u8 >> (i * 2)) & 3) * 2 + 8) << (i * 16 + 0);
u64 |= ((uint64_t)((u8 >> (i * 2)) & 3) * 2 + 9) << (i * 16 + 8);
}
MOV64x(x2, u64);
VMOVQDfrom(d0, 0, x2);
VTBL1_8(d0, v1, d0);
}
MOV64x(x2, u64);
d0 = fpu_get_scratch(dyn);
VMOVQDfrom(d0, 0, x2);
VTBL1_8(d0, v1, d0);
VMOVeD(v0, 1, d0, 0);
if(v0!=v1) {
VMOVeD(v0, 0, v1, 0);
@@ -371,18 +460,58 @@ uintptr_t dynarec64_F30F(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));
VMOVQ(v1, v0);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VST128(v0, ed, fixedaddress);
IF_UNALIGNED(ip) {
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(wback!=x1) {
MOVx_REG(x1, wback);
wback = x1;
}
for(int i=0; i<16; ++i) {
VST1_8(v0, i, wback);
ADDx_U12(wback, wback, 1);
}
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
VST128(v0, ed, fixedaddress);
}
SMWRITE2();
}
break;
case 0xAE:
nextop = F8;
switch((nextop>>3)&7) {
case 2:
INST_NAME("(unsupported) WRFSBASE Ed");
FAKEED;
UDF(0);
break;
case 3:
INST_NAME("(unsupported) WRGSBASE Ed");
FAKEED;
UDF(0);
break;
case 5:
INST_NAME("(unsupported) INCSSPD/INCSSPQ Ed");
FAKEED;
UDF(0);
break;
case 6:
INST_NAME("(unsupported) UMONITOR Ed");
FAKEED;
UDF(0);
break;
default:
DEFAULT;
}
break;
case 0xB8:
INST_NAME("POPCNT Gd, Ed");
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x1);
SET_DFNONE();
nextop = F8;
v1 = fpu_get_scratch(dyn);
v1 = fpu_get_scratch(dyn, ninst);
GETGD;
if(MODREG) {
GETED(0);
@@ -404,45 +533,61 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
CNT_8(v1, v1);
UADDLV_8(v1, v1);
VMOVQDto(gd, v1, 0);
VMOVHto(gd, v1, 0);
IFX(X_ALL) {
MOV32w(x1, (1<<F_OF) | (1<<F_SF) | (1<<F_ZF) | (1<<F_AF) | (1<<F_CF) | (1<<F_PF));
BICw(xFlags, xFlags, x1);
CBNZx(gd, 4+4);
BFIw(xFlags, xFlags, F_ZF, 1);
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);
}
}
}
break;
case 0xBC:
INST_NAME("TZCNT Gd, Ed");
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
SET_DFNONE(x1);
SET_DFNONE();
nextop = F8;
GETED(0);
GETGD;
TSTxw_REG(ed, ed);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
IFX(X_CF) {
TSTxw_REG(ed, ed);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
}
RBITxw(x3, ed); // reverse
CLZxw(gd, x3); // x2 gets leading 0 == TZCNT
TSTxw_REG(gd, gd);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0?
IFX(X_ZF) {
TSTxw_REG(gd, gd);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0?
}
break;
case 0xBD:
INST_NAME("LZCNT Gd, Ed");
SETFLAGS(X_CF|X_ZF, SF_SUBSET);
SET_DFNONE(x1);
SET_DFNONE();
nextop = F8;
GETED(0);
GETGD;
TSTxw_REG(ed, ed);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
IFX(X_CF) {
TSTxw_REG(ed, ed);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_CF, 1); // CF = is source 0?
}
CLZxw(gd, ed); // x2 gets leading 0 == LZCNT
TSTxw_REG(gd, gd);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0?
IFX(X_ZF) {
TSTxw_REG(gd, gd);
CSETw(x3, cEQ);
BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0?
}
break;
case 0xC2:
@@ -485,7 +630,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
GETEXSD(v1, 0, 0);
GETGX_empty(v0);
d0 = fpu_get_scratch(dyn);
d0 = fpu_get_scratch(dyn, ninst);
SXTL_32(v0, v1);
SCVTQFD(v0, v0); // there is only I64 -> Double vector conversion, not from i32
break;
+646 -87
View File
@@ -25,27 +25,57 @@
#include "dynarec_arm64_functions.h"
#include "custommem.h"
#include "bridge.h"
#define XMM0 0
#define XMM8 16
#define X870 8
#define EMM0 8
#include "gdbjit.h"
// Get a FPU scratch reg
int fpu_get_scratch(dynarec_arm_t* dyn)
int fpu_get_scratch(dynarec_arm_t* dyn, int ninst)
{
return SCRATCH0 + dyn->n.fpu_scratch++; // return an Sx
int ret = SCRATCH0 + dyn->n.fpu_scratch++;
if(dyn->n.ymm_used) printf_log(LOG_INFO, "Warning, getting a scratch register after getting some YMM at inst=%d\n", ninst);
if(dyn->n.neoncache[ret].t==NEON_CACHE_YMMR || dyn->n.neoncache[ret].t==NEON_CACHE_YMMW) {
// should only happens in step 0...
dyn->insts[ninst].purge_ymm |= (1<<dyn->n.neoncache[ret].n); // mark as purged
dyn->n.neoncache[ret].v = 0; // reset it
}
return ret;
}
// Get 2 consicutive FPU scratch reg
int fpu_get_double_scratch(dynarec_arm_t* dyn, int ninst)
{
int ret = SCRATCH0 + dyn->n.fpu_scratch;
if(dyn->n.ymm_used) printf_log(LOG_INFO, "Warning, getting a double scratch register after getting some YMM at inst=%d\n", ninst);
if(dyn->n.neoncache[ret].t==NEON_CACHE_YMMR || dyn->n.neoncache[ret].t==NEON_CACHE_YMMW) {
// should only happens in step 0...
dyn->insts[ninst].purge_ymm |= (1<<dyn->n.neoncache[ret].n); // mark as purged
dyn->n.neoncache[ret].v = 0; // reset it
}
if(dyn->n.neoncache[ret+1].t==NEON_CACHE_YMMR || dyn->n.neoncache[ret+1].t==NEON_CACHE_YMMW) {
// should only happens in step 0...
dyn->insts[ninst].purge_ymm |= (1<<dyn->n.neoncache[ret+1].n); // mark as purged
dyn->n.neoncache[ret+1].v = 0; // reset it
}
dyn->n.fpu_scratch+=2;
return ret;
}
// Reset scratch regs counter
void fpu_reset_scratch(dynarec_arm_t* dyn)
{
dyn->n.fpu_scratch = 0;
dyn->n.ymm_used = 0;
dyn->n.ymm_regs = 0;
dyn->n.ymm_write = 0;
dyn->n.ymm_removed = 0;
}
// Get a x87 double reg
int fpu_get_reg_x87(dynarec_arm_t* dyn, int t, int n)
int fpu_get_reg_x87(dynarec_arm_t* dyn, int ninst, int t, int n)
{
int i=X870;
while (dyn->n.fpuused[i]) ++i;
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMR || dyn->n.neoncache[i].t==NEON_CACHE_YMMW) {
// should only happens in step 0...
dyn->insts[ninst].purge_ymm |= (1<<dyn->n.neoncache[i].n); // mark as purged
dyn->n.neoncache[i].v = 0; // reset it
}
dyn->n.fpuused[i] = 1;
dyn->n.neoncache[i].n = n;
dyn->n.neoncache[i].t = t;
@@ -57,17 +87,34 @@ void fpu_free_reg(dynarec_arm_t* dyn, int reg)
{
// TODO: check upper limit?
dyn->n.fpuused[reg] = 0;
if(dyn->n.neoncache[reg].t==NEON_CACHE_YMMR || dyn->n.neoncache[reg].t==NEON_CACHE_YMMW) {
dyn->n.ymm_removed |= 1<<dyn->n.neoncache[reg].n;
if(dyn->n.neoncache[reg].t==NEON_CACHE_YMMW)
dyn->n.ymm_write |= 1<<dyn->n.neoncache[reg].n;
if(reg>SCRATCH0)
dyn->n.ymm_regs |= (8LL+reg-SCRATCH0)<<(dyn->n.neoncache[reg].n*4);
else
dyn->n.ymm_regs |= ((uint64_t)(reg-EMM0))<<(dyn->n.neoncache[reg].n*4);
}
if(dyn->n.neoncache[reg].t!=NEON_CACHE_ST_F && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_D && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_I64)
dyn->n.neoncache[reg].v = 0;
if(dyn->n.fpu_scratch && reg==SCRATCH0+dyn->n.fpu_scratch-1)
--dyn->n.fpu_scratch;
}
// Get an MMX double reg
int fpu_get_reg_emm(dynarec_arm_t* dyn, int emm)
int fpu_get_reg_emm(dynarec_arm_t* dyn, int ninst, int emm)
{
dyn->n.fpuused[EMM0 + emm] = 1;
dyn->n.neoncache[EMM0 + emm].t = NEON_CACHE_MM;
dyn->n.neoncache[EMM0 + emm].n = emm;
dyn->n.news |= (1<<(EMM0 + emm));
return EMM0 + emm;
int ret = EMM0 + emm;
if(dyn->n.neoncache[ret].t==NEON_CACHE_YMMR || dyn->n.neoncache[ret].t==NEON_CACHE_YMMW) {
// should only happens in step 0...
dyn->insts[ninst].purge_ymm |= (1<<dyn->n.neoncache[ret].n); // mark as purged
dyn->n.neoncache[ret].v = 0; // reset it
}
dyn->n.fpuused[ret] = 1;
dyn->n.neoncache[ret].t = NEON_CACHE_MM;
dyn->n.neoncache[ret].n = emm;
dyn->n.news |= (1<<(ret));
return ret;
}
// Get an XMM quad reg
int fpu_get_reg_xmm(dynarec_arm_t* dyn, int t, int xmm)
@@ -84,15 +131,54 @@ int fpu_get_reg_xmm(dynarec_arm_t* dyn, int t, int xmm)
dyn->n.news |= (1<<i);
return i;
}
int internal_mark_ymm(dynarec_arm_t* dyn, int t, int ymm, int reg)
{
if((dyn->n.neoncache[reg].t==NEON_CACHE_YMMR) || (dyn->n.neoncache[reg].t==NEON_CACHE_YMMW)) {
if(dyn->n.neoncache[reg].n == ymm) {
// already there!
if(t==NEON_CACHE_YMMW)
dyn->n.neoncache[reg].t=t;
return reg;
}
} else if(!dyn->n.neoncache[reg].v) {
// found a slot!
dyn->n.neoncache[reg].t=t;
dyn->n.neoncache[reg].n=ymm;
dyn->n.news |= (1<<reg);
return reg;
}
return -1;
}
int is_ymm_to_keep(dynarec_arm_t* dyn, int reg, int k1, int k2, int k3)
{
if((k1!=-1) && (dyn->n.neoncache[reg].n==k1))
return 1;
if((k2!=-1) && (dyn->n.neoncache[reg].n==k2))
return 1;
if((k3!=-1) && (dyn->n.neoncache[reg].n==k3))
return 1;
if((dyn->n.neoncache[reg].t==NEON_CACHE_YMMR || dyn->n.neoncache[reg].t==NEON_CACHE_YMMW) && (dyn->n.ymm_used&(1<<dyn->n.neoncache[reg].n)))
return 1;
return 0;
}
// Reset fpu regs counter
static void fpu_reset_reg_neoncache(neoncache_t* n)
{
n->fpu_reg = 0;
for (int i=0; i<32; ++i) {
n->fpuused[i]=0;
n->neoncache[i].v = 0;
}
n->ymm_regs = 0;
n->ymm_removed = 0;
n->ymm_used = 0;
n->ymm_write = 0;
}
void fpu_reset_reg(dynarec_arm_t* dyn)
{
dyn->n.fpu_reg = 0;
for (int i=0; i<24; ++i) {
dyn->n.fpuused[i]=0;
dyn->n.neoncache[i].v = 0;
}
fpu_reset_reg_neoncache(&dyn->n);
}
int neoncache_no_i64(dynarec_arm_t* dyn, int ninst, int st, int a)
@@ -201,38 +287,36 @@ static void neoncache_promote_double_combined(dynarec_arm_t* dyn, int ninst, int
} else
a = dyn->insts[ninst].n.combined1;
int i = neoncache_get_st_f_i64_noback(dyn, ninst, a);
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_combined, ninst=%d combined%c %d i=%d (stack:%d/%d)\n", ninst, (a == dyn->insts[ninst].n.combined2)?'2':'1', a ,i, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_combined, ninst=%d combined%c %d i=%d (stack:%d/%d)\n", ninst, (a == dyn->insts[ninst].n.combined2)?'2':'1', a ,i, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop);
if(i>=0) {
dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
if(!dyn->insts[ninst].n.barrier)
neoncache_promote_double_internal(dyn, ninst-1, maxinst, a-dyn->insts[ninst].n.stack_push);
// go forward is combined is not pop'd
if(a-dyn->insts[ninst].n.stack_pop>=0)
if(!dyn->insts[ninst+1].n.barrier)
if(!((ninst+1<dyn->size) && dyn->insts[ninst+1].n.barrier))
neoncache_promote_double_forward(dyn, ninst+1, maxinst, a-dyn->insts[ninst].n.stack_pop);
}
}
}
static void neoncache_promote_double_internal(dynarec_arm_t* dyn, int ninst, int maxinst, int a)
{
if(dyn->insts[ninst+1].n.barrier)
return;
while(ninst>=0) {
a+=dyn->insts[ninst].n.stack_pop; // adjust Stack depth: add pop'd ST (going backward)
int i = neoncache_get_st_f_i64(dyn, ninst, a);
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_internal, ninst=%d, a=%d st=%d:%d, i=%d\n", ninst, a, dyn->insts[ninst].n.stack, dyn->insts[ninst].n.stack_next, i);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_internal, ninst=%d, a=%d st=%d:%d, i=%d\n", ninst, a, dyn->insts[ninst].n.stack, dyn->insts[ninst].n.stack_next, i);
if(i<0) return;
dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
// check combined propagation too
if(dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2) {
if(dyn->insts[ninst].n.swapped) {
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_internal, ninst=%d swapped %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_internal, ninst=%d swapped %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
if (a==dyn->insts[ninst].n.combined1)
a = dyn->insts[ninst].n.combined2;
else if (a==dyn->insts[ninst].n.combined2)
a = dyn->insts[ninst].n.combined1;
} else {
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_internal, ninst=%d combined %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_internal, ninst=%d combined %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
neoncache_promote_double_combined(dyn, ninst, maxinst, a);
}
}
@@ -248,19 +332,19 @@ static void neoncache_promote_double_forward(dynarec_arm_t* dyn, int ninst, int
while((ninst!=-1) && (ninst<maxinst) && (a>=0)) {
a+=dyn->insts[ninst].n.stack_push; // // adjust Stack depth: add push'd ST (going forward)
if((dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2) && dyn->insts[ninst].n.swapped) {
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d swapped %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d swapped %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
if (a==dyn->insts[ninst].n.combined1)
a = dyn->insts[ninst].n.combined2;
else if (a==dyn->insts[ninst].n.combined2)
a = dyn->insts[ninst].n.combined1;
}
int i = neoncache_get_st_f_i64_noback(dyn, ninst, a);
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d, a=%d st=%d:%d(%d/%d), i=%d\n", ninst, a, dyn->insts[ninst].n.stack, dyn->insts[ninst].n.stack_next, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop, i);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d, a=%d st=%d:%d(%d/%d), i=%d\n", ninst, a, dyn->insts[ninst].n.stack, dyn->insts[ninst].n.stack_next, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop, i);
if(i<0) return;
dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
// check combined propagation too
if((dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2) && !dyn->insts[ninst].n.swapped) {
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d combined %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d combined %d/%d vs %d with st %d\n", ninst, dyn->insts[ninst].n.combined1 ,dyn->insts[ninst].n.combined2, a, dyn->insts[ninst].n.stack);
neoncache_promote_double_combined(dyn, ninst, maxinst, a);
}
a-=dyn->insts[ninst].n.stack_pop; // adjust Stack depth: remove pop'd ST (going forward)
@@ -276,20 +360,20 @@ static void neoncache_promote_double_forward(dynarec_arm_t* dyn, int ninst, int
void neoncache_promote_double(dynarec_arm_t* dyn, int ninst, int a)
{
int i = neoncache_get_current_st_f_i64(dyn, a);
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double, ninst=%d a=%d st=%d i=%d\n", ninst, a, dyn->n.stack, i);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double, ninst=%d a=%d st=%d i=%d\n", ninst, a, dyn->n.stack, i);
if(i<0) return;
dyn->n.neoncache[i].t = NEON_CACHE_ST_D;
dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
// check combined propagation too
if(dyn->n.combined1 || dyn->n.combined2) {
if(dyn->n.swapped) {
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double, ninst=%d swapped! %d/%d vs %d\n", ninst, dyn->n.combined1 ,dyn->n.combined2, a);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double, ninst=%d swapped! %d/%d vs %d\n", ninst, dyn->n.combined1 ,dyn->n.combined2, a);
if(dyn->n.combined1 == a)
a = dyn->n.combined2;
else if(dyn->n.combined2 == a)
a = dyn->n.combined1;
} else {
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double, ninst=%d combined! %d/%d vs %d\n", ninst, dyn->n.combined1 ,dyn->n.combined2, a);
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "neoncache_promote_double, ninst=%d combined! %d/%d vs %d\n", ninst, dyn->n.combined1 ,dyn->n.combined2, a);
if(dyn->n.combined1 == a)
neoncache_promote_double(dyn, ninst, dyn->n.combined2);
else if(dyn->n.combined2 == a)
@@ -341,10 +425,11 @@ int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst) {
return ((dyn->insts[ninst].x64.barrier&BARRIER_FLOAT))?0:(isCacheEmpty(dyn, ninst)?0:1);
int ret = 0;
if(!i2) { // just purge
if(dyn->insts[ninst].n.stack_next) {
if(dyn->insts[ninst].n.stack_next)
return 1;
}
for(int i=0; i<24 && !ret; ++i)
if(dyn->insts[ninst].ymm0_out)
return 1;
for(int i=0; i<32 && !ret; ++i)
if(dyn->insts[ninst].n.neoncache[i].v) { // there is something at ninst for i
if(!(
(dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F
@@ -359,10 +444,12 @@ int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst) {
if(dyn->insts[ninst].n.stack_next != dyn->insts[i2].n.stack-dyn->insts[i2].n.stack_push) {
return 1;
}
if(dyn->insts[ninst].ymm0_out && (dyn->insts[ninst].ymm0_out&~dyn->insts[i2].ymm0_in))
return 1;
neoncache_t cache_i2 = dyn->insts[i2].n;
neoncacheUnwind(&cache_i2);
for(int i=0; i<24; ++i) {
for(int i=0; i<32; ++i) {
if(dyn->insts[ninst].n.neoncache[i].v) { // there is something at ninst for i
if(!cache_i2.neoncache[i].v) { // but there is nothing at i2 for i
ret = 1;
@@ -372,6 +459,8 @@ int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst) {
}
else if(dyn->insts[ninst].n.neoncache[i].t == NEON_CACHE_XMMR && cache_i2.neoncache[i].t == NEON_CACHE_XMMW)
{/* nothing */ }
else if(dyn->insts[ninst].n.neoncache[i].t == NEON_CACHE_YMMR && cache_i2.neoncache[i].t == NEON_CACHE_YMMW)
{/* nothing */ }
else
ret = 1;
}
@@ -387,6 +476,7 @@ void neoncacheUnwind(neoncache_t* cache)
// unswap
int a = -1;
int b = -1;
// in neoncache
for(int j=0; j<24 && ((a==-1) || (b==-1)); ++j)
if((cache->neoncache[j].t == NEON_CACHE_ST_D || cache->neoncache[j].t == NEON_CACHE_ST_F || cache->neoncache[j].t == NEON_CACHE_ST_I64)) {
if(cache->neoncache[j].n == cache->combined1)
@@ -399,12 +489,13 @@ void neoncacheUnwind(neoncache_t* cache)
cache->neoncache[a].n = cache->neoncache[b].n;
cache->neoncache[b].n = tmp;
}
// done
cache->swapped = 0;
cache->combined1 = cache->combined2 = 0;
}
if(cache->news) {
// reove the newly created neoncache
for(int i=0; i<24; ++i)
// remove the newly created neoncache
for(int i=0; i<32; ++i)
if(cache->news&(1<<i))
cache->neoncache[i].v = 0;
cache->news = 0;
@@ -420,17 +511,28 @@ void neoncacheUnwind(neoncache_t* cache)
}
}
cache->x87stack-=cache->stack_push;
cache->tags>>=(cache->stack_push*2);
cache->stack-=cache->stack_push;
if(cache->pushed>=cache->stack_push)
cache->pushed-=cache->stack_push;
else
cache->pushed = 0;
cache->stack_push = 0;
}
cache->x87stack+=cache->stack_pop;
cache->stack_next = cache->stack;
if(cache->stack_pop) {
if(cache->poped>=cache->stack_pop)
cache->poped-=cache->stack_pop;
else
cache->poped = 0;
cache->tags<<=(cache->stack_pop*2);
}
cache->stack_pop = 0;
cache->barrier = 0;
// And now, rebuild the x87cache info with neoncache
cache->mmxcount = 0;
cache->fpu_scratch = 0;
cache->fpu_extra_qscratch = 0;
cache->fpu_reg = 0;
for(int i=0; i<8; ++i) {
cache->x87cache[i] = -1;
@@ -440,7 +542,7 @@ void neoncacheUnwind(neoncache_t* cache)
cache->ssecache[i*2+1].v = -1;
}
int x87reg = 0;
for(int i=0; i<24; ++i) {
for(int i=0; i<32; ++i) {
if(cache->neoncache[i].v) {
cache->fpuused[i] = 1;
switch (cache->neoncache[i].t) {
@@ -455,6 +557,10 @@ void neoncacheUnwind(neoncache_t* cache)
cache->ssecache[cache->neoncache[i].n].write = (cache->neoncache[i].t==NEON_CACHE_XMMW)?1:0;
++cache->fpu_reg;
break;
case NEON_CACHE_YMMR:
case NEON_CACHE_YMMW:
cache->fpuused[i] = 0; // YMM does not mark the fpu reg as used
break;
case NEON_CACHE_ST_F:
case NEON_CACHE_ST_D:
case NEON_CACHE_ST_I64:
@@ -472,11 +578,29 @@ void neoncacheUnwind(neoncache_t* cache)
cache->fpuused[i] = 0;
}
}
// add back removed YMM
if(cache->ymm_removed) {
for(int i=0; i<16; ++i)
if(cache->ymm_removed&(1<<i)) {
int reg = cache->ymm_regs>>(i*4)&15;
if(reg>7)
reg = reg - 8 + SCRATCH0;
else
reg = reg + EMM0;
if(cache->neoncache[reg].v)
printf_log(LOG_INFO, "Warning, recreating YMM%d on non empty slot %s", i, getCacheName(cache->neoncache[reg].t, cache->neoncache[reg].n));
cache->neoncache[reg].t = (cache->ymm_write&(1<<i))?NEON_CACHE_YMMW:NEON_CACHE_YMMR;
cache->neoncache[reg].n = i;
}
cache->ymm_regs = 0;
cache->ymm_write = cache->ymm_removed = 0;
}
cache->ymm_used = 0;
}
#define F8 *(uint8_t*)(addr++)
#define F32S64 (uint64_t)(int64_t)*(int32_t*)(addr+=4, addr-4)
// Get if ED will have the correct parity. Not emiting anything. Parity is 2 for DWORD or 3 for QWORD
// Get if ED will have the correct parity. Not emitting anything. Parity is 2 for DWORD or 3 for QWORD
int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, int parity, int delta)
{
(void)dyn; (void)ninst;
@@ -527,65 +651,500 @@ const char* getCacheName(int t, int n)
case NEON_CACHE_MM: sprintf(buff, "MM%d", n); break;
case NEON_CACHE_XMMW: sprintf(buff, "XMM%d", n); break;
case NEON_CACHE_XMMR: sprintf(buff, "xmm%d", n); break;
case NEON_CACHE_YMMW: sprintf(buff, "YMM%d", n); break;
case NEON_CACHE_YMMR: sprintf(buff, "ymm%d", n); break;
case NEON_CACHE_SCR: sprintf(buff, "Scratch"); break;
case NEON_CACHE_NONE: buff[0]='\0'; break;
}
return buff;
}
static register_mapping_t register_mappings[] = {
{ "rax", "x10" },
{ "eax", "w10" },
{ "ax", "x10" },
{ "ah", "x10" },
{ "al", "x10" },
{ "rcx", "x11" },
{ "ecx", "w11" },
{ "cx", "x11" },
{ "ch", "x11" },
{ "cl", "x11" },
{ "rdx", "x12" },
{ "edx", "w12" },
{ "dx", "x12" },
{ "dh", "x12" },
{ "dl", "x12" },
{ "rbx", "x13" },
{ "ebx", "w13" },
{ "bx", "x13" },
{ "bh", "x13" },
{ "bl", "x13" },
{ "rsi", "x14" },
{ "esi", "w14" },
{ "si", "x14" },
{ "sil", "x14" },
{ "rdi", "x15" },
{ "edi", "w15" },
{ "di", "x15" },
{ "dil", "x15" },
{ "rsp", "x16" },
{ "esp", "w16" },
{ "sp", "x16" },
{ "spl", "x16" },
{ "rbp", "x17" },
{ "ebp", "w17" },
{ "bp", "x17" },
{ "bpl", "x17" },
{ "r8", "x18" },
{ "r8d", "w18" },
{ "r8w", "x18" },
{ "r8b", "x18" },
{ "r9", "x19" },
{ "r9d", "w19" },
{ "r9w", "x19" },
{ "r9b", "x19" },
{ "r10", "x20" },
{ "r10d", "w20" },
{ "r10w", "x20" },
{ "r10b", "x20" },
{ "r11", "x21" },
{ "r11d", "w21" },
{ "r11w", "x21" },
{ "r11b", "x21" },
{ "r12", "x22" },
{ "r12d", "w22" },
{ "r12w", "x22" },
{ "r12b", "x22" },
{ "r13", "x23" },
{ "r13d", "w23" },
{ "r13w", "x23" },
{ "r13b", "x23" },
{ "r14", "x24" },
{ "r14d", "w24" },
{ "r14w", "x24" },
{ "r14b", "x24" },
{ "r15", "x25" },
{ "r15d", "w25" },
{ "r15w", "x25" },
{ "r15b", "x25" },
{ "rip", "x27" },
};
void printf_x64_instruction(dynarec_native_t* dyn, zydis_dec_t* dec, instruction_x64_t* inst, const char* name);
void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex)
{
if(box64_dynarec_dump) {
printf_x64_instruction(rex.is32bits?my_context->dec32:my_context->dec, &dyn->insts[ninst].x64, name);
dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d/%d",
(box64_dynarec_dump>1)?"\e[32m":"",
(void*)(dyn->native_start+dyn->insts[ninst].address),
dyn->insts[ninst].size/4,
ninst,
dyn->insts[ninst].x64.barrier,
dyn->insts[ninst].x64.state_flags,
dyn->f.pending,
dyn->f.dfnone,
dyn->insts[ninst].x64.may_set?"may":"set",
dyn->insts[ninst].x64.set_flags,
dyn->insts[ninst].x64.gen_flags,
dyn->insts[ninst].x64.use_flags,
dyn->insts[ninst].x64.need_before,
dyn->insts[ninst].x64.need_after,
dyn->smread, dyn->smwrite);
if(dyn->insts[ninst].pred_sz) {
dynarec_log(LOG_NONE, ", pred=");
for(int ii=0; ii<dyn->insts[ninst].pred_sz; ++ii)
dynarec_log(LOG_NONE, "%s%d", ii?"/":"", dyn->insts[ninst].pred[ii]);
if (!BOX64DRENV(dynarec_dump) && !BOX64ENV(dynarec_gdbjit) && !BOX64ENV(dynarec_perf_map)) return;
static char buf[256];
int length = sprintf(buf, "barrier=%d state=%d/%d/%d(%d:%d->%d:%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)",
dyn->insts[ninst].x64.barrier,
dyn->insts[ninst].x64.state_flags,
dyn->f.pending,
dyn->f.dfnone,
dyn->insts[ninst].f_entry.pending,
dyn->insts[ninst].f_entry.dfnone,
dyn->insts[ninst].f_exit.pending,
dyn->insts[ninst].f_exit.dfnone,
dyn->insts[ninst].x64.may_set ? "may" : "set",
dyn->insts[ninst].x64.set_flags,
dyn->insts[ninst].x64.gen_flags,
dyn->insts[ninst].x64.use_flags,
dyn->insts[ninst].x64.need_before,
dyn->insts[ninst].x64.need_after,
dyn->smwrite, dyn->insts[ninst].will_write, dyn->insts[ninst].last_write);
if (dyn->insts[ninst].nat_flags_op) {
if (dyn->insts[ninst].nat_flags_op == NAT_FLAG_OP_TOUCH && dyn->insts[ninst].before_nat_flags)
length += sprintf(buf + length, " NF:%d/read:%x", dyn->insts[ninst].nat_flags_op, dyn->insts[ninst].before_nat_flags);
else
length += sprintf(buf + length, " NF:%d", dyn->insts[ninst].nat_flags_op);
}
if (dyn->insts[ninst].use_nat_flags || dyn->insts[ninst].set_nat_flags || dyn->insts[ninst].need_nat_flags) {
length += sprintf(buf + length, " nf:%hhx/%hhx/%hhx", dyn->insts[ninst].set_nat_flags, dyn->insts[ninst].use_nat_flags, dyn->insts[ninst].need_nat_flags);
}
if (dyn->insts[ninst].invert_carry)
length += sprintf(buf + length, " CI");
if (dyn->insts[ninst].gen_inverted_carry)
length += sprintf(buf + length, " gic");
if (dyn->insts[ninst].before_nat_flags & NF_CF) {
length += sprintf(buf + length, " %ccb", dyn->insts[ninst].normal_carry_before ? 'n' : 'i');
}
if (dyn->insts[ninst].need_nat_flags & NF_CF) {
length += sprintf(buf + length, " %cc", dyn->insts[ninst].normal_carry ? 'n' : 'i');
}
if (dyn->insts[ninst].pred_sz) {
length += sprintf(buf + length, ", pred=");
for (int ii = 0; ii < dyn->insts[ninst].pred_sz; ++ii)
length += sprintf(buf + length, "%s%d", ii ? "/" : "", dyn->insts[ninst].pred[ii]);
}
if (!dyn->insts[ninst].x64.alive)
length += sprintf(buf + length, "not executed");
if (dyn->insts[ninst].x64.jmp && dyn->insts[ninst].x64.jmp_insts >= 0) {
length += sprintf(buf + length, ", jmp=%d", dyn->insts[ninst].x64.jmp_insts);
}
if (dyn->insts[ninst].x64.jmp && dyn->insts[ninst].x64.jmp_insts == -1)
length += sprintf(buf + length, ", jmp=out");
if (dyn->insts[ninst].x64.has_callret)
length += sprintf(buf + length, ", callret");
if (dyn->last_ip) {
length += sprintf(buf + length, ", last_ip=%p", (void*)dyn->last_ip);
}
for (int ii = 0; ii < 32; ++ii) {
switch (dyn->insts[ninst].n.neoncache[ii].t) {
case NEON_CACHE_ST_D: length += sprintf(buf + length, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_ST_F: length += sprintf(buf + length, " S%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_ST_I64: length += sprintf(buf + length, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_MM: length += sprintf(buf + length, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_XMMW: length += sprintf(buf + length, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_XMMR: length += sprintf(buf + length, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_YMMW: length += sprintf(buf + length, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_YMMR: length += sprintf(buf + length, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
// case NEON_CACHE_SCR: length += sprintf(buf + length, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_NONE:
default: break;
}
if(dyn->insts[ninst].x64.jmp && dyn->insts[ninst].x64.jmp_insts>=0)
dynarec_log(LOG_NONE, ", jmp=%d", dyn->insts[ninst].x64.jmp_insts);
if(dyn->insts[ninst].x64.jmp && dyn->insts[ninst].x64.jmp_insts==-1)
dynarec_log(LOG_NONE, ", jmp=out");
if(dyn->last_ip)
dynarec_log(LOG_NONE, ", last_ip=%p", (void*)dyn->last_ip);
for(int ii=0; ii<24; ++ii) {
switch(dyn->insts[ninst].n.neoncache[ii].t) {
case NEON_CACHE_ST_D: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_ST_F: dynarec_log(LOG_NONE, " S%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_ST_I64: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_MM: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_XMMW: dynarec_log(LOG_NONE, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_XMMR: dynarec_log(LOG_NONE, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_SCR: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
case NEON_CACHE_NONE:
default: break;
}
if (memcmp(dyn->insts[ninst].n.neoncache, dyn->n.neoncache, sizeof(dyn->n.neoncache))) {
length += sprintf(buf + length, " %s(Change:", (BOX64DRENV(dynarec_dump) > 1) ? "\e[1;91m" : "");
for (int ii = 0; ii < 32; ++ii)
if (dyn->insts[ninst].n.neoncache[ii].v != dyn->n.neoncache[ii].v) {
length += sprintf(buf + length, " V%d:%s", ii, getCacheName(dyn->n.neoncache[ii].t, dyn->n.neoncache[ii].n));
length += sprintf(buf + length, "->%s", getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n));
}
length += sprintf(buf + length, ")%s", (BOX64DRENV(dynarec_dump) > 1) ? "\e[0;32m" : "");
}
if (dyn->insts[ninst].n.ymm_used) {
length += sprintf(buf + length, " ymmUsed=%04x", dyn->insts[ninst].n.ymm_used);
}
if (dyn->ymm_zero || dyn->insts[ninst].ymm0_add || dyn->insts[ninst].ymm0_sub || dyn->insts[ninst].ymm0_out) {
length += sprintf(buf + length, " ymm0=(%04x/%04x+%04x-%04x=%04x)", dyn->ymm_zero, dyn->insts[ninst].ymm0_in, dyn->insts[ninst].ymm0_add, dyn->insts[ninst].ymm0_sub, dyn->insts[ninst].ymm0_out);
}
if (dyn->insts[ninst].purge_ymm) {
length += sprintf(buf + length, " purgeYmm=%04x", dyn->insts[ninst].purge_ymm);
}
if (dyn->n.stack || dyn->insts[ninst].n.stack_next || dyn->insts[ninst].n.x87stack) {
length += sprintf(buf + length, " X87:%d/%d(+%d/-%d)%d", dyn->n.stack, dyn->insts[ninst].n.stack_next, dyn->insts[ninst].n.stack_push, dyn->insts[ninst].n.stack_pop, dyn->insts[ninst].n.x87stack);
}
if (dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2) {
length += sprintf(buf + length, " %s:%d/%d", dyn->insts[ninst].n.swapped ? "SWP" : "CMB", dyn->insts[ninst].n.combined1, dyn->insts[ninst].n.combined2);
}
if (BOX64DRENV(dynarec_dump)) {
printf_x64_instruction(dyn, rex.is32bits ? my_context->dec32 : my_context->dec, &dyn->insts[ninst].x64, name);
dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, %s%s\n",
(BOX64DRENV(dynarec_dump) > 1) ? "\e[32m" : "",
(void*)(dyn->native_start + dyn->insts[ninst].address), dyn->insts[ninst].size / 4, ninst, buf, (BOX64DRENV(dynarec_dump) > 1) ? "\e[m" : "");
}
if (BOX64ENV(dynarec_gdbjit)) {
static char buf2[512];
if (BOX64ENV(dynarec_gdbjit) > 1) {
sprintf(buf2, "; %d: %d opcodes, %s", ninst, dyn->insts[ninst].size / 4, buf);
dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), buf2);
}
if(dyn->n.stack || dyn->insts[ninst].n.stack_next || dyn->insts[ninst].n.x87stack)
dynarec_log(LOG_NONE, " X87:%d/%d(+%d/-%d)%d", dyn->n.stack, dyn->insts[ninst].n.stack_next, dyn->insts[ninst].n.stack_push, dyn->insts[ninst].n.stack_pop, dyn->insts[ninst].n.x87stack);
if(dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2)
dynarec_log(LOG_NONE, " %s:%d/%d", dyn->insts[ninst].n.swapped?"SWP":"CMB", dyn->insts[ninst].n.combined1, dyn->insts[ninst].n.combined2);
dynarec_log(LOG_NONE, "%s\n", (box64_dynarec_dump>1)?"\e[m":"");
zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;
const char* inst_name = name;
if (dec) {
inst_name = DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0);
x64disas_add_register_mapping_annotations(buf2, inst_name, register_mappings, sizeof(register_mappings) / sizeof(register_mappings[0]));
inst_name = buf2;
}
dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), inst_name);
}
if (BOX64ENV(dynarec_perf_map) && BOX64ENV(dynarec_perf_map_fd) != -1) {
writePerfMap(dyn->insts[ninst].x64.addr, dyn->native_start + dyn->insts[ninst].address, dyn->insts[ninst].size / 4, name);
}
}
void print_opcode(dynarec_native_t* dyn, int ninst, uint32_t opcode)
{
dynarec_log(LOG_NONE, "\t%08x\t%s\n", opcode, arm64_print(opcode, (uintptr_t)dyn->block));
dynarec_log_prefix(0, LOG_NONE, "\t%08x\t%s\n", opcode, arm64_print(opcode, (uintptr_t)dyn->block));
}
static void x87_reset(neoncache_t* n)
{
for (int i=0; i<8; ++i)
n->x87cache[i] = -1;
n->tags = 0;
n->x87stack = 0;
n->stack = 0;
n->stack_next = 0;
n->stack_pop = 0;
n->stack_push = 0;
n->combined1 = n->combined2 = 0;
n->swapped = 0;
n->barrier = 0;
n->pushed = 0;
n->poped = 0;
for(int i=0; i<24; ++i)
if(n->neoncache[i].t == NEON_CACHE_ST_F
|| n->neoncache[i].t == NEON_CACHE_ST_D
|| n->neoncache[i].t == NEON_CACHE_ST_I64)
n->neoncache[i].v = 0;
}
static void mmx_reset(neoncache_t* n)
{
n->mmxcount = 0;
for (int i=0; i<8; ++i)
n->mmxcache[i] = -1;
}
static void sse_reset(neoncache_t* n)
{
for (int i=0; i<16; ++i)
n->ssecache[i].v = -1;
for (int i=0; i<32; ++i)
if(n->neoncache[i].t==NEON_CACHE_YMMR || n->neoncache[i].t==NEON_CACHE_YMMW)
n->neoncache[i].v = 0;
}
void fpu_reset(dynarec_native_t* dyn)
{
x87_reset(&dyn->n);
mmx_reset(&dyn->n);
sse_reset(&dyn->n);
fpu_reset_reg(dyn);
dyn->ymm_zero = 0;
}
void fpu_reset_ninst(dynarec_native_t* dyn, int ninst)
{
x87_reset(&dyn->insts[ninst].n);
mmx_reset(&dyn->insts[ninst].n);
sse_reset(&dyn->insts[ninst].n);
fpu_reset_reg_neoncache(&dyn->insts[ninst].n);
}
int fpu_is_st_freed(dynarec_native_t* dyn, int ninst, int st)
{
return (dyn->n.tags&(0b11<<(st*2)))?1:0;
}
uint8_t mark_natflag(dynarec_arm_t* dyn, int ninst, uint8_t flag, int before)
{
if(dyn->insts[ninst].x64.set_flags && !before) {
dyn->insts[ninst].set_nat_flags |= flag;
//if(dyn->insts[ninst].x64.use_flags) {
// dyn->insts[ninst].use_nat_flags |= flag;
//}
} else {
if(before)
dyn->insts[ninst].use_nat_flags_before |= flag;
else
dyn->insts[ninst].use_nat_flags |= flag;
}
return flag;
}
uint8_t flag2native(uint8_t flags)
{
uint8_t ret = 0;
#ifdef ARM64
if(flags&X_ZF) ret|=NF_EQ;
if(flags&X_SF) ret|=NF_SF;
if(flags&X_OF) ret|=NF_VF;
if(flags&X_CF) ret|=NF_CF;
#else
// no native flags on rv64 or la64
#endif
return ret;
}
int flagIsNative(uint8_t flags)
{
if(flags&(X_AF|X_PF)) return 0;
return 1;
}
static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags)
{
// propagate and check wich flags are actually used
uint8_t used_flags = 0;
int nat_flags_used = 0;
int ninst = start;
while(ninst<dyn->size) {
//printf_log(LOG_INFO, "getNativeFlagsUsed ninst:%d/%d, flags=%x, used_flags=%x(%d), nat_flags_op_before:%x, nat_flags_op:%x, need_after:%x set_nat_flags:%x nat_flags_used:%x(%x)\n", ninst, start, flags, used_flags, nat_flags_used, dyn->insts[ninst].nat_flags_op_before, dyn->insts[ninst].nat_flags_op, flag2native(dyn->insts[ninst].x64.need_after),dyn->insts[ninst].set_nat_flags, dyn->insts[ninst].use_nat_flags, dyn->insts[ninst].use_nat_flags_before);
// check if this is an opcode that generate flags but consume flags before
if(dyn->insts[ninst].nat_flags_op_before)
return 0;
// check if nat flags are used "before"
if(dyn->insts[ninst].use_nat_flags_before) {
// check if the gen flags are compatible
if(dyn->insts[ninst].use_nat_flags_before&~flags)
return 0;
nat_flags_used = 1;
used_flags|=dyn->insts[ninst].use_nat_flags_before&flags;
}
// if the opcode generate flags, return
if(dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH && (start!=ninst)) {
if(!nat_flags_used)
return 0;
if(used_flags&~dyn->insts[ninst].set_nat_flags) {
// check partial changes that would destroy flag state
if(dyn->insts[ninst].use_nat_flags_before&flags)
return used_flags;
// check if flags are all refreshed, then it's ok
if((used_flags&dyn->insts[ninst].set_nat_flags)==used_flags)
return used_flags;
// incompatible
return 0;
}
return used_flags;
}
// check if there is a callret barrier
if(dyn->insts[ninst].x64.has_callret)
return 0;
// check if nat flags are used
if(dyn->insts[ninst].use_nat_flags) {
// check if the gen flags are compatible
if(dyn->insts[ninst].use_nat_flags&~flags)
return 0;
nat_flags_used = 1;
used_flags |= dyn->insts[ninst].use_nat_flags&flags;
}
if(ninst!=start && dyn->insts[ninst].x64.use_flags) {
// some flags not compatible with native, partial use not allowed
if(flag2native(dyn->insts[ninst].x64.use_flags)!=dyn->insts[ninst].use_nat_flags)
return 0;
// check if flags are used, but not the natives ones
//if(dyn->insts[ninst].use_nat_flags&~used_flags)
// return 0;
}
// check if flags are generated without native option
if((start!=ninst) && dyn->insts[ninst].x64.gen_flags && (flag2native(dyn->insts[ninst].x64.gen_flags&dyn->insts[ninst].x64.need_after)&used_flags)) {
if(used_flags&~flag2native(dyn->insts[ninst].x64.gen_flags&dyn->insts[ninst].x64.need_after))
return 0; // partial covert, not supported for now (TODO: this might be fixable)
else
return nat_flags_used?used_flags:0; // full covert... End of propagation
}
// check if flags are still needed
if(!(flag2native(dyn->insts[ninst].x64.need_after)&flags))
return nat_flags_used?used_flags:0;
// check if flags are destroyed, cancel the use then
if(dyn->insts[ninst].nat_flags_op && (start!=ninst))
return 0;
// update used flags
//used_flags |= (flag2native(dyn->insts[ninst].x64.need_after)&flags);
// go next
if(!dyn->insts[ninst].x64.has_next) {
// check if it's a jump to an opcode with only 1 preds, then just follow the jump
int jmp = dyn->insts[ninst].x64.jmp_insts;
if(dyn->insts[ninst].x64.jmp && (jmp!=-1) && (getNominalPred(dyn, jmp)==ninst))
ninst = jmp;
else
return nat_flags_used?used_flags:0;
} else
++ninst;
}
return nat_flags_used?used_flags:0;
}
static void propagateNativeFlags(dynarec_arm_t* dyn, int start)
{
int ninst = start;
// those are the flags generated by the opcode and used later on
uint8_t flags = dyn->insts[ninst].set_nat_flags&flag2native(dyn->insts[ninst].x64.need_after);
//check if they are actualy used before starting
//printf_log(LOG_INFO, "propagateNativeFlags called for start=%d, flags=%x, will need:%x\n", start, flags, flag2native(dyn->insts[ninst].x64.need_after));
if(!flags) return;
// also check if some native flags are used but not genereated here
if(flag2native(dyn->insts[ninst].x64.use_flags)&~flags) return;
uint8_t used_flags = getNativeFlagsUsed(dyn, start, flags);
//printf_log(LOG_INFO, " will use:%x, carry:%d, generate inverted carry:%d\n", used_flags, used_flags&NF_CF, dyn->insts[ninst].gen_inverted_carry);
if(!used_flags) return; // the flags wont be used, so just cancel
int nc = dyn->insts[ninst].gen_inverted_carry?0:1;
int carry = used_flags&NF_CF;
// propagate
while(ninst<dyn->size) {
// check if this is an opcode that generate flags but consume flags before
if((start!=ninst) && dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH) {
if(dyn->insts[ninst].use_nat_flags_before) {
dyn->insts[ninst].before_nat_flags |= used_flags;
if(carry) dyn->insts[ninst].normal_carry_before = nc;
}
// if the opcode generate flags, return
return;
}
// check if flags are generated without native option
if((start!=ninst) && dyn->insts[ninst].x64.gen_flags && (flag2native(dyn->insts[ninst].x64.gen_flags&dyn->insts[ninst].x64.need_after)&used_flags))
return;
// mark the opcode
uint8_t use_flags = flag2native(dyn->insts[ninst].x64.need_before|dyn->insts[ninst].x64.need_after);
if(dyn->insts[ninst].x64.use_flags) use_flags |= flag2native(dyn->insts[ninst].x64.use_flags); // should not change anything
//printf_log(LOG_INFO, " marking ninst=%d with %x | %x&%x => %x\n", ninst, dyn->insts[ninst].need_nat_flags, used_flags, use_flags, dyn->insts[ninst].need_nat_flags | (used_flags&use_flags));
dyn->insts[ninst].need_nat_flags |= used_flags&use_flags;
if(carry) dyn->insts[ninst].normal_carry = nc;
if(carry && dyn->insts[ninst].invert_carry) nc = 0;
// check if flags are still needed
if(!(flag2native(dyn->insts[ninst].x64.need_after)&used_flags))
return;
// go next
if(!dyn->insts[ninst].x64.has_next) {
// check if it's a jump to an opcode with only 1 preds, then just follow the jump
int jmp = dyn->insts[ninst].x64.jmp_insts;
if(dyn->insts[ninst].x64.jmp && (jmp!=-1) && (getNominalPred(dyn, jmp)==ninst))
ninst = jmp;
else
return;
} else
++ninst;
}
}
void updateNativeFlags(dynarec_native_t* dyn)
{
if(!BOX64ENV(dynarec_nativeflags))
return;
// forward check if native flags are used
for(int ninst=0; ninst<dyn->size; ++ninst)
if(flag2native(dyn->insts[ninst].x64.gen_flags) && (dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH)) {
propagateNativeFlags(dyn, ninst);
}
}
void rasNativeState(dynarec_arm_t* dyn, int ninst)
{
dyn->insts[ninst].nat_flags_op = dyn->insts[ninst].set_nat_flags = dyn->insts[ninst].use_nat_flags = dyn->insts[ninst].need_nat_flags = 0;
}
int nativeFlagsNeedsTransform(dynarec_arm_t* dyn, int ninst)
{
int jmp = dyn->insts[ninst].x64.jmp_insts;
if(jmp<0)
return 0;
if(!dyn->insts[ninst].x64.need_after || !dyn->insts[jmp].x64.need_before)
return 0;
if(dyn->insts[ninst].set_nat_flags)
return 0;
uint8_t flags_before = dyn->insts[ninst].need_nat_flags;
uint8_t nc_before = dyn->insts[ninst].normal_carry;
if(dyn->insts[ninst].invert_carry)
nc_before = 0;
uint8_t flags_after = dyn->insts[jmp].need_nat_flags;
uint8_t nc_after = dyn->insts[jmp].normal_carry;
if(dyn->insts[jmp].nat_flags_op==NAT_FLAG_OP_TOUCH) {
flags_after = dyn->insts[jmp].before_nat_flags;
nc_after = dyn->insts[jmp].normal_carry_before;
}
uint8_t flags_x86 = flag2native(dyn->insts[jmp].x64.need_before);
flags_x86 &= ~flags_after;
if((flags_before&NF_CF) && (flags_after&NF_CF) && (nc_before!=nc_after))
return 1;
// all flags_after should be present and none remaining flags_x86
if(((flags_before&flags_after)!=flags_after) || (flags_before&flags_x86))
return 1;
return 0;
}
void fpu_save_and_unwind(dynarec_arm_t* dyn, int ninst, neoncache_t* cache)
{
memcpy(cache, &dyn->insts[ninst].n, sizeof(neoncache_t));
neoncacheUnwind(&dyn->insts[ninst].n);
}
void fpu_unwind_restore(dynarec_arm_t* dyn, int ninst, neoncache_t* cache)
{
memcpy(&dyn->insts[ninst].n, cache, sizeof(neoncache_t));
}
+35 -4
View File
@@ -4,21 +4,32 @@
#include "../dynarec_native_functions.h"
#define SCRATCH0 24
#define XMM0 0
#define XMM8 16
#define X870 8
#define EMM0 8
// Get an FPU scratch reg
int fpu_get_scratch(dynarec_arm_t* dyn);
int fpu_get_scratch(dynarec_arm_t* dyn, int ninst);
// Get 2 consecutive FPU scratch reg
int fpu_get_double_scratch(dynarec_arm_t* dyn, int ninst);
// Reset scratch regs counter
void fpu_reset_scratch(dynarec_arm_t* dyn);
// Get an x87 double reg
int fpu_get_reg_x87(dynarec_arm_t* dyn, int t, int n);
int fpu_get_reg_x87(dynarec_arm_t* dyn, int ninst, int t, int n);
// Get an MMX double reg
int fpu_get_reg_emm(dynarec_arm_t* dyn, int emm);
int fpu_get_reg_emm(dynarec_arm_t* dyn, int ninst, int emm);
// Get an XMM quad reg
int fpu_get_reg_xmm(dynarec_arm_t* dyn, int t, int xmm);
// Free a FPU/MMX/XMM reg
void fpu_free_reg(dynarec_arm_t* dyn, int reg);
// Reset fpu regs counter
void fpu_reset_reg(dynarec_arm_t* dyn);
// internal YMM handling
int internal_mark_ymm(dynarec_arm_t* dyn, int t, int ymm, int reg);
// is ymm neoncache[reg] one of k1, k2, k3?
int is_ymm_to_keep(dynarec_arm_t* dyn, int reg, int k1, int k2, int k3);
// ---- Neon cache functions
// Get type for STx
@@ -40,18 +51,38 @@ int neoncache_combine_st(dynarec_arm_t* dyn, int ninst, int a, int b); // with
// Do not allow i64 type
int neoncache_no_i64(dynarec_arm_t* dyn, int ninst, int st, int a);
// transform x86 flags to native flags
uint8_t flag2native(uint8_t flags);
// mark a instruction as using/generating flags. return flag
uint8_t mark_natflag(dynarec_arm_t* dyn, int ninst, uint8_t flag, int before);
// propage the use of nativeflags or not (done between step 0 and step 1)
void updateNativeFlags(dynarec_arm_t* dyn);
// raz arm speicifc state when an opcode is unused
void rasNativeState(dynarec_arm_t* dyn, int ninst);
// check if natives flags needs some tranform to/from x86 flags
int nativeFlagsNeedsTransform(dynarec_arm_t* dyn, int ninst);
// FPU Cache transformation (for loops) // Specific, need to be written by backend
int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst);
// Undo the changes of a neoncache to get the status before the instruction
void neoncacheUnwind(neoncache_t* cache);
void fpu_save_and_unwind(dynarec_arm_t* dyn, int ninst, neoncache_t* cache);
void fpu_unwind_restore(dynarec_arm_t* dyn, int ninst, neoncache_t* cache);
// Get if ED will have the correct parity. Not emiting anything. Parity is 2 for DWORD or 3 for QWORD
// Get if ED will have the correct parity. Not emitting anything. Parity is 2 for DWORD or 3 for QWORD
int getedparity(dynarec_native_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, int parity, int delta);
const char* getCacheName(int t, int n);
void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex);
void print_opcode(dynarec_native_t* dyn, int ninst, uint32_t opcode);
// reset the cache
void fpu_reset(dynarec_native_t* dyn);
void fpu_reset_ninst(dynarec_native_t* dyn, int ninst);
// is st freed
int fpu_is_st_freed(dynarec_native_t* dyn, int ninst, int st);
#endif //__DYNAREC_ARM_FUNCTIONS_H__
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+6 -2
View File
@@ -2,10 +2,14 @@
#include "arm64_emitter.h"
#define EMIT(A) *block = (A); ++block
#define EMIT(A) \
do { \
*block = (A); \
++block; \
} while (0)
void CreateJmpNext(void* addr, void* next)
{
uint32_t* block = (uint32_t*)addr;
LDRx_literal(x2, (intptr_t)next - (intptr_t)addr);
BR(x2);
}
}
+46 -27
View File
@@ -5,28 +5,23 @@
dyn->insts[ninst].x64.addr = addr; \
if(ninst) dyn->insts[ninst-1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst-1].x64.addr
#define MESSAGE(A, ...)
#define MAYSETFLAGS() dyn->insts[ninst].x64.may_set = 1
#define MESSAGE(A, ...) do {} while (0)
#define READFLAGS(A) \
dyn->insts[ninst].x64.use_flags = A; dyn->f.dfnone = 1;\
if(!BOX64ENV(dynarec_df) && (A)&X_PEND) dyn->insts[ninst].x64.use_flags = X_ALL; \
dyn->f.pending=SF_SET
#define SETFLAGS(A,B) \
dyn->insts[ninst].x64.set_flags = A; \
dyn->insts[ninst].x64.state_flags = B; \
dyn->insts[ninst].x64.state_flags = (B)&~SF_DF; \
dyn->f.pending=(B)&SF_SET_PENDING; \
dyn->f.dfnone=((B)&SF_SET)?1:0;
#define EMIT(A)
#define JUMP(A, C) add_jump(dyn, ninst); add_next(dyn, (uintptr_t)A); SMEND(); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C
dyn->f.dfnone=((B)&SF_SET)?(((B)==SF_SET_NODF)?0:1):0; \
if(!BOX64ENV(dynarec_df)) {dyn->f.dfnone=1; dyn->f.pending=0; if((A)==SF_PENDING){printf_log(LOG_INFO, "Warning, some opcode use SF_PENDING, forcing deferedflags ON\n"); SET_BOX64ENV(dynarec_df, 1); }}
#define EMIT(A) dyn->native_size+=4
#define JUMP(A, C) add_jump(dyn, ninst); add_next(dyn, (uintptr_t)A); SMEND(); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C; dyn->insts[ninst].x64.jmp_insts = 0
#define BARRIER(A) if(A!=BARRIER_MAYBE) {fpu_purgecache(dyn, ninst, 0, x1, x2, x3); dyn->insts[ninst].x64.barrier = A;} else dyn->insts[ninst].barrier_maybe = 1
#define BARRIER_NEXT(A) dyn->insts[ninst].x64.barrier_next = A
#define SET_HASCALLRET() dyn->insts[ninst].x64.has_callret = 1
#define NEW_INST \
++dyn->size; \
if(dyn->size+3>=dyn->cap) { \
dyn->insts = (instruction_native_t*)dynaRealloc(dyn->insts, sizeof(instruction_native_t)*dyn->cap*2);\
memset(&dyn->insts[dyn->cap], 0, sizeof(instruction_native_t)*dyn->cap); \
dyn->cap *= 2; \
} \
dyn->insts[ninst].x64.addr = ip; \
dyn->n.combined1 = dyn->n.combined2 = 0;\
dyn->n.swapped = 0; dyn->n.barrier = 0; \
@@ -36,20 +31,44 @@
#define INST_EPILOG \
dyn->insts[ninst].f_exit = dyn->f; \
dyn->insts[ninst].n = dyn->n; \
if(dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH && !dyn->insts[ninst].set_nat_flags) \
dyn->insts[ninst].nat_flags_op=NAT_FLAG_OP_UNUSABLE; \
dyn->insts[ninst].x64.has_next = (ok>0)?1:0;
#define INST_NAME(name)
#define DEFAULT \
--dyn->size; \
*ok = -1; \
if(box64_dynarec_log>=LOG_INFO || box64_dynarec_dump || box64_dynarec_missing) {\
dynarec_log(LOG_NONE, "%p: Dynarec stopped because of %sOpcode %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", \
(void*)ip, rex.is32bits?"32bits ":"",\
PKip(0), \
PKip(1), PKip(2), PKip(3), \
PKip(4), PKip(5), PKip(6), \
PKip(7), PKip(8), PKip(9), \
PKip(10),PKip(11),PKip(12), \
PKip(13),PKip(14)); \
printFunctionAddr(ip, " => "); \
dynarec_log(LOG_NONE, "\n"); \
#define INST_NAME(name)
#define DEFAULT \
--dyn->size; \
*ok = -1; \
if (ninst) { dyn->insts[ninst - 1].x64.size = ip - dyn->insts[ninst - 1].x64.addr; } \
if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing) == 1) \
if (!dyn->size || BOX64ENV(dynarec_log) > LOG_INFO || BOX64DRENV(dynarec_dump)) { \
dynarec_log(LOG_NONE, "%p: Dynarec stopped because of %s Opcode ", (void*)ip, rex.is32bits ? "x86" : "x64"); \
zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec; \
if (dec) { \
dynarec_log_prefix(0, LOG_NONE, "%s", DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 1)); \
} else { \
dynarec_log_prefix(0, LOG_NONE, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", \
PKip(0), PKip(1), PKip(2), PKip(3), PKip(4), PKip(5), PKip(6), PKip(7), PKip(8), PKip(9), \
PKip(10), PKip(11), PKip(12), PKip(13), PKip(14)); \
} \
printFunctionAddr(ip, " => "); \
dynarec_log_prefix(0, LOG_NONE, "\n"); \
}
#define FEMIT(A) dyn->insts[ninst].nat_flags_op = dyn->insts[ninst].x64.set_flags?NAT_FLAG_OP_TOUCH:NAT_FLAG_OP_UNUSABLE
#define IFNATIVE(A) if(mark_natflag(dyn, ninst, A, 0))
#define IFNATIVEN(A) if(mark_natflag(dyn, ninst, A, 0))
#define IFX(A) if((dyn->insts[ninst].x64.set_flags&(A)))
#define IFX2(A, B) if((dyn->insts[ninst].x64.set_flags&(A)) B)
#define IFX_PENDOR0 if((dyn->insts[ninst].x64.set_flags&(X_PEND) || !dyn->insts[ninst].x64.set_flags))
#define IFXX(A) if((dyn->insts[ninst].x64.set_flags==(A)))
#define IFX2X(A, B) if((dyn->insts[ninst].x64.set_flags==(A) || dyn->insts[ninst].x64.set_flags==(B) || dyn->insts[ninst].x64.set_flags==((A)|(B))))
#define IFXN(A, B) if((dyn->insts[ninst].x64.set_flags&(A) && !(dyn->insts[ninst].x64.set_flags&(B))))
#define IFXNATIVE(X, N) if((dyn->insts[ninst].x64.set_flags&(X)) && mark_natflag(dyn, ninst, N, 0))
#define GEN_INVERTED_CARRY() dyn->insts[ninst].gen_inverted_carry = 1
#define IFNATIVE_BEFORE(A) if(mark_natflag(dyn, ninst, A, 1))
#define INVERT_CARRY(A) dyn->insts[ninst].invert_carry = 1
#define INVERT_CARRY_BEFORE(A) dyn->insts[ninst].invert_carry_before = 1
// mark opcode as "unaligned" possible only if the current address is not marked as already unaligned
#define IF_UNALIGNED(A) if((dyn->insts[ninst].unaligned=(is_addr_unaligned(A)?0:1)))
#define IF_ALIGNED(A) if((dyn->insts[ninst].unaligned=(is_addr_unaligned(A)?1:0)))
+12 -2
View File
@@ -1,7 +1,17 @@
#define INIT
#define FINI
#define MESSAGE(A, ...)
#define EMIT(A)
#define MESSAGE(A, ...) do {} while (0)
#define EMIT(A) do {} while (0)
#define SET_NODF() \
if(!dyn->insts[ninst].x64.gen_flags && !dyn->insts[ninst].x64.use_flags) \
propagate_nodf(dyn, ninst); \
dyn->f.dfnone = 0
#define SETFLAGS(A,B) \
dyn->insts[ninst].x64.set_flags = A; \
dyn->insts[ninst].x64.state_flags = (B)&~SF_DF; \
dyn->f.pending=(B)&SF_SET_PENDING; \
dyn->f.dfnone=((B)&SF_SET)?(((B)==SF_SET_NODF)?0:1):0; \
if(!BOX64ENV(dynarec_df)) {dyn->f.dfnone=1; dyn->f.pending=0; }
#define NEW_INST \
dyn->insts[ninst].f_entry = dyn->f; \
dyn->n.combined1 = dyn->n.combined2 = 0;\
+4 -3
View File
@@ -2,17 +2,18 @@
#define FINI \
if(ninst) { \
dyn->insts[ninst].address = (dyn->insts[ninst-1].address+dyn->insts[ninst-1].size); \
dyn->insts_size += 1+((dyn->insts[ninst].x64.size>(dyn->insts[ninst].size/4))?dyn->insts[ninst].x64.size:(dyn->insts[ninst].size/4))/15; \
dyn->insts_size += 1+((dyn->insts[ninst-1].x64.size>(dyn->insts[ninst-1].size/4))?dyn->insts[ninst-1].x64.size:(dyn->insts[ninst-1].size/4))/15; \
}
#define MESSAGE(A, ...)
#define MESSAGE(A, ...) do {} while (0)
#define EMIT(A) do{dyn->insts[ninst].size+=4; dyn->native_size+=4;}while(0)
#define NEW_INST \
if(ninst) { \
dyn->insts[ninst].address = (dyn->insts[ninst-1].address+dyn->insts[ninst-1].size); \
dyn->insts_size += 1+((dyn->insts[ninst-1].x64.size>(dyn->insts[ninst-1].size/4))?dyn->insts[ninst-1].x64.size:(dyn->insts[ninst-1].size/4))/15; \
dyn->insts[ninst].ymm0_pass2 = dyn->ymm_zero; \
}
#define INST_EPILOG dyn->insts[ninst].epilog = dyn->native_size;
#define INST_NAME(name)
#define TABLE64(A, V) {Table64(dyn, (V), 2); EMIT(0);}
#define FTABLE64(A, V) {mmx87_regs_t v = {.d = V}; Table64(dyn, v.q, 2); EMIT(0);}
#define FTABLE64(A, V) {mmx87_regs_t v = {.d = V}; Table64(dyn, v.q, 2); EMIT(0);}
+8 -5
View File
@@ -1,21 +1,24 @@
#define INIT
#define FINI \
if(ninst) \
addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst].x64.size, dyn->insts[ninst].size/4); \
addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst-1].x64.size, dyn->insts[ninst-1].size/4); \
addInst(dyn->instsize, &dyn->insts_size, 0, 0);
#define EMIT(A) \
do{ \
if(box64_dynarec_dump) print_opcode(dyn, ninst, (uint32_t)(A)); \
if(BOX64DRENV(dynarec_dump)) print_opcode(dyn, ninst, (uint32_t)(A)); \
if((uintptr_t)dyn->block<dyn->tablestart) \
*(uint32_t*)(dyn->block) = (uint32_t)(A); \
dyn->block += 4; dyn->native_size += 4; \
dyn->insts[ninst].size2 += 4; \
}while(0)
#define MESSAGE(A, ...) if(box64_dynarec_dump) dynarec_log(LOG_NONE, __VA_ARGS__)
#define MESSAGE(A, ...) if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, __VA_ARGS__)
#define NEW_INST \
if(ninst) \
addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst-1].x64.size, dyn->insts[ninst-1].size/4);
if(ninst) { \
if(dyn->insts[ninst].address!=(uintptr_t)dyn->block-(uintptr_t)dyn->native_start) dyn->abort = 1; \
addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst-1].x64.size, dyn->insts[ninst-1].size/4); \
dyn->insts[ninst].ymm0_pass3 = dyn->ymm_zero; \
}
#define INST_EPILOG
#define INST_NAME(name) inst_name_pass3(dyn, ninst, name, rex)
#define TABLE64(A, V) {int val64offset = Table64(dyn, (V), 3); MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); LDRx_literal(A, val64offset);}
+61 -10
View File
@@ -9,6 +9,20 @@ typedef struct instsize_s instsize_t;
#define BARRIER_MAYBE 8
#define NF_EQ (1<<0)
#define NF_SF (1<<1)
#define NF_VF (1<<2)
#define NF_CF (1<<3)
// Nothing happens to the native flags
#define NAT_FLAG_OP_NONE 0
// Native flags are touched on this opcode
#define NAT_FLAG_OP_TOUCH 1
// Native flags are destroyed and unusable
#define NAT_FLAG_OP_UNUSABLE 2
// Native flags usaged are canceled here
#define NAT_FLAG_OP_CANCELED 3
#define NEON_CACHE_NONE 0
#define NEON_CACHE_ST_D 1
#define NEON_CACHE_ST_F 2
@@ -16,7 +30,9 @@ typedef struct instsize_s instsize_t;
#define NEON_CACHE_MM 4
#define NEON_CACHE_XMMW 5
#define NEON_CACHE_XMMR 6
#define NEON_CACHE_SCR 7
#define NEON_CACHE_YMMW 7
#define NEON_CACHE_YMMR 8
#define NEON_CACHE_SCR 9
typedef union neon_cache_s {
int8_t v;
struct {
@@ -33,7 +49,7 @@ typedef union sse_cache_s {
} sse_cache_t;
typedef struct neoncache_s {
// Neon cache
neon_cache_t neoncache[24];
neon_cache_t neoncache[32];
int8_t stack;
int8_t stack_next;
int8_t stack_pop;
@@ -42,23 +58,30 @@ typedef struct neoncache_s {
uint8_t combined2;
uint8_t swapped; // the combined reg were swapped
uint8_t barrier; // is there a barrier at instruction epilog?
uint8_t pushed; // positive pushed value (to check for overflow)
uint8_t poped; // positive poped value (to check for underflow)
uint32_t news; // bitmask, wich neoncache are new for this opcode
// fpu cache
int8_t x87cache[8]; // cache status for the 8 x87 register behind the fpu stack
int8_t x87reg[8]; // reg used for x87cache entry
int16_t tags; // similar to fpu_tags
int8_t mmxcache[8]; // cache status for the 8 MMX registers
sse_cache_t ssecache[16]; // cache status for the 16 SSE(2) registers
int8_t fpuused[24]; // all 0..24 double reg from fpu, used by x87, sse and mmx
int8_t fpuused[32]; // all neon regs, used by x87, mmx, sse and avx
int8_t x87stack; // cache stack counter
int8_t mmxcount; // number of mmx register used (not both mmx and x87 at the same time)
int8_t fpu_scratch; // scratch counter
int8_t fpu_extra_qscratch; // some opcode need an extra quad scratch register
int8_t fpu_reg; // x87/sse/mmx reg counter
uint16_t ymm_used; // mask of the ymm regs used in this opcode
uint64_t ymm_regs; // 4bits (0-15) position of 16 ymmXX regs removed
uint16_t ymm_write; // 1bits of ymmXX removed write
uint16_t ymm_removed; // 1bits if ymmXX was removed
} neoncache_t;
typedef struct flagcache_s {
int pending; // is there a pending flags here, or to check?
int dfnone; // if deferred flags is already set to df_none
uint8_t dfnone; // if deferred flags is already set to df_none
uint8_t dfnone_here;// defered flags is cleared in this opcode
} flagcache_t;
typedef struct instruction_arm64_s {
@@ -75,8 +98,31 @@ typedef struct instruction_arm64_s {
uintptr_t marklock;
int pass2choice;// value for choices that are fixed on pass2 for pass3
uintptr_t natcall;
int retn;
int barrier_maybe;
uint16_t retn;
uint16_t purge_ymm; // need to purge some ymm
uint16_t ymm0_in; // bitmap of ymm to zero at purge
uint16_t ymm0_add; // the ymm0 added by the opcode
uint16_t ymm0_sub; // the ymm0 removed by the opcode
uint16_t ymm0_out; // the ymm0 at th end of the opcode
uint16_t ymm0_pass2, ymm0_pass3;
uint8_t barrier_maybe;
uint8_t will_write:2; // [strongmem] will write to memory
uint8_t last_write:1; // [strongmem] the last write in a SEQ
uint8_t lock:1; // [strongmem] lock semantic
uint8_t wfe:1; // opcode uses sevl + wfe
uint8_t set_nat_flags; // 0 or combinaison of native flags define
uint8_t use_nat_flags; // 0 or combinaison of native flags define
uint8_t use_nat_flags_before; // 0 or combinaison of native flags define
uint8_t nat_flags_op:4;// what happens to native flags here
uint8_t nat_flags_op_before:4;// what happens to native flags here
uint8_t before_nat_flags; // 0 or combinaison of native flags define
uint8_t need_nat_flags;
unsigned gen_inverted_carry:1;
unsigned normal_carry:1;
unsigned normal_carry_before:1;
unsigned invert_carry:1; // this opcode force an inverted carry
unsigned df_notneeded:1;
unsigned unaligned:1; // this opcode can be re-generated for unaligned special case
flagcache_t f_exit; // flags status at end of instruction
neoncache_t n; // neoncache at end of instruction (but before poping)
flagcache_t f_entry; // flags status before the instruction begin
@@ -109,21 +155,24 @@ typedef struct dynarec_arm_s {
dynablock_t* dynablock;
instsize_t* instsize;
size_t insts_size; // size of the instruction size array (calculated)
uint8_t smread; // for strongmem model emulation
uint8_t smwrite; // for strongmem model emulation
uintptr_t forward; // address of the last end of code while testing forward
uintptr_t forward_to; // address of the next jump to (to check if everything is ok)
int32_t forward_size; // size at the forward point
int forward_ninst; // ninst at the forward point
uint16_t ymm_zero; // bitmap of ymm to zero at purge
uint8_t smwrite; // for strongmem model emulation
uint8_t doublepush;
uint8_t doublepop;
uint8_t always_test;
uint8_t abort; // abort the creation of the block
void* gdbjit_block;
} dynarec_arm_t;
void add_next(dynarec_arm_t *dyn, uintptr_t addr);
uintptr_t get_closest_next(dynarec_arm_t *dyn, uintptr_t addr);
void add_jump(dynarec_arm_t *dyn, int ninst);
int get_first_jump(dynarec_arm_t *dyn, int next);
int get_first_jump_addr(dynarec_arm_t *dyn, uintptr_t next);
int is_nops(dynarec_arm_t *dyn, uintptr_t addr, int n);
int is_instructions(dynarec_arm_t *dyn, uintptr_t addr, int n);
@@ -134,9 +183,11 @@ void CreateJmpNext(void* addr, void* next);
#define GO_TRACE(A, B, s0) \
GETIP(addr); \
MOVx_REG(x1, xRIP); \
MRS_nzcv(s0); \
STORE_XEMU_CALL(xRIP); \
MOV32w(x2, B); \
CALL(A, -1); \
CALL_(A, -1, s0); \
MSR_nzcv(s0); \
LOAD_XEMU_CALL(xRIP)
#endif //__DYNAREC_ARM_PRIVATE_H_
+61 -58
View File
@@ -19,20 +19,22 @@
#include "dynarec_private.h"
#include "elfloader.h"
#include "bridge.h"
#include "signals.h"
#include "dynarec_native.h"
#include "native_lock.h"
#include "custommem.h"
#include "khash.h"
#include "rbtree.h"
uint32_t X31_hash_code(void* addr, int len)
{
if(!len) return 0;
uint8_t* p = (uint8_t*)addr;
int32_t h = *p;
for (--len, ++p; len; --len, ++p) h = (h << 5) - h + (int32_t)*p;
return (uint32_t)h;
int32_t h = *p;
for (--len, ++p; len; --len, ++p) h = (h << 5) - h + (int32_t)*p;
return (uint32_t)h;
}
dynablock_t* InvalidDynablock(dynablock_t* db, int need_lock)
@@ -47,6 +49,18 @@ dynablock_t* InvalidDynablock(dynablock_t* db, int need_lock)
mutex_lock(&my_context->mutex_dyndump);
db->done = 0;
db->gone = 1;
uintptr_t db_size = db->x64_size;
if(db_size && my_context) {
uint32_t n = rb_get(my_context->db_sizes, db_size);
if(n>1)
rb_set(my_context->db_sizes, db_size, db_size+1, n-1);
else
rb_unset(my_context->db_sizes, db_size, db_size+1);
if(db_size == my_context->max_db_size) {
my_context->max_db_size = rb_get_righter(my_context->db_sizes);
dynarec_log(LOG_INFO, "BOX64 Dynarec: lower max_db=%d\n", my_context->max_db_size);
}
}
if(need_lock)
mutex_unlock(&my_context->mutex_dyndump);
}
@@ -81,6 +95,18 @@ void FreeDynablock(dynablock_t* db, int need_lock)
dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->actual_block, db->size);
db->done = 0;
db->gone = 1;
uintptr_t db_size = db->x64_size;
if(db_size && my_context) {
uint32_t n = rb_get(my_context->db_sizes, db_size);
if(n>1)
rb_set(my_context->db_sizes, db_size, db_size+1, n-1);
else
rb_unset(my_context->db_sizes, db_size, db_size+1);
if(db_size == my_context->max_db_size) {
my_context->max_db_size = rb_get_righter(my_context->db_sizes);
dynarec_log(LOG_INFO, "BOX64 Dynarec: lower max_db=%d\n", my_context->max_db_size);
}
}
if(db->previous)
FreeInvalidDynablock(db->previous, 0);
FreeDynarecMap((uintptr_t)db->actual_block);
@@ -120,15 +146,6 @@ static int IntervalIntersects(uintptr_t start1, uintptr_t end1, uintptr_t start2
return 1;
}
static int MarkedDynablock(dynablock_t* db)
{
if(db) {
if(getNeedTest((uintptr_t)db->x64_addr))
return 1; // already done
}
return 0;
}
void MarkRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size)
{
// Mark will try to find *any* blocks that intersect the range to mark
@@ -155,15 +172,6 @@ int FreeRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size)
dynablock_t *AddNewDynablock(uintptr_t addr)
{
dynablock_t* block;
#if 0
// check if memory as the correct flags
int prot = getProtection(addr);
if(!(prot&(PROT_EXEC|PROT_DYNAREC|PROT_DYNAREC_R))) {
dynarec_log(LOG_VERBOSE, "Block asked on a memory with no execution flags 0x%02X\n", prot);
return NULL;
}
#endif
// create and add new block
dynarec_log(LOG_VERBOSE, "Ask for DynaRec Block creation @%p\n", (void*)addr);
block = (dynablock_t*)customCalloc(1, sizeof(dynablock_t));
@@ -191,12 +199,16 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
{
if(hasAlternate((void*)addr))
return NULL;
const uint32_t req_prot = (box64_pagesize==4096)?(PROT_EXEC|PROT_READ):PROT_READ;
dynablock_t* block = getDB(addr);
if(block || !create)
if(block || !create) {
if(block && getNeedTest(addr) && (getProtection(addr)&req_prot)!=req_prot)
block = NULL;
return block;
}
if(need_lock) {
if(box64_dynarec_wait) {
if(BOX64ENV(dynarec_wait)) {
mutex_lock(&my_context->mutex_dyndump);
} else {
if(mutex_trylock(&my_context->mutex_dyndump)) // FillBlock not available for now
@@ -204,11 +216,17 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
}
block = getDB(addr); // just in case
if(block) {
if(block && getNeedTest(addr) && (getProtection_fast(addr)&req_prot)!=req_prot)
block = NULL;
mutex_unlock(&my_context->mutex_dyndump);
return block;
}
}
if((getProtection_fast(addr)&req_prot)!=req_prot) {// cannot be run, get out of the Dynarec
if(need_lock)
mutex_unlock(&my_context->mutex_dyndump);
return NULL;
}
block = AddNewDynablock(addr);
// fill the block
@@ -228,17 +246,20 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
}
// check size
if(block) {
int blocksz = block->x64_size;
if(blocksz>my_context->max_db_size)
my_context->max_db_size = blocksz;
// fill-in jumptable
if(!addJumpTableIfDefault64(block->x64_addr, block->dirty?block->jmpnext:block->block)) {
FreeDynablock(block, 0);
block = getDB(addr);
MarkDynablock(block); // just in case...
} else {
if(block->x64_size)
if(block->x64_size) {
if(block->x64_size>my_context->max_db_size) {
my_context->max_db_size = block->x64_size;
dynarec_log(LOG_INFO, "BOX64 Dynarec: higher max_db=%d\n", my_context->max_db_size);
}
block->done = 1; // don't validate the block if the size is null, but keep the block
rb_set(my_context->db_sizes, block->x64_size, block->x64_size+1, rb_get(my_context->db_sizes, block->x64_size)+1);
}
}
}
if(need_lock)
@@ -251,33 +272,17 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
{
if(isInHotPage(addr))
return NULL;
dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits);
if(db && db->done && db->block && getNeedTest(addr)) {
if(db->always_test)
sched_yield(); // just calm down...
if(AreaInHotPage((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr + db->x64_size - 1)) {
emu->test.test = 0;
if(box64_dynarec_fastpage) {
uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size);
if(hash==db->hash) { // seems ok, run it without reprotecting it
setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext);
return db;
}
db->done = 0; // invalidating the block, it's already not good
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, (void*)addr);
// Free db, it's now invalid!
FreeDynablock(db, 1);
return NULL; // not building a new one, it's still a hotpage
} else {
dynarec_log(LOG_INFO, "Not running block %p from %p:%p with for %p because it's in a hotpage\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, (void*)addr);
return NULL;
}
}
uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size);
int need_lock = mutex_trylock(&my_context->mutex_dyndump);
if(hash!=db->hash) {
db->done = 0; // invalidating the block
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, (void*)addr);
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X, always_test:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, db->always_test,(void*)addr);
// Free db, it's now invalid!
dynablock_t* old = InvalidDynablock(db, need_lock);
// start again... (will create a new block)
@@ -289,12 +294,11 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
} else
FreeInvalidDynablock(old, need_lock);
} else {
dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, (void*)addr);
protectDB((uintptr_t)db->x64_addr, db->x64_size);
// fill back jumptable
if(isprotectedDB((uintptr_t)db->x64_addr, db->x64_size) && !db->always_test) {
setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext);
}
dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X, always_test:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, db->always_test, (void*)addr);
if(db->always_test)
protectDB((uintptr_t)db->x64_addr, db->x64_size);
else
protectDBJumpTable((uintptr_t)db->x64_addr, db->x64_size, db->block, db->jmpnext);
}
if(!need_lock)
mutex_unlock(&my_context->mutex_dyndump);
@@ -328,11 +332,10 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr,
} else
FreeInvalidDynablock(old, need_lock);
} else {
protectDB((uintptr_t)db->x64_addr, db->x64_size);
// fill back jumptable
if(isprotectedDB((uintptr_t)db->x64_addr, db->x64_size) && !db->always_test) {
setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext);
}
if(db->always_test)
protectDB((uintptr_t)db->x64_addr, db->x64_size);
else
protectDBJumpTable((uintptr_t)db->x64_addr, db->x64_size, db->block, db->jmpnext);
}
if(!need_lock)
mutex_unlock(&my_context->mutex_dyndump);
+6 -3
View File
@@ -10,17 +10,20 @@ typedef struct dynablock_s {
void* block; // block-sizeof(void*) == self
void* actual_block; // the actual start of the block (so block-sizeof(void*))
struct dynablock_s* previous; // a previous block that might need to be freed
int size;
void* x64_addr;
uintptr_t x64_size;
int size;
uint32_t hash;
uint8_t done;
uint8_t gone;
uint8_t always_test;
uint8_t dirty; // if need to be tested as soon as it's created
uint8_t always_test:1;
uint8_t is32bits:1;
int isize;
instsize_t* instsize;
void* arch; // arch dependant per inst info (can be NULL)
size_t arch_size; // size of of arch dependant infos
void* jmpnext; // a branch jmpnext code when block is marked
} dynablock_t;
#endif //__DYNABLOCK_PRIVATE_H_
#endif //__DYNABLOCK_PRIVATE_H_
+80 -29
View File
@@ -19,6 +19,7 @@
#include "dynablock_private.h"
#include "bridge.h"
#include "dynarec_next.h"
#include "custommem.h"
#endif
#ifdef HAVE_TRACE
#include "elfloader.h"
@@ -33,14 +34,25 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
#ifdef HAVE_TRACE
if(!addr) {
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
printf_log(LOG_NONE, "Warning, jumping to NULL address from %p (db=%p, x64addr=%p/%s)\n", x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, db?getAddrFunctionName(getX64Address(db, (uintptr_t)x2-4)):"(nil)");
printf_log(LOG_INFO, "Warning, jumping to NULL address from %p (db=%p, x64addr=%p/%s)\n", x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, db?getAddrFunctionName(getX64Address(db, (uintptr_t)x2-4)):"(nil)");
} else if(addr<0x10000) {
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
printf_log(LOG_INFO, "Warning, jumping to low address %p from %p (db=%p, x64addr=%p/%s)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, db?getAddrFunctionName(getX64Address(db, (uintptr_t)x2-4)):"(nil)");
#ifdef BOX32
} else if(emu->segs[_CS]==0x23 && addr>0x100000000LL) {
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
printf_log(LOG_INFO, "Warning, jumping to high address %p from %p (db=%p, x64addr=%p/%s)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, db?getAddrFunctionName(getX64Address(db, (uintptr_t)x2-4)):"(nil)");
} else if(!memExist(addr)) {
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
printf_log(LOG_INFO, "Warning, jumping to an unmapped address %p from %p (db=%p, x64addr=%p/%s)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, db?getAddrFunctionName(getX64Address(db, (uintptr_t)x2-4)):"(nil)");
#endif
}
#endif
void * jblock;
dynablock_t* block = NULL;
if(hasAlternate((void*)addr)) {
printf_log(LOG_DEBUG, "Jmp address has alternate: %p", (void*)addr);
if(box64_log<LOG_DEBUG) dynarec_log(LOG_INFO, "Jmp address has alternate: %p", (void*)addr);
if (BOX64ENV(log)<LOG_DEBUG) dynarec_log(LOG_INFO, "Jmp address has alternate: %p", (void*)addr);
uintptr_t old_addr = addr;
addr = (uintptr_t)getAlternate((void*)addr); // set new address
R_RIP = addr; // but also new RIP!
@@ -51,10 +63,14 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
block = DBGetBlock(emu, addr, 1, is32bits);
if(!block) {
#ifdef HAVE_TRACE
if(LOG_INFO<=box64_dynarec_log) {
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2-4);
dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p(elf=%s))\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)");
if(LOG_INFO<=BOX64ENV(dynarec_log)) {
if(checkInHotPage(addr)) {
dynarec_log(LOG_INFO, "Not trying to run a block from a Hotpage at %p\n", (void*)addr);
} else {
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2-4);
dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p(elf=%s), RIP=%p)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)", (void*)*x3);
}
}
#endif
//tableupdate(native_epilog, addr, table);
@@ -62,6 +78,12 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
}
if(!block->done) {
// not finished yet... leave linker
#ifdef HAVE_TRACE
if(BOX64ENV(dynarec_log) && !block->isize) {
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
printf_log(LOG_NONE, "Warning, NULL block at %p from %p (db=%p, x64addr=%p/%s)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, db?getAddrFunctionName(getX64Address(db, (uintptr_t)x2-4)):"(nil)");
}
#endif
return native_epilog;
}
if(!(jblock=block->block)) {
@@ -81,25 +103,24 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
uint64_t old_rsi = R_RSI;
uint64_t old_rbp = R_RBP;
uint64_t old_rip = R_RIP;
x64flags_t old_eflags = emu->eflags;
// save defered flags
deferred_flags_t old_df = emu->df;
multiuint_t old_op1 = emu->op1;
multiuint_t old_op2 = emu->op2;
multiuint_t old_res = emu->res;
multiuint_t old_op1_sav= emu->op1_sav;
multiuint_t old_res_sav= emu->res_sav;
deferred_flags_t old_df_sav= emu->df_sav;
// uc_link
x64_ucontext_t* old_uc_link = emu->uc_link;
emu->uc_link = NULL;
PushExit(emu);
#ifdef BOX32
if(box64_is32bits)
PushExit_32(emu);
else
#endif
PushExit(emu);
R_RIP = addr;
emu->df = d_none;
DynaRun(emu);
emu->quit = 0; // reset Quit flags...
emu->df = d_none;
emu->uc_link = old_uc_link;
if(emu->flags.quitonlongjmp && emu->flags.longjmp) {
if(emu->flags.quitonlongjmp==1)
emu->flags.longjmp = 0; // don't change anything because of the longjmp
@@ -109,10 +130,8 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
emu->op1 = old_op1;
emu->op2 = old_op2;
emu->res = old_res;
emu->op1_sav = old_op1_sav;
emu->res_sav = old_res_sav;
emu->df_sav = old_df_sav;
// and the old registers
emu->eflags = old_eflags;
R_RBX = old_rbx;
R_RDI = old_rdi;
R_RSI = old_rsi;
@@ -123,27 +142,37 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
}
int my_setcontext(x64emu_t* emu, void* ucp);
#ifdef BOX32
int my32_setcontext(x64emu_t* emu, void* ucp);
#endif
extern int running32bits;
void DynaRun(x64emu_t* emu)
{
// prepare setjump for signal handling
JUMPBUFF jmpbuf[1] = {0};
int skip = 0;
JUMPBUFF *old_jmpbuf = emu->jmpbuf;
#ifdef RV64
uintptr_t old_savesp = emu->xSPSave;
#endif
emu->flags.jmpbuf_ready = 0;
int is32bits = (emu->segs[_CS]==0x23);
while(!(emu->quit)) {
if(!emu->jmpbuf || (emu->flags.need_jmpbuf && emu->jmpbuf!=jmpbuf)) {
emu->jmpbuf = jmpbuf;
#ifdef RV64
emu->old_savedsp = emu->xSPSave;
#endif
emu->flags.jmpbuf_ready = 1;
#ifdef ANDROID
if((skip=sigsetjmp(*(JUMPBUFF*)emu->jmpbuf, 1)))
if((skip=sigsetjmp(*(JUMPBUFF*)emu->jmpbuf, 1)))
#else
if((skip=sigsetjmp(emu->jmpbuf, 1)))
if((skip=sigsetjmp(emu->jmpbuf, 1)))
#endif
{
printf_log(LOG_DEBUG, "Setjmp DynaRun, fs=0x%x\n", emu->segs[_FS]);
#ifdef DYNAREC
if(box64_dynarec_test) {
if(BOX64ENV(dynarec_test)) {
if(emu->test.clean)
x64test_check(emu, R_RIP);
emu->test.clean = 0;
@@ -155,23 +184,46 @@ void DynaRun(x64emu_t* emu)
emu->flags.need_jmpbuf = 0;
#ifdef DYNAREC
if(!box64_dynarec)
if(!BOX64ENV(dynarec))
#endif
Run(emu, 0);
#ifdef DYNAREC
else {
int is32bits = (emu->segs[_CS]==0x23);
int newis32bits = (emu->segs[_CS]==0x23);
if(newis32bits!=is32bits) {
is32bits = newis32bits;
if(is32bits) {
// Zero upper part of the 32bits regs
R_RAX = R_EAX;
R_RBX = R_EBX;
R_RCX = R_ECX;
R_RDX = R_EDX;
R_RSP = R_ESP;
R_RBP = R_EBP;
R_RSI = R_ESI;
R_RDI = R_EDI;
running32bits = 1;
}
}
dynablock_t* block = (skip)?NULL:DBGetBlock(emu, R_RIP, 1, is32bits);
if(!block || !block->block || !block->done || ACCESS_FLAG(F_TF)) {
skip = 0;
// no block, of block doesn't have DynaRec content (yet, temp is not null)
// Use interpreter (should use single instruction step...)
dynarec_log(LOG_DEBUG, "%04d|Running Interpreter @%p, emu=%p\n", GetTID(), (void*)R_RIP, emu);
if(box64_dynarec_test)
if(BOX64ENV(dynarec_log)) {
if(ACCESS_FLAG(F_TF))
dynarec_log(LOG_INFO, "%04d|Running Interpreter @%p, emu=%p because TF is on\n", GetTID(), (void*)R_RIP, emu);
else
dynarec_log(LOG_DEBUG, "%04d|Running Interpreter @%p, emu=%p\n", GetTID(), (void*)R_RIP, emu);
}
if (BOX64ENV(dynarec_test))
emu->test.clean = 0;
Run(emu, 1);
} else {
dynarec_log(LOG_DEBUG, "%04d|Running DynaRec Block @%p (%p) of %d x64 insts (hash=0x%x) emu=%p\n", GetTID(), (void*)R_RIP, block->block, block->isize, block->hash, emu);
if(!BOX64ENV(dynarec_df)) {
CHECK_FLAGS(emu);
}
// block is here, let's run it!
native_prolog(emu, block->block);
}
@@ -181,10 +233,6 @@ void DynaRun(x64emu_t* emu)
emu->fork = 0;
emu = x64emu_fork(emu, forktype);
}
if(emu->quit && emu->uc_link) {
emu->quit = 0;
my_setcontext(emu, emu->uc_link);
}
}
#endif
if(emu->flags.need_jmpbuf)
@@ -192,4 +240,7 @@ void DynaRun(x64emu_t* emu)
}
// clear the setjmp
emu->jmpbuf = old_jmpbuf;
#ifdef RV64
emu->xSPSave = old_savesp;
#endif
}
+60 -14
View File
@@ -5,42 +5,88 @@
#define instruction_native_t instruction_arm64_t
#define dynarec_native_t dynarec_arm_t
#define extcache_native_t neoncache_t
#define ADDITIONNAL_DEFINITION() \
int fpuCacheNeedsTransform(dynarec_native_t* dyn, int ninst);
#define OTHER_CACHE() \
if (fpuCacheNeedsTransform(dyn, ninst)) ret|=2;
#define OTHER_CACHE() \
if (fpuCacheNeedsTransform(dyn, ninst)) ret|=2; \
if (nativeFlagsNeedsTransform(dyn, ninst)) ret|=4;
#include "arm64/arm64_printer.h"
#include "arm64/dynarec_arm64_private.h"
#include "arm64/dynarec_arm64_functions.h"
#elif defined(LA464)
#include "arm64/dynarec_arm64_arch.h"
// Limit here is defined by LD litteral, that is 19bits
#define MAXBLOCK_SIZE ((1<<19)-200)
#define instruction_native_t instruction_la464_t
#define dynarec_native_t dynarec_la464_t
#define RAZ_SPECIFIC(A, N) rasNativeState(A, N)
#define UPDATE_SPECIFICS(A) updateNativeFlags(A)
#define PREUPDATE_SPECIFICS(A)
#define ADDITIONNAL_DEFINITION()
#define ARCH_SIZE(A) get_size_arch(A)
#define ARCH_FILL(A, B, C) populate_arch(A, B, C)
#define ARCH_ADJUST(A, B, C, D) adjust_arch(A, B, C, D)
#define STOP_NATIVE_FLAGS(A, B) A->insts[B].nat_flags_op = NAT_FLAG_OP_UNUSABLE
#define ARCH_UNALIGNED(A, B) arch_unaligned(A, B)
#elif defined(LA64)
#define OTHER_CACHE()
#define instruction_native_t instruction_la64_t
#define dynarec_native_t dynarec_la64_t
#define extcache_native_t lsxcache_t
#include "la464/la464_printer.h"
#include "la464/dynarec_la464_private.h"
#include "la464/dynarec_la464_functions.h"
#define ADDITIONNAL_DEFINITION() \
int fpuCacheNeedsTransform(dynarec_native_t* dyn, int ninst);
#define OTHER_CACHE() \
if (fpuCacheNeedsTransform(dyn, ninst)) ret |= 2;
#include "la64/la64_printer.h"
#include "la64/dynarec_la64_private.h"
#include "la64/dynarec_la64_functions.h"
// Limit here is unconditionnal jump, that is signed 28bits
#define MAXBLOCK_SIZE ((1 << 27) - 200)
#define RAZ_SPECIFIC(A, N)
#define UPDATE_SPECIFICS(A)
#define PREUPDATE_SPECIFICS(A) updateNativeFlags(A)
#define ARCH_SIZE(A) 0
#define ARCH_FILL(A, B, C) NULL
#define ARCH_ADJUST(A, B, C, D) {}
#define STOP_NATIVE_FLAGS(A, B) {}
#define ARCH_UNALIGNED(A, B) 0
#elif defined(RV64)
#define instruction_native_t instruction_rv64_t
#define dynarec_native_t dynarec_rv64_t
#define extcache_native_t extcache_t
#define ADDITIONNAL_DEFINITION() \
int fpuCacheNeedsTransform(dynarec_native_t* dyn, int ninst);
#define ADDITIONNAL_DEFINITION() \
int fpuCacheNeedsTransform(dynarec_native_t* dyn, int ninst); \
int sewNeedsTransform(dynarec_rv64_t* dyn, int ninst);
#define OTHER_CACHE() \
if (fpuCacheNeedsTransform(dyn, ninst)) ret|=2;
#define OTHER_CACHE() \
if (fpuCacheNeedsTransform(dyn, ninst)) ret |= 2; \
if (sewNeedsTransform(dyn, ninst)) ret |= 4;
#include "rv64/rv64_printer.h"
#include "rv64/dynarec_rv64_private.h"
#include "rv64/dynarec_rv64_functions.h"
#include "rv64/dynarec_rv64_arch.h"
// Limit here is unconditionnal jump, that is signed 21bits
#define MAXBLOCK_SIZE ((1<<20)-200)
#define RAZ_SPECIFIC(A, N)
#define UPDATE_SPECIFICS(A)
#define PREUPDATE_SPECIFICS(A) updateNativeFlags(A)
#define ARCH_SIZE(A) get_size_arch(A)
#define ARCH_FILL(A, B, C) populate_arch(A, B, C)
#define ARCH_ADJUST(A, B, C, D) {}
#define STOP_NATIVE_FLAGS(A, B) {}
#define ARCH_UNALIGNED(A, B) arch_unaligned(A, B)
#else
#error Unsupported platform
#endif
+188 -3
View File
@@ -1,14 +1,199 @@
#ifndef __DYNAREC_HELPER__H_
#define __DYNAREC_HELPER__H_
/* Box64 Strong Memory Model Emulation
*
* Definition of a SEQ:
* A SEQ is a sequence of opcodes that writes to guest memory, terminated by JMP, RET, CALL, etc.
*
* Memory barriers are added in the following cases to emulate the strong memory model:
* 1. End of a SEQ:
* - Scalar operations (a1)
* - SIMD operations (a2)
* 2. Start of a SEQ:
* - Scalar operations (b1)
* - SIMD operations (b2)
* 3. Right before the last guest memory store in a SEQ:
* - Scalar operations (c1)
* - SIMD operations (c2)
* 4. After every third guest memory store in a SEQ (d)
*
* STRONGMEM levels (coarse-grained):
* 1: Includes a1, b1, c1
* 2: Includes LEVEL1, plus a2, b2, c2
* 3: Includes LEVEL2, plus d
*
* WEAKBARRIER levels (fine-grained):
* 1: Use dmb.ishld and dmb.ishst over dmb.ish for more performance
* 2. All 1. Plus disabled the last write barriers (c1, c2)
*/
#define STRONGMEM_SIMD_WRITE 2 // The level of SIMD memory writes will be tracked
#define STRONGMEM_LAST_WRITE 1 // The level of a barrier before the last guest memory store will be put
#define STRONGMEM_SEQ_WRITE 3 // The level of a barrier at every third memory store will be put
#if STEP == 1
#define SMWRITE() \
do { \
/* Mark that current sequence writes to guest memory. */ \
/* This will be used in SMEND for last_write. */ \
dyn->smwrite = 1; \
/* Mark that current opcode writes to guest memory. */ \
dyn->insts[ninst].will_write = 1; \
} while (0)
#define SMWRITELOCK(lock) \
do { \
dyn->insts[ninst].lock = lock; \
SMWRITE(); \
} while (0)
#define SMWRITE2() \
do { \
if (BOX64DRENV(dynarec_strongmem) >= STRONGMEM_SIMD_WRITE) { \
dyn->smwrite = 1; \
dyn->insts[ninst].will_write = 2; \
} \
} while (0)
#define SMREAD()
#define SMREADLOCK(lock)
#define WILLWRITE()
#define WILLWRITELOCK(lock)
#define SMSTART() \
do { \
/* Clear current state at the start of a potential SEQ. */ \
dyn->smwrite = 0; \
} while (0)
#define SMEND() \
do { \
/* If there is any guest memory write, which is a SEQ, then compute the last_write. */ \
if (dyn->smwrite && (BOX64DRENV(dynarec_strongmem) >= STRONGMEM_LAST_WRITE)) { \
int i = ninst; \
while (i >= 0 && !dyn->insts[i].will_write) \
--i; \
if (i >= 0) { dyn->insts[i].last_write = 1; } \
} \
dyn->smwrite = 0; \
} while (0)
#define SMDMB()
#else
// An opcode writes guest memory, this need to be put after the STORE instruction manually.
#define SMWRITE() \
do { \
/* Put a barrier at every third memory write. */ \
if (BOX64DRENV(dynarec_strongmem) >= STRONGMEM_SEQ_WRITE) { \
if (++dyn->smwrite >= 3 /* Every third memory write */) { \
DMB_ISH(); \
dyn->smwrite = 1; \
} \
} else { \
/* Mark that current sequence writes to guest memory. */ \
dyn->smwrite = 1; \
} \
} while (0)
// Similar to SMWRITE, but checks lock.
#define SMWRITELOCK(lock) \
do { \
if (lock) { \
DMB_ISH(); \
} else { \
SMWRITE(); \
} \
} while (0)
// Similar to SMWRITE, but for SIMD instructions.
#define SMWRITE2() \
do { \
if (BOX64DRENV(dynarec_strongmem) >= STRONGMEM_SIMD_WRITE) \
SMWRITE(); \
} while (0)
// An opcode reads guest memory, this need to be put before the LOAD instruction manually.
#define SMREAD()
// Similar to SMREAD, but checks lock.
#define SMREADLOCK(lock) \
do { \
if (lock) { \
DMB_ISH(); \
} else { \
SMREAD(); \
} \
} while (0)
// An opcode will write memory, this will be put before the STORE instruction automatically.
#define WILLWRITE() \
do { \
if (BOX64DRENV(dynarec_strongmem) >= dyn->insts[ninst].will_write && dyn->smwrite == 0) { \
/* Will write but never written, this is the start of a SEQ, put a barrier. */ \
if (BOX64ENV(dynarec_weakbarrier)) \
DMB_ISHLD(); \
else \
DMB_ISH(); \
} else if (BOX64DRENV(dynarec_strongmem) >= STRONGMEM_LAST_WRITE && BOX64ENV(dynarec_weakbarrier) != 2 \
&& dyn->insts[ninst].last_write) { \
/* Last write, put a barrier */ \
if (BOX64ENV(dynarec_weakbarrier)) \
DMB_ISHST(); \
else \
DMB_ISH(); \
} \
} while (0)
// Similar to WILLWRITE, but checks lock.
#define WILLWRITELOCK(lock) \
do { \
if (lock) { \
DMB_ISH(); \
} else { \
WILLWRITE(); \
} \
} while (0)
// Used to clear the state at the start of a SEQ
#define SMSTART() \
do { \
dyn->smwrite = 0; \
} while (0)
// Will be put at the end of the SEQ
#define SMEND() \
do { \
if (BOX64DRENV(dynarec_strongmem)) { \
/* It's a SEQ, put a barrier here. */ \
if (dyn->smwrite) { \
/* Check if the next instruction has a end loop mark */ \
if (BOX64ENV(dynarec_weakbarrier)) \
DMB_ISHST(); \
else \
DMB_ISH(); \
} \
} \
dyn->smwrite = 0; \
} while (0)
// The barrier.
#define SMDMB() DMB_ISH()
#endif
int is_addr_unaligned(uintptr_t addr);
#ifdef ARM64
#include "arm64/dynarec_arm64_helper.h"
#elif defined(LA464)
#include "la464/dynarec_la464_helper.h"
#elif defined(LA64)
#include "la64/dynarec_la64_helper.h"
#elif defined(RV64)
#include "rv64/dynarec_rv64_helper.h"
#else
#error Unsupported architecture
#endif
#endif //__DYNAREC_HELPER__H_
#endif //__DYNAREC_HELPER__H_
+316 -86
View File
@@ -1,3 +1,4 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -22,25 +23,26 @@
#include "dynarec_native.h"
#include "dynarec_arch.h"
#include "dynarec_next.h"
#include "gdbjit.h"
void printf_x64_instruction(zydis_dec_t* dec, instruction_x64_t* inst, const char* name) {
void printf_x64_instruction(dynarec_native_t* dyn, zydis_dec_t* dec, instruction_x64_t* inst, const char* name) {
uint8_t *ip = (uint8_t*)inst->addr;
if(ip[0]==0xcc && ip[1]=='S' && ip[2]=='C') {
uintptr_t a = *(uintptr_t*)(ip+3);
if(a==0) {
dynarec_log(LOG_NONE, "%s%p: Exit x64emu%s\n", (box64_dynarec_dump>1)?"\e[01;33m":"", (void*)ip, (box64_dynarec_dump>1)?"\e[m":"");
dynarec_log(LOG_NONE, "%s%p: Exit x64emu%s\n", (BOX64DRENV(dynarec_dump)>1)?"\e[01;33m":"", (void*)ip, (BOX64DRENV(dynarec_dump)>1)?"\e[m":"");
} else {
dynarec_log(LOG_NONE, "%s%p: Native call to %p%s\n", (box64_dynarec_dump>1)?"\e[01;33m":"", (void*)ip, (void*)a, (box64_dynarec_dump>1)?"\e[m":"");
dynarec_log(LOG_NONE, "%s%p: Native call to %p%s\n", (BOX64DRENV(dynarec_dump)>1)?"\e[01;33m":"", (void*)ip, (void*)a, (BOX64DRENV(dynarec_dump)>1)?"\e[m":"");
}
} else {
if(dec) {
dynarec_log(LOG_NONE, "%s%p: %s", (box64_dynarec_dump>1)?"\e[01;33m":"", ip, DecodeX64Trace(dec, inst->addr));
dynarec_log(LOG_NONE, "%s%p: %s", (BOX64DRENV(dynarec_dump) > 1) ? "\e[01;33m" : "", ip, DecodeX64Trace(dec, inst->addr, 1));
} else {
dynarec_log(LOG_NONE, "%s%p: ", (box64_dynarec_dump>1)?"\e[01;33m":"", ip);
dynarec_log(LOG_NONE, "%s%p: ", (BOX64DRENV(dynarec_dump)>1)?"\e[01;33m":"", ip);
for(int i=0; i<inst->size; ++i) {
dynarec_log(LOG_NONE, "%02X ", ip[i]);
dynarec_log_prefix(0, LOG_NONE, "%02X ", ip[i]);
}
dynarec_log(LOG_NONE, " %s", name);
dynarec_log_prefix(0, LOG_NONE, " %s", name);
}
// print Call function name if possible
if(ip[0]==0xE8 || ip[0]==0xE9) { // Call / Jmp
@@ -53,12 +55,12 @@ void printf_x64_instruction(zydis_dec_t* dec, instruction_x64_t* inst, const cha
}
}
// end of line and colors
dynarec_log(LOG_NONE, "%s\n", (box64_dynarec_dump>1)?"\e[m":"");
dynarec_log_prefix(0, LOG_NONE, "%s\n", (BOX64DRENV(dynarec_dump)>1)?"\e[m":"");
}
}
void add_next(dynarec_native_t *dyn, uintptr_t addr) {
if(!box64_dynarec_bigblock)
if (!BOX64DRENV(dynarec_bigblock))
return;
// exist?
for(int i=0; i<dyn->next_sz; ++i)
@@ -72,8 +74,7 @@ void add_next(dynarec_native_t *dyn, uintptr_t addr) {
}
// add slots
if(dyn->next_sz == dyn->next_cap) {
dyn->next_cap += 64;
dyn->next = (uintptr_t*)dynaRealloc(dyn->next, dyn->next_cap*sizeof(uintptr_t));
printf_log(LOG_NONE, "Warning, overallocating next\n");
}
dyn->next[dyn->next_sz++] = addr;
}
@@ -97,15 +98,19 @@ uintptr_t get_closest_next(dynarec_native_t *dyn, uintptr_t addr) {
void add_jump(dynarec_native_t *dyn, int ninst) {
// add slots
if(dyn->jmp_sz == dyn->jmp_cap) {
dyn->jmp_cap += 64;
dyn->jmps = (int*)dynaRealloc(dyn->jmps, dyn->jmp_cap*sizeof(int));
printf_log(LOG_NONE, "Warning, overallocating jmps\n");
}
dyn->jmps[dyn->jmp_sz++] = ninst;
}
int get_first_jump(dynarec_native_t *dyn, int next) {
if(next<0 || next>dyn->size)
return -2;
return get_first_jump_addr(dyn, dyn->insts[next].x64.addr);
}
int get_first_jump_addr(dynarec_native_t *dyn, uintptr_t next) {
for(int i=0; i<dyn->jmp_sz; ++i)
if(dyn->insts[dyn->jmps[i]].x64.jmp == next)
return i;
return dyn->jmps[i];
return -2;
}
@@ -118,6 +123,8 @@ int is_nops(dynarec_native_t *dyn, uintptr_t addr, int n)
return is_nops(dyn, addr+1, n-1);
if(n>1 && PK(0)==0x66) // if opcode start with 0x66, and there is more after, than is *can* be a NOP
return is_nops(dyn, addr+1, n-1);
if(n>1 && PK(0)==0xF3 && PK(1)==0x90)
return is_nops(dyn, addr+2, n-2);
if(n>2 && PK(0)==0x0f && PK(1)==0x1f && PK(2)==0x00)
return is_nops(dyn, addr+3, n-3);
if(n>2 && PK(0)==0x8d && PK(1)==0x76 && PK(2)==0x00) // lea esi, [esi]
@@ -226,6 +233,14 @@ int next_instruction(dynarec_native_t *dyn, uintptr_t addr)
case 0xBE:
case 0xBF:
return 5;
case 0xF3:
nextop = PK(1);
switch(nextop) {
case 0x90:
return 2;
default: break;
}
break;
case 0xFF:
nextop = PK(1);
switch((nextop>>3)&7) {
@@ -289,15 +304,10 @@ int Table64(dynarec_native_t *dyn, uint64_t val, int pass)
idx = i;
// not found, add it
if(idx==-1) {
if(dyn->table64size == dyn->table64cap) {
dyn->table64cap+=16;
if(pass<3) // do not resize on pass3, it's not the same type of memory anymore
dyn->table64 = (uint64_t*)dynaRealloc(dyn->table64, dyn->table64cap * sizeof(uint64_t));
}
idx = dyn->table64size++;
if(idx < dyn->table64cap)
dyn->table64[idx] = val;
else
else if(pass==3)
printf_log(LOG_NONE, "Warning, table64 bigger than expected %d vs %d\n", idx, dyn->table64cap);
}
// calculate offset
@@ -305,23 +315,35 @@ int Table64(dynarec_native_t *dyn, uint64_t val, int pass)
return delta;
}
static void fillPredecessors(dynarec_native_t* dyn)
static void recurse_mark_alive(dynarec_native_t* dyn, int i)
{
if(dyn->insts[i].x64.alive)
return;
dyn->insts[i].x64.alive = 1;
if(dyn->insts[i].x64.jmp && dyn->insts[i].x64.jmp_insts!=-1)
recurse_mark_alive(dyn, dyn->insts[i].x64.jmp_insts);
if(i<dyn->size-1 && dyn->insts[i].x64.has_next)
recurse_mark_alive(dyn, i+1);
}
static int sizePredecessors(dynarec_native_t* dyn)
{
int pred_sz = 1; // to be safe
// compute total size of predecessor to allocate the array
// mark alive...
recurse_mark_alive(dyn, 0);
// first compute the jumps
int jmpto;
for(int i=0; i<dyn->size; ++i) {
if(dyn->insts[i].x64.jmp && (dyn->insts[i].x64.jmp_insts!=-1)) {
if(dyn->insts[i].x64.alive && dyn->insts[i].x64.jmp && ((jmpto=dyn->insts[i].x64.jmp_insts)!=-1)) {
pred_sz++;
dyn->insts[dyn->insts[i].x64.jmp_insts].pred_sz++;
dyn->insts[jmpto].pred_sz++;
}
}
// remove "has_next" from orphan branch
for(int i=0; i<dyn->size-1; ++i) {
if(!dyn->insts[i].x64.has_next) {
if(dyn->insts[i+1].x64.has_next && !dyn->insts[i+1].pred_sz)
dyn->insts[i+1].x64.has_next = 0;
}
if(dyn->insts[i].x64.has_next && !dyn->insts[i+1].x64.alive)
dyn->insts[i].x64.has_next = 0;
}
// second the "has_next"
for(int i=0; i<dyn->size-1; ++i) {
@@ -330,8 +352,10 @@ static void fillPredecessors(dynarec_native_t* dyn)
dyn->insts[i+1].pred_sz++;
}
}
int alloc_size = pred_sz;
dyn->predecessor = (int*)dynaMalloc(pred_sz*sizeof(int));
return pred_sz;
}
static void fillPredecessors(dynarec_native_t* dyn)
{
// fill pred pointer
int* p = dyn->predecessor;
for(int i=0; i<dyn->size; ++i) {
@@ -340,7 +364,7 @@ static void fillPredecessors(dynarec_native_t* dyn)
dyn->insts[i].pred_sz=0; // reset size, it's reused to actually fill pred[]
}
// fill pred
for(int i=0; i<dyn->size; ++i) {
for(int i=0; i<dyn->size; ++i) if(dyn->insts[i].x64.alive) {
if((i!=dyn->size-1) && dyn->insts[i].x64.has_next)
dyn->insts[i+1].pred[dyn->insts[i+1].pred_sz++] = i;
if(dyn->insts[i].x64.jmp && (dyn->insts[i].x64.jmp_insts!=-1)) {
@@ -350,18 +374,15 @@ static void fillPredecessors(dynarec_native_t* dyn)
}
}
// updateNeed goes backward, from last instruction to top
// updateNeed for the current block. recursive function that goes backward
static int updateNeed(dynarec_native_t* dyn, int ninst, uint8_t need) {
while (ninst>=0) {
// need pending but instruction is only a subset: remove pend and use an X_ALL instead
need |= dyn->insts[ninst].x64.need_after;
if((need&X_PEND) && (dyn->insts[ninst].x64.state_flags==SF_SUBSET)) {
if((need&X_PEND) && ((dyn->insts[ninst].x64.state_flags==SF_SUBSET) || (dyn->insts[ninst].x64.state_flags==SF_SET) || (dyn->insts[ninst].x64.state_flags==SF_SET_NODF))) {
need &=~X_PEND;
need |= X_ALL;
}
if((need&X_PEND) && (dyn->insts[ninst].x64.state_flags==SF_SET)) {
need &=~X_PEND;
need |= dyn->insts[ninst].x64.set_flags; // SF_SET will compute all flags, it's not SUBSET!
STOP_NATIVE_FLAGS(dyn, ninst);
}
if((need&X_PEND) && dyn->insts[ninst].x64.state_flags==SF_SUBSET_PENDING) {
need |= X_ALL&~(dyn->insts[ninst].x64.set_flags);
@@ -397,26 +418,137 @@ static int updateNeed(dynarec_native_t* dyn, int ninst, uint8_t need) {
return ninst;
}
static void updateYmm0s(dynarec_native_t* dyn, int ninst, int max_ninst_reached) {
int can_incr = ninst == max_ninst_reached; // Are we the top-level call?
int ok = 1;
while ((can_incr || ok) && ninst<dyn->size) {
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "update ninst=%d (%d): can_incr=%d\n", ninst, max_ninst_reached, can_incr);
uint16_t new_purge_ymm, new_ymm0_in, new_ymm0_out;
if (dyn->insts[ninst].pred_sz && dyn->insts[ninst].x64.alive) {
// The union of the empty set is empty (0), the intersection is the universe (-1)
// The first instruction is the entry point, which has a virtual pred with ymm0_out = 0
// Similarly, float barriers reset ymm0s
uint16_t ymm0_union = 0;
uint16_t ymm0_inter = (ninst && !(dyn->insts[ninst].x64.barrier & BARRIER_FLOAT)) ? ((uint16_t)-1) : (uint16_t)0;
for (int i = 0; i < dyn->insts[ninst].pred_sz; ++i) {
int pred = dyn->insts[ninst].pred[i];
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "\twith pred[%d] = %d", i, pred);
if (pred >= max_ninst_reached) {
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, " (skipped)\n");
continue;
}
int pred_out = dyn->insts[pred].x64.has_callret ? 0 : dyn->insts[pred].ymm0_out;
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, " ~> %04X\n", pred_out);
ymm0_union |= pred_out;
ymm0_inter &= pred_out;
}
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "\t=> %04X,%04X\n", ymm0_union, ymm0_inter);
// Notice the default values yield something coherent here (if all pred are after ninst)
new_purge_ymm = ymm0_union & ~ymm0_inter;
new_ymm0_in = ymm0_inter;
new_ymm0_out = (ymm0_inter | dyn->insts[ninst].ymm0_add) & ~dyn->insts[ninst].ymm0_sub;
if ((dyn->insts[ninst].purge_ymm != new_purge_ymm) || (dyn->insts[ninst].ymm0_in != new_ymm0_in) || (dyn->insts[ninst].ymm0_out != new_ymm0_out)) {
// Need to update self and next(s)
dyn->insts[ninst].purge_ymm = new_purge_ymm;
dyn->insts[ninst].ymm0_in = new_ymm0_in;
dyn->insts[ninst].ymm0_out = new_ymm0_out;
if (can_incr) {
// We always have ninst == max_ninst_reached when can_incr == 1
++max_ninst_reached;
} else {
// We need to stop here if the opcode has no "real" next or if we reached the ninst of the toplevel
ok = (max_ninst_reached - 1 != ninst) && dyn->insts[ninst].x64.has_next && !dyn->insts[ninst].x64.has_callret;
}
int jmp = (dyn->insts[ninst].x64.jmp)?dyn->insts[ninst].x64.jmp_insts:-1;
if((jmp!=-1) && (jmp < max_ninst_reached)) {
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "\t! jump to %d\n", jmp);
// The jump goes before the last instruction reached, update the destination
// If this is the top level call, this means the jump goes backward (jmp != ninst)
// Otherwise, since we don't update all instructions, we may miss the update (don't use jmp < ninst)
updateYmm0s(dyn, jmp, max_ninst_reached);
}
} else {
if (can_incr) {
// We always have ninst == max_ninst_reached when can_incr == 1
++max_ninst_reached;
// Also update jumps to before (they are skipped otherwise)
int jmp = (dyn->insts[ninst].x64.jmp)?dyn->insts[ninst].x64.jmp_insts:-1;
if((jmp!=-1) && (jmp < max_ninst_reached)) {
//if(BOX64DRENV(dynarec_dump)) dynarec_log(LOG_NONE, "\t! jump to %d\n", jmp);
updateYmm0s(dyn, jmp, max_ninst_reached);
}
} else {
// We didn't update anything, we can leave
ok = 0;
}
}
} else if (can_incr) {
// We always have ninst == max_ninst_reached when can_incr == 1
++max_ninst_reached;
} else {
// We didn't update anything, we can leave
ok = 0;
}
++ninst;
}
}
void* current_helper = NULL;
static int static_jmps[MAX_INSTS+2];
static uintptr_t static_next[MAX_INSTS+2];
static uint64_t static_table64[(MAX_INSTS+3)/4];
static instruction_native_t static_insts[MAX_INSTS+2] = {0};
// TODO: ninst could be a uint16_t instead of an int, that could same some temp. memory
void ClearCache(void* start, size_t len)
{
#if defined(ARM64)
// manually clear cache, I have issue with regular function on Ampere with kernel 6.12.4
uintptr_t xstart = (uintptr_t)start;
uintptr_t xend = (uintptr_t)start + len + 1;
// Cache Type Info. Only grab the info once
static uint64_t ctr_el0 = 0;
if (ctr_el0 == 0)
__asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0));
const int ctr_el0_idc = (ctr_el0>>28)&1; // 0: datacache needs to be cleaned too, 1: no need
const int ctr_el0_dic = (ctr_el0>>29)&1; // 0: instruction cache needs to be cleaned, 1: no need
const uintptr_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15);
const uintptr_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15);
if (!ctr_el0_idc) {
//purge each dcache line if no icache is defined...
for (uint64_t addr=xstart&~(dcache_line_size-1); addr<xend; addr+=dcache_line_size)
__asm __volatile("dc cvau, %0" ::"r"(addr));
}
// ignoring idc...
if (1/*ctr_el0_idx*/) {
// purge each icache line
for (uint64_t addr=xstart&~(icache_line_size-1); addr<xend; addr+=icache_line_size)
__asm __volatile("ic ivau, %0" ::"r"(addr));
}
__asm __volatile("isb sy");
#else
__builtin___clear_cache(start, start+len+1);
#endif
}
void CancelBlock64(int need_lock)
{
if(need_lock)
mutex_lock(&my_context->mutex_dyndump);
dynarec_native_t* helper = (dynarec_native_t*)current_helper;
current_helper = NULL;
if(helper) {
dynaFree(helper->next);
dynaFree(helper->jmps);
dynaFree(helper->insts);
dynaFree(helper->predecessor);
if(helper->table64 && (helper->table64!=(uint64_t*)helper->tablestart))
dynaFree(helper->table64);
if(helper->dynablock && helper->dynablock->actual_block) {
FreeDynarecMap((uintptr_t)helper->dynablock->actual_block);
helper->dynablock->actual_block = NULL;
}
}
current_helper = NULL;
if(need_lock)
mutex_unlock(&my_context->mutex_dyndump);
}
@@ -426,7 +558,7 @@ uintptr_t native_pass1(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
uintptr_t native_pass2(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits);
uintptr_t native_pass3(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits);
void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr) {
void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr, int is32bits) {
block->isize = 0;
block->done = 0;
size_t sz = 4*sizeof(void*);
@@ -441,11 +573,12 @@ void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr) {
block->actual_block = actual_p;
block->block = p;
block->jmpnext = p;
block->is32bits = is32bits;
*(dynablock_t**)actual_p = block;
*(void**)(p+2*sizeof(void*)) = native_epilog;
CreateJmpNext(block->jmpnext, p+2*sizeof(void*));
// all done...
__clear_cache(actual_p, actual_p+sz); // need to clear the cache before execution...
ClearCache(actual_p+sizeof(void*), 3*sizeof(void*)); // need to clear the cache before execution...
return block;
}
@@ -458,18 +591,15 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
A .. A+8*n : Table64: n 64bits values
B .. B+7 : dynablock_t* : self (as part of JmpNext, that simulate another block)
B+8 .. B+15 : 2 Native code for jmpnext (or jmp epilog in case of empty block)
B+16 .. B+23 : jmpnext (or jmp_epilog) address
B+16 .. B+23 : jmpnext (or jmp_epilog) address. jumpnext is used when the block needs testing
B+24 .. B+31 : empty (in case an architecture needs more than 2 opcodes)
B+32 .. B+32+sz : instsize (compressed array with each instruction length on x64 and native side)
C .. C+sz : arch: arch specific info (likes flags info) per inst (can be absent)
*/
if(IsInHotPage(addr)) {
dynarec_log(LOG_DEBUG, "Canceling dynarec FillBlock on hotpage for %p\n", (void*)addr);
return NULL;
}
if(addr>=box64_nodynarec_start && addr<box64_nodynarec_end) {
if(addr>=BOX64ENV(nodynarec_start) && addr<BOX64ENV(nodynarec_end)) {
dynarec_log(LOG_INFO, "Create empty block in no-dynarec zone\n");
return CreateEmptyBlock(block, addr);
return CreateEmptyBlock(block, addr, is32bits);
}
if(current_helper) {
dynarec_log(LOG_DEBUG, "Canceling dynarec FillBlock at %p as another one is going on\n", (void*)addr);
@@ -479,28 +609,42 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
protectDB(addr, 1);
// init the helper
dynarec_native_t helper = {0};
dynarec_native_t* dyn = &helper;
#ifdef GDBJIT
helper.gdbjit_block = box_calloc(1, sizeof(gdbjit_block_t));
#endif
current_helper = &helper;
helper.dynablock = block;
helper.start = addr;
uintptr_t start = addr;
helper.cap = 128;
helper.insts = (instruction_native_t*)dynaCalloc(helper.cap, sizeof(instruction_native_t));
helper.cap = MAX_INSTS;
helper.insts = static_insts;
helper.jmps = static_jmps;
helper.jmp_cap = MAX_INSTS;
helper.next = static_next;
helper.next_cap = MAX_INSTS;
helper.table64 = static_table64;
helper.table64cap = sizeof(static_table64)/sizeof(uint64_t);
// pass 0, addresses, x64 jump addresses, overall size of the block
uintptr_t end = native_pass0(&helper, addr, alternate, is32bits);
if(helper.abort) {
if(BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_log))dynarec_log(LOG_NONE, "Abort dynablock on pass0\n");
CancelBlock64(0);
return NULL;
}
// basic checks
if(!helper.size) {
dynarec_log(LOG_INFO, "Warning, null-sized dynarec block (%p)\n", (void*)addr);
CancelBlock64(0);
return CreateEmptyBlock(block, addr);
return CreateEmptyBlock(block, addr, is32bits);
}
if(!isprotectedDB(addr, 1)) {
dynarec_log(LOG_INFO, "Warning, write on current page on pass0, aborting dynablock creation (%p)\n", (void*)addr);
AddHotPage(addr);
CancelBlock64(0);
return NULL;
}
// protect the block of it goes over the 1st page
if((addr&~box64_pagesize)!=(end&~box64_pagesize)) // need to protect some other pages too
if((addr&~(box64_pagesize-1))!=(end&~(box64_pagesize-1))) // need to protect some other pages too
protectDB(addr, end-addr); //end is 1byte after actual end
// compute hash signature
uint32_t hash = X31_hash_code((void*)addr, end-addr);
@@ -508,10 +652,10 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
for(int ii=0; ii<helper.jmp_sz; ++ii) {
int i = helper.jmps[ii];
uintptr_t j = helper.insts[i].x64.jmp;
helper.insts[i].x64.jmp_insts = -1;
if(j<start || j>=end || j==helper.insts[i].x64.addr) {
if(j==helper.insts[i].x64.addr) // if there is a loop on some opcode, make the block "always to tested"
helper.always_test = 1;
helper.insts[i].x64.jmp_insts = -1;
helper.insts[i].x64.need_after |= X_PEND;
} else {
// find jump address instruction
@@ -544,42 +688,87 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
if(helper.insts[i2].x64.addr==j)
k=i2;
}*/
if(k!=-1 && !helper.insts[i].barrier_maybe)
helper.insts[k].x64.barrier |= BARRIER_FULL;
helper.insts[i].x64.jmp_insts = k;
if(k!=-1) {
if(!helper.insts[i].barrier_maybe)
helper.insts[k].x64.barrier |= BARRIER_FULL;
// special case, loop on itself with some nop in between
if(k<i && !helper.insts[i].x64.has_next && is_nops(&helper, helper.insts[k].x64.addr, helper.insts[i].x64.addr-helper.insts[k].x64.addr)) {
helper.always_test = 1;
k = -1;
}
helper.insts[i].x64.jmp_insts = k;
}
}
}
// no need for next and jmps anymore
dynaFree(helper.next);
// no need for next anymore
helper.next_sz = helper.next_cap = 0;
helper.next = NULL;
dynaFree(helper.jmps);
helper.jmp_sz = helper.jmp_cap = 0;
helper.jmps = NULL;
// fill predecessors with the jump address
int alloc_size = sizePredecessors(&helper);
helper.predecessor = (int*)alloca(alloc_size*sizeof(int));
fillPredecessors(&helper);
int pos = helper.size;
PREUPDATE_SPECIFICS(&helper);
int pos = helper.size-1;
while (pos>=0)
pos = updateNeed(&helper, pos, 0);
// remove fpu stuff on non-executed code
for(int i=1; i<helper.size-1; ++i)
if(!helper.insts[i].pred_sz) {
int ii = i;
while(ii<helper.size && !helper.insts[ii].pred_sz) {
fpu_reset_ninst(&helper, ii);
helper.insts[ii].ymm0_in = helper.insts[ii].ymm0_sub = helper.insts[ii].ymm0_add = helper.insts[ii].ymm0_out = helper.insts[ii].purge_ymm = 0;
RAZ_SPECIFIC(&helper, ii);
++ii;
}
i = ii;
}
// remove trailling dead code
while(helper.size && !helper.insts[helper.size-1].x64.alive) {
helper.isize-=helper.insts[helper.size-1].x64.size;
--helper.size;
}
if(!helper.size) {
// NULL block after removing dead code, how is that possible?
dynarec_log(LOG_INFO, "Warning, null-sized dynarec block after trimming dead code (%p)\n", (void*)addr);
CancelBlock64(0);
return CreateEmptyBlock(block, addr, is32bits);
}
updateYmm0s(&helper, 0, 0);
UPDATE_SPECIFICS(&helper);
// pass 1, float optimizations, first pass for flags
native_pass1(&helper, addr, alternate, is32bits);
if(helper.abort) {
if(BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_log))dynarec_log(LOG_NONE, "Abort dynablock on pass1\n");
CancelBlock64(0);
return NULL;
}
// pass 2, instruction size
native_pass2(&helper, addr, alternate, is32bits);
if(helper.abort) {
if(BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_log))dynarec_log(LOG_NONE, "Abort dynablock on pass2\n");
CancelBlock64(0);
return NULL;
}
// keep size of instructions for signal handling
size_t insts_rsize = (helper.insts_size+2)*sizeof(instsize_t);
insts_rsize = (insts_rsize+7)&~7; // round the size...
size_t native_size = (helper.native_size+7)&~7; // round the size...
size_t arch_size = ARCH_SIZE(&helper);
// ok, now allocate mapped memory, with executable flag on
size_t sz = sizeof(void*) + native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize;
// dynablock_t* block (arm insts) table64 jmpnext code instsize
size_t sz = sizeof(void*) + native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize + arch_size;
// dynablock_t* block (arm insts) table64 jmpnext code instsize arch
void* actual_p = (void*)AllocDynarecMap(sz);
void* p = (void*)(((uintptr_t)actual_p) + sizeof(void*));
void* tablestart = p + native_size;
void* next = tablestart + helper.table64size*sizeof(uint64_t);
void* instsize = next + 4*sizeof(void*);
void* arch = instsize + insts_rsize;
if(actual_p==NULL) {
dynarec_log(LOG_INFO, "AllocDynarecMap(%p, %zu) failed, canceling block\n", block, sz);
CancelBlock64(0);
@@ -593,29 +782,36 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
helper.instsize = (instsize_t*)instsize;
*(dynablock_t**)actual_p = block;
helper.table64cap = helper.table64size;
dynaFree(helper.table64);
helper.table64 = (uint64_t*)helper.tablestart;
// pass 3, emit (log emit native opcode)
if(box64_dynarec_dump) {
dynarec_log(LOG_NONE, "%s%04d|Emitting %zu bytes for %u %s bytes", (box64_dynarec_dump>1)?"\e[01;36m":"", GetTID(), helper.native_size, helper.isize, is32bits?"x86":"x64");
if(BOX64DRENV(dynarec_dump)) {
dynarec_log(LOG_NONE, "%s%04d|Emitting %zu bytes for %u %s bytes (native=%zu, table64=%zu, instsize=%zu, arch=%zu)", (BOX64DRENV(dynarec_dump)>1)?"\e[01;36m":"", GetTID(), helper.native_size, helper.isize, is32bits?"x86":"x64", native_size, helper.table64size*sizeof(uint64_t), insts_rsize, arch_size);
printFunctionAddr(helper.start, " => ");
dynarec_log(LOG_NONE, "%s\n", (box64_dynarec_dump>1)?"\e[m":"");
dynarec_log(LOG_NONE, "%s\n", (BOX64DRENV(dynarec_dump)>1)?"\e[m":"");
}
if (BOX64ENV(dynarec_gdbjit) && (!BOX64ENV(dynarec_gdbjit_end) || (addr >= BOX64ENV(dynarec_gdbjit_start) && addr < BOX64ENV(dynarec_gdbjit_end)))) {
GdbJITNewBlock(helper.gdbjit_block, (GDB_CORE_ADDR)block->actual_block, (GDB_CORE_ADDR)block->actual_block + native_size, helper.start);
}
int oldtable64size = helper.table64size;
size_t oldnativesize = helper.native_size;
size_t oldinstsize = helper.insts_size;
int oldsize= helper.size;
helper.native_size = 0;
helper.table64size = 0; // reset table64 (but not the cap)
helper.insts_size = 0; // reset
native_pass3(&helper, addr, alternate, is32bits);
if(helper.abort) {
if(BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_log))dynarec_log(LOG_NONE, "Abort dynablock on pass3\n");
CancelBlock64(0);
return NULL;
}
// no need for jmps anymore
helper.jmp_sz = helper.jmp_cap = 0;
helper.jmps = NULL;
// keep size of instructions for signal handling
block->instsize = instsize;
// ok, free the helper now
dynaFree(helper.insts);
helper.insts = NULL;
helper.table64 = NULL;
helper.instsize = NULL;
dynaFree(helper.predecessor);
helper.predecessor = NULL;
block->size = sz;
block->isize = helper.size;
@@ -623,46 +819,80 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
block->jmpnext = next+sizeof(void*);
block->always_test = helper.always_test;
block->dirty = block->always_test;
block->is32bits = is32bits;
if(arch_size) {
block->arch_size = arch_size;
block->arch = ARCH_FILL(&helper, arch, arch_size);
if(!block->arch) block->arch_size = 0;
} else {
block->arch = NULL;
block->arch_size = arch_size;
}
*(dynablock_t**)next = block;
*(void**)(next+3*sizeof(void*)) = native_next;
CreateJmpNext(block->jmpnext, next+3*sizeof(void*));
ClearCache(block->jmpnext, 4*sizeof(void*));
//block->x64_addr = (void*)start;
block->x64_size = end-start;
// all done...
__clear_cache(actual_p, actual_p+sz); // need to clear the cache before execution...
if (BOX64ENV(dynarec_gdbjit) && (!BOX64ENV(dynarec_gdbjit_end) || (addr >= BOX64ENV(dynarec_gdbjit_start) && addr < BOX64ENV(dynarec_gdbjit_end)))) {
GdbJITBlockReady(helper.gdbjit_block);
}
ClearCache(actual_p+sizeof(void*), native_size); // need to clear the cache before execution...
block->hash = X31_hash_code(block->x64_addr, block->x64_size);
// Check if something changed, to abort if it is
if((block->hash != hash)) {
if((helper.abort || (block->hash != hash))) {
dynarec_log(LOG_DEBUG, "Warning, a block changed while being processed hash(%p:%ld)=%x/%x\n", block->x64_addr, block->x64_size, block->hash, hash);
AddHotPage(addr);
CancelBlock64(0);
return NULL;
}
if((oldnativesize!=helper.native_size) || (oldtable64size<helper.table64size)) {
printf_log(LOG_NONE, "BOX64: Warning, size difference in block between pass2 (%zu) & pass3 (%zu)!\n", sz, helper.native_size+helper.table64size*8);
printf_log(LOG_NONE, "Warning, size difference in block between pass2 (%zu, %d) & pass3 (%zu, %d)!\n", oldnativesize+oldtable64size*8, oldsize, helper.native_size+helper.table64size*8, helper.size);
uint8_t *dump = (uint8_t*)helper.start;
printf_log(LOG_NONE, "Dump of %d x64 opcodes:\n", helper.size);
for(int i=0; i<helper.size; ++i) {
printf_log(LOG_NONE, "%p:", dump);
printf_log(LOG_NONE, "%s%p:", (helper.insts[i].size2!=helper.insts[i].size)?"=====> ":"", dump);
for(; dump<(uint8_t*)helper.insts[i+1].x64.addr; ++dump)
printf_log(LOG_NONE, " %02X", *dump);
printf_log(LOG_NONE, "\t%d -> %d\n", helper.insts[i].size2, helper.insts[i].size);
printf_log_prefix(0, LOG_NONE, " %02X", *dump);
printf_log_prefix(0, LOG_NONE, "\t%d -> %d", helper.insts[i].size2, helper.insts[i].size);
if(helper.insts[i].ymm0_pass2 || helper.insts[i].ymm0_pass3)
printf_log_prefix(0, LOG_NONE, "\t %04x -> %04x", helper.insts[i].ymm0_pass2, helper.insts[i].ymm0_pass3);
printf_log_prefix(0, LOG_NONE, "\n");
}
printf_log(LOG_NONE, "Table64 \t%d -> %d\n", oldtable64size*8, helper.table64size*8);
printf_log(LOG_NONE, " ------------\n");
CancelBlock64(0);
return NULL;
}
// ok, free the helper now
//dynaFree(helper.insts);
helper.insts = NULL;
if(insts_rsize/sizeof(instsize_t)<helper.insts_size) {
printf_log(LOG_NONE, "BOX64: Warning, insts_size difference in block between pass2 (%zu) and pass3 (%zu), allocated: %zu\n", oldinstsize, helper.insts_size, insts_rsize/sizeof(instsize_t));
printf_log(LOG_NONE, "Warning, insts_size difference in block between pass2 (%zu) and pass3 (%zu), allocated: %zu\n", oldinstsize, helper.insts_size, insts_rsize/sizeof(instsize_t));
}
if(!isprotectedDB(addr, end-addr)) {
dynarec_log(LOG_DEBUG, "Warning, block unprotected while being processed %p:%ld, marking as need_test\n", block->x64_addr, block->x64_size);
AddHotPage(addr);
block->dirty = 1;
//protectDB(addr, end-addr);
}
if(getProtection(addr)&PROT_NEVERCLEAN) {
block->dirty = 1;
block->always_test = 1;
}
if(block->always_test) {
dynarec_log(LOG_DEBUG, "Note: block marked as always dirty %p:%ld\n", block->x64_addr, block->x64_size);
}
current_helper = NULL;
//block->done = 1;
return (void*)block;
}
void writePerfMap(uintptr_t func_addr, uintptr_t code_addr, size_t code_size, const char* inst_name)
{
char pbuf[128];
uint64_t sz = 0;
uintptr_t start = 0;
const char* symbname = FindNearestSymbolName(FindElfAddress(my_context, func_addr), (void*)func_addr, &start, &sz);
snprintf(pbuf, sizeof(pbuf), "0x%lx %ld %s:%s\n", code_addr, code_size, symbname, inst_name);
write(BOX64ENV(dynarec_perf_map_fd), pbuf, strlen(pbuf));
}
+257 -51
View File
@@ -42,7 +42,7 @@ void native_print_armreg(x64emu_t* emu, uintptr_t reg, uintptr_t n)
void native_f2xm1(x64emu_t* emu)
{
ST0.d = exp2(ST0.d) - 1.0;
ST0.d = expm1(LN2 * ST0.d);
}
void native_fyl2x(x64emu_t* emu)
{
@@ -50,19 +50,32 @@ void native_fyl2x(x64emu_t* emu)
}
void native_ftan(x64emu_t* emu)
{
#pragma STDC FENV_ACCESS ON
// seems that tan of glib doesn't follow the rounding direction mode
ST0.d = tan(ST0.d);
emu->sw.f.F87_C2 = 0;
}
void native_fpatan(x64emu_t* emu)
{
#pragma STDC FENV_ACCESS ON
ST1.d = atan2(ST1.d, ST0.d);
}
void native_fxtract(x64emu_t* emu)
{
int32_t tmp32s = (ST1.q&0x7ff0000000000000LL)>>52;
tmp32s -= 1023;
ST1.d /= exp2(tmp32s);
ST0.d = tmp32s;
int tmp32s;
if(isnan(ST1.d)) {
ST0.d = ST1.d;
} else if(isinf(ST1.d)) {
ST0.d = ST1.d;
ST1.d = INFINITY;
} else if(ST1.d==0.0) {
ST0.d = ST1.d;
ST1.d = -INFINITY;
} else {
// LD80bits doesn't have implicit "1" bit, so need to adjust for that
ST0.d = frexp(ST1.d, &tmp32s)*2;
ST1.d = tmp32s-1;
}
}
void native_fprem(x64emu_t* emu)
{
@@ -87,10 +100,12 @@ void native_fprem(x64emu_t* emu)
}
void native_fyl2xp1(x64emu_t* emu)
{
ST(1).d = log2(ST0.d + 1.0)*ST(1).d;
ST(1).d = log1p(ST0.d)*ST(1).d/LN2;
}
void native_fsincos(x64emu_t* emu)
{
#pragma STDC FENV_ACCESS ON
// seems that sincos of glib doesn't follow the rounding direction mode
sincos(ST1.d, &ST1.d, &ST0.d);
emu->sw.f.F87_C2 = 0;
}
@@ -100,16 +115,21 @@ void native_frndint(x64emu_t* emu)
}
void native_fscale(x64emu_t* emu)
{
#pragma STDC FENV_ACCESS ON
if(ST0.d!=0.0)
ST0.d *= exp2(trunc(ST1.d));
ST0.d = ldexp(ST0.d, trunc(ST1.d));
}
void native_fsin(x64emu_t* emu)
{
#pragma STDC FENV_ACCESS ON
// seems that sin of glib doesn't follow the rounding direction mode
ST0.d = sin(ST0.d);
emu->sw.f.F87_C2 = 0;
}
void native_fcos(x64emu_t* emu)
{
#pragma STDC FENV_ACCESS ON
// seems that cos of glib doesn't follow the rounding direction mode
ST0.d = cos(ST0.d);
emu->sw.f.F87_C2 = 0;
}
@@ -164,15 +184,22 @@ void native_fld(x64emu_t* emu, uint8_t* ed)
void native_ud(x64emu_t* emu)
{
if(box64_dynarec_test)
if(BOX64ENV(dynarec_test))
emu->test.test = 0;
emit_signal(emu, SIGILL, (void*)R_RIP, 0);
}
void native_br(x64emu_t* emu)
{
if(BOX64ENV(dynarec_test))
emu->test.test = 0;
emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xb09d);
}
void native_priv(x64emu_t* emu)
{
emu->test.test = 0;
emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);
}
void native_int(x64emu_t* emu, int num)
@@ -188,13 +215,13 @@ void native_singlestep(x64emu_t* emu)
void native_int3(x64emu_t* emu)
{
emit_signal(emu, SIGTRAP, (void*)R_RIP, 128);
emit_signal(emu, SIGTRAP, NULL, 3);
}
void native_div0(x64emu_t* emu)
{
emu->test.test = 0;
emit_div0(emu, (void*)R_RIP, 0);
emit_div0(emu, (void*)R_RIP, 1);
}
void native_fsave(x64emu_t* emu, uint8_t* ed)
@@ -204,7 +231,18 @@ void native_fsave(x64emu_t* emu, uint8_t* ed)
uint8_t* p = ed;
p += 28;
for (int i=0; i<8; ++i) {
LD2D(p, &ST(i).d);
LD2D(p, &emu->x87[7-i].d);
p+=10;
}
}
void native_fsave16(x64emu_t* emu, uint8_t* ed)
{
fpu_savenv(emu, (char*)ed, 1);
uint8_t* p = ed;
p += 14;
for (int i=0; i<8; ++i) {
LD2D(p, &emu->x87[7-i].d);
p+=10;
}
}
@@ -215,7 +253,19 @@ void native_frstor(x64emu_t* emu, uint8_t* ed)
uint8_t* p = ed;
p += 28;
for (int i=0; i<8; ++i) {
D2LD(&ST(i).d, p);
D2LD(&emu->x87[7-i].d, p);
p+=10;
}
}
void native_frstor16(x64emu_t* emu, uint8_t* ed)
{
fpu_loadenv(emu, (char*)ed, 1);
uint8_t* p = ed;
p += 14;
for (int i=0; i<8; ++i) {
D2LD(&emu->x87[7-i].d, p);
p+=10;
}
@@ -245,23 +295,23 @@ void native_fprem1(x64emu_t* emu)
static uint8_t ff_mult(uint8_t a, uint8_t b)
{
int retval = 0;
int retval = 0;
for(int i = 0; i < 8; i++) {
if((b & 1) == 1)
retval ^= a;
for(int i = 0; i < 8; i++) {
if((b & 1) == 1)
retval ^= a;
if((a & 0x80)) {
a <<= 1;
a ^= 0x1b;
} else {
a <<= 1;
}
if((a & 0x80)) {
a <<= 1;
a ^= 0x1b;
} else {
a <<= 1;
}
b >>= 1;
}
b >>= 1;
}
return retval;
return retval;
}
void native_aesimc(x64emu_t* emu, int xmm)
@@ -275,6 +325,17 @@ void native_aesimc(x64emu_t* emu, int xmm)
emu->xmm[xmm].ub[3+j*4] = ff_mult(0x0B, eax1.ub[0+j*4]) ^ ff_mult(0x0D, eax1.ub[1+j*4]) ^ ff_mult(0x09, eax1.ub[2+j*4]) ^ ff_mult(0x0E, eax1.ub[3+j*4]);
}
}
void native_aesimc_y(x64emu_t* emu, int ymm)
{
sse_regs_t eay1 = emu->ymm[ymm];
for(int j=0; j<4; ++j) {
emu->ymm[ymm].ub[0+j*4] = ff_mult(0x0E, eay1.ub[0+j*4]) ^ ff_mult(0x0B, eay1.ub[1+j*4]) ^ ff_mult(0x0D, eay1.ub[2+j*4]) ^ ff_mult(0x09, eay1.ub[3+j*4]);
emu->ymm[ymm].ub[1+j*4] = ff_mult(0x09, eay1.ub[0+j*4]) ^ ff_mult(0x0E, eay1.ub[1+j*4]) ^ ff_mult(0x0B, eay1.ub[2+j*4]) ^ ff_mult(0x0D, eay1.ub[3+j*4]);
emu->ymm[ymm].ub[2+j*4] = ff_mult(0x0D, eay1.ub[0+j*4]) ^ ff_mult(0x09, eay1.ub[1+j*4]) ^ ff_mult(0x0E, eay1.ub[2+j*4]) ^ ff_mult(0x0B, eay1.ub[3+j*4]);
emu->ymm[ymm].ub[3+j*4] = ff_mult(0x0B, eay1.ub[0+j*4]) ^ ff_mult(0x0D, eay1.ub[1+j*4]) ^ ff_mult(0x09, eay1.ub[2+j*4]) ^ ff_mult(0x0E, eay1.ub[3+j*4]);
}
}
void native_aesmc(x64emu_t* emu, int xmm)
{
sse_regs_t eax1 = emu->xmm[xmm];
@@ -286,29 +347,40 @@ void native_aesmc(x64emu_t* emu, int xmm)
emu->xmm[xmm].ub[3+j*4] = ff_mult(0x03, eax1.ub[0+j*4]) ^ eax1.ub[1+j*4] ^ eax1.ub[2+j*4] ^ ff_mult(0x02, eax1.ub[3+j*4]);
}
}
void native_aesmc_y(x64emu_t* emu, int ymm)
{
sse_regs_t eay1 = emu->ymm[ymm];
for(int j=0; j<4; ++j) {
emu->ymm[ymm].ub[0+j*4] = ff_mult(0x02, eay1.ub[0+j*4]) ^ ff_mult(0x03, eay1.ub[1+j*4]) ^ eay1.ub[2+j*4] ^ eay1.ub[3+j*4] ;
emu->ymm[ymm].ub[1+j*4] = eay1.ub[0+j*4] ^ ff_mult(0x02, eay1.ub[1+j*4]) ^ ff_mult(0x03, eay1.ub[2+j*4]) ^ eay1.ub[3+j*4] ;
emu->ymm[ymm].ub[2+j*4] = eay1.ub[0+j*4] ^ eay1.ub[1+j*4] ^ ff_mult(0x02, eay1.ub[2+j*4]) ^ ff_mult(0x03, eay1.ub[3+j*4]);
emu->ymm[ymm].ub[3+j*4] = ff_mult(0x03, eay1.ub[0+j*4]) ^ eay1.ub[1+j*4] ^ eay1.ub[2+j*4] ^ ff_mult(0x02, eay1.ub[3+j*4]);
}
}
// A0 B1 C2 D3 E4 F5 G6 H7 I8 J9 Ka Lb Mc Nd Oe Pf
// A N K H E B O L I F C P M J G D
static const uint8_t invshiftrows[] = {0,13,10, 7, 4, 1,14,11, 8, 5, 2,15,12, 9, 6, 3};
static const uint8_t invsubbytes[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
};
void native_aesdlast(x64emu_t* emu, int xmm)
{
// A0 B1 C2 D3 E4 F5 G6 H7 I8 J9 Ka Lb Mc Nd Oe Pf
// A N K H E B O L I F C P M J G D
const uint8_t invshiftrows[] = {0,13,10, 7, 4, 1,14,11, 8, 5, 2,15,12, 9, 6, 3};
const uint8_t invsubbytes[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
};
sse_regs_t eax1;
for(int i=0; i<16; ++i)
@@ -317,6 +389,17 @@ void native_aesdlast(x64emu_t* emu, int xmm)
for(int i=0; i<16; ++i)
emu->xmm[xmm].ub[i] = invsubbytes[eax1.ub[i]];
}
void native_aesdlast_y(x64emu_t* emu, int ymm)
{
sse_regs_t eay1;
for(int i=0; i<16; ++i)
eay1.ub[i] = emu->ymm[ymm].ub[invshiftrows[i]];
//STATE ← InvSubBytes( STATE );
for(int i=0; i<16; ++i)
emu->ymm[ymm].ub[i] = invsubbytes[eay1.ub[i]];
}
static const uint8_t shiftrows[] = {0, 5,10,15, 4, 9,14, 3, 8,13, 2, 7,12, 1, 6,11};
static const uint8_t subbytes[256] = {
@@ -348,16 +431,34 @@ void native_aeselast(x64emu_t* emu, int xmm)
for(int i=0; i<16; ++i)
emu->xmm[xmm].ub[i] = subbytes[eax1.ub[i]];
}
void native_aeselast_y(x64emu_t* emu, int ymm)
{
sse_regs_t eay1;
for(int i=0; i<16; ++i)
eay1.ub[i] = emu->ymm[ymm].ub[shiftrows[i]];
for(int i=0; i<16; ++i)
emu->ymm[ymm].ub[i] = subbytes[eay1.ub[i]];
}
void native_aesd(x64emu_t* emu, int xmm)
{
native_aesdlast(emu, xmm);
native_aesimc(emu, xmm);
}
void native_aesd_y(x64emu_t* emu, int ymm)
{
native_aesdlast_y(emu, ymm);
native_aesimc_y(emu, ymm);
}
void native_aese(x64emu_t* emu, int xmm)
{
native_aeselast(emu, xmm);
native_aesmc(emu, xmm);
}
void native_aese_y(x64emu_t* emu, int ymm)
{
native_aeselast_y(emu, ymm);
native_aesmc_y(emu, ymm);
}
void native_aeskeygenassist(x64emu_t* emu, int gx, int ex, void* p, uint32_t u8)
{
sse_regs_t *EX = p?((sse_regs_t*)p):&emu->xmm[ex];
@@ -393,6 +494,40 @@ void native_pclmul(x64emu_t* emu, int gx, int ex, void* p, uint32_t u8)
GX->q[0] = result&0xffffffffffffffffLL;
GX->q[1] = (result>>64)&0xffffffffffffffffLL;
}
void native_pclmul_x(x64emu_t* emu, int gx, int vx, void* p, uint32_t u8)
{
sse_regs_t *EX = ((uintptr_t)p<16)?((sse_regs_t*)p):&emu->xmm[(uintptr_t)p];
sse_regs_t *GX = &emu->xmm[gx];
sse_regs_t *VX = &emu->xmm[vx];
int g = (u8&1)?1:0;
int e = (u8&0b10000)?1:0;
__int128 result = 0;
__int128 op2 = EX->q[e];
for (int i=0; i<64; ++i)
if(VX->q[g]&(1LL<<i))
result ^= (op2<<i);
GX->q[0] = result&0xffffffffffffffffLL;
GX->q[1] = (result>>64)&0xffffffffffffffffLL;
}
void native_pclmul_y(x64emu_t* emu, int gy, int vy, void* p, uint32_t u8)
{
sse_regs_t *EY = ((uintptr_t)p<16)?((sse_regs_t*)p):&emu->ymm[(uintptr_t)p];
sse_regs_t *GY = &emu->ymm[gy];
sse_regs_t *VY = &emu->ymm[vy];
int g = (u8&1)?1:0;
int e = (u8&0b10000)?1:0;
__int128 result = 0;
__int128 op2 = EY->q[e];
for (int i=0; i<64; ++i)
if(VY->q[g]&(1LL<<i))
result ^= (op2<<i);
GY->q[0] = result&0xffffffffffffffffLL;
GY->q[1] = (result>>64)&0xffffffffffffffffLL;
}
void native_clflush(x64emu_t* emu, void* p)
{
@@ -405,7 +540,7 @@ static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) {
return 0;
if(dyn->insts[ninst].f_exit.dfnone) // flags are fully known, nothing we can do more
return 0;
if(dyn->insts[jmp].f_entry.dfnone && !dyn->insts[ninst].f_exit.dfnone)
if(dyn->insts[jmp].f_entry.dfnone && !dyn->insts[ninst].f_exit.dfnone && !dyn->insts[jmp].df_notneeded)
return 1;
switch (dyn->insts[jmp].f_entry.pending) {
case SF_UNKNOWN: return 0;
@@ -476,7 +611,7 @@ uintptr_t fakeed(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nexto
}
return addr;
}
// return Ib on a mod/rm opcode without emiting anything
// return Ib on a mod/rm opcode without emitting anything
uint8_t geted_ib(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nextop)
{
addr = fakeed(dyn, addr, ninst, nextop);
@@ -484,9 +619,11 @@ uint8_t geted_ib(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nexto
}
#undef F8
int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn)
int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, int is32bits, uintptr_t* calladdress, uint16_t* retn)
{
(void)dyn;
if(is32bits)
addr &= 0xFFFFFFFFLL;
#define PK(a) *(uint8_t*)(addr+a)
#define PK32(a) *(int32_t*)(addr+a)
@@ -500,7 +637,7 @@ int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, uintptr_t* calladdress,
if(!addr || !getProtection(addr))
return 0;
onebridge_t *b = (onebridge_t*)(addr);
if(b->CC==0xCC && b->S=='S' && b->C=='C' && b->w!=(wrapper_t)0 && b->f!=(uintptr_t)PltResolver) {
if(b->CC==0xCC && b->S=='S' && b->C=='C' && b->w!=(wrapper_t)0 && b->f!=(uintptr_t)PltResolver64) {
// found !
if(retn) *retn = (b->C3==0xC2)?b->N:0;
if(calladdress) *calladdress = addr+1;
@@ -510,3 +647,72 @@ int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, uintptr_t* calladdress,
#undef PK32
#undef PK
}
// AVX
void avx_mark_zero(dynarec_native_t* dyn, int ninst, int reg)
{
dyn->ymm_zero |= (1<<reg);
}
int is_avx_zero(dynarec_native_t* dyn, int ninst, int reg)
{
return (dyn->ymm_zero>>reg)&1;
}
int is_avx_zero_unset(dynarec_native_t* dyn, int ninst, int reg)
{
if((dyn->ymm_zero>>reg)&1) {
dyn->ymm_zero &= ~(1<<reg);
return 1;
}
return 0;
}
void avx_mark_zero_reset(dynarec_native_t* dyn, int ninst)
{
dyn->ymm_zero = 0;
}
void avx_unmark_zero(dynarec_native_t* dyn, int ninst, int reg)
{
dyn->ymm_zero &= ~(1<<reg);
}
void propagate_nodf(dynarec_native_t* dyn, int ninst)
{
while(ninst>=0) {
if(dyn->insts[ninst].df_notneeded)
return; // already flagged
if(dyn->insts[ninst].x64.gen_flags || dyn->insts[ninst].x64.use_flags)
return; // flags are use, so maybe it's needed
dyn->insts[ninst].df_notneeded = 1;
--ninst;
}
}
void x64disas_add_register_mapping_annotations(char* buf, const char* disas, const register_mapping_t* mappings, size_t mappings_sz)
{
static char tmp[32];
tmp[0] = '\0';
int len = 0;
// skip the mnemonic
char* p = strchr(disas, ' ');
if (!p) {
sprintf(buf, "%s", disas);
return;
}
p++; // skip the space
while (*p) {
while (*p && !(*p >= 'a' && *p <= 'e') && *p != 's' && *p != 'r') // skip non-register characters
p++;
if (!*p) break;
for (int i = 0; i < mappings_sz; ++i) {
if (!strncmp(p, mappings[i].name, strlen(mappings[i].name))) {
len += sprintf(tmp + len, " %s,", mappings[i].native);
p += strlen(mappings[i].name) - 1;
break;
}
}
p++;
}
if (tmp[0]) tmp[strlen(tmp) - 1] = '\0';
sprintf(buf, "%-35s ;%s", disas, tmp);
}
Loaded 100 of 1910 files, more files were not shown because too many files have changed in this diff. Show more