mirror of
https://github.com/ptitSeb/box86.git
synced 2026-11-08 17:39:19 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2d5587ea1 | ||
|
|
4b020ab4f5 | ||
|
|
088a85c125 | ||
|
|
2bf60dc00d | ||
|
|
b5ffa0e92a | ||
|
|
258f7f9b50 | ||
|
|
07c403243d | ||
|
|
709de6a858 | ||
|
|
dfed557f61 | ||
|
|
f143771be8 | ||
|
|
fc20c410c0 | ||
|
|
677205a288 | ||
|
|
abb9acfd42 | ||
|
|
75dca68db0 | ||
|
|
5c1a8ad128 | ||
|
|
e4cf8f8c94 | ||
|
|
30968917a4 | ||
|
|
84ea9e3301 | ||
|
|
1f9c046919 | ||
|
|
cefe210184 | ||
|
|
02aa791fd9 | ||
|
|
d8c1341068 | ||
|
|
ca648ea128 | ||
|
|
daf5a9d91d | ||
|
|
16b95f2088 | ||
|
|
41dfcb559a | ||
|
|
37c871ec2e | ||
|
|
34bd1ff42f | ||
|
|
e0f1d4fecf | ||
|
|
c94d992ef6 | ||
|
|
bfe83d827d | ||
|
|
1c45795828 | ||
|
|
8dc5c164d8 | ||
|
|
326032aa23 | ||
|
|
b79e234da2 | ||
|
|
5bc6962a9d | ||
|
|
168717a90a | ||
|
|
dd6b0f6c9a | ||
|
|
0a3c678877 | ||
|
|
e2df6f6ce0 | ||
|
|
e58ebdac18 | ||
|
|
537312a91f | ||
|
|
11c08acd6c | ||
|
|
cf9a38fb02 | ||
|
|
83dff2bf25 | ||
|
|
49694f300a | ||
|
|
daddc8246e | ||
|
|
9f92377edc | ||
|
|
1ce392d968 | ||
|
|
bf730b43e2 | ||
|
|
a4adb47caf | ||
|
|
9317572874 | ||
|
|
eca39e6a8f | ||
|
|
4639dc8ffd | ||
|
|
5a9b34f54b | ||
|
|
dc07d477de | ||
|
|
db5efa8908 | ||
|
|
7d462dd837 | ||
|
|
76010f63c0 | ||
|
|
be7f72808b | ||
|
|
25f1e8e6fa | ||
|
|
047df311f0 | ||
|
|
bcdd99328c | ||
|
|
5cc76a0071 | ||
|
|
dee55a9ac2 | ||
|
|
9ff20da9bb | ||
|
|
0520f5abcd | ||
|
|
e1201ff0de | ||
|
|
bc2d7e7396 | ||
|
|
9a058a2416 | ||
|
|
49fea86b28 | ||
|
|
1617439d37 | ||
|
|
540459cb78 | ||
|
|
54b8522df6 | ||
|
|
bf65e606d3 | ||
|
|
5335a641df | ||
|
|
323ece7417 | ||
|
|
ca1fc0ffad | ||
|
|
c0706e227e | ||
|
|
995e4a9b68 | ||
|
|
7f53379552 | ||
|
|
3e17299a34 | ||
|
|
c63cdc9506 | ||
|
|
7965186817 | ||
|
|
f107612753 | ||
|
|
2295f7bb8b | ||
|
|
cc0845a9d3 | ||
|
|
e9019461b7 | ||
|
|
a19e3ed3dd | ||
|
|
10ec424e96 | ||
|
|
b838c8a7d0 | ||
|
|
0331af0643 | ||
|
|
24561fc37c | ||
|
|
d4ad5334b8 | ||
|
|
7fe3299282 | ||
|
|
23fef75ed5 | ||
|
|
62722b0618 | ||
|
|
e810dba2c9 | ||
|
|
7dfe545161 | ||
|
|
a5f3966b44 | ||
|
|
886573ed8b | ||
|
|
2758c1c955 | ||
|
|
591bafe8c3 | ||
|
|
211a8f42db | ||
|
|
fbc9029a8e | ||
|
|
ceb4b8b06d | ||
|
|
b88dda442f | ||
|
|
6e8163bded | ||
|
|
9b253abb53 | ||
|
|
e5e51e3ea3 | ||
|
|
6a2d9d7663 | ||
|
|
0546b1e212 | ||
|
|
320e6dae72 | ||
|
|
96f944c804 | ||
|
|
fd0e2195f7 | ||
|
|
d2f130a834 | ||
|
|
a3459712ce | ||
|
|
8bf2e49164 | ||
|
|
0f5cd39a64 | ||
|
|
e0ed0076f2 | ||
|
|
bfd4ad39af | ||
|
|
a8ff7d8769 | ||
|
|
39c77beb1c | ||
|
|
d576f7af39 | ||
|
|
74c3f43f75 | ||
|
|
ecacace01d | ||
|
|
a3b0149a84 | ||
|
|
63111577ec | ||
|
|
eb68520709 | ||
|
|
a7bf2c6cc3 | ||
|
|
190788efd9 | ||
|
|
2592a6a342 | ||
|
|
16ee4c348d | ||
|
|
8389097cd3 | ||
|
|
79a885c15e | ||
|
|
eb7c683a6d | ||
|
|
95b2b314f6 | ||
|
|
07eb0aa5cd | ||
|
|
fdce28590a | ||
|
|
572613e377 | ||
|
|
29e597b4ed | ||
|
|
981c464c36 | ||
|
|
d406c5717c | ||
|
|
92208efd24 | ||
|
|
edef6d7f99 |
No files matched your search
@@ -1,3 +1,19 @@
|
||||
v0.2.0
|
||||
======
|
||||
* Improvoment on x86 Flags handling
|
||||
* A few more opcode added
|
||||
* A few potential BusError fixed
|
||||
* Added BOX86_NOVULKAN en. var. disable the wrapping of vulkan libs
|
||||
* Improvments on libc O_XXXX flags handling
|
||||
* Now use a custom allocator for Dynarec and Hash tables
|
||||
* Improvment wrapping of pulse audio
|
||||
* Optimisation to a few Dynarec opcode (like SHRD/SHLD)
|
||||
* Improved the tracking of memory protection
|
||||
* A few more wrapping of libs (like libgssapi_krb5)
|
||||
* More function wrapping on libturbojpeg
|
||||
* Preliminary support for POWER9 (ppcle) build
|
||||
* Many contributed typo and rephrasing of README, COMPILE and USAGE docs
|
||||
|
||||
v0.1.8
|
||||
======
|
||||
* Fixes on some float to int x87 convertions opcodes
|
||||
|
||||
+32
-4
@@ -5,15 +5,17 @@ option(PYRA "Set to ON if targeting an OpenPandora device" ${PYRA})
|
||||
option(RPI2 "Set to ON if targeting an RaspberryPI2 device" ${RPI2})
|
||||
option(RPI3 "Set to ON if targeting an RaspberryPI3 device" ${RPI3})
|
||||
option(RPI4 "Set to ON if targeting an RaspberryPI4 device" ${RPI4})
|
||||
option(RPI4ARM64 "Set to ON if targeting an RaspberryPI4 device with multiarch arm64 and armhf" ${RPI4ARM64})
|
||||
option(RK3399 "Set to ON if targeting an Rockchip RK3399 based device" ${RK3399})
|
||||
option(GAMESHELL "Set to ON if targeting a GameShell device" ${GAMESHELL})
|
||||
option(ODROID "Set to ON if targeting an ODroid device" ${ODROID})
|
||||
option(POWER9 "Set to ON if targeting a POWER9 processor" ${POWER9})
|
||||
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
|
||||
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
|
||||
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box86" ${NO_LOADAADR})
|
||||
option(NOGETCLOCK "Set to ON to avoid using clock_gettime with CLOCK_MONOTONIC_COARSE for RDTSC opcode (use gltimeofday instead)" ${NOGETCLOCK})
|
||||
option(NOGIT "Set to ON if not building from a git clone repo (like when building from a zip download from github)" ${NOGIT})
|
||||
if(PANDORA OR PYRA OR RPI2 OR RPI3 OR RPI4 OR GAMESHELL OR ODROID OR RK3399)
|
||||
if(PANDORA OR PYRA OR RPI2 OR RPI3 OR RPI4 OR GAMESHELL OR ODROID OR RK3399 OR RPI4ARM64)
|
||||
set(LD80BITS OFF CACHE BOOL "")
|
||||
set(NOALIGN OFF CACHE BOOL "")
|
||||
set(ARM_DYNAREC ON CACHE BOOL "")
|
||||
@@ -21,6 +23,8 @@ endif()
|
||||
option(LD80BITS "Set to ON if host device have 80bits long double (i.e. i386)" ${LD80BITS})
|
||||
option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NOALIGN})
|
||||
option(ARM_DYNAREC "Set to ON to use ARM Dynamic Recompilation (WIP, don't use yet)" ${ARM_DYNAREC})
|
||||
option(POWERPCLE "Set to ON if targeting a little-endian PowerPC device" ${POWERPCLE})
|
||||
option(SYSV_VARARG "Set to ON if host device uses SysVR4 vararg calling convention" ${SYSV_VARARG})
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.12.2")
|
||||
find_package(PythonInterp 3)
|
||||
@@ -38,7 +42,7 @@ else()
|
||||
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE} CACHE INTERNAL "The Python3 executable" FORCE)
|
||||
endif()
|
||||
|
||||
if(RK3399)
|
||||
if(RK3399 OR RPI4ARM64)
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
#set(CMAKE_ASM_COMPILER arm-linux-gnueabihf-as) #will use gcc in fact
|
||||
set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf)
|
||||
@@ -87,6 +91,12 @@ if(RPI4)
|
||||
add_definitions(-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
endif()
|
||||
if(RPI4ARM64)
|
||||
add_definitions(-DRPI)
|
||||
add_definitions(-DRPI4ARM64)
|
||||
add_definitions(-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
|
||||
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
|
||||
endif()
|
||||
if(ODROID)
|
||||
add_definitions(-DODROID)
|
||||
add_definitions(-mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm)
|
||||
@@ -98,6 +108,10 @@ if(RK3399)
|
||||
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a72+crypto")
|
||||
endif()
|
||||
|
||||
if(POWER9)
|
||||
add_definitions(-mcpu=power9 -mtune=power9)
|
||||
endif()
|
||||
|
||||
if(NOGIT)
|
||||
add_definitions(-DNOGIT)
|
||||
endif()
|
||||
@@ -132,6 +146,14 @@ if(ARM_DYNAREC)
|
||||
enable_language(ASM)
|
||||
endif()
|
||||
|
||||
if(POWERPCLE)
|
||||
add_definitions(-DPOWERPCLE)
|
||||
endif()
|
||||
|
||||
if(SYSV_VARARG)
|
||||
add_definitions(-DSYSV_VARARG)
|
||||
endif()
|
||||
|
||||
if(NOGETCLOCK)
|
||||
add_definitions(-DNOGETCLOCK)
|
||||
endif()
|
||||
@@ -176,6 +198,7 @@ set(ELFLOADER_SRC
|
||||
"${BOX86_ROOT}/src/main.c"
|
||||
"${BOX86_ROOT}/src/box86context.c"
|
||||
"${BOX86_ROOT}/src/build_info.c"
|
||||
"${BOX86_ROOT}/src/custommem.c"
|
||||
"${BOX86_ROOT}/src/tools/bridge.c"
|
||||
"${BOX86_ROOT}/src/tools/pathcoll.c"
|
||||
"${BOX86_ROOT}/src/tools/fileutils.c"
|
||||
@@ -335,8 +358,10 @@ set(WRAPPEDS
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedxslt.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedldapr.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlber.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlcms2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappednsl.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedlcms2.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedkrb5.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedgssapikrb5.c"
|
||||
"${BOX86_ROOT}/src/wrapped/wrappedldlinux.c"
|
||||
)
|
||||
|
||||
@@ -351,7 +376,10 @@ set(WRAPPER "${BOX86_ROOT}/src/wrapped/generated/wrapper.c" "${BOX86_ROOT}/src/w
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${BOX86_ROOT}/src/wrapped/generated/functions_list.txt"
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${BOX86_ROOT}/rebuild_wrappers.py" "${BOX86_ROOT}" "PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "--" ${WRAPPEDS_HEAD}
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${BOX86_ROOT}/rebuild_wrappers.py"
|
||||
"${BOX86_ROOT}"
|
||||
"PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "POWERPCLE" "--"
|
||||
${WRAPPEDS_HEAD}
|
||||
MAIN_DEPENDENCY "${BOX86_ROOT}/rebuild_wrappers.py"
|
||||
DEPENDS ${WRAPPEDS} ${WRAPPEDS_HEAD}
|
||||
BYPRODUCTS ${WRAPPER}
|
||||
|
||||
+6
-6
@@ -35,9 +35,9 @@ sudo systemctl restart systemd-binfmt
|
||||
|
||||
`mkdir build; cd build; cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j4`
|
||||
|
||||
As most RK3399 device run AARCH64 OS, you'll need an `armhf` multiarch env, and an armhf gcc: use `sudo apt install gcc-arm-linux-gnueabihf` to install it.
|
||||
As most RK3399 device run AARCH64 OS, you'll need an `armhf` multiarch environment, and an armhf gcc: On debian, install it with `sudo apt install gcc-arm-linux-gnueabihf`.
|
||||
|
||||
#### for Other ARM Linux
|
||||
#### for Other ARM Linux platforms
|
||||
|
||||
`mkdir build; cd build; cmake .. -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo; make`
|
||||
|
||||
@@ -57,19 +57,19 @@ Add `-DUSE_CCACHE=1` if you have ccache (it's better if you plan to touch the so
|
||||
|
||||
*have some debug info*
|
||||
|
||||
The `-DCMAKE_BUILD_TYPE=RelWithDebInfo` argument make a build that is both optimized for speed, and have debug information embedded. That way, if you have a crash or try to analyse performances, you'll have some symbols.
|
||||
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.
|
||||
|
||||
*to have a Trace Enabled build*
|
||||
|
||||
To have a trace enabled build (warning, it will be slower), add `-DHAVE_TRACE=1` but you will need, at runtime, to have the [Zydis library](https://github.com/zyantific/zydis) library in your `LD_LIBRARY_PATH` or in the system lib folders.
|
||||
To have a trace enabled build ( ***it will be slower***), add `-DHAVE_TRACE=1` but you will need, at runtime, to have the [Zydis library](https://github.com/zyantific/zydis) library in your `LD_LIBRARY_PATH` or in the system library folders.
|
||||
|
||||
*to have ARM Dynarec*
|
||||
|
||||
The Dynarec is only avaiable on ARM Cpu. Notes also that VFPv3 and NEON are required for the Dynarec. Activate it by using `-DARM_DYNAREC=1`. Also, be sure to use `-marm` in compilation flags (because many compileur use Thumb as default, and the dynarec will not work in this mode).
|
||||
The Dynarec is only available on the ARM architecture(Right now, anyways.). Notes also that VFPv3 and NEON are required for the Dynarec. Activate it by using `-DARM_DYNAREC=1`. Also, be sure to use `-marm` in compilation flags (because many compileur use Thumb as default, and the dynarec will not work in this mode).
|
||||
|
||||
*not building from a git clone*
|
||||
|
||||
If you are not building from a git clone (for example downloading a release sources Zipped from github), you need to activate `-DNOGIT=1` from cmake to be able to build (normal process include git sha1 of HEAD in the version that box86 print).
|
||||
If you are not building from a git clone (for example, downloading a release source zipped from github), you need to activate `-DNOGIT=1` from cmake to be able to build (normal process include git sha1 of HEAD in the version that box86 print).
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ You *NEED* a 32-bit subsystem to run and build Box86. Box86 is useless on 64-bit
|
||||
|
||||
Because Box86 uses the native versions of some "system" libraries, like libc, libm, SDL, and OpenGL, it's easy to integrate and use, and performance can be surprisingly high in some cases.
|
||||
|
||||
Most x86 Games need OpenGL, so on ARM platforms a solution like [gl4es](https://github.com/ptitSeb/gl4es) is usually necessary.
|
||||
Most x86 Games need OpenGL, so on ARM platforms a solution like [gl4es](https://github.com/ptitSeb/gl4es) is usually necessary(most ARM platforms only support OpenGL ES and/or their OpenGL implementation is dodgy (see OpenGL on Android)) .
|
||||
|
||||
Box86 now integrates a DynaRec (dynamic recompiler) for the ARM platform, providing a speed boost between 5 to 10 times faster than only using the interpreter.
|
||||
|
||||
@@ -32,14 +32,14 @@ Compatibility list is there: https://github.com/ptitSeb/box86-compatibility-list
|
||||
|
||||
Logo and Icon made by @grayduck, thanks!
|
||||
|
||||
Note that this project is not to be mystaken with [86box](https://github.com/86Box/86Box), a nice "Full system" emulator specialized in early (to fairly recent) PC hardware.
|
||||
Note that this project is not to be mistaken with [86box](https://github.com/86Box/86Box), a nice "Full system" emulator specialized in early (to fairly recent) PC hardware.
|
||||
|
||||
----
|
||||
|
||||
Discord
|
||||
----
|
||||
|
||||
If you want to discuss about box86 on Discord, there is a frendly server there: [PI Lab Discord](https://discord.gg/Fh8sjmu)
|
||||
If you want to discuss(or have any problems) about box86, there is a Discord friendly server there: [PI Lab Discord](https://discord.gg/Fh8sjmu)
|
||||
|
||||
|
||||
----
|
||||
@@ -53,11 +53,11 @@ Compilation instructions can be found [here](COMPILE.md)
|
||||
Usage
|
||||
----
|
||||
|
||||
There are a few environment variables avaiable to control the behaviour of Box86.
|
||||
There are a few environment variables to control the behaviour of Box86.
|
||||
|
||||
See [here](USAGE.md) for all variables and what they do.
|
||||
See [here](USAGE.md) for all environment variables and what they do.
|
||||
|
||||
Note that now the Dynarec of Box86 uses a mecanism with Memory Protection and a SegFault signal handler to handle JIT code. That means if you want to use gdb to debug running a program that use JIT'd code (like mono/Unity3D), you will have many "normal" segfaults triggering. I suggest you 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.
|
||||
Note: Box86'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.
|
||||
|
||||
----
|
||||
|
||||
@@ -68,41 +68,41 @@ The change log is available [here](CHANGELOG.md)
|
||||
|
||||
----
|
||||
|
||||
A note about 64-bit platforms
|
||||
Notes about 64-bit platforms
|
||||
----
|
||||
|
||||
Because Box86 works by directly translating function calls from x86 to host system, the host system (the one Box86 is running on) needs to have 32-bit libraries. Box86 doesn't include any 32-bit <-> 64-bit translation. So basically, to run Box86 on, for example, an ARM64 platform, you will need to build Box86 for ARM 32-bit, and also need to have a chroot with 32-bit libraries.
|
||||
|
||||
Also note that, even if, on day, there is a Box86_64, this one will only be able to run x86_64 binaries on 64-bit platforms. You will still need Box86 (and see 32-bit chroot) to run x86 binaries (in fact, the same is the case on actual x86_64 Linux).
|
||||
Also note that, even if, on day, there is a Box86_64, this one will only be able to run x86_64 binaries on 64-bit platforms. You will still need Box86 (and a 32-bit chroot) to run x86 binaries (in fact, the same is the case on actual x86_64 Linux).
|
||||
|
||||
----
|
||||
|
||||
A note about Unity game emulation
|
||||
----
|
||||
|
||||
Running Unity games is a hit or miss for now. Unity uses Mono (which uses signals that are not well emulated enough), and a runtime embedded in the main binary. A solution would be to use a native version of the libmono library used by Unity (it can be found here: https://github.com/Unity-Technologies/mono and needs to be built from source). But the wrapping of this lib is tricky, and not done for now, so the only solution is to emulate everything. The tricky part is to emulate the "JIT" code emitted by Mono, however with he new "protected memory" mechanism implemented it is running with correct performance now.
|
||||
Running Unity games is a hit or miss for now. Unity uses Mono (which uses signals that are not well emulated enough), and a runtime embedded in the main binary. A solution would be to use a native version of the libmono library used by Unity (it can be found here: https://github.com/Unity-Technologies/mono and needs to be built from source). But the wrapping of this lib is tricky, and not done for now, so the only solution is to emulate everything. The tricky part is to emulate the "JIT" code emitted by Mono, however with the new "protected memory" mechanism implemented it should be running with correct performance now.
|
||||
You should also note that some Unity3D games require OpenGL 3+ which can be tricky to provide on ARM SBC (single-board computers) for now.
|
||||
|
||||
TL;DR: Not all Unity games work and can require a high OpenGL profile, but the speed, for the ones running, should be correct now.
|
||||
|
||||
----
|
||||
|
||||
A note about Steam
|
||||
Notes about Steam
|
||||
----
|
||||
|
||||
Linux Steam can run now with box86. But it's still a bit unstable., and not everything works. First is steam crashes after the Sign in, you may need to add libappindicator. On debian it's `sudo apt install libappindicator1`.
|
||||
Once open, Steam will only work on "Small mode" and in "Big Picture", not in the regular "Browser mode". So go in the "View" menu and witch to Small view (or Compact view?), else the list will stay empty (this is because some steam component used in the browser view are only 64bits now).
|
||||
Final word, to avoid the "libc.so.6 is absent" message, you can use `STEAMOS=1` and `STEAM_RUNTIME=1` export.
|
||||
(Steam for Windows install fine but doesn't work yet)
|
||||
Some steam games (most of Source engine one, like "Portal" or "Half-Life 2") use libtcmalloc. Box86 will detect it's use and will try to LD_PRELOAD it, for better compatibility. While it should work without, it is better to add it to your system if you intend to play those game (something like `sudo apt install libtcmalloc-minimal4` on debian familly)
|
||||
Linux Steam's can run now with box86. But it's still a bit unstable, and not everything works. First problem is steam crashing after the Sign in window, if you encounter this issue, you may need to add libappindicator. Installing the package on debian `sudo apt install libappindicator1`.
|
||||
Once open, Steam will only work on "Small Mode" and in "Big Picture", not in the regular "Large Mode"(This is because some steam component used in the browser view are only 64 bits now.). So go in the "View" menu and switch to Small view, else the list will stay empty.
|
||||
Final words, to avoid the "libc.so.6 is absent" message, you can use `STEAMOS=1` and `STEAM_RUNTIME=1` as environment variables.
|
||||
(Steam for Windows installs fine but doesn't work yet)
|
||||
Some Steam games (most Source engine games, like "Portal" or "Half-Life 2") use libtcmalloc. Box86 will detect it and will try to LD_PRELOAD it, for better compatibility. While it should work without the aformentionned feature, it is safer to add it to your system if you intend to play those game (something like `sudo apt install libtcmalloc-minimal4` to install it on Debian and Debian's deriatives)
|
||||
|
||||
----
|
||||
|
||||
A note about Wine
|
||||
Notes about Wine
|
||||
----
|
||||
|
||||
Wine is now partly supported. Wine integreted program all runs, annd some windows program and games now run fine. Don't forget most Windows games use Direct3D, that may require a complete OpenGL driver and as high profile as possible (and gl4es with ES2 backend have issue with Wine for now). Also, vulkan is not wrapped on box86, so vk3d is not usable yet, even if supported by the hardware.
|
||||
A not if you plan to use box86 with wine on Raspberry PI 3 or earlier: those model use a default OS that have a kernle with a 2/2 Split (meaning 2G of space for user program, and 2G of space for Kernel). This is not compatible with wine, that need to access memory > 2Gb address. So you'll need to reconfigure your kernel for a 3G/1G split. Use your favorite search engine to find tutos on how to do that.
|
||||
Wine is now partly supported. Wine integrated program all runs, and some windows programs and games now runs fine. Don't forget most Windows games use Direct3D, this may require a complete OpenGL driver and as high profile as possible (and gl4es with ES2 backend have issue with Wine for now). Also, vulkan is not wrapped on box86, so vk3d is not usable yet, even if supported by the hardware.
|
||||
Note: if you plan to use box86 with Wine on Raspberry Pi 3 or earlier, those models use a default OS that have a kernel with a 2/2 Split (meaning 2G of space for user program, and 2G of space for the Kernel). This is not compatible with Wine programs that needs to access memory > 2Gb address. So you'll need to reconfigure your kernel for a 3G/1G split. Use your favorite search engine for instructions on how to do that.
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
|
||||
Usage
|
||||
----
|
||||
|
||||
There are many environment variable to control Box86 behaviour.
|
||||
There are many environment variables to control Box86 behaviour.
|
||||
|
||||
#### BOX86_LOG
|
||||
Controls the Verbose level of the log
|
||||
Controls the Verbosity level of the logs
|
||||
* 0
|
||||
* NONE : No message (except some fatal error)
|
||||
* NONE : Current default. No message (except some fatal error)
|
||||
* 1
|
||||
* INFO : Current default. Show some log
|
||||
* INFO : Show some minimum log (like librairies not found)
|
||||
* 2
|
||||
* DEBUG : Verbose a lot of stuffs (like relocations or function called)
|
||||
* DEBUG : Details a lot of stuff (like relocations or function called)
|
||||
* 3
|
||||
* DUMP : All DEBUG plus DUMP of all ELF Info
|
||||
|
||||
#### BOX86_NOBANNER
|
||||
Control Box86 printing it's version and build
|
||||
* 0 : Enabled the printing
|
||||
* 1 : Diable the printing
|
||||
Control Box86 printing its version and build
|
||||
* 0 : Enable printing
|
||||
* 1 : Disable printing
|
||||
|
||||
#### BOX86_LD_LIBRARY_PATH
|
||||
Controls the folder scanned to look for x86 libs. Default is current folder and `lib` in current folder.
|
||||
Path to look for x86 libs. Default is current folder and `lib` in current folder.
|
||||
Also `/usr/lib/i386-linux-gnu` and `/lib/i386-linux-gnu` are added if they exists
|
||||
|
||||
#### BOX86_PATH
|
||||
Controls the folder scanned to look for x86 executable. Default is current folder and `bin` in current folder.
|
||||
Path to look for x86 executable. Default is current folder and `bin` in current folder.
|
||||
|
||||
#### BOX86_DLSYM_ERROR
|
||||
* 0 : default. Don't log `dlsym` error
|
||||
@@ -32,17 +33,17 @@ Controls the folder scanned to look for x86 executable. Default is current folde
|
||||
|
||||
#### BOX86_TRACE_FILE
|
||||
Send all log and trace to a file instead of `stdout`
|
||||
Also, if name contains `%pid` then this is replaced by actual PID of box86 instance
|
||||
Also, if name contains `%pid` then this is replaced by the actual PID of box86 instance
|
||||
|
||||
#### BOX86_TRACE
|
||||
Only on build with trace enabled. Trace allow the logging of all instruction execute, along with register dump
|
||||
Only on build with trace enabled. Trace allow the logging of all instruction executed, along with register dump
|
||||
* 0 : No trace
|
||||
* 1 : Trace enabled. The trace start after the init of all depending libs is done
|
||||
* 1 : Trace enabled. Trace start after the initialisation of all depending libraries is done
|
||||
* symbolname : Trace only `symbolname` (trace is disable if the symbol is not found)
|
||||
* 0xXXXXXXX-0xYYYYYYY : trace only between the 2 addresses
|
||||
|
||||
#### BOX86_TRACE_INIT
|
||||
Use BOX86_TRACE_INIT instead of BOX_TRACE to start trace before init of Libs and main program
|
||||
Use BOX86_TRACE_INIT instead of BOX_TRACE to start trace before the initialisation of libraries and the running program
|
||||
* 0 : No trace
|
||||
* 1 : Trace enabled. The trace start with the init of all depending libs is done
|
||||
|
||||
@@ -52,39 +53,40 @@ Only on build with trace enabled.
|
||||
|
||||
#### BOX86_TRACE_XMM
|
||||
Only on build with trace enabled.
|
||||
* 0 : Default, the XMM (i.e. SSE/SSE2) register will not be logged with the general and x87 registers
|
||||
* 0 : Default, the XMM (i.e. SSE/SSE2) register will not be logged with the general and x86 registers
|
||||
* 1 : Dump the XMM registers
|
||||
|
||||
#### BOX86_LOAD_ADDR
|
||||
Try to load at 0xXXXXXX main binaray (if binary is a PIE)
|
||||
Try to load at 0xXXXXXX main binary (if binary is a PIE)
|
||||
* 0xXXXXXXXX the load address (only active on PIE programs)
|
||||
|
||||
#### BOX86_NOSIGSEGV
|
||||
To disable handling of SigSEGV (to ease debugging mainly)
|
||||
Disable handling of SigSEGV ( Very useful for debugging.)
|
||||
* 0 : default, let x86 program set sighandler for SEGV
|
||||
* 1 : disable handling of SigSEGV
|
||||
|
||||
#### BOX86_NOSIGILL
|
||||
To disable handling of SigILL (to ease debugging mainly)
|
||||
Disable handling of SigILL (to ease debugging mainly)
|
||||
* 0 : default, let x86 program set sighandler for Illegal Instruction
|
||||
* 1 : disable handling of SigILL
|
||||
|
||||
#### BOX86_X11COLOR16
|
||||
PANDORA only: to try convert X11 color from 32 bits to 16 bits (to avoid light green on light cyan windows
|
||||
PANDORA only: Try converting X11 color from 32 bits to 16 bits (to avoid light green on light cyan windows)
|
||||
* 0 : default, don't touch X11 colors
|
||||
* 1 : Change colors arguments in XSetForeground, XSetBackground and XCreateGC
|
||||
|
||||
#### BOX86_X11THREADS
|
||||
To call XInitThreads when loading X11 (for old Loki games with Loki_Compat lib)
|
||||
Call XInitThreads when loading X11 (for old Loki games with Loki_Compat lib)
|
||||
* 0 : default, don't force call XInitThreads
|
||||
* 1 : Call XInitThreads as soon as libX11 is loaded
|
||||
|
||||
#### BOX86_X11GLX
|
||||
To Force libX11 GLX extension to be present
|
||||
Force libX11 GLX extension to be present.
|
||||
* 0 : Disable the force.
|
||||
* 1 : default, GLX will always be present when using XQueryExtension
|
||||
|
||||
#### BOX86_DYNAREC_DUMP
|
||||
Enables/disables box86's dynarec dump.
|
||||
* 0 : Disable Dynarec blocks dump (default)
|
||||
* 1 : Enable Dynarec blocks dump
|
||||
* 2 : Enable Dynarec blocks dump with some colors
|
||||
@@ -113,6 +115,7 @@ Set level of DynaRec log
|
||||
* 1 : Consider all mmap/mmap64 safe to use linker (potential speedup, but potential crash for apps using JIT/Dynarec)
|
||||
|
||||
#### BOX86_DYNAREC_TRACE
|
||||
Enables/Disables trace for generated code
|
||||
* 0 : Disable trace for generated code (default)
|
||||
* 1 : Enable trace for generated code (like regular Trace, this will slow down a lot and generate huge logs)
|
||||
|
||||
@@ -127,31 +130,39 @@ Set level of DynaRec log
|
||||
|
||||
#### BOX86_EMULATED_LIBS
|
||||
* XXXX[:YYYYY] force lib XXXX (and YYYY...) to be emulated (and not wrapped)
|
||||
Some games use old version of some lib, with an ABI incompatible with native version.
|
||||
Some games uses an old version of some libraries, with an ABI incompatible with native version.
|
||||
Note that LittleInferno for example is auto detected, and libvorbis.so.0 is automatical added to emulated libs, and same for Don't Starve (and Together / Server variant) that use an old SDL2 too
|
||||
|
||||
#### BOX86_ALLOWMISSINGLIBS
|
||||
Allow box86 to continue even if a lib is missing
|
||||
* 0 : default, stop if a lib cannot be loaded
|
||||
* 1 : continue even if a needed lib cannot be loaded. Unadvised, this will, in most cases, crash later on.
|
||||
Allow box86 to continue even if a library is missing
|
||||
* 0 : default, stop if a library cannot be loaded
|
||||
* 1 : continue even if a needed library cannot be loaded. Unadvised, this will, in most cases, crash later on.
|
||||
|
||||
#### BOX86_NOPULSE
|
||||
Disable the load of pulseaudio libs
|
||||
* 0 : default, load pulseaudio libs if present
|
||||
* 1 : disable the load of pulse audio libs (libpulse and libpulse-simple), both native and x86 version
|
||||
Disable the load of pulseaudio libraries
|
||||
* 0 : default, load pulseaudio libraries if present
|
||||
* 1 : disable the load of pulse audio libraries (libpulse and libpulse-simple), both native and x86 version
|
||||
|
||||
#### BOX86_NOGTK
|
||||
Disable the load of wrapped gtk libs
|
||||
Disable the load of wrapped GTK libraries
|
||||
* 0 : default, load wrapped gtk libs if present
|
||||
* 1 : disable the load of wrapped gtk libs (can be used with Steam, along with STEAM_RUNTIME=1 to use i386 versio of gtk)
|
||||
|
||||
#### BOX86_NOVULKAN
|
||||
Disable the load of vulkan libraries
|
||||
* 0 : default, load vulkan libraries if present
|
||||
* 1 : disable the load of vulkan libraries both native and x86 version (can be usefull on Pi4)
|
||||
|
||||
#### BOX86_FIX_64BIT_INODES
|
||||
* 0 : Don't fix 64bit inodes (default)
|
||||
* 1 : Fix 64bit inodes. Helps when running on filesystems with 64bit inodes, the program uses API functions which don't support it and the program doesn't use inodes information.
|
||||
* 1 : Fix 64bit inodes. Helps when running on filesystems with 64bit inodes, the program uses API functions which doesn't support it and the program doesn't use inodes information.
|
||||
|
||||
#### BOX86_JITGDB
|
||||
* 0 : Just print the Segfault message on segfault (default)
|
||||
* 1 : Launch `gdb` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process, and go in an endless loop, waiting.
|
||||
When in gdb, you need to find the correct thread yourself (the one with `my_box86signalhandler` in is stack)
|
||||
then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box86signalhandler`,
|
||||
just before the printf of the Segfault message. Then simply `set waiting=0` to exit the infinite loop.
|
||||
just before the printf of the Segfault message. Then simply `set waiting=0` to exit the infinite loop.
|
||||
* 2 : Launch `gdbserver` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process, and go in an endless loop, waiting.
|
||||
Use `gdb /PATH/TO/box86` and then `target remote 127.0.0.1:1234` to connect to the gdbserver (or use actual IP if not on the machine). After that, the procedure is the same as with ` BOX86_JITGDB=1`.
|
||||
This mode can be usefull when program redirect all console output to a file (like Unity3D Games)
|
||||
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-hacker
|
||||
+14
-8
@@ -1,5 +1,5 @@
|
||||
# Maintainer: SpacingBat3 <youremail@domain.com>
|
||||
# Contributor: Sebastien Chevalier
|
||||
# Maintainer: SpacingBat3 <[email protected].com>
|
||||
# Contributor: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-arm-git
|
||||
pkgver=r2798.0edc0374
|
||||
pkgrel=1
|
||||
@@ -9,18 +9,18 @@ url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}")
|
||||
conflicts=("${pkgname%-git}")
|
||||
provides=("${pkgname%-git}" "${_pkgname%-arm-git}-git" "${_pkgname%-arm-git}")
|
||||
conflicts=("${pkgname%-git}" "${_pkgname%-arm-git}-git" "${_pkgname%-arm-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-git}"
|
||||
cd "$srcdir/${pkgname%-arm-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-git}"
|
||||
cd "${srcdir}/${pkgname%-arm-git}"
|
||||
if [[ ! -d ./build ]]; then
|
||||
mkdir build && cd build
|
||||
cmake .. -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
@@ -28,11 +28,17 @@ prepare() {
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-arm-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-arm-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
# /usr/local/bin isn't in PATH by the default,
|
||||
# we should move it to /usr/bin
|
||||
cd ${pkgdir}
|
||||
mv usr/local/bin/ usr/bin/
|
||||
# cleanup when dir is empty
|
||||
rmdir usr/local || exit 0
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
# Maintainer: SpacingBat3 <youremail@domain.com>
|
||||
# Contributor: Sebastien Chevalier
|
||||
# Maintainer: SpacingBat3 <[email protected].com>
|
||||
# Contributor: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-gameshell-git
|
||||
pkgver=r2798.0edc0374
|
||||
pkgrel=1
|
||||
@@ -9,18 +9,18 @@ url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}")
|
||||
conflicts=("${pkgname%-git}")
|
||||
provides=("${pkgname%-git}" "${pkgname%-gameshell-git}-git" "${pkgname%-gameshell-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-gameshell-git}-git" "${pkgname%-gameshell-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-git}"
|
||||
cd "$srcdir/${pkgname%-gameshell-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-git}"
|
||||
cd "${srcdir}/${pkgname%-gameshell-git}"
|
||||
if [[ ! -d ./build ]]; then
|
||||
mkdir build && cd build
|
||||
cmake .. -DGAMESHELL=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
@@ -28,11 +28,17 @@ prepare() {
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-gameshell-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-gameshell-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
# /usr/local/bin isn't in PATH by the default,
|
||||
# we should move it to /usr/bin
|
||||
cd ${pkgdir}
|
||||
mv usr/local/bin/ usr/bin/
|
||||
# cleanup when dir is empty
|
||||
rmdir usr/local || exit 0
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
# Maintainer: SpacingBat3 <youremail@domain.com>
|
||||
# Contributor: Sebastien Chevalier
|
||||
# Maintainer: SpacingBat3 <[email protected].com>
|
||||
# Contributor: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-odroid-git
|
||||
pkgver=r2798.0edc0374
|
||||
pkgrel=1
|
||||
@@ -9,18 +9,18 @@ url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}")
|
||||
conflicts=("${pkgname%-git}")
|
||||
provides=("${pkgname%-git}" "${_pkgname%-odroid-git}-git" "${_pkgname%-odroid-git}")
|
||||
conflicts=("${pkgname%-git}" "${_pkgname%-odroid-git}-git" "${_pkgname%-odroid-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-git}"
|
||||
cd "$srcdir/${pkgname%-odroid-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-git}"
|
||||
cd "${srcdir}/${pkgname%-odroid-git}"
|
||||
if [[ ! -d ./build ]]; then
|
||||
mkdir build && cd build
|
||||
cmake .. -DODROID=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
@@ -28,11 +28,17 @@ prepare() {
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-odroid-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-odroid-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
# /usr/local/bin isn't in PATH by the default,
|
||||
# we should move it to /usr/bin
|
||||
cd ${pkgdir}
|
||||
mv usr/local/bin/ usr/bin/
|
||||
# cleanup when dir is empty
|
||||
rmdir usr/local || exit 0
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
# Maintainer: SpacingBat3 <youremail@domain.com>
|
||||
# Contributor: Sebastien Chevalier
|
||||
# Maintainer: SpacingBat3 <[email protected].com>
|
||||
# Contributor: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-pandora-git
|
||||
_pkgname=box86-git
|
||||
pkgver=r2798.0edc0374
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
@@ -9,18 +10,18 @@ url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}")
|
||||
conflicts=("${pkgname%-git}")
|
||||
provides=("${pkgname%-git}" "${pkgname%-pandora-git}"-git "${pkgname%-pandora-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-pandora-git}"-git "${pkgname%-pandora-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-git}"
|
||||
cd "$srcdir/${pkgname%-pandora-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-git}"
|
||||
cd "${srcdir}/${pkgname%-pandora-git}"
|
||||
if [[ ! -d ./build ]]; then
|
||||
mkdir build && cd build
|
||||
cmake .. -DPANDORA=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
@@ -28,11 +29,17 @@ prepare() {
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-pandora-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
# /usr/local/bin isn't in PATH by the default,
|
||||
# we should move it to /usr/bin
|
||||
cd ${pkgdir}
|
||||
mv usr/local/bin/ usr/bin/
|
||||
# cleanup when dir is empty
|
||||
rmdir usr/local || exit 0
|
||||
}
|
||||
+15
-8
@@ -1,6 +1,7 @@
|
||||
# Maintainer: SpacingBat3 <youremail@domain.com>
|
||||
# Contributor: Sebastien Chevalier
|
||||
# Maintainer: SpacingBat3 <[email protected].com>
|
||||
# Contributor: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-pyra-git
|
||||
_pkgname=box86-git
|
||||
pkgver=r2798.0edc0374
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
@@ -9,18 +10,18 @@ url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}")
|
||||
conflicts=("${pkgname%-git}")
|
||||
provides=("${pkgname%-git}" "${pkgname%-pyra-git}-git" "${pkgname%-pyra-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-pyra-git}-git" "${pkgname%-pyra-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-git}"
|
||||
cd "$srcdir/${pkgname%-pyra-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-git}"
|
||||
cd "${srcdir}/${pkgname%-pyra-git}"
|
||||
if [[ ! -d ./build ]]; then
|
||||
mkdir build && cd build
|
||||
cmake .. -DPYRA=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
@@ -28,11 +29,17 @@ prepare() {
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-pyra-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-pyra-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
# /usr/local/bin isn't in PATH by the default,
|
||||
# we should move it to /usr/bin
|
||||
cd ${pkgdir}
|
||||
mv usr/local/bin/ usr/bin/
|
||||
# cleanup when dir is empty
|
||||
rmdir usr/local || exit 0
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
# Maintainer: SpacingBat3 <youremail@domain.com>
|
||||
# Contributor: Sebastien Chevalier
|
||||
# Maintainer: SpacingBat3 <[email protected].com>
|
||||
# Contributor: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-rpi-git
|
||||
_pkgname=box86-git
|
||||
pkgver=r2798.0edc0374
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
@@ -9,29 +10,30 @@ url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}")
|
||||
conflicts=("${pkgname%-git}")
|
||||
provides=("${pkgname%-git}" "${pkgname%-rpi-git}-git" "${pkgname%--rpi-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-rpi-git}-git" "${pkgname%--rpi-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
_pimodel=`tr -d '\0' < /sys/firmware/devicetree/base/model`
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-git}"
|
||||
cd "$srcdir/${pkgname%-rpi-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-git}"
|
||||
cd "${srcdir}/${pkgname%-rpi-git}"
|
||||
# Check for Pi version number
|
||||
if [[ ${_pimodel} ~= "Raspberry Pi 4" ]]; then
|
||||
if [[ ${_pimodel} =~ "Raspberry Pi 4" ]]; then
|
||||
_piversion=4
|
||||
elif [[ ${_pimodel} ~= "Raspberry Pi 3" ]]; then
|
||||
elif [[ ${_pimodel} =~ "Raspberry Pi 3" ]]; then
|
||||
_piversion=3
|
||||
elif [[ ${_pimodel} ~= "Raspberry Pi 2" ]]; then
|
||||
elif [[ ${_pimodel} =~ "Raspberry Pi 2" ]]; then
|
||||
_piversion=2
|
||||
else
|
||||
# Your RPI is not supported or this device is not a pi, cancel build then
|
||||
echo -e "\033[01m\033[01;31m==> ERROR:\033[00;01m Your device is not supported! This script is for RPi model 4/3/2 (1/0 not supported).\033[00m"
|
||||
# This RPI is not supported or this device is not a pi.
|
||||
# We should cancel then the build.
|
||||
echo -e "\033[01m\033[01;31m==> ERROR:\033[00;01m Your device is not supported! This script is for RPi model 4/3/2 (1/0 isn't supported yet).\033[00m"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "\033[01m\033[01;34m==> INFO:\033[00;01m Your detected Pi verion number is: \033[01;31m${_piversion}\033[01m.\033[00m"
|
||||
@@ -42,11 +44,17 @@ prepare() {
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-rpi-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-rpi-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
# /usr/local/bin isn't in PATH by the default,
|
||||
# we should move it to /usr/bin
|
||||
cd ${pkgdir}
|
||||
mv usr/local/bin/ usr/bin/
|
||||
# cleanup when dir is empty
|
||||
rmdir usr/local || exit 0
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Maintainer: SpacingBat3 <[email protected]>
|
||||
# Contributor: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-rk3399-git
|
||||
_pkgname=box86-git
|
||||
pkgver=r2798.0edc0374
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
arch=('armv7h')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}" "${pkgname%-rk3399-git}-git" "${pkgname%-rk3399-git}")
|
||||
conflicts=("${pkgname%-git}" "${pkgname%-rk3399-git}-git" "${pkgname%-rk3399-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-rk3399-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-rk3399-git}"
|
||||
if [[ ! -d ./build ]]; then
|
||||
mkdir build && cd build
|
||||
cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
fi
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/${pkgname%-rk3399-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/${pkgname%-rk3399-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
}
|
||||
+15
-8
@@ -1,6 +1,7 @@
|
||||
# Maintainer: SpacingBat3 <youremail@domain.com>
|
||||
# Contributor: Sebastien Chevalier
|
||||
# Maintainer: SpacingBat3 <[email protected].com>
|
||||
# Contributor: Sebastien Chevalier <[email protected]>
|
||||
pkgname=box86-x86-git
|
||||
_pkgname=box86-git
|
||||
pkgver=r2798.0edc0374
|
||||
pkgrel=1
|
||||
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
|
||||
@@ -8,18 +9,18 @@ arch=('i386')
|
||||
url="https://github.com/ptitSeb/box86"
|
||||
license=('MIT')
|
||||
makedepends=('git' 'cmake' 'make')
|
||||
provides=("${pkgname%-git}")
|
||||
conflicts=("${pkgname%-git}")
|
||||
provides=("${pkgname%-x86-git}")
|
||||
conflicts=("${pkgname%-x86-git}")
|
||||
source=('git+https://github.com/ptitSeb/box86')
|
||||
md5sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "$srcdir/${pkgname%-git}"
|
||||
cd "$srcdir/${pkgname%-x86-git}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${pkgname%-git}"
|
||||
cd "${srcdir}/${pkgname%-x86-git}"
|
||||
if [[ ! -d ./build ]]; then
|
||||
mkdir build && cd build
|
||||
cmake .. -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
@@ -27,11 +28,17 @@ prepare() {
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-x86-git}/build"
|
||||
make -j$(nproc)
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/${pkgname%-git}/build"
|
||||
cd "$srcdir/${pkgname%-x86-git}/build"
|
||||
make DESTDIR="${pkgdir}/" install
|
||||
# /usr/local/bin isn't in PATH by the default,
|
||||
# we should move it to /usr/bin
|
||||
cd ${pkgdir}
|
||||
mv usr/local/bin/ usr/bin/
|
||||
# cleanup when dir is empty
|
||||
rmdir usr/local || exit 0
|
||||
}
|
||||
+14
-8
@@ -3,7 +3,7 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
values = ['E', 'e', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', '2', 'P', 'G']
|
||||
values = ['E', 'e', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', '2', 'P', 'G', 'N', 'M']
|
||||
def splitchar(s):
|
||||
try:
|
||||
ret = [len(s), values.index(s[0])]
|
||||
@@ -312,6 +312,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
// 2 = struct of 2 uint
|
||||
// P = Vulkan struture pointer
|
||||
// G = a single GValue pointer
|
||||
// N = ... automatically sending 1 arg
|
||||
// M = ... automatically sending 2 args
|
||||
|
||||
"""
|
||||
}
|
||||
@@ -347,8 +349,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
|
||||
# First part: typedefs
|
||||
for v in gbl["()"]:
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G
|
||||
types = ["x86emu_t*", "x86emu_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*", "_2uint_struct_t", "void*", "void*"]
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N M
|
||||
types = ["x86emu_t*", "x86emu_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*", "_2uint_struct_t", "void*", "void*", "...", "..."]
|
||||
if len(values) != len(types):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
|
||||
|
||||
@@ -357,8 +359,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
for k in gbl_idxs:
|
||||
file.write("\n#if " + k + "\n")
|
||||
for v in gbl[k]:
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G
|
||||
types = ["x86emu_t*", "x86emu_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*", "_2uint_struct_t", "void*", "void*"]
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N M
|
||||
types = ["x86emu_t*", "x86emu_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*", "_2uint_struct_t", "void*", "void*", "...", "..."]
|
||||
if len(values) != len(types):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
|
||||
|
||||
@@ -393,12 +395,14 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
"(void*)(R_ESP + {p}), ", # V
|
||||
"of_convert(*(int32_t*)(R_ESP + {p})), ", # O
|
||||
"io_convert(*(void**)(R_ESP + {p})), ", # S
|
||||
"(_2uint_struct_t){{*(uintptr_t*)(R_ESP + {p}),*(uintptr_t*)(R_ESP + {p} + 4)}}, ", #2
|
||||
"(_2uint_struct_t){{*(uintptr_t*)(R_ESP + {p}),*(uintptr_t*)(R_ESP + {p} + 4)}}, ", # 2
|
||||
"arg{p}, ", # P
|
||||
"&arg{p}, ", # G
|
||||
"*(void**)(R_ESP + {p}), ", # N
|
||||
"*(void**)(R_ESP + {p}),*(void**)(R_ESP + {p} + 4), ", # M
|
||||
]
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G
|
||||
deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 4, 4, 0, 4, 4, 8, 4, 4]
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 4, 4, 0, 4, 4, 8, 4, 4, 0, 0]
|
||||
vals = [
|
||||
"\n#error Invalid return type: emulator\n", # E
|
||||
"\n#error Invalid return type: &emulator\n", # e
|
||||
@@ -424,6 +428,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
"\n#error Invalid return type: _2uint_struct\n", # 2
|
||||
"\n#error Invalid return type: Vulkan Struct\n", # P
|
||||
"\n#error Invalid return type: GValue Pointer\n", # G
|
||||
"\n#error Invalid return type: ... with 1 arg\n", # N
|
||||
"\n#error Invalid return type: ... with 2 args\n", # M
|
||||
]
|
||||
# Asserts
|
||||
if len(values) != len(arg):
|
||||
|
||||
+70
-349
@@ -19,334 +19,80 @@
|
||||
#include "threads.h"
|
||||
#include "x86trace.h"
|
||||
#include "signals.h"
|
||||
#ifdef DYNAREC
|
||||
#include <sys/mman.h>
|
||||
#include "custommem.h"
|
||||
#ifdef DYNAREC
|
||||
#include "dynablock.h"
|
||||
#include "khash.h"
|
||||
|
||||
#define MMAPSIZE (256*1024) // allocate 256kb sized blocks
|
||||
|
||||
// init inside dynablocks.c
|
||||
KHASH_MAP_INIT_INT(dynablocks, dynablock_t*)
|
||||
|
||||
typedef union mark_s {
|
||||
struct {
|
||||
unsigned int fill:1;
|
||||
unsigned int size:31;
|
||||
};
|
||||
uint32_t x32;
|
||||
} mark_t;
|
||||
typedef struct blockmark_s {
|
||||
mark_t prev;
|
||||
mark_t next;
|
||||
} blockmark_t;
|
||||
|
||||
typedef struct mmaplist_s {
|
||||
void* block;
|
||||
int maxfree;
|
||||
kh_dynablocks_t* dblist;
|
||||
} mmaplist_t;
|
||||
#include "dynarec/arm_lock_helper.h"
|
||||
#endif
|
||||
|
||||
|
||||
// get first subblock free in block, stating at start (from block). return NULL if no block, else first subblock free (mark included), filling size
|
||||
static void* getFirstBlock(void* block, int maxsize, int* size)
|
||||
{
|
||||
// get start of block
|
||||
blockmark_t *m = (blockmark_t*)block;
|
||||
while(m->next.x32) { // while there is a subblock
|
||||
if(!m->next.fill && m->next.size>=maxsize+sizeof(blockmark_t)) {
|
||||
*size = m->next.size;
|
||||
return m;
|
||||
}
|
||||
m = (blockmark_t*)((uintptr_t)m + m->next.size);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int getMaxFreeBlock(void* block)
|
||||
{
|
||||
// get start of block
|
||||
blockmark_t *m = (blockmark_t*)((uintptr_t)block+MMAPSIZE-sizeof(blockmark_t)); // styart with the end
|
||||
int maxsize = 0;
|
||||
while(m->prev.x32) { // while there is a subblock
|
||||
if(!m->prev.fill && m->prev.size>maxsize) {
|
||||
maxsize = m->prev.size;
|
||||
if((uintptr_t)block+maxsize>(uintptr_t)m)
|
||||
return maxsize; // no block large enough left...
|
||||
}
|
||||
m = (blockmark_t*)((uintptr_t)m - m->prev.size);
|
||||
}
|
||||
return maxsize;
|
||||
}
|
||||
|
||||
static void* allocBlock(void* block, void *sub, int size)
|
||||
{
|
||||
blockmark_t *s = (blockmark_t*)sub;
|
||||
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
|
||||
|
||||
s->next.fill = 1;
|
||||
s->next.size = size+sizeof(blockmark_t);
|
||||
blockmark_t *m = (blockmark_t*)((uintptr_t)s + s->next.size); // this is new n
|
||||
m->prev.fill = 1;
|
||||
m->prev.size = s->next.size;
|
||||
if(n!=m) {
|
||||
// new mark
|
||||
m->prev.fill = 1;
|
||||
m->prev.size = s->next.size;
|
||||
m->next.fill = 0;
|
||||
m->next.size = (uintptr_t)n - (uintptr_t)m;
|
||||
n->prev.fill = 0;
|
||||
n->prev.size = m->next.size;
|
||||
}
|
||||
|
||||
return (void*)((uintptr_t)sub + sizeof(blockmark_t));
|
||||
}
|
||||
static void freeBlock(void *block, void* sub, int size)
|
||||
{
|
||||
blockmark_t *m = (blockmark_t*)block;
|
||||
blockmark_t *s = (blockmark_t*)sub;
|
||||
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
|
||||
if(block!=sub)
|
||||
m = (blockmark_t*)((uintptr_t)s - s->prev.size);
|
||||
s->next.fill = 0;
|
||||
n->prev.fill = 0;
|
||||
// check if merge with previous
|
||||
if (s->prev.x32 && !s->prev.fill) {
|
||||
// remove s...
|
||||
m->next.size += s->next.size;
|
||||
n->prev.size = m->next.size;
|
||||
s = m;
|
||||
}
|
||||
// check if merge with next
|
||||
if(n->next.x32 && !n->next.fill) {
|
||||
blockmark_t *n2 = (blockmark_t*)((uintptr_t)n + n->next.size);
|
||||
//remove n
|
||||
s->next.size += n->next.size;
|
||||
n2->prev.size = s->next.size;
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t FindFreeDynarecMap(dynablock_t* db, int size)
|
||||
{
|
||||
// look for free space
|
||||
void* sub = NULL;
|
||||
for(int i=0; i<my_context->mmapsize; ++i) {
|
||||
if(my_context->mmaplist[i].maxfree>=size) {
|
||||
int rsize = 0;
|
||||
sub = getFirstBlock(my_context->mmaplist[i].block, size, &rsize);
|
||||
if(sub) {
|
||||
uintptr_t ret = (uintptr_t)allocBlock(my_context->mmaplist[i].block, sub, size);
|
||||
if(rsize==my_context->mmaplist[i].maxfree)
|
||||
my_context->mmaplist[i].maxfree = getMaxFreeBlock(my_context->mmaplist[i].block);
|
||||
kh_dynablocks_t *blocks = my_context->mmaplist[i].dblist;
|
||||
if(!blocks) {
|
||||
blocks = my_context->mmaplist[i].dblist = kh_init(dynablocks);
|
||||
kh_resize(dynablocks, blocks, 64);
|
||||
}
|
||||
khint_t k;
|
||||
int r;
|
||||
k = kh_put(dynablocks, blocks, (uintptr_t)db, &r);
|
||||
kh_value(blocks, k) = db;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t AddNewDynarecMap(dynablock_t* db, int size)
|
||||
{
|
||||
int i = my_context->mmapsize++; // yeah, useful post incrementation
|
||||
dynarec_log(LOG_DEBUG, "Ask for DynaRec Block Alloc #%d\n", my_context->mmapsize);
|
||||
my_context->mmaplist = (mmaplist_t*)realloc(my_context->mmaplist, my_context->mmapsize*sizeof(mmaplist_t));
|
||||
void *p = NULL;
|
||||
if(posix_memalign(&p, box86_pagesize, MMAPSIZE)) {
|
||||
dynarec_log(LOG_INFO, "Cannot create memory map of %d byte for dynarec block #%d\n", MMAPSIZE, i);
|
||||
--my_context->mmapsize;
|
||||
return 0;
|
||||
}
|
||||
mprotect(p, MMAPSIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
|
||||
my_context->mmaplist[i].block = p;
|
||||
// setup marks
|
||||
blockmark_t* m = (blockmark_t*)p;
|
||||
m->prev.x32 = 0;
|
||||
m->next.fill = 0;
|
||||
m->next.size = MMAPSIZE-sizeof(blockmark_t);
|
||||
m = (blockmark_t*)(p+MMAPSIZE-sizeof(blockmark_t));
|
||||
m->next.x32 = 0;
|
||||
m->prev.fill = 0;
|
||||
m->prev.size = MMAPSIZE-sizeof(blockmark_t);
|
||||
// alloc 1st block
|
||||
uintptr_t sub = (uintptr_t)allocBlock(my_context->mmaplist[i].block, p, size);
|
||||
my_context->mmaplist[i].maxfree = getMaxFreeBlock(my_context->mmaplist[i].block);
|
||||
kh_dynablocks_t *blocks = my_context->mmaplist[i].dblist = kh_init(dynablocks);
|
||||
kh_resize(dynablocks, blocks, 64);
|
||||
khint_t k;
|
||||
int ret;
|
||||
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
|
||||
kh_value(blocks, k) = db;
|
||||
return sub;
|
||||
}
|
||||
|
||||
void ActuallyFreeDynarecMap(dynablock_t* db, uintptr_t addr, int size)
|
||||
{
|
||||
if(!addr || !size)
|
||||
return;
|
||||
for(int i=0; i<my_context->mmapsize; ++i) {
|
||||
if ((addr>(uintptr_t)my_context->mmaplist[i].block)
|
||||
&& (addr<((uintptr_t)my_context->mmaplist[i].block+MMAPSIZE))) {
|
||||
void* sub = (void*)(addr-sizeof(blockmark_t));
|
||||
freeBlock(my_context->mmaplist[i].block, sub, size);
|
||||
my_context->mmaplist[i].maxfree = getMaxFreeBlock(my_context->mmaplist[i].block);
|
||||
kh_dynablocks_t *blocks = my_context->mmaplist[i].dblist;
|
||||
if(blocks) {
|
||||
khint_t k = kh_get(dynablocks, blocks, (uintptr_t)db);
|
||||
if(k!=kh_end(blocks))
|
||||
kh_del(dynablocks, blocks, k);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(my_context->mmapsize)
|
||||
dynarec_log(LOG_NONE, "Warning, block %p (size %d) not found in mmaplist for Free\n", (void*)addr, size);
|
||||
}
|
||||
|
||||
dynablock_t* FindDynablockFromNativeAddress(void* addr)
|
||||
{
|
||||
// look in actual list
|
||||
for(int i=0; i<my_context->mmapsize; ++i) {
|
||||
if ((uintptr_t)addr>=(uintptr_t)my_context->mmaplist[i].block
|
||||
&& ((uintptr_t)addr<(uintptr_t)my_context->mmaplist[i].block+MMAPSIZE))
|
||||
return FindDynablockDynablocklist(addr, my_context->mmaplist[i].dblist);
|
||||
}
|
||||
// look in oversized
|
||||
return FindDynablockDynablocklist(addr, my_context->dblist_oversized);
|
||||
}
|
||||
|
||||
uintptr_t AllocDynarecMap(dynablock_t* db, int size)
|
||||
{
|
||||
if(!size)
|
||||
return 0;
|
||||
if(size>MMAPSIZE-2*sizeof(blockmark_t)) {
|
||||
void *p = NULL;
|
||||
if(posix_memalign(&p, box86_pagesize, size)) {
|
||||
dynarec_log(LOG_INFO, "Cannot create dynamic map of %d bytes\n", size);
|
||||
return 0;
|
||||
}
|
||||
mprotect(p, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
kh_dynablocks_t *blocks = my_context->dblist_oversized;
|
||||
if(!blocks) {
|
||||
blocks = my_context->dblist_oversized = kh_init(dynablocks);
|
||||
kh_resize(dynablocks, blocks, 64);
|
||||
}
|
||||
khint_t k;
|
||||
int ret;
|
||||
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
|
||||
kh_value(blocks, k) = db;
|
||||
return (uintptr_t)p;
|
||||
}
|
||||
|
||||
if(pthread_mutex_trylock(&my_context->mutex_mmap)) {
|
||||
sched_yield(); // give it a chance
|
||||
if(pthread_mutex_trylock(&my_context->mutex_mmap))
|
||||
return 0; // cannot lock, baillout
|
||||
}
|
||||
|
||||
uintptr_t ret = FindFreeDynarecMap(db, size);
|
||||
if(!ret)
|
||||
ret = AddNewDynarecMap(db, size);
|
||||
|
||||
pthread_mutex_unlock(&my_context->mutex_mmap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FreeDynarecMap(dynablock_t* db, uintptr_t addr, uint32_t size)
|
||||
{
|
||||
if(size>MMAPSIZE) {
|
||||
munmap((void*)addr, size);
|
||||
kh_dynablocks_t *blocks = my_context->dblist_oversized;
|
||||
if(blocks) {
|
||||
khint_t k = kh_get(dynablocks, blocks, (uintptr_t)db);
|
||||
if(k!=kh_end(blocks))
|
||||
kh_del(dynablocks, blocks, k);
|
||||
}
|
||||
return;
|
||||
}
|
||||
pthread_mutex_lock(&my_context->mutex_mmap);
|
||||
ActuallyFreeDynarecMap(db, addr, size);
|
||||
pthread_mutex_unlock(&my_context->mutex_mmap);
|
||||
}
|
||||
|
||||
// each dynmap is 64k of size
|
||||
|
||||
void addDBFromAddressRange(box86context_t* context, uintptr_t addr, uintptr_t size, int nolinker)
|
||||
{
|
||||
dynarec_log(LOG_DEBUG, "addDBFromAddressRange %p -> %p\n", (void*)addr, (void*)(addr+size-1));
|
||||
uintptr_t idx = (addr>>DYNAMAP_SHIFT);
|
||||
uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
if(!context->dynmap[i]) {
|
||||
context->dynmap[i] = NewDynablockList(i<<DYNAMAP_SHIFT, i<<DYNAMAP_SHIFT, 1<<DYNAMAP_SHIFT, nolinker, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cleanDBFromAddressRange(box86context_t* context, uintptr_t addr, uintptr_t size, int destroy)
|
||||
{
|
||||
dynarec_log(LOG_DEBUG, "cleanDBFromAddressRange %p -> %p %s\n", (void*)addr, (void*)(addr+size-1), destroy?"destroy":"mark");
|
||||
uintptr_t idx = (addr>box86_dynarec_largest && !destroy)?((addr-box86_dynarec_largest)>>DYNAMAP_SHIFT):(addr>>DYNAMAP_SHIFT);
|
||||
uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
dynablocklist_t* dblist = context->dynmap[i];
|
||||
if(dblist) {
|
||||
uintptr_t startdb = StartDynablockList(dblist);
|
||||
uintptr_t enddb = EndDynablockList(dblist);
|
||||
uintptr_t startaddr = addr;
|
||||
if(startaddr<startdb) startaddr = startdb;
|
||||
uintptr_t endaddr = addr + size - 1;
|
||||
if(endaddr>enddb) endaddr = enddb;
|
||||
if(startaddr==startdb && endaddr==enddb) {
|
||||
if(destroy) {
|
||||
context->dynmap[i] = NULL;
|
||||
FreeDynablockList(&dblist);
|
||||
} else
|
||||
MarkDynablockList(&dblist);
|
||||
} else
|
||||
if(destroy)
|
||||
FreeRangeDynablock(dblist, startaddr, endaddr-startaddr+1);
|
||||
else
|
||||
MarkRangeDynablock(dblist, startaddr, endaddr-startaddr+1);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DYNAREC
|
||||
// Remove the Write flag from an adress range, so DB can be executed
|
||||
// no log, as it can be executed inside a signal handler
|
||||
void protectDB(uintptr_t addr, uintptr_t size)
|
||||
{
|
||||
uintptr_t start = (addr)&~(box86_pagesize-1);
|
||||
uintptr_t end = (addr+size+(box86_pagesize-1))&~(box86_pagesize-1);
|
||||
// should get "end" according to last block inside the window
|
||||
mprotect((void*)start, end-start, PROT_READ|PROT_EXEC);
|
||||
uintptr_t idx = (addr>>DYNAMAP_SHIFT);
|
||||
uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
uint32_t prot;
|
||||
do {
|
||||
prot=arm_lock_read_d(&my_context->memprot[i]);
|
||||
if(!prot)
|
||||
prot = PROT_READ | PROT_WRITE; // comes from malloc & co, so should not be able to execute
|
||||
} while(arm_lock_write_d(&my_context->memprot[i], prot|PROT_DYNAREC));
|
||||
if(!(prot&PROT_DYNAREC))
|
||||
mprotect((void*)(i<<DYNAMAP_SHIFT), 1<<DYNAMAP_SHIFT, prot&~PROT_WRITE);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the Write flag from an adress range, and mark all block as dirty
|
||||
// no log, as it can be executed inside a signal handler
|
||||
void unprotectDB(uintptr_t addr, uintptr_t size)
|
||||
{
|
||||
uintptr_t start = (addr)&~(box86_pagesize-1);
|
||||
uintptr_t end = (addr+size+(box86_pagesize-1))&~(box86_pagesize-1);
|
||||
// should get "end" according to last block inside the window
|
||||
mprotect((void*)start, end-start, PROT_READ|PROT_WRITE|PROT_EXEC);
|
||||
cleanDBFromAddressRange(my_context, start, end-start, 0);
|
||||
uintptr_t idx = (addr>>DYNAMAP_SHIFT);
|
||||
uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
uint32_t prot;
|
||||
do {
|
||||
prot=arm_lock_read_d(&my_context->memprot[i]);
|
||||
} while(arm_lock_write_d(&my_context->memprot[i], prot&~PROT_DYNAREC));
|
||||
if(prot&PROT_DYNAREC) {
|
||||
mprotect((void*)(i<<DYNAMAP_SHIFT), 1<<DYNAMAP_SHIFT, prot&~PROT_DYNAREC);
|
||||
cleanDBFromAddressRange((i<<DYNAMAP_SHIFT), 1<<DYNAMAP_SHIFT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void updateProtection(uintptr_t addr, uintptr_t size, uint32_t prot)
|
||||
{
|
||||
const uintptr_t idx = (addr>>DYNAMAP_SHIFT);
|
||||
const uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
#ifdef DYNAREC
|
||||
uint32_t dyn;
|
||||
do {
|
||||
dyn=arm_lock_read_d(&my_context->memprot[i])&PROT_DYNAREC;
|
||||
} while(arm_lock_write_d(&my_context->memprot[i], prot|dyn));
|
||||
if(dyn && (prot&PROT_WRITE)) // need to remove the write protection from this block
|
||||
mprotect((void*)(i<<DYNAMAP_SHIFT), 1<<DYNAMAP_SHIFT, prot&~PROT_WRITE);
|
||||
#else
|
||||
uint32_t dyn=(my_context->memprot[i]&PROT_DYNAREC);
|
||||
if(dyn && (prot&PROT_WRITE)) // need to remove the write protection from this block
|
||||
mprotect((void*)(i<<DYNAMAP_SHIFT), 1<<DYNAMAP_SHIFT, prot&~PROT_WRITE);
|
||||
my_context->memprot[i] = prot|dyn;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getProtection(uintptr_t addr)
|
||||
{
|
||||
const uintptr_t idx = (addr>>DYNAMAP_SHIFT);
|
||||
return my_context->memprot[idx];
|
||||
}
|
||||
|
||||
EXPORTDYN
|
||||
void initAllHelpers(box86context_t* context)
|
||||
{
|
||||
@@ -372,6 +118,7 @@ void finiAllHelpers(box86context_t* context)
|
||||
fini_pthread_helper(context);
|
||||
fini_signal_helper();
|
||||
cleanAlternate();
|
||||
fini_custommem_helper(context);
|
||||
finied = 1;
|
||||
}
|
||||
|
||||
@@ -382,11 +129,11 @@ int getrand(int maxval)
|
||||
{
|
||||
if(maxval<1024) {
|
||||
return ((random()&0x7fff)*maxval)/0x7fff;
|
||||
} else {
|
||||
}
|
||||
uint64_t r = random();
|
||||
r = (r*maxval) / RAND_MAX;
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void free_tlsdatasize(void* p)
|
||||
@@ -408,7 +155,7 @@ box86context_t *NewBox86Context(int argc)
|
||||
}
|
||||
#endif
|
||||
// init and put default values
|
||||
box86context_t *context = (box86context_t*)calloc(1, sizeof(box86context_t));
|
||||
box86context_t *context = my_context = (box86context_t*)calloc(1, sizeof(box86context_t));
|
||||
|
||||
#ifdef BUILD_LIB
|
||||
context->deferedInit = 0;
|
||||
@@ -417,17 +164,15 @@ box86context_t *NewBox86Context(int argc)
|
||||
#endif
|
||||
context->sel_serial = 1;
|
||||
|
||||
#ifdef DYNAREC
|
||||
pthread_mutex_init(&context->mutex_blocks, NULL);
|
||||
pthread_mutex_init(&context->mutex_mmap, NULL);
|
||||
context->dynmap = (dynablocklist_t**)calloc(DYNAMAP_SIZE, sizeof(dynablocklist_t*));
|
||||
#endif
|
||||
init_custommem_helper(context);
|
||||
|
||||
context->memprot = (uint32_t*)calloc(DYNAMAP_SIZE, sizeof(uint32_t));
|
||||
|
||||
context->maplib = NewLibrarian(context, 1);
|
||||
context->local_maplib = NewLibrarian(context, 1);
|
||||
context->system = NewBridge();
|
||||
// create vsyscall
|
||||
context->vsyscall = AddBridge(context->system, context, vFv, x86Syscall, 0);
|
||||
context->vsyscall = AddBridge(context->system, vFv, x86Syscall, 0);
|
||||
#ifdef BUILD_LIB
|
||||
context->box86lib = RTLD_DEFAULT; // not ideal
|
||||
#else
|
||||
@@ -443,12 +188,11 @@ box86context_t *NewBox86Context(int argc)
|
||||
pthread_mutex_init(&context->mutex_trace, NULL);
|
||||
#ifndef DYNAREC
|
||||
pthread_mutex_init(&context->mutex_lock, NULL);
|
||||
#else
|
||||
pthread_mutex_init(&context->mutex_dyndump, NULL);
|
||||
#endif
|
||||
pthread_mutex_init(&context->mutex_tls, NULL);
|
||||
pthread_mutex_init(&context->mutex_thread, NULL);
|
||||
#ifdef DYNAREC
|
||||
pthread_mutex_init(&context->mutex_dyndump, NULL);
|
||||
#endif
|
||||
pthread_key_create(&context->tlskey, free_tlsdatasize);
|
||||
|
||||
InitFTSMap(context);
|
||||
@@ -518,28 +262,6 @@ void FreeBox86Context(box86context_t** context)
|
||||
signal(i, SIG_DFL);
|
||||
}
|
||||
|
||||
#ifdef DYNAREC
|
||||
dynarec_log(LOG_DEBUG, "Free global Dynarecblocks\n");
|
||||
for (int i=0; i<ctx->mmapsize; ++i) {
|
||||
if(ctx->mmaplist[i].block)
|
||||
free(ctx->mmaplist[i].block);
|
||||
if(ctx->mmaplist[i].dblist) {
|
||||
kh_destroy(dynablocks, ctx->mmaplist[i].dblist);
|
||||
ctx->mmaplist[i].dblist = NULL;
|
||||
}
|
||||
}
|
||||
if(ctx->dblist_oversized) {
|
||||
kh_destroy(dynablocks, ctx->dblist_oversized);
|
||||
ctx->dblist_oversized = NULL;
|
||||
}
|
||||
ctx->mmapsize = 0;
|
||||
dynarec_log(LOG_DEBUG, "Free dynamic Dynarecblocks\n");
|
||||
cleanDBFromAddressRange(ctx, 0, 0xffffffff, 1);
|
||||
pthread_mutex_destroy(&ctx->mutex_blocks);
|
||||
pthread_mutex_destroy(&ctx->mutex_mmap);
|
||||
free(ctx->mmaplist);
|
||||
#endif
|
||||
|
||||
*context = NULL; // bye bye my_context
|
||||
|
||||
CleanStackSize(ctx);
|
||||
@@ -583,14 +305,13 @@ void FreeBox86Context(box86context_t** context)
|
||||
pthread_mutex_destroy(&ctx->mutex_trace);
|
||||
#ifndef DYNAREC
|
||||
pthread_mutex_destroy(&ctx->mutex_lock);
|
||||
#else
|
||||
pthread_mutex_destroy(&ctx->mutex_dyndump);
|
||||
#endif
|
||||
pthread_mutex_destroy(&ctx->mutex_tls);
|
||||
pthread_mutex_destroy(&ctx->mutex_thread);
|
||||
#ifdef DYNAREC
|
||||
pthread_mutex_destroy(&ctx->mutex_dyndump);
|
||||
free(ctx->dynmap);
|
||||
ctx->dynmap = NULL;
|
||||
#endif
|
||||
free(ctx->memprot);
|
||||
ctx->memprot = NULL;
|
||||
|
||||
free_neededlib(&ctx->neededlibs);
|
||||
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
#define __BOX86_VERSION_H_
|
||||
|
||||
#define BOX86_MAJOR 0
|
||||
#define BOX86_MINOR 1
|
||||
#define BOX86_REVISION 8
|
||||
#define BOX86_MINOR 2
|
||||
#define BOX86_REVISION 0
|
||||
|
||||
#endif //__BOX86_VERSION_H_
|
||||
+530
@@ -0,0 +1,530 @@
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "box86context.h"
|
||||
#include "elfloader.h"
|
||||
#include "debug.h"
|
||||
#include "x86trace.h"
|
||||
#include "x86emu.h"
|
||||
#include "librarian.h"
|
||||
#include "bridge.h"
|
||||
#include "library.h"
|
||||
#include "callback.h"
|
||||
#include "wrapper.h"
|
||||
#include "myfts.h"
|
||||
#include "threads.h"
|
||||
#include "x86trace.h"
|
||||
#include "signals.h"
|
||||
#include <sys/mman.h>
|
||||
#include "custommem.h"
|
||||
#ifdef DYNAREC
|
||||
#include "dynablock.h"
|
||||
#include "dynarec/arm_lock_helper.h"
|
||||
#include "khash.h"
|
||||
|
||||
|
||||
// init inside dynablocks.c
|
||||
KHASH_MAP_INIT_INT(dynablocks, dynablock_t*)
|
||||
static dynablocklist_t** dynmap; // 4G of memory mapped by 4K block
|
||||
static pthread_mutex_t mutex_mmap;
|
||||
static mmaplist_t *mmaplist;
|
||||
static int mmapsize;
|
||||
static kh_dynablocks_t *dblist_oversized; // store the list of oversized dynablocks (normal sized are inside mmaplist)
|
||||
#endif
|
||||
|
||||
typedef struct blocklist_s {
|
||||
void* block;
|
||||
int maxfree;
|
||||
size_t size;
|
||||
} blocklist_t;
|
||||
|
||||
#define MMAPSIZE (256*1024) // allocate 256kb sized blocks
|
||||
|
||||
static pthread_mutex_t mutex_blocks = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int n_blocks = 0; // number of blocks for custom malloc
|
||||
static blocklist_t* p_blocks = NULL; // actual blocks for custom malloc
|
||||
|
||||
typedef union mark_s {
|
||||
struct {
|
||||
unsigned int fill:1;
|
||||
unsigned int size:31;
|
||||
};
|
||||
uint32_t x32;
|
||||
} mark_t;
|
||||
typedef struct blockmark_s {
|
||||
mark_t prev;
|
||||
mark_t next;
|
||||
} blockmark_t;
|
||||
|
||||
|
||||
// get first subblock free in block, stating at start (from block). return NULL if no block, else first subblock free (mark included), filling size
|
||||
static void* getFirstBlock(void* block, int maxsize, int* size)
|
||||
{
|
||||
// get start of block
|
||||
blockmark_t *m = (blockmark_t*)block;
|
||||
while(m->next.x32) { // while there is a subblock
|
||||
if(!m->next.fill && m->next.size>=maxsize+sizeof(blockmark_t)) {
|
||||
*size = m->next.size;
|
||||
return m;
|
||||
}
|
||||
m = (blockmark_t*)((uintptr_t)m + m->next.size);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int getMaxFreeBlock(void* block, size_t block_size)
|
||||
{
|
||||
// get start of block
|
||||
blockmark_t *m = (blockmark_t*)((uintptr_t)block+block_size-sizeof(blockmark_t)); // styart with the end
|
||||
int maxsize = 0;
|
||||
while(m->prev.x32) { // while there is a subblock
|
||||
if(!m->prev.fill && m->prev.size>maxsize) {
|
||||
maxsize = m->prev.size;
|
||||
if((uintptr_t)block+maxsize>(uintptr_t)m)
|
||||
return maxsize; // no block large enough left...
|
||||
}
|
||||
m = (blockmark_t*)((uintptr_t)m - m->prev.size);
|
||||
}
|
||||
return maxsize;
|
||||
}
|
||||
|
||||
static void* allocBlock(void* block, void *sub, int size)
|
||||
{
|
||||
blockmark_t *s = (blockmark_t*)sub;
|
||||
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
|
||||
|
||||
s->next.fill = 1;
|
||||
s->next.size = size+sizeof(blockmark_t);
|
||||
blockmark_t *m = (blockmark_t*)((uintptr_t)s + s->next.size); // this is new n
|
||||
m->prev.fill = 1;
|
||||
m->prev.size = s->next.size;
|
||||
if(n!=m) {
|
||||
// new mark
|
||||
m->prev.fill = 1;
|
||||
m->prev.size = s->next.size;
|
||||
m->next.fill = 0;
|
||||
m->next.size = (uintptr_t)n - (uintptr_t)m;
|
||||
n->prev.fill = 0;
|
||||
n->prev.size = m->next.size;
|
||||
}
|
||||
|
||||
return (void*)((uintptr_t)sub + sizeof(blockmark_t));
|
||||
}
|
||||
static void freeBlock(void *block, void* sub)
|
||||
{
|
||||
blockmark_t *m = (blockmark_t*)block;
|
||||
blockmark_t *s = (blockmark_t*)sub;
|
||||
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
|
||||
if(block!=sub)
|
||||
m = (blockmark_t*)((uintptr_t)s - s->prev.size);
|
||||
s->next.fill = 0;
|
||||
n->prev.fill = 0;
|
||||
// check if merge with previous
|
||||
if (s->prev.x32 && !s->prev.fill) {
|
||||
// remove s...
|
||||
m->next.size += s->next.size;
|
||||
n->prev.size = m->next.size;
|
||||
s = m;
|
||||
}
|
||||
// check if merge with next
|
||||
if(n->next.x32 && !n->next.fill) {
|
||||
blockmark_t *n2 = (blockmark_t*)((uintptr_t)n + n->next.size);
|
||||
//remove n
|
||||
s->next.size += n->next.size;
|
||||
n2->prev.size = s->next.size;
|
||||
}
|
||||
}
|
||||
// return 1 if block has been expanded to new size, 0 if not
|
||||
static int expandBlock(void* block, void* sub, int newsize)
|
||||
{
|
||||
newsize = (newsize+3)&~3;
|
||||
blockmark_t *s = (blockmark_t*)sub;
|
||||
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
|
||||
if(s->next.fill)
|
||||
return 0; // next block is filled
|
||||
if(s->next.size + n->next.size < newsize)
|
||||
return 0; // free space too short
|
||||
// ok, doing the alloc!
|
||||
s->next.size = newsize+sizeof(blockmark_t);
|
||||
blockmark_t *m = (blockmark_t*)((uintptr_t)s + s->next.size); // this is new n
|
||||
m->prev.fill = 1;
|
||||
m->prev.size = s->next.size;
|
||||
if(n!=m) {
|
||||
// new mark
|
||||
m->prev.fill = 1;
|
||||
m->prev.size = s->next.size;
|
||||
m->next.fill = 0;
|
||||
m->next.size = (uintptr_t)n - (uintptr_t)m;
|
||||
n->prev.fill = 0;
|
||||
n->prev.size = m->next.size;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// return size of block
|
||||
static int sizeBlock(void* sub)
|
||||
{
|
||||
blockmark_t *s = (blockmark_t*)sub;
|
||||
return s->next.size;
|
||||
}
|
||||
|
||||
void* customMalloc(size_t size)
|
||||
{
|
||||
// look for free space
|
||||
void* sub = NULL;
|
||||
pthread_mutex_lock(&mutex_blocks);
|
||||
for(int i=0; i<n_blocks; ++i) {
|
||||
if(p_blocks[i].maxfree>=size) {
|
||||
int rsize = 0;
|
||||
sub = getFirstBlock(p_blocks[i].block, size, &rsize);
|
||||
if(sub) {
|
||||
void* ret = allocBlock(p_blocks[i].block, sub, size);
|
||||
if(rsize==p_blocks[i].maxfree)
|
||||
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size);
|
||||
pthread_mutex_unlock(&mutex_blocks);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
// add a new block
|
||||
int i = n_blocks++;
|
||||
p_blocks = (blocklist_t*)realloc(p_blocks, n_blocks*sizeof(blocklist_t));
|
||||
size_t allocsize = MMAPSIZE;
|
||||
if(size+2*sizeof(blockmark_t)>allocsize)
|
||||
allocsize = size+2*sizeof(blockmark_t);
|
||||
void* p = calloc(1, allocsize);
|
||||
p_blocks[i].block = p;
|
||||
p_blocks[i].size = allocsize;
|
||||
// setup marks
|
||||
blockmark_t* m = (blockmark_t*)p;
|
||||
m->prev.x32 = 0;
|
||||
m->next.fill = 0;
|
||||
m->next.size = allocsize-sizeof(blockmark_t);
|
||||
m = (blockmark_t*)(p+allocsize-sizeof(blockmark_t));
|
||||
m->next.x32 = 0;
|
||||
m->prev.fill = 0;
|
||||
m->prev.size = allocsize-sizeof(blockmark_t);
|
||||
// alloc 1st block
|
||||
void* ret = allocBlock(p_blocks[i].block, p, size);
|
||||
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size);
|
||||
pthread_mutex_unlock(&mutex_blocks);
|
||||
return ret;
|
||||
}
|
||||
void* customCalloc(size_t n, size_t size)
|
||||
{
|
||||
size_t newsize = n*size;
|
||||
void* ret = customMalloc(newsize);
|
||||
memset(ret, 0, newsize);
|
||||
return ret;
|
||||
}
|
||||
void* customRealloc(void* p, size_t size)
|
||||
{
|
||||
if(!p)
|
||||
return customMalloc(size);
|
||||
uintptr_t addr = (uintptr_t)p;
|
||||
pthread_mutex_lock(&mutex_blocks);
|
||||
for(int i=0; i<n_blocks; ++i) {
|
||||
if ((addr>(uintptr_t)p_blocks[i].block)
|
||||
&& (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) {
|
||||
void* sub = (void*)(addr-sizeof(blockmark_t));
|
||||
if(expandBlock(p_blocks[i].block, sub, size)) {
|
||||
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size);
|
||||
pthread_mutex_unlock(&mutex_blocks);
|
||||
return p;
|
||||
}
|
||||
pthread_mutex_unlock(&mutex_blocks);
|
||||
void* newp = customMalloc(size);
|
||||
memcpy(newp, p, sizeBlock(sub));
|
||||
customFree(p);
|
||||
return newp;
|
||||
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mutex_blocks);
|
||||
if(n_blocks)
|
||||
dynarec_log(LOG_NONE, "Warning, block %p not found in p_blocks for Realloc, Malloc'ng again without free\n", (void*)addr);
|
||||
return customMalloc(size);
|
||||
}
|
||||
void customFree(void* p)
|
||||
{
|
||||
if(!p)
|
||||
return;
|
||||
uintptr_t addr = (uintptr_t)p;
|
||||
pthread_mutex_lock(&mutex_blocks);
|
||||
for(int i=0; i<n_blocks; ++i) {
|
||||
if ((addr>(uintptr_t)p_blocks[i].block)
|
||||
&& (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) {
|
||||
void* sub = (void*)(addr-sizeof(blockmark_t));
|
||||
freeBlock(p_blocks[i].block, sub);
|
||||
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size);
|
||||
pthread_mutex_unlock(&mutex_blocks);
|
||||
return;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mutex_blocks);
|
||||
if(n_blocks)
|
||||
dynarec_log(LOG_NONE, "Warning, block %p not found in p_blocks for Free\n", (void*)addr);
|
||||
}
|
||||
|
||||
#ifdef DYNAREC
|
||||
typedef struct mmaplist_s {
|
||||
void* block;
|
||||
int maxfree;
|
||||
size_t size;
|
||||
kh_dynablocks_t* dblist;
|
||||
} mmaplist_t;
|
||||
|
||||
uintptr_t FindFreeDynarecMap(dynablock_t* db, int size)
|
||||
{
|
||||
// look for free space
|
||||
void* sub = NULL;
|
||||
for(int i=0; i<mmapsize; ++i) {
|
||||
if(mmaplist[i].maxfree>=size) {
|
||||
int rsize = 0;
|
||||
sub = getFirstBlock(mmaplist[i].block, size, &rsize);
|
||||
if(sub) {
|
||||
uintptr_t ret = (uintptr_t)allocBlock(mmaplist[i].block, sub, size);
|
||||
if(rsize==mmaplist[i].maxfree)
|
||||
mmaplist[i].maxfree = getMaxFreeBlock(mmaplist[i].block, mmaplist[i].size);
|
||||
kh_dynablocks_t *blocks = mmaplist[i].dblist;
|
||||
if(!blocks) {
|
||||
blocks = mmaplist[i].dblist = kh_init(dynablocks);
|
||||
kh_resize(dynablocks, blocks, 64);
|
||||
}
|
||||
khint_t k;
|
||||
int r;
|
||||
k = kh_put(dynablocks, blocks, (uintptr_t)db, &r);
|
||||
kh_value(blocks, k) = db;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t AddNewDynarecMap(dynablock_t* db, int size)
|
||||
{
|
||||
int i = mmapsize++; // yeah, useful post incrementation
|
||||
dynarec_log(LOG_DEBUG, "Ask for DynaRec Block Alloc #%d\n", mmapsize);
|
||||
mmaplist = (mmaplist_t*)realloc(mmaplist, mmapsize*sizeof(mmaplist_t));
|
||||
void *p = NULL;
|
||||
if(posix_memalign(&p, box86_pagesize, MMAPSIZE)) {
|
||||
dynarec_log(LOG_INFO, "Cannot create memory map of %d byte for dynarec block #%d\n", MMAPSIZE, i);
|
||||
--mmapsize;
|
||||
return 0;
|
||||
}
|
||||
mprotect(p, MMAPSIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
updateProtection((uintptr_t)p, MMAPSIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
|
||||
mmaplist[i].block = p;
|
||||
mmaplist[i].size = MMAPSIZE;
|
||||
// setup marks
|
||||
blockmark_t* m = (blockmark_t*)p;
|
||||
m->prev.x32 = 0;
|
||||
m->next.fill = 0;
|
||||
m->next.size = MMAPSIZE-sizeof(blockmark_t);
|
||||
m = (blockmark_t*)(p+MMAPSIZE-sizeof(blockmark_t));
|
||||
m->next.x32 = 0;
|
||||
m->prev.fill = 0;
|
||||
m->prev.size = MMAPSIZE-sizeof(blockmark_t);
|
||||
// alloc 1st block
|
||||
uintptr_t sub = (uintptr_t)allocBlock(mmaplist[i].block, p, size);
|
||||
mmaplist[i].maxfree = getMaxFreeBlock(mmaplist[i].block, mmaplist[i].size);
|
||||
kh_dynablocks_t *blocks = mmaplist[i].dblist = kh_init(dynablocks);
|
||||
kh_resize(dynablocks, blocks, 64);
|
||||
khint_t k;
|
||||
int ret;
|
||||
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
|
||||
kh_value(blocks, k) = db;
|
||||
return sub;
|
||||
}
|
||||
|
||||
void ActuallyFreeDynarecMap(dynablock_t* db, uintptr_t addr, int size)
|
||||
{
|
||||
if(!addr || !size)
|
||||
return;
|
||||
for(int i=0; i<mmapsize; ++i) {
|
||||
if ((addr>(uintptr_t)mmaplist[i].block)
|
||||
&& (addr<((uintptr_t)mmaplist[i].block+mmaplist[i].size))) {
|
||||
void* sub = (void*)(addr-sizeof(blockmark_t));
|
||||
freeBlock(mmaplist[i].block, sub);
|
||||
mmaplist[i].maxfree = getMaxFreeBlock(mmaplist[i].block, mmaplist[i].size);
|
||||
kh_dynablocks_t *blocks = mmaplist[i].dblist;
|
||||
if(blocks) {
|
||||
khint_t k = kh_get(dynablocks, blocks, (uintptr_t)db);
|
||||
if(k!=kh_end(blocks))
|
||||
kh_del(dynablocks, blocks, k);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(mmapsize)
|
||||
dynarec_log(LOG_NONE, "Warning, block %p (size %d) not found in mmaplist for Free\n", (void*)addr, size);
|
||||
}
|
||||
|
||||
dynablock_t* FindDynablockFromNativeAddress(void* addr)
|
||||
{
|
||||
// look in actual list
|
||||
for(int i=0; i<mmapsize; ++i) {
|
||||
if ((uintptr_t)addr>=(uintptr_t)mmaplist[i].block
|
||||
&& ((uintptr_t)addr<(uintptr_t)mmaplist[i].block+mmaplist[i].size))
|
||||
return FindDynablockDynablocklist(addr, mmaplist[i].dblist);
|
||||
}
|
||||
// look in oversized
|
||||
return FindDynablockDynablocklist(addr, dblist_oversized);
|
||||
}
|
||||
|
||||
uintptr_t AllocDynarecMap(dynablock_t* db, int size)
|
||||
{
|
||||
if(!size)
|
||||
return 0;
|
||||
if(size>MMAPSIZE-2*sizeof(blockmark_t)) {
|
||||
void *p = NULL;
|
||||
if(posix_memalign(&p, box86_pagesize, size)) {
|
||||
dynarec_log(LOG_INFO, "Cannot create dynamic map of %d bytes\n", size);
|
||||
return 0;
|
||||
}
|
||||
mprotect(p, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
updateProtection((uintptr_t)p, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
kh_dynablocks_t *blocks = dblist_oversized;
|
||||
if(!blocks) {
|
||||
blocks = dblist_oversized = kh_init(dynablocks);
|
||||
kh_resize(dynablocks, blocks, 64);
|
||||
}
|
||||
khint_t k;
|
||||
int ret;
|
||||
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
|
||||
kh_value(blocks, k) = db;
|
||||
return (uintptr_t)p;
|
||||
}
|
||||
|
||||
if(pthread_mutex_trylock(&mutex_mmap)) {
|
||||
sched_yield(); // give it a chance
|
||||
if(pthread_mutex_trylock(&mutex_mmap))
|
||||
return 0; // cannot lock, baillout
|
||||
}
|
||||
|
||||
uintptr_t ret = FindFreeDynarecMap(db, size);
|
||||
if(!ret)
|
||||
ret = AddNewDynarecMap(db, size);
|
||||
|
||||
pthread_mutex_unlock(&mutex_mmap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FreeDynarecMap(dynablock_t* db, uintptr_t addr, uint32_t size)
|
||||
{
|
||||
if(size>MMAPSIZE) {
|
||||
munmap((void*)addr, size);
|
||||
kh_dynablocks_t *blocks = dblist_oversized;
|
||||
if(blocks) {
|
||||
khint_t k = kh_get(dynablocks, blocks, (uintptr_t)db);
|
||||
if(k!=kh_end(blocks))
|
||||
kh_del(dynablocks, blocks, k);
|
||||
}
|
||||
return;
|
||||
}
|
||||
pthread_mutex_lock(&mutex_mmap);
|
||||
ActuallyFreeDynarecMap(db, addr, size);
|
||||
pthread_mutex_unlock(&mutex_mmap);
|
||||
}
|
||||
|
||||
dynablocklist_t* getDB(uintptr_t idx)
|
||||
{
|
||||
return dynmap[idx];
|
||||
}
|
||||
|
||||
// each dynmap is 64k of size
|
||||
|
||||
void addDBFromAddressRange(uintptr_t addr, uintptr_t size, int nolinker)
|
||||
{
|
||||
dynarec_log(LOG_DEBUG, "addDBFromAddressRange %p -> %p\n", (void*)addr, (void*)(addr+size-1));
|
||||
uintptr_t idx = (addr>>DYNAMAP_SHIFT);
|
||||
uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
if(!dynmap[i]) {
|
||||
dynmap[i] = NewDynablockList(i<<DYNAMAP_SHIFT, 1<<DYNAMAP_SHIFT, nolinker, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cleanDBFromAddressRange(uintptr_t addr, uintptr_t size, int destroy)
|
||||
{
|
||||
dynarec_log(LOG_DEBUG, "cleanDBFromAddressRange %p -> %p %s\n", (void*)addr, (void*)(addr+size-1), destroy?"destroy":"mark");
|
||||
uintptr_t idx = (addr>box86_dynarec_largest && !destroy)?((addr-box86_dynarec_largest)>>DYNAMAP_SHIFT):(addr>>DYNAMAP_SHIFT);
|
||||
uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
dynablocklist_t* dblist = dynmap[i];
|
||||
if(dblist) {
|
||||
uintptr_t startdb = StartDynablockList(dblist);
|
||||
uintptr_t enddb = EndDynablockList(dblist);
|
||||
uintptr_t startaddr = addr;
|
||||
if(startaddr<startdb) startaddr = startdb;
|
||||
uintptr_t endaddr = addr + size - 1;
|
||||
if(endaddr>enddb) endaddr = enddb;
|
||||
if(destroy)
|
||||
FreeRangeDynablock(dblist, startaddr, endaddr-startaddr+1);
|
||||
else
|
||||
MarkRangeDynablock(dblist, startaddr, endaddr-startaddr+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_custommem_helper(box86context_t* ctx)
|
||||
{
|
||||
#ifdef DYNAREC
|
||||
if(dynmap) // already initialized
|
||||
return;
|
||||
pthread_mutex_init(&mutex_mmap, NULL);
|
||||
dynmap = (dynablocklist_t**)calloc(DYNAMAP_SIZE, sizeof(dynablocklist_t*));
|
||||
#endif
|
||||
}
|
||||
|
||||
void fini_custommem_helper(box86context_t *ctx)
|
||||
{
|
||||
#ifdef DYNAREC
|
||||
dynarec_log(LOG_DEBUG, "Free global Dynarecblocks\n");
|
||||
for (int i=0; i<mmapsize; ++i) {
|
||||
if(mmaplist[i].block)
|
||||
free(mmaplist[i].block);
|
||||
if(mmaplist[i].dblist) {
|
||||
kh_destroy(dynablocks, mmaplist[i].dblist);
|
||||
mmaplist[i].dblist = NULL;
|
||||
}
|
||||
}
|
||||
if(dblist_oversized) {
|
||||
kh_destroy(dynablocks, dblist_oversized);
|
||||
dblist_oversized = NULL;
|
||||
}
|
||||
mmapsize = 0;
|
||||
dynarec_log(LOG_DEBUG, "Free dynamic Dynarecblocks\n");
|
||||
uintptr_t idx = 0;
|
||||
uintptr_t end = ((0xFFFFFFFF)>>DYNAMAP_SHIFT);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
dynablocklist_t* dblist = dynmap[i];
|
||||
if(dblist) {
|
||||
uintptr_t startdb = StartDynablockList(dblist);
|
||||
uintptr_t enddb = EndDynablockList(dblist);
|
||||
uintptr_t startaddr = 0;
|
||||
if(startaddr<startdb) startaddr = startdb;
|
||||
uintptr_t endaddr = 0xFFFFFFFF;
|
||||
if(endaddr>enddb) endaddr = enddb;
|
||||
FreeRangeDynablock(dblist, startaddr, endaddr-startaddr+1);
|
||||
}
|
||||
}
|
||||
pthread_mutex_destroy(&mutex_mmap);
|
||||
free(mmaplist);
|
||||
free(dynmap);
|
||||
dynmap = NULL;
|
||||
#endif
|
||||
for(int i=0; i<n_blocks; ++i)
|
||||
free(p_blocks[i].block);
|
||||
free(p_blocks);
|
||||
pthread_mutex_destroy(&mutex_blocks);
|
||||
}
|
||||
@@ -21,12 +21,13 @@ Op is 20-27
|
||||
#define xEBP 9
|
||||
#define xESI 10
|
||||
#define xEDI 11
|
||||
#define xEIP 12
|
||||
#define xFlags 12
|
||||
#define xEIP 14
|
||||
// scratch registers
|
||||
#define x1 1
|
||||
#define x2 2
|
||||
#define x3 3
|
||||
#define x12 12
|
||||
#define x14 14
|
||||
// emu is r0
|
||||
#define xEmu 0
|
||||
// ARM SP is r13
|
||||
@@ -234,13 +235,22 @@ Op is 20-27
|
||||
// orr.s dst, src1, src2, lsl #imm
|
||||
#define ORRS_REG_LSL_IMM5(dst, src1, src2, imm5) \
|
||||
EMIT(0xe1900000 | ((dst) << 12) | ((src1) << 16) | brLSL(imm5, src2) )
|
||||
// orr dst, src1, src2, lsr #imm
|
||||
#define ORR_REG_LSR_IMM5(dst, src1, src2, imm5) \
|
||||
EMIT(0xe1800000 | ((dst) << 12) | ((src1) << 16) | brLSR(imm5, src2) )
|
||||
// orr.s dst, src1, src2, lsr #imm
|
||||
#define ORRS_REG_LSR_IMM5(dst, src1, src2, imm5) \
|
||||
EMIT(0xe1900000 | ((dst) << 12) | ((src1) << 16) | brLSR(imm5, src2) )
|
||||
// orr dst, src1, #imm8
|
||||
#define ORR_IMM8(dst, src, imm8, rot) \
|
||||
EMIT(0xe3800000 | ((dst) << 12) | ((src) << 16) | ((rot)<<8) | imm8 )
|
||||
// orr.s dst, src1, #imm8
|
||||
#define ORRS_IMM8(dst, src, imm8, rot) \
|
||||
EMIT(0xe3900000 | ((dst) << 12) | ((src) << 16) | ((rot)<<8) | imm8 )
|
||||
// orr dst, src1, src2, lsl #rs
|
||||
// orr.cond dst, src1, #imm8
|
||||
#define ORR_IMM8_COND(cond, dst, src, imm8, rot) \
|
||||
EMIT((cond) | 0x03800000 | ((dst) << 12) | ((src) << 16) | ((rot)<<8) | imm8 )
|
||||
// orr dst, src1, src2, lsl rs
|
||||
#define ORR_REG_LSL_REG(dst, src1, src2, rs) \
|
||||
EMIT(0xe1800000 | ((dst) << 12) | ((src1) << 16) | brRLSL(rs, src2) )
|
||||
// xor dst, src1, src2, lsl #imm
|
||||
@@ -271,6 +281,9 @@ Op is 20-27
|
||||
// bic dst, src, IMM8
|
||||
#define BIC_IMM8(dst, src, imm8, rot) \
|
||||
EMIT(0xe3c00000 | ((dst) << 12) | ((src) << 16) | ((rot)<<8) | imm8 )
|
||||
// bic.cond dst, src, IMM8
|
||||
#define BIC_IMM8_COND(cond, dst, src, imm8, rot) \
|
||||
EMIT((cond) | 0x03c00000 | ((dst) << 12) | ((src) << 16) | ((rot)<<8) | imm8 )
|
||||
// bic.s dst, src1, #imm ror rot*2
|
||||
#define BICS_IMM8_ROR(dst, src, imm8, rot) \
|
||||
EMIT(0xe3d00000 | ((dst) << 12) | ((src) << 16) | ((rot)<<8) | brIMM(imm8) )
|
||||
@@ -327,6 +340,8 @@ Op is 20-27
|
||||
#define STR_IMM9(reg, addr, imm9) EMIT(0xe5000000 | (((imm9)<0)?0:1)<<23 | ((reg) << 12) | ((addr) << 16) | brIMM(imm9) )
|
||||
// str with cond reg, [addr, #+/-imm9]
|
||||
#define STR_IMM9_COND(cond, reg, addr, imm9) EMIT(cond | 0x05000000 | (((imm9)<0)?0:1)<<23 | ((reg) << 12) | ((addr) << 16) | brIMM(imm9) )
|
||||
// str reg, [addr, #+/-imm9]!
|
||||
#define STR_IMM9_W(reg, addr, imm9) EMIT(0xe5200000 | (((imm9)<0)?0:1)<<23 | ((reg) << 12) | ((addr) << 16) | brIMM(imm9) )
|
||||
// strb reg, [addr, #+/-imm9]
|
||||
#define STRB_IMM9(reg, addr, imm9) EMIT(0xe5400000 | (((imm9)<0)?0:1)<<23 | ((reg) << 12) | ((addr) << 16) | brIMM(imm9) )
|
||||
// str reg, [addr], #+/-imm9
|
||||
@@ -364,10 +379,16 @@ Op is 20-27
|
||||
// all | const |pre-index| subs | no PSR |writeback| store | base |reg list
|
||||
#define PUSH(reg, list) EMIT(c__ | (0b100<<25) | (1<<24) | (0<<23) | (0<<22) | (1<<21) | (0<<20) | ((reg)<<16) | (list))
|
||||
|
||||
// push reg to xESP
|
||||
#define PUSH1(reg) STR_IMM9_W(reg, xESP, -4)
|
||||
|
||||
// pop reg!, {list}
|
||||
// all | const |postindex| add | no PSR |writeback| load | base |reg list
|
||||
#define POP(reg, list) EMIT(c__ | (0b100<<25) | (0<<24) | (1<<23) | (0<<22) | (1<<21) | (1<<20) | ((reg)<<16) | (list))
|
||||
|
||||
// pop reg from xESP
|
||||
#define POP1(reg) LDRAI_IMM9_W(reg, xESP, 4)
|
||||
|
||||
// STMDB reg, {list}
|
||||
// all | const |pre-index| subs | no PSR | no wb | store | base |reg list
|
||||
#define STMDB(reg, list) EMIT(c__ | (0b100<<25) | (1<<24) | (0<<23) | (0<<22) | (0<<21) | (0<<20) | ((reg)<<16) | (list))
|
||||
@@ -433,6 +454,11 @@ Op is 20-27
|
||||
// BFI_COND: Bit Field Insert with condition: copy any number of low order bit from Rn to any position of Rd
|
||||
#define BFI_COND(cond, rd, rn, lsb, width) EMIT(cond | (0b0111110<<21) | (((lsb)+(width)-1)<<16) | ((rd)<<12) | ((lsb)<<7) | (0b001<<4) | (rn))
|
||||
|
||||
// BFC: Bit Field Clear: clear any number of adjacent bit from Rd
|
||||
#define BFC(rd, lsb, width) EMIT(c__ | (0b0111110<<21) | (((lsb)+(width)-1)<<16) | ((rd)<<12) | ((lsb)<<7) | (0b001<<4) | 0b1111)
|
||||
// BFC_COND: Bit Field Clear with condition: clear any number of adjacent bit from Rd
|
||||
#define BFC_COND(cond, rd, lsb, width) EMIT(cond | (0b0111110<<21) | (((lsb)+(width)-1)<<16) | ((rd)<<12) | ((lsb)<<7) | (0b001<<4) | 0b1111)
|
||||
|
||||
// REV: Reverse byte of a 32bits word
|
||||
#define REV(rd, rm) EMIT(c__ | (0b01101<<23) | (0<<22) | (0b11<<20) | (0b1111<<16) | ((rd)<<12) | (0b1111<<8) | (0b0011<<4) | (rm))
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
arm_epilog:
|
||||
//update register -> emu
|
||||
//pop {r0}
|
||||
stm r0, {r4-r12} // put back reg value in emu, including EIP (so r12 must be EIP now)
|
||||
stm r0, {r4-r12,r14} // put back reg value in emu, including EIP (so r14 must be EIP now)
|
||||
//restore all used register
|
||||
//vpop {d8-d15}
|
||||
pop {r4-r11, pc}
|
||||
|
||||
@@ -7,19 +7,33 @@
|
||||
.align 4
|
||||
|
||||
.extern UpdateLinkTable
|
||||
.extern LinkNext
|
||||
|
||||
.global arm_linker
|
||||
arm_linker:
|
||||
// emu is r0
|
||||
stm r0, {r4-r12} // put back reg value in emu, including EIP (easier debugging, and safer)
|
||||
stm r0, {r4-r12,r14} // put back reg value in emu, including EIP (easier debugging, and safer)
|
||||
// table offset is r1
|
||||
// IP address is r12
|
||||
push {r0, r1, r12}
|
||||
mov r2, r12
|
||||
// IP address is r14
|
||||
push {r0, r1, r12, r14}
|
||||
mov r2, r14
|
||||
// call the function
|
||||
bl UpdateLinkTable
|
||||
// return offset is jump address
|
||||
mov r3, r0
|
||||
pop {r0, r1, r12}
|
||||
pop {r0, r1, r12, r14}
|
||||
bx r3
|
||||
|
||||
.global arm_next
|
||||
arm_next:
|
||||
// emu is r0
|
||||
//stm r0, {r4-r12,r14} // don't put put back reg value in emu, faster but more tricky to debug
|
||||
// IP address is r1
|
||||
push {r0, r1, r12, r14}
|
||||
// call the function
|
||||
bl LinkNext
|
||||
// return offset is jump address
|
||||
mov r3, r0
|
||||
pop {r0, r1, r12, r14}
|
||||
bx r3
|
||||
|
||||
@@ -13,7 +13,7 @@ arm_prolog:
|
||||
//vpush {d8-d15}
|
||||
//setup emu -> register
|
||||
//push {r0}
|
||||
ldm r0, {r4-r11} // all 8 register in direct access, no EIP (so r12 can be used as scratch)
|
||||
ldm r0, {r4-r12} // all 8 register in direct access, plus flags, no EIP (so r14 can be used as scratch)
|
||||
//TODO
|
||||
//jump to function
|
||||
bx r1
|
||||
+55
-18
@@ -24,7 +24,7 @@
|
||||
#else
|
||||
#error Unsupported architecture!
|
||||
#endif
|
||||
|
||||
#include "custommem.h"
|
||||
#include "khash.h"
|
||||
|
||||
KHASH_MAP_INIT_INT(dynablocks, dynablock_t*)
|
||||
@@ -38,14 +38,13 @@ uint32_t X31_hash_code(void* addr, int len)
|
||||
return (uint32_t)h;
|
||||
}
|
||||
|
||||
dynablocklist_t* NewDynablockList(uintptr_t base, uintptr_t text, int textsz, int nolinker, int direct)
|
||||
dynablocklist_t* NewDynablockList(uintptr_t text, int textsz, int nolinker, int direct)
|
||||
{
|
||||
if(!textsz) {
|
||||
printf_log(LOG_NONE, "Error, creating a NULL sized Dynablock\n");
|
||||
return NULL;
|
||||
}
|
||||
dynablocklist_t* ret = (dynablocklist_t*)calloc(1, sizeof(dynablocklist_t));
|
||||
ret->base = base;
|
||||
ret->text = text;
|
||||
ret->textsz = textsz;
|
||||
ret->nolinker = nolinker;
|
||||
@@ -176,25 +175,35 @@ uintptr_t EndDynablockList(dynablocklist_t* db)
|
||||
return db->text+db->textsz-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IntervalIntersects(uintptr_t start1, uintptr_t end1, uintptr_t start2, uintptr_t end2)
|
||||
{
|
||||
if(start1 > end2 || start2 > end1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MarkDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size)
|
||||
{
|
||||
if(!dynablocks)
|
||||
return;
|
||||
if(!dynablocks->nolinker)
|
||||
if(!dynablocks->nolinker || !dynablocks->direct)
|
||||
return;
|
||||
uintptr_t startdb = dynablocks->text;
|
||||
uintptr_t enddb = startdb + dynablocks->textsz;
|
||||
uintptr_t start = addr;
|
||||
uintptr_t end = addr+size;
|
||||
uintptr_t enddb = startdb + dynablocks->textsz -1;
|
||||
int maxsz = dynablocks->maxsz;
|
||||
uintptr_t start = addr - maxsz;
|
||||
uintptr_t end = addr+size-1;
|
||||
if(start<startdb)
|
||||
start = startdb;
|
||||
if(end>enddb)
|
||||
end = enddb;
|
||||
dynablock_t *db;
|
||||
if(end>startdb && start<enddb)
|
||||
for(uintptr_t i = start; i<end; ++i)
|
||||
if(dynablocks->direct[i-startdb]) {
|
||||
MarkDynablock(dynablocks->direct[i-startdb]);
|
||||
}
|
||||
if((db=dynablocks->direct[i-startdb]))
|
||||
if(IntervalIntersects((uintptr_t)db->x86_addr, (uintptr_t)db->x86_addr+db->x86_size-1, addr, addr+size+1))
|
||||
MarkDynablock(db);
|
||||
}
|
||||
|
||||
void ProtectDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size)
|
||||
@@ -239,8 +248,10 @@ void FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t s
|
||||
if(db) {
|
||||
if(db->father)
|
||||
db = db->father;
|
||||
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
|
||||
kh_value(blocks, k) = db;
|
||||
if(db->parent==dynablocks) {
|
||||
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
|
||||
kh_value(blocks, k) = db;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,8 +268,12 @@ void MarkRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t s
|
||||
return;
|
||||
if(!dynablocks->nolinker)
|
||||
return;
|
||||
if(dynablocks->direct)
|
||||
if(dynablocks->direct) {
|
||||
MarkDirectDynablock(dynablocks, addr, size);
|
||||
// the blocks check before
|
||||
for(int idx=(addr-dynablocks->maxsz)>>DYNAMAP_SHIFT; idx<addr>>DYNAMAP_SHIFT; ++idx)
|
||||
MarkDirectDynablock(getDB(idx), addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
dynablock_t* FindDynablockDynablocklist(void* addr, kh_dynablocks_t* dynablocks)
|
||||
@@ -278,7 +293,7 @@ dynablock_t* FindDynablockDynablocklist(void* addr, kh_dynablocks_t* dynablocks)
|
||||
static dynablocklist_t* getDBFromAddress(uintptr_t addr)
|
||||
{
|
||||
const int idx = (addr>>DYNAMAP_SHIFT);
|
||||
return (my_context->dynmap[idx])?my_context->dynmap[idx]:NULL;
|
||||
return getDB(idx);
|
||||
}
|
||||
|
||||
dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* created)
|
||||
@@ -368,14 +383,34 @@ static dynablock_t* internalDBGetBlock(x86emu_t* emu, uintptr_t addr, uintptr_t
|
||||
// fill the block
|
||||
block->x86_addr = (void*)addr;
|
||||
if(!FillBlock(block, filladdr)) {
|
||||
dynablocks->direct[addr-dynablocks->text] = NULL;
|
||||
void* old = (void*)arm_lock_xchg(&dynablocks->direct[addr-dynablocks->text], 0);
|
||||
if(old!=block) {// put it back in place, strange things are happening here!
|
||||
dynarec_log(LOG_NONE, "Warning, a wild block appeared at %p: %p\n", (void*)addr, old);
|
||||
arm_lock_xchg(&dynablocks->direct[addr-dynablocks->text], (uintptr_t)old);
|
||||
}
|
||||
free(block);
|
||||
block = NULL;
|
||||
}
|
||||
if(box86_dynarec_dump)
|
||||
pthread_mutex_unlock(&my_context->mutex_dyndump);
|
||||
// check size
|
||||
if(block) {
|
||||
int blocksz = block->x86_size;
|
||||
if(dynablocks->maxsz<blocksz) {
|
||||
dynablocks->maxsz = blocksz;
|
||||
for(int idx=(addr>>DYNAMAP_SHIFT)+1; idx<=((addr+blocksz)>>DYNAMAP_SHIFT); ++idx) {
|
||||
dynablocklist_t* dblist;
|
||||
if((dblist = getDB(idx)))
|
||||
if(dblist->maxsz<blocksz)
|
||||
dblist->maxsz = blocksz;
|
||||
}
|
||||
}
|
||||
|
||||
dynarec_log(LOG_DEBUG, " --- DynaRec Block %s @%p:%p (%p, 0x%x bytes, with %d son(s))\n", created?"created":"recycled", (void*)addr, (void*)(addr-((block)?block->x86_size:0)), (block)?block->block:0, (block)?block->size:0, (block)?block->sons_size:0);
|
||||
if(block->parent->nolinker)
|
||||
protectDB((uintptr_t)block->x86_addr, block->x86_size);
|
||||
}
|
||||
|
||||
dynarec_log(LOG_DEBUG, " --- DynaRec Block %s @%p:%p (%p, 0x%x bytes, with %d son(s))\n", created?"created":"recycled", (void*)addr, (void*)(addr+((block)?block->x86_size:0)), (block)?block->block:0, (block)?block->size:0, (block)?block->sons_size:0);
|
||||
|
||||
return block;
|
||||
}
|
||||
@@ -397,7 +432,8 @@ dynablock_t* DBGetBlock(x86emu_t* emu, uintptr_t addr, int create, dynablock_t**
|
||||
db = internalDBGetBlock(emu, addr, addr, create, *current);
|
||||
} else {
|
||||
father->need_test = 0;
|
||||
protectDB((uintptr_t)father->x86_addr, father->x86_size);
|
||||
if(father->nolinker)
|
||||
protectDB((uintptr_t)father->x86_addr, father->x86_size);
|
||||
}
|
||||
}
|
||||
return db;
|
||||
@@ -419,7 +455,8 @@ dynablock_t* DBAlternateBlock(x86emu_t* emu, uintptr_t addr, uintptr_t filladdr)
|
||||
db = internalDBGetBlock(emu, addr, filladdr, create, NULL);
|
||||
} else {
|
||||
father->need_test = 0;
|
||||
protectDB((uintptr_t)father->x86_addr, father->x86_size);
|
||||
if(father->nolinker)
|
||||
protectDB((uintptr_t)father->x86_addr, father->x86_size);
|
||||
}
|
||||
}
|
||||
return db;
|
||||
|
||||
@@ -13,7 +13,7 @@ typedef struct dynablock_s {
|
||||
void* block;
|
||||
int size;
|
||||
void* x86_addr;
|
||||
int x86_size;
|
||||
uintptr_t x86_size;
|
||||
uint32_t hash;
|
||||
uintptr_t* table;
|
||||
int tablesz;
|
||||
@@ -31,9 +31,9 @@ typedef struct dynablock_s {
|
||||
typedef struct dynablocklist_s {
|
||||
uintptr_t text;
|
||||
int textsz;
|
||||
uintptr_t base;
|
||||
int nolinker; // in case this dynablock can disapear (also, block memory are allocated with a temporary scheme)
|
||||
dynablock_t** direct; // direct mapping (waste of space, so not always there)
|
||||
int maxsz; // maxblock size (for this block or previous block)
|
||||
int nolinker; // in case this dynablock can be deleted
|
||||
dynablock_t** direct; // direct mapping (waste of space, so the array is created at first write)
|
||||
} dynablocklist_t;
|
||||
|
||||
#endif //__DYNABLOCK_PRIVATE_H_
|
||||
@@ -85,6 +85,28 @@ void* UpdateLinkTable(x86emu_t* emu, void** table, uintptr_t addr)
|
||||
}
|
||||
return jblock;
|
||||
}
|
||||
void* LinkNext(x86emu_t* emu, uintptr_t addr)
|
||||
{
|
||||
dynablock_t* current = NULL;
|
||||
void * jblock;
|
||||
dynablock_t* block = DBGetBlock(emu, addr, 1, ¤t);
|
||||
if(!block) {
|
||||
// no block, let link table as is...
|
||||
//tableupdate(arm_epilog, addr, table);
|
||||
return arm_epilog;
|
||||
}
|
||||
if(!block->done) {
|
||||
// not finished yet... leave linker
|
||||
//tableupdate(arm_linker, addr, table);
|
||||
return arm_epilog;
|
||||
}
|
||||
if(!(jblock=block->block)) {
|
||||
// null block, but done: go to epilog, no linker here
|
||||
return arm_epilog;
|
||||
}
|
||||
//dynablock_t *father = block->father?block->father:block;
|
||||
return jblock;
|
||||
}
|
||||
#endif
|
||||
|
||||
void DynaCall(x86emu_t* emu, uintptr_t addr)
|
||||
|
||||
+119
-4
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86context.h"
|
||||
#include "custommem.h"
|
||||
#include "dynarec.h"
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "tools/bridge_private.h"
|
||||
@@ -19,6 +20,7 @@
|
||||
#include "dynablock_private.h"
|
||||
#include "dynarec_arm.h"
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "elfloader.h"
|
||||
|
||||
void printf_x86_instruction(zydis_dec_t* dec, instruction_x86_t* inst, const char* name) {
|
||||
@@ -81,9 +83,9 @@ uintptr_t get_closest_next(dynarec_arm_t *dyn, uintptr_t addr) {
|
||||
}
|
||||
return best;
|
||||
}
|
||||
#define PK(A) (*((uint8_t*)(addr+(A))))
|
||||
int is_nops(dynarec_arm_t *dyn, uintptr_t addr, int n)
|
||||
{
|
||||
#define PK(A) (*((uint8_t*)(addr+(A))))
|
||||
if(!n)
|
||||
return 1;
|
||||
if(PK(0)==0x90)
|
||||
@@ -109,7 +111,122 @@ int is_nops(dynarec_arm_t *dyn, uintptr_t addr, int n)
|
||||
if(n>7 && PK(0)==0x0f && PK(1)==0x1f && PK(2)==0x84 && PK(3)==0x00 && PK(4)==0x00 && PK(5)==0x00 && PK(6)==0x00 && PK(7)==0x00)
|
||||
return is_nops(dyn, addr+8, n-8);
|
||||
return 0;
|
||||
#undef PK
|
||||
}
|
||||
|
||||
// return size of next instuciton, -1 is unknown
|
||||
// not all instrction are setup
|
||||
int next_instruction(dynarec_arm_t *dyn, uintptr_t addr)
|
||||
{
|
||||
uint8_t opcode = PK(0);
|
||||
uint8_t nextop;
|
||||
switch (opcode) {
|
||||
case 0x66:
|
||||
opcode = PK(1);
|
||||
switch(opcode) {
|
||||
case 0x90:
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
case 0x81:
|
||||
nextop = PK(1);
|
||||
return fakeed(dyn, addr+2, 0, nextop)-addr + 4;
|
||||
case 0x83:
|
||||
nextop = PK(1);
|
||||
return fakeed(dyn, addr+2, 0, nextop)-addr + 1;
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8A:
|
||||
case 0x8B:
|
||||
case 0x8C:
|
||||
case 0x8D:
|
||||
case 0x8E:
|
||||
case 0x8F:
|
||||
nextop = PK(1);
|
||||
return fakeed(dyn, addr+2, 0, nextop)-addr;
|
||||
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:
|
||||
case 0x90:
|
||||
case 0x91:
|
||||
case 0x92:
|
||||
case 0x93:
|
||||
case 0x94:
|
||||
case 0x95:
|
||||
case 0x96:
|
||||
case 0x97:
|
||||
case 0x98:
|
||||
case 0x99:
|
||||
case 0x9B:
|
||||
case 0x9C:
|
||||
case 0x9D:
|
||||
case 0x9E:
|
||||
case 0x9F:
|
||||
return 1;
|
||||
case 0xA0:
|
||||
case 0xA1:
|
||||
case 0xA2:
|
||||
case 0xA3:
|
||||
return 5;
|
||||
case 0xB0:
|
||||
case 0xB1:
|
||||
case 0xB2:
|
||||
case 0xB3:
|
||||
case 0xB4:
|
||||
case 0xB5:
|
||||
case 0xB6:
|
||||
case 0xB7:
|
||||
return 2;
|
||||
case 0xB8:
|
||||
case 0xB9:
|
||||
case 0xBA:
|
||||
case 0xBB:
|
||||
case 0xBC:
|
||||
case 0xBD:
|
||||
case 0xBE:
|
||||
case 0xBF:
|
||||
return 5;
|
||||
case 0xFF:
|
||||
nextop = PK(1);
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: // INC Ed
|
||||
case 1: //DEC Ed
|
||||
case 2: // CALL Ed
|
||||
case 4: // JMP Ed
|
||||
case 6: // Push Ed
|
||||
return fakeed(dyn, addr+2, 0, nextop)-addr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#undef PK
|
||||
|
||||
int is_instructions(dynarec_arm_t *dyn, uintptr_t addr, int n)
|
||||
{
|
||||
int i = 0;
|
||||
while(i<n) {
|
||||
int j=next_instruction(dyn, addr+i);
|
||||
if(j<=0) return 0;
|
||||
i+=j;
|
||||
}
|
||||
return (i==n)?1:0;
|
||||
}
|
||||
|
||||
uint32_t needed_flags(dynarec_arm_t *dyn, int ninst, uint32_t setf, int recurse)
|
||||
@@ -332,8 +449,6 @@ void* FillBlock(dynablock_t* block, uintptr_t addr) {
|
||||
} else
|
||||
free(sons);
|
||||
}
|
||||
if(block->parent->nolinker)
|
||||
protectDB((uintptr_t)block->x86_addr, block->x86_size);
|
||||
free(helper.sons_x86);
|
||||
free(helper.sons_arm);
|
||||
block->done = 1;
|
||||
|
||||
+291
-322
File diff suppressed because it is too large.
Load diff
+207
-221
@@ -341,7 +341,7 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
d0 = v0;
|
||||
else
|
||||
d0 = fpu_get_scratch_double(dyn);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x12);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x14);
|
||||
VCVTR_S32_F32(d0*2, d1*2);
|
||||
VCVTR_S32_F32(d0*2+1, d1*2+1);
|
||||
if(v0>=16) {
|
||||
@@ -447,107 +447,93 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0x40:
|
||||
INST_NAME("CMOVO Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_OF)
|
||||
GO( TSTS_IMM8_ROR(xFlags, 0b10, 0x0b)
|
||||
, cEQ, cNE, X_OF)
|
||||
break;
|
||||
case 0x41:
|
||||
INST_NAME("CMOVNO Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_OF)
|
||||
GO( TSTS_IMM8_ROR(xFlags, 0b10, 0x0b)
|
||||
, cNE, cEQ, X_OF)
|
||||
break;
|
||||
case 0x42:
|
||||
INST_NAME("CMOVC Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_CF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_CF)
|
||||
, cEQ, cNE, X_CF)
|
||||
break;
|
||||
case 0x43:
|
||||
INST_NAME("CMOVNC Gd, Ed");
|
||||
GO( LDR_IMM9(2, 0, offsetof(x86emu_t, flags[F_CF]));
|
||||
CMPS_IMM8(2, 1)
|
||||
, cEQ, cNE, X_CF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_CF)
|
||||
, cNE, cEQ, X_CF)
|
||||
break;
|
||||
case 0x44:
|
||||
INST_NAME("CMOVZ Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_ZF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_ZF)
|
||||
, cEQ, cNE, X_ZF)
|
||||
break;
|
||||
case 0x45:
|
||||
INST_NAME("CMOVNZ Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_ZF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_ZF)
|
||||
, cNE, cEQ, X_ZF)
|
||||
break;
|
||||
case 0x46:
|
||||
INST_NAME("CMOVBE Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORRS_REG_LSL_IMM5(x2, x2, x3, 0);
|
||||
GO( TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF))
|
||||
, cEQ, cNE, X_CF|X_ZF)
|
||||
break;
|
||||
case 0x47:
|
||||
INST_NAME("CMOVNBE Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORRS_REG_LSL_IMM5(x2, x2, x3, 0);
|
||||
GO( TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF))
|
||||
, cNE, cEQ, X_CF|X_ZF)
|
||||
break;
|
||||
case 0x48:
|
||||
INST_NAME("CMOVS Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
CMPS_IMM8(x2, x1)
|
||||
, cNE, cEQ, X_SF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_SF)
|
||||
, cEQ, cNE, X_SF)
|
||||
break;
|
||||
case 0x49:
|
||||
INST_NAME("CMOVNS Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_SF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_SF)
|
||||
, cNE, cEQ, X_SF)
|
||||
break;
|
||||
case 0x4A:
|
||||
INST_NAME("CMOVP Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
CMPS_IMM8(x2, x1)
|
||||
, cNE, cEQ, X_PF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_PF)
|
||||
, cEQ, cNE, X_PF)
|
||||
break;
|
||||
case 0x4B:
|
||||
INST_NAME("CMOVNP Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_PF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_PF)
|
||||
, cNE, cEQ, X_PF)
|
||||
break;
|
||||
case 0x4C:
|
||||
INST_NAME("CMOVL Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
CMPS_REG_LSL_IMM5(x1, x2, 0)
|
||||
, cEQ, cNE, X_SF|X_OF)
|
||||
break;
|
||||
case 0x4D:
|
||||
INST_NAME("CMOVGE Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
CMPS_REG_LSL_IMM5(x1, x2, 0)
|
||||
, cNE, cEQ, X_SF|X_OF)
|
||||
break;
|
||||
case 0x4E:
|
||||
INST_NAME("CMOVLE Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
UBFX(x2, xFlags, F_ZF, 1);
|
||||
ORRS_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
, cEQ, cNE, X_SF|X_OF|X_ZF)
|
||||
break;
|
||||
case 0x4F:
|
||||
INST_NAME("CMOVG Gd, Ed");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
UBFX(x2, xFlags, F_ZF, 1);
|
||||
ORRS_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
, cNE, cEQ, X_SF|X_OF|X_ZF)
|
||||
break;
|
||||
@@ -1164,107 +1150,93 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0x80:
|
||||
INST_NAME("JO id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_OF)
|
||||
GO( TSTS_IMM8_ROR(xFlags, 0b10, 0x0b)
|
||||
, cEQ, cNE, X_OF)
|
||||
break;
|
||||
case 0x81:
|
||||
INST_NAME("JNO id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_OF)
|
||||
GO( TSTS_IMM8_ROR(xFlags, 0b10, 0x0b)
|
||||
, cNE, cEQ, X_OF)
|
||||
break;
|
||||
case 0x82:
|
||||
INST_NAME("JC id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_CF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_CF)
|
||||
, cEQ, cNE, X_CF)
|
||||
break;
|
||||
case 0x83:
|
||||
INST_NAME("JNC id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_CF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_CF)
|
||||
, cNE, cEQ, X_CF)
|
||||
break;
|
||||
case 0x84:
|
||||
INST_NAME("JZ id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_ZF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_ZF)
|
||||
, cEQ, cNE, X_ZF)
|
||||
break;
|
||||
case 0x85:
|
||||
INST_NAME("JNZ id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_ZF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_ZF)
|
||||
, cNE, cEQ, X_ZF)
|
||||
break;
|
||||
case 0x86:
|
||||
INST_NAME("JBE id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORRS_REG_LSL_IMM5(x2, x2, x3, 0);
|
||||
GO( TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF))
|
||||
, cEQ, cNE, X_CF|X_ZF)
|
||||
break;
|
||||
case 0x87:
|
||||
INST_NAME("JNBE id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORRS_REG_LSL_IMM5(x2, x2, x3, 0);
|
||||
GO( TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF))
|
||||
, cNE, cEQ, X_CF|X_ZF)
|
||||
break;
|
||||
case 0x88:
|
||||
INST_NAME("JS id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_SF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_SF)
|
||||
, cEQ, cNE, X_SF)
|
||||
break;
|
||||
case 0x89:
|
||||
INST_NAME("JNS id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_SF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_SF)
|
||||
, cNE, cEQ, X_SF)
|
||||
break;
|
||||
case 0x8A:
|
||||
INST_NAME("JP id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_PF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_PF)
|
||||
, cEQ, cNE, X_PF)
|
||||
break;
|
||||
case 0x8B:
|
||||
INST_NAME("JNP id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_PF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_PF)
|
||||
, cNE, cEQ, X_PF)
|
||||
break;
|
||||
case 0x8C:
|
||||
INST_NAME("JL id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
CMPS_REG_LSL_IMM5(x1, x2, 0)
|
||||
, cEQ, cNE, X_SF|X_OF)
|
||||
break;
|
||||
case 0x8D:
|
||||
INST_NAME("JGE id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
CMPS_REG_LSL_IMM5(x1, x2, 0)
|
||||
, cNE, cEQ, X_SF|X_OF)
|
||||
break;
|
||||
case 0x8E:
|
||||
INST_NAME("JLE id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
UBFX(x2, xFlags, F_ZF, 1);
|
||||
ORRS_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
, cEQ, cNE, X_SF|X_OF|X_ZF)
|
||||
break;
|
||||
case 0x8F:
|
||||
INST_NAME("JG id");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
UBFX(x2, xFlags, F_ZF, 1);
|
||||
ORRS_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
, cNE, cEQ, X_SF|X_OF|X_ZF)
|
||||
break;
|
||||
@@ -1287,107 +1259,93 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0x90:
|
||||
INST_NAME("SETO Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_OF)
|
||||
GO( TSTS_IMM8_ROR(xFlags, 0b10, 0x0b)
|
||||
, cEQ, cNE, X_OF)
|
||||
break;
|
||||
case 0x91:
|
||||
INST_NAME("SETNO Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_OF)
|
||||
GO( TSTS_IMM8_ROR(xFlags, 0b10, 0x0b)
|
||||
, cNE, cEQ, X_OF)
|
||||
break;
|
||||
case 0x92:
|
||||
INST_NAME("SETC Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_CF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_CF)
|
||||
, cEQ, cNE, X_CF)
|
||||
break;
|
||||
case 0x93:
|
||||
INST_NAME("SETNC Eb");
|
||||
GO( LDR_IMM9(2, 0, offsetof(x86emu_t, flags[F_CF]));
|
||||
CMPS_IMM8(2, 1)
|
||||
, cEQ, cNE, X_CF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_CF)
|
||||
, cNE, cEQ, X_CF)
|
||||
break;
|
||||
case 0x94:
|
||||
INST_NAME("SETZ Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_ZF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_ZF)
|
||||
, cEQ, cNE, X_ZF)
|
||||
break;
|
||||
case 0x95:
|
||||
INST_NAME("SETNZ Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_ZF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_ZF)
|
||||
, cNE, cEQ, X_ZF)
|
||||
break;
|
||||
case 0x96:
|
||||
INST_NAME("SETBE Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORRS_REG_LSL_IMM5(x2, x2, x3, 0);
|
||||
GO( TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF))
|
||||
, cEQ, cNE, X_CF|X_ZF)
|
||||
break;
|
||||
case 0x97:
|
||||
INST_NAME("SETNBE Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORRS_REG_LSL_IMM5(x2, x2, x3, 0);
|
||||
GO( TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF))
|
||||
, cNE, cEQ, X_CF|X_ZF)
|
||||
break;
|
||||
case 0x98:
|
||||
INST_NAME("SETS Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
CMPS_IMM8(x2, x1)
|
||||
, cNE, cEQ, X_SF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_SF)
|
||||
, cEQ, cNE, X_SF)
|
||||
break;
|
||||
case 0x99:
|
||||
INST_NAME("SETNS Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_SF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_SF)
|
||||
, cNE, cEQ, X_SF)
|
||||
break;
|
||||
case 0x9A:
|
||||
INST_NAME("SETP Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
CMPS_IMM8(x2, x1)
|
||||
, cNE, cEQ, X_PF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_PF)
|
||||
, cEQ, cNE, X_PF)
|
||||
break;
|
||||
case 0x9B:
|
||||
INST_NAME("SETNP Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_PF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_PF)
|
||||
, cNE, cEQ, X_PF)
|
||||
break;
|
||||
case 0x9C:
|
||||
INST_NAME("SETL Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
CMPS_REG_LSL_IMM5(x1, x2, 0)
|
||||
, cEQ, cNE, X_SF|X_OF)
|
||||
break;
|
||||
case 0x9D:
|
||||
INST_NAME("SETGE Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
CMPS_REG_LSL_IMM5(x1, x2, 0)
|
||||
, cNE, cEQ, X_SF|X_OF)
|
||||
break;
|
||||
case 0x9E:
|
||||
INST_NAME("SETLE Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
UBFX(x2, xFlags, F_ZF, 1);
|
||||
ORRS_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
, cEQ, cNE, X_SF|X_OF|X_ZF)
|
||||
break;
|
||||
case 0x9F:
|
||||
INST_NAME("SETG Eb");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
UBFX(x2, xFlags, F_ZF, 1);
|
||||
ORRS_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
, cNE, cEQ, X_SF|X_OF|X_ZF)
|
||||
break;
|
||||
@@ -1397,12 +1355,12 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
INST_NAME("PUSH FS");
|
||||
MOVW(x1, offsetof(x86emu_t, segs[_FS]));
|
||||
LDRH_REG(x2, xEmu, x1);
|
||||
PUSH(xESP, 1<<x2);
|
||||
PUSH1(x2);
|
||||
break;
|
||||
case 0xA1:
|
||||
INST_NAME("POP FS");
|
||||
MOVW(x1, offsetof(x86emu_t, segs[_FS]));
|
||||
POP(xESP, 1<<x2);
|
||||
POP1(x2);
|
||||
STRH_REG(x2, xEmu, x1);
|
||||
MOVW(x1, 0);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_FS]));
|
||||
@@ -1410,11 +1368,11 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 0xA2:
|
||||
INST_NAME("CPUID");
|
||||
MOV_REG(x1, xEAX);
|
||||
MOV32(x12, ip+2); // EIP is useless, but why not...
|
||||
MOV32(x14, ip+2); // EIP is useless, but why not...
|
||||
// not purging stuff like x87 here, there is no float math or anything
|
||||
STM(xEmu, (1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12));
|
||||
CALL_(my_cpuid, -1, 0);
|
||||
LDM(xEmu, (1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12));
|
||||
STM(xEmu, (1<<xEAX)|(1<<xEBX)|(1<<xECX)|(1<<xEDX)|(1<<xESI)|(1<<xEDI)|(1<<xESP)|(1<<xEBP)|(1<<xEIP)|(1<<xFlags));
|
||||
CALL_S(my_cpuid, -1, 0);
|
||||
LDM(xEmu, (1<<xEAX)|(1<<xEBX)|(1<<xECX)|(1<<xEDX)|(1<<xESI)|(1<<xEDI)|(1<<xESP)|(1<<xEBP)|(1<<xEIP)|(1<<xFlags));
|
||||
break;
|
||||
case 0xA3:
|
||||
INST_NAME("BT Ed, Gd");
|
||||
@@ -1432,25 +1390,25 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x1, ed, x2);
|
||||
AND_IMM8(x1, x1, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, x1, F_CF, 1);
|
||||
break;
|
||||
case 0xA4:
|
||||
nextop = F8;
|
||||
INST_NAME("SHLD Ed, Gd, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETED;
|
||||
GETGD;
|
||||
u8 = F8;
|
||||
emit_shld32c(dyn, ninst, ed, gd, u8&0x1f, x3, x14);
|
||||
WBACK;
|
||||
break;
|
||||
case 0xA5:
|
||||
nextop = F8;
|
||||
if(opcode==0xA4) {
|
||||
INST_NAME("SHLD Ed, Gd, Ib");
|
||||
} else {
|
||||
INST_NAME("SHLD Ed, Gd, CL");
|
||||
UXTB(x3, xECX, 0);
|
||||
}
|
||||
INST_NAME("SHLD Ed, Gd, CL");
|
||||
UXTB(x3, xECX, 0);
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEDW(x12, x1);
|
||||
GETEDW(x14, x1);
|
||||
GETGD;
|
||||
if(opcode==0xA4) {
|
||||
u8 = F8;
|
||||
MOVW(x3, u8);
|
||||
}
|
||||
MOV_REG(x2, gd);
|
||||
CALL(shld32, ed, (wback?(1<<wback):0));
|
||||
WBACK;
|
||||
@@ -1460,12 +1418,12 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
INST_NAME("PUSH GS");
|
||||
MOVW(x1, offsetof(x86emu_t, segs[_GS]));
|
||||
LDRH_REG(x2, xEmu, x1);
|
||||
PUSH(xESP, 1<<x2);
|
||||
PUSH1(x2);
|
||||
break;
|
||||
case 0xA9:
|
||||
INST_NAME("POP GS");
|
||||
MOVW(x1, offsetof(x86emu_t, segs[_GS]));
|
||||
POP(xESP, 1<<x2);
|
||||
POP1(x2);
|
||||
STRH_REG(x2, xEmu, x1);
|
||||
MOVW(x1, 0);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_GS]));
|
||||
@@ -1488,32 +1446,33 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wback = x3;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
ANDS_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
ANDS_IMM8(x14, x14, 1);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
B_NEXT(cNE); // bit already set, jump to next instruction
|
||||
MOVW(x12, 1);
|
||||
ORR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
MOVW(x14, 1);
|
||||
ORR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STR_IMM9(ed, wback, fixedaddress);
|
||||
}
|
||||
break;
|
||||
case 0xAC:
|
||||
nextop = F8;
|
||||
INST_NAME("SHRD Ed, Gd, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETED;
|
||||
GETGD;
|
||||
u8 = F8;
|
||||
emit_shrd32c(dyn, ninst, ed, gd, u8, x3, x14);
|
||||
WBACK;
|
||||
break;
|
||||
case 0xAD:
|
||||
nextop = F8;
|
||||
if(opcode==0xAC) {
|
||||
INST_NAME("SHRD Ed, Gd, Ib");
|
||||
} else {
|
||||
INST_NAME("SHRD Ed, Gd, CL");
|
||||
UXTB(x3, xECX, 0);
|
||||
}
|
||||
INST_NAME("SHRD Ed, Gd, CL");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEDW(x12, x1);
|
||||
UXTB(x3, xECX, 0);
|
||||
GETEDW(x14, x1);
|
||||
GETGD;
|
||||
if(opcode==0xAC) {
|
||||
u8 = F8;
|
||||
MOVW(x3, u8);
|
||||
}
|
||||
MOV_REG(x2, gd);
|
||||
CALL(shrd32, ed, (wback?(1<<wback):0));
|
||||
WBACK;
|
||||
@@ -1564,8 +1523,8 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
LDR_IMM9(ed, xEmu, offsetof(x86emu_t, mxcsr));
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 4095, 0);
|
||||
LDR_IMM9(x12, xEmu, offsetof(x86emu_t, mxcsr));
|
||||
STR_IMM9(x12, ed, fixedaddress);
|
||||
LDR_IMM9(x14, xEmu, offsetof(x86emu_t, mxcsr));
|
||||
STR_IMM9(x14, ed, fixedaddress);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1605,11 +1564,10 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MARK;
|
||||
// AL != Eb
|
||||
BFI(xEAX, ed, 0, 8);
|
||||
MOVW(x1, 0);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
BFC(xFlags, F_ZF, 1);
|
||||
MARK3;
|
||||
// done, do the cmp now
|
||||
emit_cmp8(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp8(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
case 0xB1:
|
||||
INST_NAME("CMPXCHG Ed, Gd");
|
||||
@@ -1623,11 +1581,11 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV_REG(x3, ed);
|
||||
MOV_REG(ed, gd);
|
||||
WBACK;
|
||||
emit_cmp32(dyn, ninst, xEAX, x3, x1, x12);
|
||||
emit_cmp32(dyn, ninst, xEAX, x3, x1, x14);
|
||||
B_MARK3(c__); // not next, in case its called with a LOCK prefix
|
||||
MARK;
|
||||
// EAX != Ed
|
||||
emit_cmp32(dyn, ninst, xEAX, ed, x3, x12);
|
||||
emit_cmp32(dyn, ninst, xEAX, ed, x3, x14);
|
||||
MOV_REG(xEAX, ed);
|
||||
MARK3
|
||||
break;
|
||||
@@ -1648,12 +1606,12 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
ed = x1;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
ANDS_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
ANDS_IMM8(x14, x14, 1);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
B_MARK3(cEQ); // bit already clear, jump to end of instruction
|
||||
MOVW(x12, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
MOVW(x14, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STR_IMM9(ed, wback, fixedaddress);
|
||||
}
|
||||
@@ -1709,8 +1667,7 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV_REG_LSR_IMM5(x1, ed, u8);
|
||||
ed = x1;
|
||||
}
|
||||
AND_IMM8(x1, ed, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, ed, F_CF, 1);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("BTS Ed, Ib");
|
||||
@@ -1732,12 +1689,12 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wback = x3;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
ANDS_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
ANDS_IMM8(x14, x14, 1);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
B_MARK3(cNE); // bit already set, jump to next instruction
|
||||
MOVW(x12, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
MOVW(x14, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STR_IMM9(ed, wback, fixedaddress);
|
||||
}
|
||||
@@ -1763,12 +1720,12 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wback = x3;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
ANDS_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
ANDS_IMM8(x14, x14, 1);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
B_MARK3(cEQ); // bit already clear, jump to next instruction
|
||||
//MOVW(x12, 1); // already 0x01
|
||||
XOR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
//MOVW(x14, 1); // already 0x01
|
||||
XOR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STR_IMM9(ed, wback, fixedaddress);
|
||||
}
|
||||
@@ -1794,11 +1751,11 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wback = x3;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
ANDS_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOVW_COND(cEQ, x12, 1); // may already 0x01
|
||||
XOR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
ANDS_IMM8(x14, x14, 1);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
MOVW_COND(cEQ, x14, 1); // may already 0x01
|
||||
XOR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STR_IMM9(ed, wback, fixedaddress);
|
||||
}
|
||||
@@ -1825,11 +1782,10 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wback = x3;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
AND_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOVW(x12, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
MOVW(x14, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STR_IMM9(ed, wback, fixedaddress);
|
||||
}
|
||||
@@ -1847,9 +1803,8 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
CLZ(gd, x1); // x2 gets leading 0 == BSF
|
||||
MOVW(x1, 0); //ZF not set
|
||||
MARK;
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
BFI(xFlags, x1, F_ZF, 1);
|
||||
SET_DFNONE(x1);
|
||||
break;
|
||||
case 0xBD:
|
||||
INST_NAME("BSR Gd, Ed");
|
||||
@@ -1864,9 +1819,8 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
RSB_IMM8(gd, gd, 31); // complement
|
||||
MOVW(x1, 0); //ZF not set
|
||||
MARK;
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
BFI(xFlags, x1, F_ZF, 1);
|
||||
SET_DFNONE(x1);
|
||||
break;
|
||||
case 0xBE:
|
||||
INST_NAME("MOVSX Gd, Eb");
|
||||
@@ -1901,8 +1855,8 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETEB(x2);
|
||||
GETGB(x1);
|
||||
BFI(gb1, ed, gb2*8, 8); // gb <- eb
|
||||
emit_add8(dyn, ninst, ed, gd, x12, x3, 1);
|
||||
ADD_REG_LSL_IMM5(x12, ed, gd, 0);
|
||||
emit_add8(dyn, ninst, ed, gd, x14, x3, 1);
|
||||
ADD_REG_LSL_IMM5(x14, ed, gd, 0);
|
||||
EBBACK;
|
||||
break;
|
||||
case 0xC1:
|
||||
@@ -1916,7 +1870,7 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
XOR_REG_LSL_IMM5(ed, gd, ed, 0);
|
||||
XOR_REG_LSL_IMM5(gd, gd, ed, 0);
|
||||
}
|
||||
emit_add32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_add32(dyn, ninst, ed, gd, x3, x14);
|
||||
WBACK;
|
||||
break;
|
||||
case 0xC2:
|
||||
@@ -2051,7 +2005,7 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV_REG(xEDX, x2);
|
||||
MOVW(x1, 0);
|
||||
MARK3;
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
BFI(xFlags, x1, F_ZF, 1);
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
@@ -2207,7 +2161,39 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETEM(v1);
|
||||
VRHADD_U8(v0, v0, v1);
|
||||
break;
|
||||
|
||||
case 0xE1:
|
||||
INST_NAME("PSRAW Gm,Em");
|
||||
nextop = F8;
|
||||
GETGM(d0);
|
||||
GETEM(d1);
|
||||
v0 = fpu_get_scratch_quad(dyn);
|
||||
VMOVD(v0, d1);
|
||||
VMOVD(v0+1, d1);
|
||||
VQMOVN_S64(v0, v0); // 2*d1 in 32bits now
|
||||
VMOVD(v0+1, v0);
|
||||
VQMOVN_S32(v0, v0); // 4*d1 in 16bits now
|
||||
VNEGN_16(v0, v0); // because we want SHR and not SHL
|
||||
VSHL_S16(d0, d0, v0);
|
||||
break;
|
||||
case 0xE2:
|
||||
INST_NAME("PSRAD Gm,Em");
|
||||
nextop = F8;
|
||||
GETGM(d0);
|
||||
GETEM(d1);
|
||||
v0 = fpu_get_scratch_quad(dyn);
|
||||
VMOVD(v0, d1);
|
||||
VMOVD(v0+1, d1);
|
||||
VQMOVN_S64(v0, v0); // 2*q1 in 32bits now
|
||||
VNEGN_32(v0, v0); // because we want SHR and not SHL
|
||||
VSHL_S32(d0, d0, v0);
|
||||
break;
|
||||
case 0xE3:
|
||||
INST_NAME("PAVGW Gm,Em");
|
||||
nextop = F8;
|
||||
GETGM(d0);
|
||||
GETEM(d1);
|
||||
VRHADD_U16(d0, d0, d1);
|
||||
break;
|
||||
case 0xE4:
|
||||
INST_NAME("PMULHUW Gm,Em");
|
||||
nextop = F8;
|
||||
|
||||
@@ -38,41 +38,41 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 0x03:
|
||||
INST_NAME("ADD Gd, FS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x12);
|
||||
emit_add32(dyn, ninst, gd, ed, x3, x12);
|
||||
GETEDO(x14);
|
||||
emit_add32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x2B:
|
||||
INST_NAME("SUB Gd, FS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x12);
|
||||
emit_sub32(dyn, ninst, gd, ed, x3, x12);
|
||||
GETEDO(x14);
|
||||
emit_sub32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x33:
|
||||
INST_NAME("XOR Gd, FS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x12);
|
||||
emit_xor32(dyn, ninst, gd, ed, x3, x12);
|
||||
GETEDO(x14);
|
||||
emit_xor32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x3B:
|
||||
INST_NAME("CMP Gd, FS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x12);
|
||||
emit_cmp32(dyn, ninst, gd, ed, x3, x12);
|
||||
GETEDO(x14);
|
||||
emit_cmp32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
@@ -82,7 +82,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 0x89:
|
||||
INST_NAME("MOV FS:Ew16, Gw");
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
GETGD; // don't need GETGW here
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
@@ -91,33 +91,33 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
}
|
||||
} else {
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
STRH_REG(gd, x12, ed);
|
||||
STRH_REG(gd, x14, ed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, FS:Ew16");
|
||||
nextop=F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(gd, xEAX+(nextop&7));
|
||||
} else { // mem <= reg
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x12, 0);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP FS:Ew16");
|
||||
nextop=F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
POP(xESP, (1<<(xEAX+(nextop&7)))); // 67 ignored
|
||||
POP1(xEAX+(nextop&7)); // 67 ignored
|
||||
} else {
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
|
||||
POP(xESP, (1<<x2));
|
||||
STR_REG_LSL_IMM5(x2, x1, x12, 0);
|
||||
POP1(x2);
|
||||
STR_REG_LSL_IMM5(x2, x1, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -145,7 +145,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 6: // Push Ed
|
||||
INST_NAME("PUSH FS:Ew");
|
||||
@@ -153,8 +153,8 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
DEFAULT;
|
||||
} else { // mem <= i32
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x12, 0);
|
||||
PUSH(xESP, 1<<x3);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
PUSH1(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -168,40 +168,40 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0x89:
|
||||
INST_NAME("MOV FS:Ed, Gd");
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(xEAX+(nextop&7), gd);
|
||||
} else { // mem <= reg
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
STR_REG_LSL_IMM5(gd, ed, x12, 0);
|
||||
STR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, FS:Ed");
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(gd, xEAX+(nextop&7));
|
||||
} else { // mem <= reg
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x12, 0);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP FS:Ed");
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
POP(xESP, (1<<(xEAX+(nextop&7))));
|
||||
POP1(xEAX+(nextop&7));
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
|
||||
POP(xESP, (1<<x2));
|
||||
STR_REG_LSL_IMM5(x2, ed, x12, 0);
|
||||
POP1(x2);
|
||||
STR_REG_LSL_IMM5(x2, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -252,7 +252,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0xC7:
|
||||
INST_NAME("MOV FS:Ed, Id");
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= i32
|
||||
i32 = F32S;
|
||||
@@ -262,7 +262,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
i32 = F32S;
|
||||
MOV32(x3, i32);
|
||||
STR_REG_LSL_IMM5(x3, ed, x12, 0);
|
||||
STR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -274,7 +274,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 2: // CALL Ed
|
||||
INST_NAME("CALL Ed");
|
||||
@@ -287,7 +287,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV_REG(xEIP, xEAX+(nextop&7));
|
||||
} else { // mem
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(xEIP, ed, x12, 0);
|
||||
LDR_REG_LSL_IMM5(xEIP, ed, x14, 0);
|
||||
}
|
||||
BARRIER(1);
|
||||
BARRIER_NEXT(1);
|
||||
@@ -299,7 +299,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
*ok = 0;
|
||||
MOV32(x2, addr);
|
||||
}
|
||||
PUSH(xESP, 1<<x2);
|
||||
PUSH1(x2);
|
||||
jump_to_linker(dyn, 0, xEIP, ninst); // smart linker
|
||||
break;
|
||||
case 6: // Push Ed
|
||||
@@ -308,8 +308,8 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
DEFAULT;
|
||||
} else { // mem <= i32
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x12, 0);
|
||||
PUSH(xESP, 1<<x3);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
PUSH1(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -41,41 +41,41 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 0x03:
|
||||
INST_NAME("ADD Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x12);
|
||||
emit_add32(dyn, ninst, gd, ed, x3, x12);
|
||||
GETEDO(x14);
|
||||
emit_add32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x2B:
|
||||
INST_NAME("SUB Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x12);
|
||||
emit_sub32(dyn, ninst, gd, ed, x3, x12);
|
||||
GETEDO(x14);
|
||||
emit_sub32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x33:
|
||||
INST_NAME("XOR Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x12);
|
||||
emit_xor32(dyn, ninst, gd, ed, x3, x12);
|
||||
GETEDO(x14);
|
||||
emit_xor32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x3B:
|
||||
INST_NAME("CMP Gd, GS:Ed");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
GETEDO(x12);
|
||||
emit_cmp32(dyn, ninst, gd, ed, x3, x12);
|
||||
GETEDO(x14);
|
||||
emit_cmp32(dyn, ninst, gd, ed, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
@@ -88,7 +88,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_add8c(dyn, ninst, x1, u8, x2, x12);
|
||||
emit_add8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK;
|
||||
break;
|
||||
case 1: //OR
|
||||
@@ -97,7 +97,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_or8c(dyn, ninst, x1, u8, x2, x12);
|
||||
emit_or8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK;
|
||||
break;
|
||||
case 2: //ADC
|
||||
@@ -107,7 +107,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_adc8c(dyn, ninst, x1, u8, x2, x12);
|
||||
emit_adc8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK;
|
||||
break;
|
||||
case 3: //SBB
|
||||
@@ -117,7 +117,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_sbb8c(dyn, ninst, x1, u8, x2, x12);
|
||||
emit_sbb8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK;
|
||||
break;
|
||||
case 4: //AND
|
||||
@@ -126,7 +126,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_and8c(dyn, ninst, x1, u8, x2, x12);
|
||||
emit_and8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK;
|
||||
break;
|
||||
case 5: //SUB
|
||||
@@ -135,7 +135,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_sub8c(dyn, ninst, x1, u8, x2, x12);
|
||||
emit_sub8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK;
|
||||
break;
|
||||
case 6: //XOR
|
||||
@@ -144,7 +144,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
grab_tlsdata(dyn, addr, ninst, x1);
|
||||
GETEBO(x1);
|
||||
u8 = F8;
|
||||
emit_xor8c(dyn, ninst, x1, u8, x2, x12);
|
||||
emit_xor8c(dyn, ninst, x1, u8, x2, x14);
|
||||
EBBACK;
|
||||
break;
|
||||
case 7: //CMP
|
||||
@@ -155,9 +155,9 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
u8 = F8;
|
||||
if(u8) {
|
||||
MOVW(x2, u8);
|
||||
emit_cmp8(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp8(dyn, ninst, x1, x2, x3, x14);
|
||||
} else {
|
||||
emit_cmp8_0(dyn, ninst, x1, x3, x12);
|
||||
emit_cmp8_0(dyn, ninst, x1, x3, x14);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -165,40 +165,40 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0x89:
|
||||
INST_NAME("MOV GS:Ed, Gd");
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(xEAX+(nextop&7), gd);
|
||||
} else { // mem <= reg
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
STR_REG_LSL_IMM5(gd, ed, x12, 0);
|
||||
STR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, GS:Ed");
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
MOV_REG(gd, xEAX+(nextop&7));
|
||||
} else { // mem <= reg
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x12, 0);
|
||||
LDR_REG_LSL_IMM5(gd, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP GS:Ed");
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop = F8;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
POP(xESP, (1<<(xEAX+(nextop&7))));
|
||||
POP1((xEAX+(nextop&7)));
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
|
||||
POP(xESP, (1<<x2));
|
||||
STR_REG_LSL_IMM5(x2, ed, x12, 0);
|
||||
POP1(x2);
|
||||
STR_REG_LSL_IMM5(x2, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -226,7 +226,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0xC7:
|
||||
INST_NAME("MOV GS:Ed, Id");
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
nextop=F8;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= i32
|
||||
i32 = F32S;
|
||||
@@ -236,7 +236,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
i32 = F32S;
|
||||
MOV32(x3, i32);
|
||||
STR_REG_LSL_IMM5(x3, ed, x12, 0);
|
||||
STR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -248,7 +248,7 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_tlsdata(dyn, addr, ninst, x12);
|
||||
grab_tlsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 6: // Push Ed
|
||||
INST_NAME("PUSH GS:Ed");
|
||||
@@ -256,8 +256,8 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
DEFAULT;
|
||||
} else { // mem <= i32
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x12, 0);
|
||||
PUSH(xESP, 1<<x3);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
PUSH1(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -47,7 +47,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1);
|
||||
emit_add16(dyn, ninst, x1, x2, x12, x3, (wb1 && (wback==x3))?1:0);
|
||||
emit_add16(dyn, ninst, x1, x2, x14, x3, (wb1 && (wback==x3))?1:0);
|
||||
EWBACK;
|
||||
break;
|
||||
case 0x03:
|
||||
@@ -56,7 +56,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x1);
|
||||
GETEW(x2);
|
||||
emit_add16(dyn, ninst, x1, x2, x3, x12, 0);
|
||||
emit_add16(dyn, ninst, x1, x2, x3, x14, 0);
|
||||
GWBACK;
|
||||
break;
|
||||
case 0x05:
|
||||
@@ -64,7 +64,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
i32 = F16;
|
||||
UXTH(x1, xEAX, 0);
|
||||
emit_add16c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_add16c(dyn, ninst, x1, i32, x3, x14);
|
||||
BFI(xEAX, x1, 0, 16);
|
||||
break;
|
||||
case 0x06:
|
||||
@@ -92,7 +92,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1);
|
||||
emit_or16(dyn, ninst, x1, x2, x12, x3, (wb1 && (wback==x3))?1:0);
|
||||
emit_or16(dyn, ninst, x1, x2, x14, x3, (wb1 && (wback==x3))?1:0);
|
||||
EWBACK;
|
||||
break;
|
||||
case 0x0B:
|
||||
@@ -101,7 +101,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x1);
|
||||
GETEW(x2);
|
||||
emit_or16(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_or16(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
GWBACK;
|
||||
break;
|
||||
case 0x0D:
|
||||
@@ -109,7 +109,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
i32 = F16;
|
||||
UXTH(x1, xEAX, 0);
|
||||
emit_or16c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_or16c(dyn, ninst, x1, i32, x3, x14);
|
||||
BFI(xEAX, x1, 0, 16);
|
||||
break;
|
||||
|
||||
@@ -123,7 +123,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1);
|
||||
emit_adc16(dyn, ninst, x1, x2, x12, x3, (wb1 && (wback==x3))?1:0);
|
||||
emit_adc16(dyn, ninst, x1, x2, x14, x3, (wb1 && (wback==x3))?1:0);
|
||||
EWBACK;
|
||||
break;
|
||||
case 0x13:
|
||||
@@ -133,7 +133,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x1);
|
||||
GETEW(x2);
|
||||
emit_adc16(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_adc16(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
GWBACK;
|
||||
break;
|
||||
case 0x15:
|
||||
@@ -142,7 +142,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
i32 = F16;
|
||||
UXTH(x1, xEAX, 0);
|
||||
emit_adc16c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_adc16c(dyn, ninst, x1, i32, x3, x14);
|
||||
BFI(xEAX, x1, 0, 16);
|
||||
break;
|
||||
|
||||
@@ -153,7 +153,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1);
|
||||
emit_sbb16(dyn, ninst, x1, x2, x12, x3, (wb1 && (wback==x3))?1:0);
|
||||
emit_sbb16(dyn, ninst, x1, x2, x14, x3, (wb1 && (wback==x3))?1:0);
|
||||
EWBACK;
|
||||
break;
|
||||
case 0x1B:
|
||||
@@ -163,7 +163,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x1);
|
||||
GETEW(x2);
|
||||
emit_sbb16(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_sbb16(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
GWBACK;
|
||||
break;
|
||||
case 0x1D:
|
||||
@@ -172,7 +172,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
i16 = F16;
|
||||
UXTH(x1, xEAX, 0);
|
||||
emit_sbb16c(dyn, ninst, x1, i16, x3, x12);
|
||||
emit_sbb16c(dyn, ninst, x1, i16, x3, x14);
|
||||
BFI(xEAX, x1, 0, 16);
|
||||
break;
|
||||
|
||||
@@ -182,7 +182,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1);
|
||||
emit_and16(dyn, ninst, x1, x2, x12, x3, (wb1 && (wback==x3))?1:0);
|
||||
emit_and16(dyn, ninst, x1, x2, x14, x3, (wb1 && (wback==x3))?1:0);
|
||||
EWBACK;
|
||||
break;
|
||||
case 0x23:
|
||||
@@ -191,7 +191,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x1);
|
||||
GETEW(x2);
|
||||
emit_and16(dyn, ninst, x1, x2, x3, x12, 0);
|
||||
emit_and16(dyn, ninst, x1, x2, x3, x14, 0);
|
||||
GWBACK;
|
||||
break;
|
||||
case 0x25:
|
||||
@@ -199,7 +199,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
i32 = F16;
|
||||
UXTH(x1, xEAX, 0);
|
||||
emit_and16c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_and16c(dyn, ninst, x1, i32, x3, x14);
|
||||
BFI(xEAX, x1, 0, 16);
|
||||
break;
|
||||
case 0x26:
|
||||
@@ -213,7 +213,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1);
|
||||
emit_sub16(dyn, ninst, x1, x2, x12, x3, (wb1 && (wback==x3))?1:0);
|
||||
emit_sub16(dyn, ninst, x1, x2, x14, x3, (wb1 && (wback==x3))?1:0);
|
||||
EWBACK;
|
||||
break;
|
||||
case 0x2B:
|
||||
@@ -222,7 +222,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x1);
|
||||
GETEW(x2);
|
||||
emit_sub16(dyn, ninst, x1, x2, x3, x12, 0);
|
||||
emit_sub16(dyn, ninst, x1, x2, x3, x14, 0);
|
||||
GWBACK;
|
||||
break;
|
||||
case 0x2D:
|
||||
@@ -230,7 +230,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
i32 = F16;
|
||||
UXTH(x1, xEAX, 0);
|
||||
emit_sub16c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_sub16c(dyn, ninst, x1, i32, x3, x14);
|
||||
BFI(xEAX, x1, 0, 16);
|
||||
break;
|
||||
|
||||
@@ -240,7 +240,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1);
|
||||
emit_xor16(dyn, ninst, x1, x2, x12, x3, (wb1 && (wback==x3))?1:0);
|
||||
emit_xor16(dyn, ninst, x1, x2, x14, x3, (wb1 && (wback==x3))?1:0);
|
||||
EWBACK;
|
||||
break;
|
||||
case 0x33:
|
||||
@@ -249,7 +249,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x1);
|
||||
GETEW(x2);
|
||||
emit_xor16(dyn, ninst, x1, x2, x3, x12, 0);
|
||||
emit_xor16(dyn, ninst, x1, x2, x3, x14, 0);
|
||||
GWBACK;
|
||||
break;
|
||||
case 0x35:
|
||||
@@ -257,7 +257,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
i32 = F16;
|
||||
UXTH(x1, xEAX, 0);
|
||||
emit_xor16c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_xor16c(dyn, ninst, x1, i32, x3, x14);
|
||||
BFI(xEAX, x1, 0, 16);
|
||||
break;
|
||||
|
||||
@@ -267,7 +267,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x2);
|
||||
GETEW(x1);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
case 0x3B:
|
||||
INST_NAME("CMP Gw, Ew");
|
||||
@@ -275,7 +275,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETGW(x1);
|
||||
GETEW(x2);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
case 0x3D:
|
||||
INST_NAME("CMP AX, Iw");
|
||||
@@ -283,7 +283,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
i32 = F16;
|
||||
MOVW(x2, i32);
|
||||
UXTH(x1, xEAX, 0);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
@@ -298,7 +298,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
|
||||
gd = xEAX+(opcode&7);
|
||||
UXTH(x1, gd, 0);
|
||||
emit_inc16(dyn, ninst, x1, x3, x12);
|
||||
emit_inc16(dyn, ninst, x1, x3, x14);
|
||||
BFI(gd, x1, 0, 16);
|
||||
break;
|
||||
case 0x48:
|
||||
@@ -313,7 +313,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
|
||||
gd = xEAX+(opcode&7);
|
||||
UXTH(x1, gd, 0);
|
||||
emit_dec16(dyn, ninst, x1, x3, x12);
|
||||
emit_dec16(dyn, ninst, x1, x3, x14);
|
||||
BFI(gd, x1, 0, 16);
|
||||
break;
|
||||
case 0x50:
|
||||
@@ -420,7 +420,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEW(x1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_add16c(dyn, ninst, ed, i16, x2, x12);
|
||||
emit_add16c(dyn, ninst, ed, i16, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 1: //OR
|
||||
@@ -428,7 +428,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEW(x1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_or16c(dyn, ninst, x1, i16, x2, x12);
|
||||
emit_or16c(dyn, ninst, x1, i16, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 2: //ADC
|
||||
@@ -437,7 +437,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEW(x1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_adc16c(dyn, ninst, x1, i16, x2, x12);
|
||||
emit_adc16c(dyn, ninst, x1, i16, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 3: //SBB
|
||||
@@ -446,7 +446,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEW(x1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_sbb16c(dyn, ninst, x1, i16, x2, x12);
|
||||
emit_sbb16c(dyn, ninst, x1, i16, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 4: //AND
|
||||
@@ -454,7 +454,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEW(x1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_and16c(dyn, ninst, x1, i16, x2, x12);
|
||||
emit_and16c(dyn, ninst, x1, i16, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 5: //SUB
|
||||
@@ -462,7 +462,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEW(x1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_sub16c(dyn, ninst, x1, i16, x2, x12);
|
||||
emit_sub16c(dyn, ninst, x1, i16, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 6: //XOR
|
||||
@@ -470,7 +470,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEW(x1);
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
emit_xor16c(dyn, ninst, x1, i16, x2, x12);
|
||||
emit_xor16c(dyn, ninst, x1, i16, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 7: //CMP
|
||||
@@ -480,9 +480,9 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if(opcode==0x81) i16 = F16S; else i16 = F8S;
|
||||
if(i16) {
|
||||
MOVW(x2, i16);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x14);
|
||||
} else
|
||||
emit_cmp16_0(dyn, ninst, x1, x3, x12);
|
||||
emit_cmp16_0(dyn, ninst, x1, x3, x14);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -493,7 +493,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
nextop = F8;
|
||||
GETEW(x1);
|
||||
GETGW(x2);
|
||||
emit_test16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_test16(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
|
||||
case 0x89:
|
||||
@@ -580,23 +580,24 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 0x99:
|
||||
INST_NAME("CWD");
|
||||
SXTH(x1, xEAX, 0);
|
||||
BFI(xEDX, x1, 16, 16);
|
||||
MOV_REG_LSR_IMM5(x1, x1, 16);
|
||||
BFI(xEDX, x1, 0, 16);
|
||||
break;
|
||||
|
||||
case 0x9C:
|
||||
INST_NAME("PUSHF (16b)");
|
||||
READFLAGS(X_ALL);
|
||||
CALL(PackFlags, -1, 0);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, packed_eflags.x32));
|
||||
STRHB_IMM8(x1, xESP, -2);
|
||||
STRHB_IMM8(xFlags, xESP, -2);
|
||||
break;
|
||||
case 0x9D:
|
||||
INST_NAME("POPF (16b)");
|
||||
SETFLAGS(X_ALL, SF_SET); // lower 16bits is all flags handled in dynarec
|
||||
LDRHA_IMM8(x1, xESP, 2);
|
||||
CALL(arm_popf16, -1, 0);
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
LDRHA_IMM8(x2, xESP, 2);
|
||||
MOV32(x1, 0x7FD7);
|
||||
AND_REG_LSL_IMM5(x2, x2, x1, 0);
|
||||
ORR_IMM8(x2, x2, 2, 0);
|
||||
BFI(xFlags, x2, 0, 16);
|
||||
SET_DFNONE(x1);
|
||||
break;
|
||||
|
||||
case 0xA1:
|
||||
@@ -633,7 +634,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
u16 = F16;
|
||||
MOVW(x2, u16);
|
||||
UBFX(x1, xEAX, 0, 16);
|
||||
emit_test16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_test16(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
|
||||
case 0xAB:
|
||||
@@ -818,15 +819,15 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 6:
|
||||
if(opcode==0xD1) {
|
||||
INST_NAME("SHL Ew, 1");
|
||||
MOVW(x12, 1);
|
||||
MOVW(x14, 1);
|
||||
} else {
|
||||
INST_NAME("SHL Ew, CL");
|
||||
AND_IMM8(x12, xECX, 0x1f);
|
||||
AND_IMM8(x14, xECX, 0x1f);
|
||||
}
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
GETEW(x1);
|
||||
UFLAG_OP12(ed, x12)
|
||||
MOV_REG_LSL_REG(ed, ed, x12);
|
||||
UFLAG_OP12(ed, x14)
|
||||
MOV_REG_LSL_REG(ed, ed, x14);
|
||||
EWBACK;
|
||||
UFLAG_RES(ed);
|
||||
UFLAG_DF(x3, d_shl16);
|
||||
@@ -834,15 +835,15 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 5:
|
||||
if(opcode==0xD1) {
|
||||
INST_NAME("SHR Ew, 1");
|
||||
MOVW(x12, 1);
|
||||
MOVW(x14, 1);
|
||||
} else {
|
||||
INST_NAME("SHR Ew, CL");
|
||||
AND_IMM8(x12, xECX, 0x1f);
|
||||
AND_IMM8(x14, xECX, 0x1f);
|
||||
}
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
GETEW(x1);
|
||||
UFLAG_OP12(ed, x12)
|
||||
MOV_REG_LSR_REG(ed, ed, x12);
|
||||
UFLAG_OP12(ed, x14)
|
||||
MOV_REG_LSR_REG(ed, ed, x14);
|
||||
EWBACK;
|
||||
UFLAG_RES(ed);
|
||||
UFLAG_DF(x3, d_shr16);
|
||||
@@ -850,15 +851,15 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 7:
|
||||
if(opcode==0xD1) {
|
||||
INST_NAME("SAR Ew, 1");
|
||||
MOVW(x12, 1);
|
||||
MOVW(x14, 1);
|
||||
} else {
|
||||
INST_NAME("SAR Ew, CL");
|
||||
AND_IMM8(x12, xECX, 0x1f);
|
||||
AND_IMM8(x14, xECX, 0x1f);
|
||||
}
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
GETSEW(x1);
|
||||
UFLAG_OP12(ed, x12)
|
||||
MOV_REG_ASR_REG(ed, ed, x12);
|
||||
UFLAG_OP12(ed, x14)
|
||||
MOV_REG_ASR_REG(ed, ed, x14);
|
||||
EWBACK;
|
||||
UFLAG_RES(ed);
|
||||
UFLAG_DF(x3, d_sar16);
|
||||
@@ -916,7 +917,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MARK2;
|
||||
SUB_IMM8(xECX, xECX, 1);
|
||||
MARK3;
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
|
||||
case 0xAB:
|
||||
@@ -952,7 +953,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MARK2;
|
||||
SUB_IMM8(xECX, xECX, 1);
|
||||
MARK3;
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp16(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
@@ -969,7 +970,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETEW(x1);
|
||||
u16 = F16;
|
||||
MOVW(x2, u16);
|
||||
emit_test16(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_test16(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("NOT Ew");
|
||||
@@ -981,7 +982,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
INST_NAME("NEG Ew");
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEW(x1);
|
||||
emit_neg16(dyn, ninst, ed, x2, x12);
|
||||
emit_neg16(dyn, ninst, ed, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 4:
|
||||
@@ -1026,23 +1027,19 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
i32 = dyn->state_flags; //TODO: find a better way to do this
|
||||
SETFLAGS(X_CF, SF_SUBSET);
|
||||
if(i32!=SF_SET) {
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
} else {
|
||||
MOVW(x1, 0);
|
||||
}
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
SET_DFNONE(x1);
|
||||
}
|
||||
BFC(xFlags, F_CF, 1);
|
||||
break;
|
||||
case 0xF9:
|
||||
INST_NAME("STC");
|
||||
i32 = dyn->state_flags; //TODO: find a better way to do this
|
||||
SETFLAGS(X_CF, SF_SUBSET);
|
||||
if(i32!=SF_SET) {
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DFNONE(x1);
|
||||
}
|
||||
MOVW(x1, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, x1, F_CF, 1);
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
@@ -1052,14 +1049,14 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
INST_NAME("INC Ew");
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
|
||||
GETEW(x1);
|
||||
emit_inc16(dyn, ninst, x1, x2, x12);
|
||||
emit_inc16(dyn, ninst, x1, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("DEC Ew");
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SET);
|
||||
GETEW(x1);
|
||||
emit_dec16(dyn, ninst, x1, x2, x12);
|
||||
emit_dec16(dyn, ninst, x1, x2, x14);
|
||||
EWBACK;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -107,8 +107,16 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
DEFAULT;
|
||||
return addr;
|
||||
}
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3);
|
||||
VLDR_64(v0, ed, fixedaddress);
|
||||
parity = getedparity(dyn, ninst, addr, nextop, 3);
|
||||
if(parity) {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3);
|
||||
VLDR_64(v0, ed, fixedaddress);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-8, 0);
|
||||
LDR_IMM9(x2, ed, fixedaddress);
|
||||
LDR_IMM9(x3, ed, fixedaddress+4);
|
||||
VMOVtoV_D(v0, x2, x3);
|
||||
}
|
||||
break;
|
||||
case 0x13:
|
||||
INST_NAME("MOVLPD Eq, Gx");
|
||||
@@ -457,107 +465,93 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
|
||||
case 0x40:
|
||||
INST_NAME("CMOVO Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_OF)
|
||||
GO( TSTS_IMM8_ROR(xFlags, 0b10, 0x0b)
|
||||
, cEQ, cNE, X_OF)
|
||||
break;
|
||||
case 0x41:
|
||||
INST_NAME("CMOVNO Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_OF)
|
||||
GO( TSTS_IMM8_ROR(xFlags, 0b10, 0x0b)
|
||||
, cNE, cEQ, X_OF)
|
||||
break;
|
||||
case 0x42:
|
||||
INST_NAME("CMOVC Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_CF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_CF)
|
||||
, cEQ, cNE, X_CF)
|
||||
break;
|
||||
case 0x43:
|
||||
INST_NAME("CMOVNC Gw, Ew");
|
||||
GO( LDR_IMM9(2, 0, offsetof(x86emu_t, flags[F_CF]));
|
||||
CMPS_IMM8(2, 1)
|
||||
, cEQ, cNE, X_CF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_CF)
|
||||
, cNE, cEQ, X_CF)
|
||||
break;
|
||||
case 0x44:
|
||||
INST_NAME("CMOVZ Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_ZF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_ZF)
|
||||
, cEQ, cNE, X_ZF)
|
||||
break;
|
||||
case 0x45:
|
||||
INST_NAME("CMOVNZ Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_ZF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_ZF)
|
||||
, cNE, cEQ, X_ZF)
|
||||
break;
|
||||
case 0x46:
|
||||
INST_NAME("CMOVBE Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORRS_REG_LSL_IMM5(x2, x2, x3, 0);
|
||||
GO( TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF))
|
||||
, cEQ, cNE, X_CF|X_ZF)
|
||||
break;
|
||||
case 0x47:
|
||||
INST_NAME("CMOVNBE Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORRS_REG_LSL_IMM5(x2, x2, x3, 0);
|
||||
GO( TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF))
|
||||
, cNE, cEQ, X_CF|X_ZF)
|
||||
break;
|
||||
case 0x48:
|
||||
INST_NAME("CMOVS Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_SF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_SF)
|
||||
, cEQ, cNE, X_SF)
|
||||
break;
|
||||
case 0x49:
|
||||
INST_NAME("CMOVNS Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_SF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_SF)
|
||||
, cNE, cEQ, X_SF)
|
||||
break;
|
||||
case 0x4A:
|
||||
INST_NAME("CMOVP Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cNE, cEQ, X_PF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_PF)
|
||||
, cEQ, cNE, X_PF)
|
||||
break;
|
||||
case 0x4B:
|
||||
INST_NAME("CMOVNP Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
CMPS_IMM8(x2, 1)
|
||||
, cEQ, cNE, X_PF)
|
||||
GO( TSTS_IMM8(xFlags, 1<<F_PF)
|
||||
, cNE, cEQ, X_PF)
|
||||
break;
|
||||
case 0x4C:
|
||||
INST_NAME("CMOVL Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
CMPS_REG_LSL_IMM5(x1, x2, 0)
|
||||
, cEQ, cNE, X_OF|X_SF)
|
||||
break;
|
||||
case 0x4D:
|
||||
INST_NAME("CMOVGE Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
CMPS_REG_LSL_IMM5(x1, x2, 0)
|
||||
, cNE, cEQ, X_OF|X_SF)
|
||||
break;
|
||||
case 0x4E:
|
||||
INST_NAME("CMOVLE Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
UBFX(x2, xFlags, F_ZF, 1);
|
||||
ORRS_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
, cEQ, cNE, X_OF|X_SF|X_ZF)
|
||||
break;
|
||||
case 0x4F:
|
||||
INST_NAME("CMOVG Gw, Ew");
|
||||
GO( LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
GO( UBFX(x2, xFlags, F_SF, 1);
|
||||
UBFX(x1, xFlags, F_OF, 1);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
UBFX(x2, xFlags, F_ZF, 1);
|
||||
ORRS_REG_LSL_IMM5(x2, x1, x2, 0);
|
||||
, cNE, cEQ, X_OF|X_SF|X_ZF)
|
||||
break;
|
||||
@@ -1186,8 +1180,7 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
GETEW(x1);
|
||||
AND_IMM8(x2, gd, 15);
|
||||
MOV_REG_LSR_REG(x1, ed, x2);
|
||||
AND_IMM8(x1, x1, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, x1, F_CF, 1);
|
||||
break;
|
||||
case 0xA4:
|
||||
case 0xA5:
|
||||
@@ -1199,7 +1192,7 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
UXTB(x3, xECX, 0);
|
||||
}
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEWW(x12, x1);
|
||||
GETEWW(x14, x1);
|
||||
GETGW(x2);
|
||||
if(opcode==0xA4) {
|
||||
u8 = F8;
|
||||
@@ -1214,11 +1207,11 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
SETFLAGS(X_CF, SF_SET);
|
||||
nextop = F8;
|
||||
GETGD; // there is an AND below, to 32bits is the same
|
||||
GETEW(x12);
|
||||
GETEW(x14);
|
||||
AND_IMM8(x2, gd, 15);
|
||||
MOV_REG_LSR_REG(x1, ed, x2);
|
||||
ANDS_IMM8(x1, x1, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, x1, F_CF, 1);
|
||||
B_NEXT(cNE);
|
||||
MOVW(x1, 1);
|
||||
ORR_REG_LSL_REG(ed, ed, x1, x2);
|
||||
@@ -1234,7 +1227,7 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
UXTB(x3, xECX, 0);
|
||||
}
|
||||
SETFLAGS(X_ALL, SF_SET);
|
||||
GETEWW(x12, x1);
|
||||
GETEWW(x14, x1);
|
||||
GETGW(x2);
|
||||
if(opcode==0xAC) {
|
||||
u8 = F8;
|
||||
@@ -1267,11 +1260,11 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
SETFLAGS(X_CF, SF_SET);
|
||||
nextop = F8;
|
||||
GETGD; // there is an AND below, to 32bits is the same
|
||||
GETEW(x12);
|
||||
GETEW(x14);
|
||||
AND_IMM8(x2, gd, 15);
|
||||
MOV_REG_LSR_REG(x1, ed, x2);
|
||||
ANDS_IMM8(x1, x1, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, x1, F_CF, 1);
|
||||
B_NEXT(cEQ);
|
||||
MOVW(x1, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x1, x2);
|
||||
@@ -1312,11 +1305,10 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
SETFLAGS(X_CF, SF_SET);
|
||||
nextop = F8;
|
||||
GETGD; // there is an AND below, to 32bits is the same
|
||||
GETEW(x12);
|
||||
GETEW(x14);
|
||||
AND_IMM8(x2, gd, 15);
|
||||
MOV_REG_LSR_REG(x1, ed, x2);
|
||||
AND_IMM8(x1, x1, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, x1, F_CF, 1);
|
||||
MOVW(x1, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x1, x2);
|
||||
EWBACK;
|
||||
@@ -1334,9 +1326,8 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
BFI(xEAX+((nextop&0x38)>>3), x2, 0, 16);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x1, 0); //ZF not set
|
||||
MARK;
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
BFI(xFlags, x1, F_ZF, 1);
|
||||
SET_DFNONE(x1);
|
||||
break;
|
||||
case 0xBD:
|
||||
INST_NAME("BSR Ew,Gw");
|
||||
@@ -1352,9 +1343,8 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
BFI(xEAX+((nextop&0x38)>>3), x2, 0, 16);
|
||||
XOR_REG_LSL_IMM5(x1, x1, x1, 0); //ZF not set
|
||||
MARK;
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
BFI(xFlags, x1, F_ZF, 1);
|
||||
SET_DFNONE(x1);
|
||||
break;
|
||||
case 0xBE:
|
||||
INST_NAME("MOVSX Gw, Eb");
|
||||
@@ -1460,6 +1450,14 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xD0:
|
||||
INST_NAME("ADDSUBPD Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGX(v0);
|
||||
GETEX(v1);
|
||||
VSUB_F64(v0+0, v0+0, v1+0);
|
||||
VADD_F64(v0+1, v0+1, v1+1);
|
||||
break;
|
||||
case 0xD1:
|
||||
INST_NAME("PSRLW Gx,Ex");
|
||||
nextop = F8;
|
||||
|
||||
@@ -45,7 +45,7 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 0x89:
|
||||
INST_NAME("MOV FS:Ew16, Gw");
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
GETGD; // don't need GETGW here
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
@@ -54,14 +54,14 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
}
|
||||
} else {
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
STRH_REG(gd, x12, ed);
|
||||
STRH_REG(gd, x14, ed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8B:
|
||||
INST_NAME("MOV Gd, FS:Ew16");
|
||||
nextop=F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) { // reg <= reg
|
||||
ed = xEAX+(nextop&7);
|
||||
@@ -70,20 +70,20 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
}
|
||||
} else { // mem <= reg
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(gd, x12, ed, 0);
|
||||
LDR_REG_LSL_IMM5(gd, x14, ed, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8F:
|
||||
INST_NAME("POP FS:Ew16");
|
||||
nextop=F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
POP(xESP, (1<<(xEAX+(nextop&7)))); // 67 ignored
|
||||
POP1(xEAX+(nextop&7)); // 67 ignored
|
||||
} else {
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
|
||||
POP(xESP, (1<<x2));
|
||||
STR_REG_LSL_IMM5(x2, x12, ed, 0);
|
||||
POP1(x2);
|
||||
STR_REG_LSL_IMM5(x2, x14, ed, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -111,7 +111,7 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
|
||||
case 0xFF:
|
||||
nextop = F8;
|
||||
grab_fsdata(dyn, addr, ninst, x12);
|
||||
grab_fsdata(dyn, addr, ninst, x14);
|
||||
switch((nextop>>3)&7) {
|
||||
case 6: // Push Ed
|
||||
INST_NAME("PUSH FS:Ew");
|
||||
@@ -119,8 +119,8 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
DEFAULT;
|
||||
} else { // mem <= i32
|
||||
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x12, 0);
|
||||
PUSH(xESP, 1<<x3);
|
||||
LDR_REG_LSL_IMM5(x3, ed, x14, 0);
|
||||
PUSH1(x3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -155,8 +155,7 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SUBS_IMM8(x1, x1, 1);
|
||||
BFI(xECX, x1, 0, 16);
|
||||
B_NEXT(cEQ); // CX is 0, no LOOP
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
TSTS_IMM8(xFlags, 1<<F_ZF);
|
||||
GO(cNE, cEQ);
|
||||
break;
|
||||
case 0xE1:
|
||||
@@ -167,8 +166,7 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SUBS_IMM8(x1, x1, 1);
|
||||
BFI(xECX, x1, 0, 16);
|
||||
B_NEXT(cEQ); // CX is 0, no LOOP
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
TSTS_IMM8(xFlags, 1<<F_ZF);
|
||||
GO(cEQ, cNE);
|
||||
break;
|
||||
case 0xE2:
|
||||
|
||||
@@ -23,13 +23,13 @@
|
||||
#include "dynarec_arm_functions.h"
|
||||
#include "dynarec_arm_helper.h"
|
||||
|
||||
static double d_1 = 1.0;
|
||||
static double d_l2t = L2T;
|
||||
static double d_l2e = L2E;
|
||||
static double d_pi = PI;
|
||||
static double d_lg2 = LG2;
|
||||
static double d_ln2 = LN2;
|
||||
static double d_0 = 0.0;
|
||||
static const double d_1 = 1.0;
|
||||
static const double d_l2t = L2T;
|
||||
static const double d_l2e = L2E;
|
||||
static const double d_pi = PI;
|
||||
static const double d_lg2 = LG2;
|
||||
static const double d_ln2 = LN2;
|
||||
static const double d_0 = 0.0;
|
||||
|
||||
uintptr_t dynarecD9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
|
||||
{
|
||||
|
||||
@@ -54,8 +54,7 @@ uintptr_t dynarecDA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
READFLAGS(X_CF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
TSTS_IMM8(xFlags, 1<<F_CF);
|
||||
VMOVcond_64(cNE, v1, v2); // F_CF==1
|
||||
break;
|
||||
case 0xC8:
|
||||
@@ -70,8 +69,7 @@ uintptr_t dynarecDA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
READFLAGS(X_ZF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
TSTS_IMM8(xFlags, 1<<F_ZF);
|
||||
VMOVcond_64(cNE, v1, v2); // F_ZF==1
|
||||
break;
|
||||
case 0xD0:
|
||||
@@ -86,9 +84,7 @@ uintptr_t dynarecDA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
READFLAGS(X_CF|X_ZF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
ORRS_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF));
|
||||
VMOVcond_64(cNE, v1, v2); // F_CF==1 | F_ZF==1
|
||||
break;
|
||||
case 0xD8:
|
||||
@@ -103,8 +99,7 @@ uintptr_t dynarecDA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
READFLAGS(X_PF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
TSTS_IMM8(xFlags, 1<<F_PF);
|
||||
VMOVcond_64(cNE, v1, v2); // F_PF==1
|
||||
break;
|
||||
case 0xE9:
|
||||
|
||||
@@ -52,8 +52,7 @@ uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
READFLAGS(X_CF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
TSTS_IMM8(xFlags, 1<<F_CF);
|
||||
VMOVcond_64(cEQ, v1, v2); // F_CF==0
|
||||
break;
|
||||
case 0xC8:
|
||||
@@ -68,8 +67,7 @@ uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
READFLAGS(X_ZF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
TSTS_IMM8(xFlags, 1<<F_ZF);
|
||||
VMOVcond_64(cEQ, v1, v2); // F_ZF==0
|
||||
break;
|
||||
case 0xD0:
|
||||
@@ -84,10 +82,8 @@ uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
READFLAGS(X_CF|X_ZF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
LDR_IMM9(x2, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
ORRS_REG_LSL_IMM5(x1, x1, x2, 0);
|
||||
VMOVcond_64(cEQ, v1, v2); // F_CF==0 | F_ZF==0
|
||||
TSTS_IMM8(xFlags, (1<<F_CF)|(1<<F_ZF));
|
||||
VMOVcond_64(cEQ, v1, v2); // F_CF==0 & F_ZF==0
|
||||
break;
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
@@ -101,8 +97,7 @@ uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
READFLAGS(X_PF);
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
TSTS_REG_LSL_IMM5(x1, x1, 0);
|
||||
TSTS_IMM8(xFlags, 1<<F_PF);
|
||||
VMOVcond_64(cEQ, v1, v2); // F_PF==0
|
||||
break;
|
||||
case 0xE1:
|
||||
@@ -110,8 +105,8 @@ uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
break;
|
||||
case 0xE2:
|
||||
INST_NAME("FNCLEX");
|
||||
MOVW(x1, 0);
|
||||
LDRH_IMM8(x2, xEmu, offsetof(x86emu_t, sw));
|
||||
MOVW(x1, 0);
|
||||
BFI(x2, x1, 0, 8); // IE .. PE, SF, ES
|
||||
BFI(x2, x1, 15, 1); // B
|
||||
STRH_IMM8(x2, xEmu, offsetof(x86emu_t, sw));
|
||||
@@ -188,8 +183,8 @@ uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
}
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
MSR_nzcvq_0();
|
||||
VMRS(x12); // Get FPCSR reg to clear exceptions flags
|
||||
ORR_IMM8(x3, x12, 0b001, 6); // enable exceptions
|
||||
VMRS(x14); // Get FPCSR reg to clear exceptions flags
|
||||
ORR_IMM8(x3, x14, 0b001, 6); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
VCVT_S32_F64(s0, v1);
|
||||
@@ -198,13 +193,13 @@ uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
TSTS_IMM8_ROR(x3, 0b00000001, 0);
|
||||
MOV_IMM_COND(cNE, ed, 0b10, 1); // 0x80000000
|
||||
WBACK;
|
||||
VMSR(x12); // put back values
|
||||
VMSR(x14); // put back values
|
||||
x87_do_pop(dyn, ninst);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FIST Ed, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x12); // x1 have the modified RPSCR reg
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x14); // x1 have the modified RPSCR reg
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
wback = 0;
|
||||
@@ -229,7 +224,7 @@ uintptr_t dynarecDB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 3:
|
||||
INST_NAME("FISTP Ed, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x12); // x1 have the modified RPSCR reg
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x14); // x1 have the modified RPSCR reg
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
wback = 0;
|
||||
|
||||
@@ -210,7 +210,7 @@ uintptr_t dynarecDD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 7:
|
||||
INST_NAME("FNSTSW m2byte");
|
||||
fpu_purgecache(dyn, ninst, x1, x2, x3);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x12, &fixedaddress, 0, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x14, &fixedaddress, 0, 0);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, top));
|
||||
MOVW(x2, offsetof(x86emu_t, sw));
|
||||
ADD_REG_LSL_IMM5(x2, xEmu, x2, 0);
|
||||
|
||||
@@ -155,8 +155,9 @@ uintptr_t dynarecDF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
ed = x1;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
MSR_nzcvq_0();
|
||||
VMRS(x14); // get fpscr
|
||||
// x1 already have FPCSR reg to clear exceptions flags
|
||||
ORR_IMM8(x3, x1, 0b001, 6); // enable exceptions
|
||||
ORR_IMM8(x3, x14, 0b001, 6); // enable exceptions
|
||||
BIC_IMM8(x3, x3, 0b10011111, 0);
|
||||
VMSR(x3);
|
||||
VCVTR_S32_F64(s0, v1);
|
||||
@@ -168,11 +169,12 @@ uintptr_t dynarecDF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOVW_COND(cNE, x3, 0x8000); // saturated
|
||||
STRH_IMM8(x3, wback, fixedaddress);
|
||||
x87_do_pop(dyn, ninst);
|
||||
VMSR(x14);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("FIST Ew, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x12);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x14);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 255, 0);
|
||||
ed = x1;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
@@ -194,7 +196,7 @@ uintptr_t dynarecDF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
case 3:
|
||||
INST_NAME("FISTP Ew, ST0");
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x12);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x14);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 255, 0);
|
||||
ed = x1;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
+409
-626
File diff suppressed because it is too large.
Load diff
@@ -30,17 +30,13 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s4, d_shl32);
|
||||
SET_DF(s4, d_shl32);
|
||||
} else IFX(X_ALL) {
|
||||
MOVW(s4, d_none);
|
||||
}
|
||||
IFX(X_PEND|X_ALL) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c==0) {
|
||||
IFX(F_OF) {
|
||||
MOVW(s4, 0);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BIC_IMM8(xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
@@ -48,10 +44,8 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
return;
|
||||
}
|
||||
IFX(X_CF) {
|
||||
if(c<31) {
|
||||
UBFX(s3, s1, 32-c, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
}
|
||||
MOV_REG_LSR_IMM5(s3, s1, 32-c);
|
||||
BFI(xFlags, s3, F_CF, 1);
|
||||
}
|
||||
IFX(X_ZF|X_OF) {
|
||||
MOVS_REG_LSL_IMM5(s1, s1, c);
|
||||
@@ -62,22 +56,20 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW_COND(cNE, s3, 0);
|
||||
MOVW_COND(cEQ, s3, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s3, s1, 31, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
IFX(X_SF) {} else {UBFX(s3, s1, 31, 1);}
|
||||
IFX(X_SF) {} else {MOV_REG_LSR_IMM5(s3, s1, 31);}
|
||||
XOR_IMM8_COND(cCS, s3, s3, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFI(xFlags, s3, F_OF, 1);
|
||||
} else {
|
||||
MOVW(s4, 0);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
@@ -87,8 +79,7 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s1, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,12 +90,9 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s4, d_shr32);
|
||||
SET_DF(s4, d_shr32);
|
||||
} else IFX(X_ALL) {
|
||||
MOVW(s4, d_none);
|
||||
}
|
||||
IFX(X_PEND|X_ALL) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
@@ -121,25 +109,22 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW_COND(cNE, s3, 0);
|
||||
MOVW_COND(cEQ, s3, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOVW_COND(cCC, s3, 0);
|
||||
MOVW_COND(cCS, s3, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
ORR_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
BIC_IMM8_COND(cCC, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s3, s1, 31, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 30);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFI(xFlags, s4, F_OF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
@@ -149,8 +134,7 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s1, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,12 +145,9 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s4, d_sar32);
|
||||
SET_DF(s4, d_sar32);
|
||||
} else IFX(X_ALL) {
|
||||
MOVW(s4, d_none);
|
||||
}
|
||||
IFX(X_PEND|X_ALL) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
@@ -183,18 +164,16 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW_COND(cNE, s3, 0);
|
||||
MOVW_COND(cEQ, s3, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOVW_COND(cCC, s3, 0);
|
||||
MOVW_COND(cCS, s3, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
ORR_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
BIC_IMM8_COND(cCC, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s3, s1, 31, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
@@ -203,8 +182,7 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s1, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,12 +192,9 @@ void emit_rol32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s4, d_rol32);
|
||||
SET_DF(s4, d_rol32);
|
||||
} else IFX(X_ALL) {
|
||||
MOVW(s4, d_none);
|
||||
}
|
||||
IFX(X_PEND|X_ALL) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
@@ -232,14 +207,13 @@ void emit_rol32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF) {
|
||||
AND_IMM8(s3, s1, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, s1, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
ADD_REG_LSR_IMM5(s3, s1, s1, 31);
|
||||
AND_IMM8(s3, s3, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFI(xFlags, s3, F_OF, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,12 +224,9 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s4, d_ror32);
|
||||
SET_DF(s4, d_ror32);
|
||||
} else IFX(X_ALL) {
|
||||
MOVW(s4, d_none);
|
||||
}
|
||||
IFX(X_PEND|X_ALL) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
@@ -268,15 +239,141 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_CF) {
|
||||
UBFX(s3, s1, 31, 1);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 30);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFI(xFlags, s4, F_OF, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit SHRD32 instruction, from s1, fill s2 , constant c, store result in s1 using s3 and s4 as scratch
|
||||
void emit_shrd32c(dynarec_arm_t* dyn, int ninst, int s1, int s2, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
// same flags calc as shr32
|
||||
SET_DF(s4, d_shr32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(!c) {
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOVS_REG_LSR_IMM5(s1, s1, c);
|
||||
} else {
|
||||
MOV_REG_LSR_IMM5(s1, s1, c);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
ORR_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
BIC_IMM8_COND(cCC, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORRS_REG_LSL_IMM5(s1, s1, s2, 32-c);
|
||||
} else {
|
||||
ORR_REG_LSL_IMM5(s1, s1, s2, 32-c);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
MOV_REG_LSR_IMM5(s4, s1, 30);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
BFI(xFlags, s4, F_OF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
AND_IMM8(s3, s1, 0xE0); // lsr 5 masking pre-applied
|
||||
LDR_IMM9(s4, xEmu, offsetof(x86emu_t, x86emu_parity_tab));
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s1, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void emit_shld32c(dynarec_arm_t* dyn, int ninst, int s1, int s2, int32_t c, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, c);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
// same flags computation as with shl32
|
||||
SET_DF(s4, d_shl32);
|
||||
} else IFX(X_ALL) {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
if(c==0) {
|
||||
IFX(F_OF) {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
return;
|
||||
}
|
||||
IFX(X_CF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 32-c);
|
||||
BFI(xFlags, s3, F_CF, 1);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
MOVS_REG_LSL_IMM5(s1, s1, c);
|
||||
} else {
|
||||
MOV_REG_LSL_IMM5(s1, s1, c);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
if(c==1) {
|
||||
UBFX(s3, s2, 0, 1);
|
||||
XOR_IMM8_COND(cCS, s3, s3, 1);
|
||||
BFI(xFlags, s3, F_OF, 1);
|
||||
} else {
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORRS_REG_LSR_IMM5(s1, s1, s2, 32-c);
|
||||
} else {
|
||||
ORR_REG_LSR_IMM5(s1, s1, s2, 32-c);
|
||||
}
|
||||
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
MOV_REG_LSR_IMM5(s3, s1, 31);
|
||||
BFI(xFlags, s3, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
AND_IMM8(s3, s1, 0xE0); // lsr 5 masking pre-applied
|
||||
LDR_IMM9(s4, xEmu, offsetof(x86emu_t, x86emu_parity_tab));
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s1, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
@@ -29,40 +29,30 @@ void emit_cmp32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s4, d_cmp32);
|
||||
SET_DF(s4, d_cmp32);
|
||||
} else {
|
||||
MOVW(s4, 0);
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
SUBS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 - s2
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
IFX(X_PEND) {
|
||||
MOVW(s4, 0);
|
||||
}
|
||||
// first the easy flag, also found on ARM
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
IFX(X_ZF|X_PEND) {
|
||||
MOVW(s4, 0);
|
||||
}
|
||||
MOVW_COND(cVS, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
ORR_IMM8_COND(cVS, xFlags, xFlags, 0b10, 0x0b);
|
||||
BIC_IMM8_COND(cVC, xFlags, xFlags, 0b10, 0x0b);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
IFX(X_ZF|X_OF|X_PEND) {
|
||||
MOVW(s4, 0);
|
||||
}
|
||||
MOVW_COND(cCC, s4, 1); // Carry flags on ARM is reversed compared to x86 one
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
// reversed carry
|
||||
ORR_IMM8_COND(cCC, xFlags, xFlags, 1<<F_CF, 0);
|
||||
BIC_IMM8_COND(cCS, xFlags, xFlags, 1<<F_CF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s3, 31, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s3, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// and now the tricky ones (and mostly unused), PF and AF
|
||||
IFX(X_AF) {
|
||||
@@ -73,8 +63,8 @@ void emit_cmp32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
BIC_REG_LSL_IMM5(s3, s2, s1, 0); // loosing res... s3 = s & ~d
|
||||
ORR_REG_LSL_IMM5(s3, s4, s3, 0); // s3 = (res & (~d | s)) | (s & ~d)
|
||||
IFX(X_AF) {
|
||||
UBFX(s4, s3, 3, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_AF])); // AF: bc & 0x08
|
||||
MOV_REG_LSR_IMM5(s4, s3, 3);
|
||||
BFI(xFlags, s4, F_AF, 1); // AF: bc & 0x08
|
||||
}
|
||||
}
|
||||
IFX(X_PF) {
|
||||
@@ -88,47 +78,38 @@ void emit_cmp32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit CMP32 instruction, from cmp s1 , 0, using s3 and s4 as scratch
|
||||
void emit_cmp32_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
{
|
||||
MOVW(s4, 0);
|
||||
IFX(X_PEND) {
|
||||
MOVW(s4, 0);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s4, d_cmp32);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
SET_DF(s4, d_cmp32);
|
||||
} else {
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
SUBS_IMM8(s3, s1, 0); // res = s1 - 0
|
||||
IFX(X_PEND) {
|
||||
IFX(X_ZF|X_OF|X_CF|X_AF) {
|
||||
MOVW(s4, 0);
|
||||
}
|
||||
}
|
||||
// and now the tricky ones (and mostly unused), PF and AF
|
||||
// bc = (res & (~d | s)) | (~d & s) => is 0 here...
|
||||
IFX(X_CF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF])); // CF : bc & 0x80000000
|
||||
}
|
||||
IFX(X_AF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_AF])); // AF: bc & 0x08
|
||||
IFX(X_CF | X_AF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
// first the easy flags, also found on ARM
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s3, 31, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s3, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
IFX(X_PF) {
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
@@ -137,8 +118,7 @@ void emit_cmp32_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s1, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,11 +128,10 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s3, d_cmp16);
|
||||
SET_DF(s3, d_cmp16);
|
||||
} else {
|
||||
MOVW(s3, 0);
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 - s2
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
@@ -160,13 +139,12 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
IFX(X_ZF) {
|
||||
MOVW(s4, 0xffff);
|
||||
TSTS_REG_LSL_IMM5(s3, s4, 0);
|
||||
MOVW_COND(cNE, s4, 0);
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s3, 15, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s3, 15);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// bc = (res & (~d | s)) | (~d & s)
|
||||
IFX(X_CF|X_AF|X_OF) {
|
||||
@@ -176,18 +154,17 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
BIC_REG_LSL_IMM5(s3, s2, s1, 0); // loosing res... s3 = s & ~d
|
||||
ORR_REG_LSL_IMM5(s3, s4, s3, 0); // s3 = (res & (~d | s)) | (s & ~d)
|
||||
IFX(X_CF) {
|
||||
UBFX(s4, s3, 15, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF])); // CF : bc & 0x8000
|
||||
MOV_REG_LSR_IMM5(s4, s3, 15);
|
||||
BFI(xFlags, s4, F_CF, 1); // CF : bc & 0x8000
|
||||
}
|
||||
IFX(X_AF) {
|
||||
UBFX(s4, s3, 3, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_AF])); // AF: bc & 0x08
|
||||
MOV_REG_LSR_IMM5(s4, s3, 3);
|
||||
BFI(xFlags, s4, F_AF, 1); // AF: bc & 0x08
|
||||
}
|
||||
IFX(X_OF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 14);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF])); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1
|
||||
BFI(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1
|
||||
}
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
@@ -201,45 +178,38 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit CMP16 instruction, from cmp s1 , #0, using s3 and s4 as scratch
|
||||
void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
{
|
||||
MOVW(s3, 0);
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
MOVW(s3, 0);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, op2));
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
MOVW(s3, d_cmp16);
|
||||
}
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
IFX(X_OF|X_CF|X_AF) {
|
||||
MOVW(s4, 0);
|
||||
SET_DF(s3, d_cmp16);
|
||||
} else {
|
||||
SET_DFNONE(s3);
|
||||
}
|
||||
// bc = (res & (~d | s)) | (~d & s) = 0
|
||||
IFX(X_CF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF])); // CF : bc & 0x8000
|
||||
}
|
||||
IFX(X_AF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_AF])); // AF: bc & 0x08
|
||||
IFX(X_CF | X_AF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF])); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW(s4, 0xffff);
|
||||
TSTS_REG_LSL_IMM5(s1, s4, 0);
|
||||
MOVW(s4, 0);
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s1, 15, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s1, 15);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_PF) {
|
||||
@@ -248,36 +218,31 @@ void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s1, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
// emit CMP8 instruction, from cmp s1 , s2, using s3 and s4 as scratch
|
||||
void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
IFX(X_PEND) {
|
||||
MOVW(s4, d_cmp8);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, op2));
|
||||
SET_DF(s4, d_cmp8);
|
||||
} else {
|
||||
MOVW(s4, 0);
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 - s2
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
IFX(X_PEND) {
|
||||
MOVW(s4, 0);
|
||||
}
|
||||
TSTS_IMM8(s3, 0xff);
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s3, 7, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s3, 7);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// bc = (res & (~d | s)) | (~d & s)
|
||||
IFX(X_CF|X_AF|X_OF) {
|
||||
@@ -287,18 +252,17 @@ void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
BIC_REG_LSL_IMM5(s3, s2, s1, 0); // loosing res... s3 = s & ~d
|
||||
ORR_REG_LSL_IMM5(s3, s4, s3, 0); // s3 = (res & (~d | s)) | (s & ~d)
|
||||
IFX(X_CF) {
|
||||
UBFX(s4, s3, 7, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF])); // CF : bc & 0x80
|
||||
MOV_REG_LSR_IMM5(s4, s3, 7);
|
||||
BFI(xFlags, s4, F_CF, 1); // CF : bc & 0x80
|
||||
}
|
||||
IFX(X_AF) {
|
||||
UBFX(s4, s3, 3, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_AF])); // AF: bc & 0x08
|
||||
MOV_REG_LSR_IMM5(s4, s3, 3);
|
||||
BFI(xFlags, s4, F_AF, 1); // AF: bc & 0x08
|
||||
}
|
||||
IFX(X_OF) {
|
||||
MOV_REG_LSR_IMM5(s4, s3, 6);
|
||||
XOR_REG_LSR_IMM8(s4, s4, s4, 1);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF])); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
|
||||
BFI(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
|
||||
}
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
@@ -312,41 +276,36 @@ void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
SUB_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
// emit CMP8 instruction, from cmp s1 , 0, using s3 and s4 as scratch
|
||||
void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
{
|
||||
MOVW(s4, 0);
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, d_cmp8);
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, op1));
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
MOVW(s4, 0);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, op2));
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, df));
|
||||
STR_IMM9(s1, xEmu, offsetof(x86emu_t, res));
|
||||
SET_DF(s3, d_cmp8);
|
||||
} else {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
// bc = (res & (~d | s)) | (~d & s) = 0
|
||||
IFX(X_CF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF])); // CF : bc & 0x80
|
||||
}
|
||||
IFX(X_AF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_AF])); // AF: bc & 0x08
|
||||
IFX(X_CF | X_AF) {
|
||||
BIC_IMM8(xFlags, xFlags, (1<<F_CF)|(1<<F_AF), 0);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF])); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
TSTS_IMM8(s1, 0xff);
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s1, 7, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s1, 7);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_PF) {
|
||||
@@ -355,38 +314,35 @@ void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
|
||||
LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer
|
||||
AND_IMM8(s3, s1, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit TEST32 instruction, from test s1 , s2, using s3 and s4 as scratch
|
||||
void emit_test32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
MOVW(s4, 0);
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, d_tst32);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DF(s3, d_tst32);
|
||||
} else {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFC(xFlags, F_CF, 1);
|
||||
}
|
||||
ANDS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 & s2
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s3, 31, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s3, 31);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_PF) {
|
||||
@@ -396,38 +352,35 @@ void emit_test32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
AND_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit TEST16 instruction, from test s1 , s2, using s3 and s4 as scratch
|
||||
void emit_test16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
MOVW(s4, 0);
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, d_tst16);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DF(s3, d_tst16);
|
||||
} else {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFC(xFlags, F_CF, 1);
|
||||
}
|
||||
ANDS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 & s2
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s3, 15, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s3, 15);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_PF) {
|
||||
@@ -437,38 +390,35 @@ void emit_test16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
AND_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// emit TEST8 instruction, from test s1 , s2, using s3 and s4 as scratch
|
||||
void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
{
|
||||
MOVW(s4, 0);
|
||||
IFX(X_PEND) {
|
||||
MOVW(s3, d_tst8);
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, df));
|
||||
SET_DF(s3, d_tst8);
|
||||
} else {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, df)); // reset flags
|
||||
SET_DFNONE(s4);
|
||||
}
|
||||
IFX(X_OF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_OF]));
|
||||
BFC(xFlags, F_OF, 1);
|
||||
}
|
||||
IFX(X_CF) {
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFC(xFlags, F_CF, 1);
|
||||
}
|
||||
ANDS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 & s2
|
||||
IFX(X_PEND) {
|
||||
STR_IMM9(s3, xEmu, offsetof(x86emu_t, res));
|
||||
}
|
||||
IFX(X_ZF) {
|
||||
MOVW_COND(cEQ, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
BIC_IMM8_COND(cNE, xFlags, xFlags, 1<<F_ZF, 0);
|
||||
}
|
||||
IFX(X_SF) {
|
||||
UBFX(s4, s3, 7, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_SF]));
|
||||
MOV_REG_LSR_IMM5(s4, s3, 7);
|
||||
BFI(xFlags, s4, F_SF, 1);
|
||||
}
|
||||
// PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
|
||||
IFX(X_PF) {
|
||||
@@ -478,7 +428,6 @@ void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
|
||||
AND_REG_LSL_IMM5(s3, s1, s2, 0);
|
||||
AND_IMM8(s3, s3, 31);
|
||||
MVN_REG_LSR_REG(s4, s4, s3);
|
||||
AND_IMM8(s4, s4, 1);
|
||||
STR_IMM9(s4, xEmu, offsetof(x86emu_t, flags[F_PF]));
|
||||
BFI(xFlags, s4, F_PF, 1);
|
||||
}
|
||||
}
|
||||
+115
-117
@@ -46,15 +46,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wb2 = (wback>>2);
|
||||
wback = xEAX+(wback&3);
|
||||
UXTB(x1, wback, wb2);
|
||||
emit_add8(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_add8(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
BFI(wback, ed, wb2*8, 8);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREXB(x1, wback);
|
||||
emit_add8(dyn, ninst, x1, x2, x12, x3, (wback==x3)?1:0);
|
||||
STREXB(x12, x1, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
emit_add8(dyn, ninst, x1, x2, x14, x3, (wback==x3)?1:0);
|
||||
STREXB(x14, x1, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE); // write failed, try again
|
||||
}
|
||||
break;
|
||||
@@ -65,12 +65,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_add32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_add32(dyn, ninst, ed, gd, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_add32(dyn, ninst, x1, gd, x3, x12);
|
||||
emit_add32(dyn, ninst, x1, gd, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -86,15 +86,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wb2 = (wback>>2);
|
||||
wback = xEAX+(wback&3);
|
||||
UXTB(x1, wback, wb2);
|
||||
emit_or8(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_or8(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
BFI(wback, ed, wb2*8, 8);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREXB(x1, wback);
|
||||
emit_or8(dyn, ninst, x1, x2, x12, x3, (wback==x3)?1:0);
|
||||
STREXB(x12, x1, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
emit_or8(dyn, ninst, x1, x2, x14, x3, (wback==x3)?1:0);
|
||||
STREXB(x14, x1, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE); // write failed, try again
|
||||
}
|
||||
break;
|
||||
@@ -105,12 +105,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_or32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_or32(dyn, ninst, ed, gd, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_or32(dyn, ninst, x1, gd, x3, x12);
|
||||
emit_or32(dyn, ninst, x1, gd, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -126,15 +126,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wb2 = (wback>>2);
|
||||
wback = xEAX+(wback&3);
|
||||
UXTB(x1, wback, wb2);
|
||||
emit_adc8(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_adc8(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
BFI(wback, ed, wb2*8, 8);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREXB(x1, wback);
|
||||
emit_adc8(dyn, ninst, x1, x2, x12, x3, (wback==x3)?1:0);
|
||||
STREXB(x12, x1, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
emit_adc8(dyn, ninst, x1, x2, x14, x3, (wback==x3)?1:0);
|
||||
STREXB(x14, x1, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE); // write failed, try again
|
||||
}
|
||||
break;
|
||||
@@ -145,12 +145,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_adc32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_adc32(dyn, ninst, ed, gd, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_adc32(dyn, ninst, x1, gd, x3, x12);
|
||||
emit_adc32(dyn, ninst, x1, gd, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -166,15 +166,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wb2 = (wback>>2);
|
||||
wback = xEAX+(wback&3);
|
||||
UXTB(x1, wback, wb2);
|
||||
emit_sbb8(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_sbb8(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
BFI(wback, ed, wb2*8, 8);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREXB(x1, wback);
|
||||
emit_sbb8(dyn, ninst, x1, x2, x12, x3, (wback==x3)?1:0);
|
||||
STREXB(x12, x1, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
emit_sbb8(dyn, ninst, x1, x2, x14, x3, (wback==x3)?1:0);
|
||||
STREXB(x14, x1, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE); // write failed, try again
|
||||
}
|
||||
break;
|
||||
@@ -185,12 +185,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_sbb32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_sbb32(dyn, ninst, ed, gd, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_sbb32(dyn, ninst, x1, gd, x3, x12);
|
||||
emit_sbb32(dyn, ninst, x1, gd, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -206,15 +206,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wb2 = (wback>>2);
|
||||
wback = xEAX+(wback&3);
|
||||
UXTB(x1, wback, wb2);
|
||||
emit_and8(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_and8(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
BFI(wback, ed, wb2*8, 8);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREXB(x1, wback);
|
||||
emit_and8(dyn, ninst, x1, x2, x12, x3, (wback==x3)?1:0);
|
||||
STREXB(x12, x1, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
emit_and8(dyn, ninst, x1, x2, x14, x3, (wback==x3)?1:0);
|
||||
STREXB(x14, x1, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE); // write failed, try again
|
||||
}
|
||||
break;
|
||||
@@ -225,12 +225,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_and32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_and32(dyn, ninst, ed, gd, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_and32(dyn, ninst, x1, gd, x3, x12);
|
||||
emit_and32(dyn, ninst, x1, gd, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -246,15 +246,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wb2 = (wback>>2);
|
||||
wback = xEAX+(wback&3);
|
||||
UXTB(x1, wback, wb2);
|
||||
emit_sub8(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_sub8(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
BFI(wback, ed, wb2*8, 8);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREXB(x1, wback);
|
||||
emit_sub8(dyn, ninst, x1, x2, x12, x3, (wback==x3)?1:0);
|
||||
STREXB(x12, x1, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
emit_sub8(dyn, ninst, x1, x2, x14, x3, (wback==x3)?1:0);
|
||||
STREXB(x14, x1, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE); // write failed, try again
|
||||
}
|
||||
break;
|
||||
@@ -265,12 +265,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_sub32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_sub32(dyn, ninst, ed, gd, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_sub32(dyn, ninst, x1, gd, x3, x12);
|
||||
emit_sub32(dyn, ninst, x1, gd, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -286,15 +286,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wb2 = (wback>>2);
|
||||
wback = xEAX+(wback&3);
|
||||
UXTB(x1, wback, wb2);
|
||||
emit_xor8(dyn, ninst, x1, x2, x12, x3, 0);
|
||||
emit_xor8(dyn, ninst, x1, x2, x14, x3, 0);
|
||||
BFI(wback, ed, wb2*8, 8);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREXB(x1, wback);
|
||||
emit_xor8(dyn, ninst, x1, x2, x12, x3, (wback==x3)?1:0);
|
||||
STREXB(x12, x1, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
emit_xor8(dyn, ninst, x1, x2, x14, x3, (wback==x3)?1:0);
|
||||
STREXB(x14, x1, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE); // write failed, try again
|
||||
}
|
||||
break;
|
||||
@@ -305,12 +305,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
GETGD;
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_xor32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_xor32(dyn, ninst, ed, gd, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_xor32(dyn, ninst, x1, gd, x3, x12);
|
||||
emit_xor32(dyn, ninst, x1, gd, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -331,7 +331,7 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_add32c(dyn, ninst, ed, i32, x3, x12);
|
||||
emit_add32c(dyn, ninst, ed, i32, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
@@ -339,16 +339,16 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
B_MARK(cNE);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_add32c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_add32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
B_NEXT(c__);
|
||||
MARK; // unaligned! also, not enough
|
||||
LDR_IMM9(x1, wback, 0);
|
||||
LDREXB(x12, wback);
|
||||
BFI(x1, x12, 0, 8); // re-inject
|
||||
emit_add32c(dyn, ninst, x1, i32, x3, x12);
|
||||
LDREXB(x14, wback);
|
||||
BFI(x1, x14, 0, 8); // re-inject
|
||||
emit_add32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREXB(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARK(cNE);
|
||||
@@ -361,13 +361,13 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_or32c(dyn, ninst, ed, i32, x3, x12);
|
||||
emit_or32c(dyn, ninst, ed, i32, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_or32c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_or32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -380,13 +380,13 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_adc32c(dyn, ninst, ed, i32, x3, x12);
|
||||
emit_adc32c(dyn, ninst, ed, i32, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_adc32c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_adc32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -399,13 +399,13 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_sbb32c(dyn, ninst, ed, i32, x3, x12);
|
||||
emit_sbb32c(dyn, ninst, ed, i32, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_sbb32c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_sbb32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -417,13 +417,13 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_and32c(dyn, ninst, ed, i32, x3, x12);
|
||||
emit_and32c(dyn, ninst, ed, i32, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_and32c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_and32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -435,7 +435,7 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_sub32c(dyn, ninst, ed, i32, x3, x12);
|
||||
emit_sub32c(dyn, ninst, ed, i32, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
@@ -443,16 +443,16 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
B_MARK(cNE);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_sub32c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_sub32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
B_NEXT(c__);
|
||||
MARK; // unaligned! also, not enough
|
||||
LDR_IMM9(x1, wback, 0);
|
||||
LDREXB(x12, wback);
|
||||
BFI(x1, x12, 0, 8); // re-inject
|
||||
emit_sub32c(dyn, ninst, x1, i32, x3, x12);
|
||||
LDREXB(x14, wback);
|
||||
BFI(x1, x14, 0, 8); // re-inject
|
||||
emit_sub32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREXB(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARK(cNE);
|
||||
@@ -465,13 +465,13 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_xor32c(dyn, ninst, ed, i32, x3, x12);
|
||||
emit_xor32c(dyn, ninst, ed, i32, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_xor32c(dyn, ninst, x1, i32, x3, x12);
|
||||
emit_xor32c(dyn, ninst, x1, i32, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -485,9 +485,9 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
if(opcode==0x81) i32 = F32S; else i32 = F8S;
|
||||
if(i32) {
|
||||
MOV32(x2, i32);
|
||||
emit_cmp32(dyn, ninst, ed, x2, x3, x12);
|
||||
emit_cmp32(dyn, ninst, ed, x2, x3, x14);
|
||||
} else {
|
||||
emit_cmp32_0(dyn, ninst, ed, x3, x12);
|
||||
emit_cmp32_0(dyn, ninst, ed, x3, x14);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -549,8 +549,8 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
// AL == Eb
|
||||
GETGB(x1);
|
||||
if(wb1) {
|
||||
STREXB(x12, x1, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
STREXB(x14, x1, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE); // write failed, try again
|
||||
if(!(gb1==xEAX && gb2==0)) {
|
||||
UXTB(x1, xEAX, 0); // readback AL if needed
|
||||
@@ -565,7 +565,7 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
BFI(xEAX, ed, 0, 8);
|
||||
MARK3;
|
||||
// done, do the cmp now
|
||||
emit_cmp8(dyn, ninst, x1, x2, x3, x12);
|
||||
emit_cmp8(dyn, ninst, x1, x2, x3, x14);
|
||||
break;
|
||||
case 0xB1:
|
||||
INST_NAME("LOCK CMPXCHG Ed, Gd");
|
||||
@@ -589,22 +589,22 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
// EAX == Ed
|
||||
if(wback) {
|
||||
TSTS_IMM8(wback, 3);
|
||||
STREX_COND(cEQ, x12, gd, wback);
|
||||
STREXB_COND(cNE, x12, gd, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
STREX_COND(cEQ, x14, gd, wback);
|
||||
STREXB_COND(cNE, x14, gd, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
TSTS_IMM8(wback, 3); // anoying, all those test
|
||||
STR_IMM9_COND(cNE, gd, wback, 0);
|
||||
emit_cmp32(dyn, ninst, xEAX, ed, x1, x12);
|
||||
emit_cmp32(dyn, ninst, xEAX, ed, x1, x14);
|
||||
} else {
|
||||
emit_cmp32(dyn, ninst, xEAX, ed, x1, x12);
|
||||
emit_cmp32(dyn, ninst, xEAX, ed, x1, x14);
|
||||
MOV_REG(ed, gd);
|
||||
}
|
||||
// done
|
||||
B_MARK3(c__); // not next, in case its called with a LOCK prefix
|
||||
MARK;
|
||||
// EAX != Ed
|
||||
emit_cmp32(dyn, ninst, xEAX, ed, x3, x12);
|
||||
emit_cmp32(dyn, ninst, xEAX, ed, x3, x14);
|
||||
MOV_REG(xEAX, ed);
|
||||
MARK3
|
||||
break;
|
||||
@@ -626,15 +626,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
ed = x1;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
ANDS_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
ANDS_IMM8(x14, x14, 1);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
B_MARK3(cEQ); // bit already clear, jump to end of instruction
|
||||
MOVW(x12, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
MOVW(x14, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STREX(x12, ed, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
STREX(x14, ed, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
}
|
||||
MARK3;
|
||||
@@ -662,8 +662,7 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV_REG_LSR_IMM5(x1, ed, u8);
|
||||
ed = x1;
|
||||
}
|
||||
AND_IMM8(x1, ed, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, ed, F_CF, 1);
|
||||
break;
|
||||
case 6:
|
||||
INST_NAME("LOCK BTR Ed, Ib");
|
||||
@@ -686,15 +685,15 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wback = x3;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
ANDS_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
ANDS_IMM8(x14, x14, 1);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
B_MARK3(cEQ); // bit already clear, jump to next instruction
|
||||
//MOVW(x12, 1); // already 0x01
|
||||
XOR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
//MOVW(x14, 1); // already 0x01
|
||||
XOR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STREX(x12, ed, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
STREX(x14, ed, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
}
|
||||
MARK3;
|
||||
@@ -721,14 +720,13 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
wback = x3;
|
||||
}
|
||||
AND_IMM8(x2, gd, 0x1f);
|
||||
MOV_REG_LSR_REG(x12, ed, x2);
|
||||
AND_IMM8(x12, x12, 1);
|
||||
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
MOVW(x12, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x12, x2);
|
||||
MOV_REG_LSR_REG(x14, ed, x2);
|
||||
BFI(xFlags, x14, F_CF, 1);
|
||||
MOVW(x14, 1);
|
||||
XOR_REG_LSL_REG(ed, ed, x14, x2);
|
||||
if(wback) {
|
||||
STREX(x12, ed, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
STREX(x14, ed, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
}
|
||||
break;
|
||||
@@ -753,10 +751,10 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
ed = x2;
|
||||
}
|
||||
BFI(gb1, ed, gb2*8, 8); // gb <- eb
|
||||
emit_add8(dyn, ninst, ed, gd, x12, x3, 1);
|
||||
emit_add8(dyn, ninst, ed, gd, x14, x3, 1);
|
||||
if(wb1) {
|
||||
STREXB(x12, ed, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
STREXB(x14, ed, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
} else {
|
||||
BFI(wback, ed, wb2*8, 8);
|
||||
@@ -774,35 +772,35 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
XOR_REG_LSL_IMM5(ed, gd, ed, 0);
|
||||
XOR_REG_LSL_IMM5(gd, gd, ed, 0);
|
||||
}
|
||||
emit_add32(dyn, ninst, ed, gd, x3, x12);
|
||||
emit_add32(dyn, ninst, ed, gd, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
TSTS_IMM8(wback, 3);
|
||||
B_MARK(cNE); // unaligned
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
ADD_REG_LSL_IMM5(x12, x1, gd, 0);
|
||||
STREX(x3, x12, wback);
|
||||
ADD_REG_LSL_IMM5(x14, x1, gd, 0);
|
||||
STREX(x3, x14, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
IFX(X_ALL|X_PEND) {
|
||||
MOV_REG(x2, x1);
|
||||
emit_add32(dyn, ninst, x2, gd, x3, x12);
|
||||
emit_add32(dyn, ninst, x2, gd, x3, x14);
|
||||
}
|
||||
MOV_REG(gd, x1);
|
||||
B_NEXT(c__);
|
||||
MARK;
|
||||
LDR_IMM9(x1, wback, 0);
|
||||
LDREXB(x12, wback);
|
||||
BFI(x1, x12, 0, 8);
|
||||
ADD_REG_LSL_IMM5(x12, x1, gd, 0);
|
||||
STREXB(x3, x12, wback);
|
||||
LDREXB(x14, wback);
|
||||
BFI(x1, x14, 0, 8);
|
||||
ADD_REG_LSL_IMM5(x14, x1, gd, 0);
|
||||
STREXB(x3, x14, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARK(cNE);
|
||||
STR_IMM9(x12, wback, 0);
|
||||
STR_IMM9(x14, wback, 0);
|
||||
IFX(X_ALL|X_PEND) {
|
||||
MOV_REG(x2, x1);
|
||||
emit_add32(dyn, ninst, x2, gd, x3, x12);
|
||||
emit_add32(dyn, ninst, x2, gd, x3, x14);
|
||||
}
|
||||
MOV_REG(gd, x1);
|
||||
}
|
||||
@@ -825,9 +823,9 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV_REG(x2, xEBX);
|
||||
MOV_REG(x3, xECX);
|
||||
TSTS_IMM8(wback, 7);
|
||||
STREXD_COND(cEQ, x12, x2, wback);
|
||||
STREX_COND(cNE, x12, x2, wback);
|
||||
CMPS_IMM8(x12, 0);
|
||||
STREXD_COND(cEQ, x14, x2, wback);
|
||||
STREX_COND(cNE, x14, x2, wback);
|
||||
CMPS_IMM8(x14, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
TSTS_IMM8(wback, 7);
|
||||
STR_IMM9_COND(cNE, x3, wback, 4);
|
||||
@@ -838,7 +836,7 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV_REG(xEDX, x3);
|
||||
MOVW(x1, 0);
|
||||
MARK3;
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
BFI(xFlags, x1, F_ZF, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -856,12 +854,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_inc32(dyn, ninst, ed, x3, x12);
|
||||
emit_inc32(dyn, ninst, ed, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_inc32(dyn, ninst, x1, x3, x12);
|
||||
emit_inc32(dyn, ninst, x1, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
@@ -872,12 +870,12 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
ed = xEAX+(nextop&7);
|
||||
emit_dec32(dyn, ninst, ed, x3, x12);
|
||||
emit_dec32(dyn, ninst, ed, x3, x14);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0);
|
||||
MARKLOCK;
|
||||
LDREX(x1, wback);
|
||||
emit_dec32(dyn, ninst, x1, x3, x12);
|
||||
emit_dec32(dyn, ninst, x1, x3, x14);
|
||||
STREX(x3, x1, wback);
|
||||
CMPS_IMM8(x3, 0);
|
||||
B_MARKLOCK(cNE);
|
||||
|
||||
@@ -137,7 +137,7 @@ uintptr_t dynarecF20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
break;
|
||||
case 0x2D:
|
||||
INST_NAME("CVTSD2SI Gd, Ex");
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x12);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
|
||||
@@ -227,7 +227,7 @@ uintptr_t dynarecF30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
break;
|
||||
case 0x2D:
|
||||
INST_NAME("CVTSS2SI Gd, Ex");
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x12);
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x14);
|
||||
nextop = F8;
|
||||
GETGD;
|
||||
s0 = fpu_get_scratch_single(dyn);
|
||||
@@ -507,7 +507,7 @@ uintptr_t dynarecF30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
VLD1Q_64(v1, ed);
|
||||
}
|
||||
u8 = F8;
|
||||
// only high part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits
|
||||
// only high part need to be shuffled. VTBL only handle 8bits value, so the 16bits shuffles need to be changed in 8bits
|
||||
u32 = 0;
|
||||
for (int i=0; i<2; ++i) {
|
||||
u32 |= (((u8>>(i*2))&3)*2+0)<<(i*16+0);
|
||||
@@ -575,11 +575,10 @@ uintptr_t dynarecF30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
|
||||
CLZ(gd, x1); // x2 gets leading 0 == TZCNT
|
||||
MOVW_COND(cEQ, x1, 1);
|
||||
MOVW_COND(cNE, x1, 0);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
|
||||
BFI(xFlags, x1, F_CF, 1);
|
||||
RSB_IMM8(x1, x1, 1);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_ZF]));
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
BFI(xFlags, x1, F_ZF, 1);
|
||||
SET_DFNONE(x1);
|
||||
break;
|
||||
|
||||
case 0xC2:
|
||||
|
||||
@@ -25,21 +25,6 @@
|
||||
#include "dynarec_arm_private.h"
|
||||
#include "dynarec_arm_functions.h"
|
||||
|
||||
void arm_popf(x86emu_t* emu, uint32_t f)
|
||||
{
|
||||
emu->packed_eflags.x32 = (f & 0x3F7FD7) | 0x2; // mask off res2 and res3 and on res1
|
||||
UnpackFlags(emu);
|
||||
RESET_FLAGS(emu);
|
||||
}
|
||||
|
||||
void arm_popf16(x86emu_t* emu, uint32_t f)
|
||||
{
|
||||
emu->packed_eflags.x32 &= 0xffff0000;
|
||||
emu->packed_eflags.x32 |= (f & 0x7FD7) | 0x2; // mask off res2 and res3 and on res1
|
||||
UnpackFlags(emu);
|
||||
RESET_FLAGS(emu);
|
||||
}
|
||||
|
||||
void arm_fstp(x86emu_t* emu, void* p)
|
||||
{
|
||||
if(ST0.ll!=STld(0).ref)
|
||||
@@ -266,11 +251,11 @@ void fpu_reset_reg(dynarec_arm_t* dyn)
|
||||
dyn->fpuused[i]=0;
|
||||
}
|
||||
|
||||
#define F8 *(uint8_t*)(addr++)
|
||||
#define F32 *(uint32_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
|
||||
int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, int parity)
|
||||
{
|
||||
#define F8 *(uint8_t*)(addr++)
|
||||
#define F32 *(uint32_t*)(addr+=4, addr-4)
|
||||
|
||||
uint32_t tested = (1<<parity)-1;
|
||||
if((nextop&0xC0)==0xC0)
|
||||
@@ -289,7 +274,7 @@ int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, i
|
||||
return (tmp&tested)?0:1;
|
||||
}
|
||||
} else {
|
||||
if(sib_reg==4)
|
||||
if(sib_reg==4 && parity<3)
|
||||
return 0; // simple [reg]
|
||||
// don't try [reg1 + reg2<<N], unless reg1 is ESP
|
||||
return ((sib&0x7)==4 && (sib>>6)>=parity)?1:0;
|
||||
@@ -303,9 +288,36 @@ int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, i
|
||||
} else {
|
||||
return 0; //Form [reg1 + reg2<<N + XXXXXX]
|
||||
}
|
||||
}
|
||||
|
||||
// Do the GETED, but don't emit anything...
|
||||
uintptr_t fakeed(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop)
|
||||
{
|
||||
if((nextop&0xC0)==0xC0)
|
||||
return addr;
|
||||
if(!(nextop&0xC0)) {
|
||||
if((nextop&7)==4) {
|
||||
uint8_t sib = F8;
|
||||
if((sib&0x7)==5) {
|
||||
addr+=4;
|
||||
}
|
||||
} else if((nextop&7)==5) {
|
||||
addr+=4;
|
||||
}
|
||||
} else {
|
||||
if((nextop&7)==4) {
|
||||
++addr;
|
||||
}
|
||||
if(nextop&0x80) {
|
||||
addr+=4;
|
||||
} else {
|
||||
++addr;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
#undef F8
|
||||
#undef F32
|
||||
}
|
||||
|
||||
int isNativeCall(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn)
|
||||
{
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
typedef struct x86emu_s x86emu_t;
|
||||
|
||||
void arm_popf(x86emu_t* emu, uint32_t f);
|
||||
void arm_popf16(x86emu_t* emu, uint32_t f);
|
||||
void arm_fstp(x86emu_t* emu, void* p);
|
||||
|
||||
void arm_print_armreg(x86emu_t* emu, uintptr_t reg, uintptr_t n);
|
||||
@@ -53,6 +51,8 @@ void fpu_reset_reg(dynarec_arm_t* dyn);
|
||||
|
||||
// Get if ED will have the correct parity. Not emiting 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);
|
||||
// Do the GETED, but don't emit anything...
|
||||
uintptr_t fakeed(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop);
|
||||
|
||||
// Is what pointed at addr a native call? And if yes, to what function?
|
||||
int isNativeCall(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn);
|
||||
|
||||
@@ -153,31 +153,6 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
|
||||
return addr;
|
||||
}
|
||||
|
||||
// Do the GETED, but don't emit anything...
|
||||
uintptr_t fakeed(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop)
|
||||
{
|
||||
if(!(nextop&0xC0)) {
|
||||
if((nextop&7)==4) {
|
||||
uint8_t sib = F8;
|
||||
if((sib&0x7)==5) {
|
||||
addr+=4;
|
||||
}
|
||||
} else if((nextop&7)==5) {
|
||||
addr+=4;
|
||||
}
|
||||
} else {
|
||||
if((nextop&7)==4) {
|
||||
++addr;
|
||||
}
|
||||
if(nextop&0x80) {
|
||||
addr+=4;
|
||||
} else {
|
||||
++addr;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* setup r2 to address pointed by ED, r3 as scratch also fixaddress is an optionnal delta in the range [-absmax, +absmax], with delta&mask==0 to be added to ed for LDR/STR */
|
||||
uintptr_t geted16(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, int* fixaddress, uint32_t absmax, uint32_t mask)
|
||||
{
|
||||
@@ -271,8 +246,10 @@ void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
|
||||
void jump_to_linker(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
|
||||
{
|
||||
MESSAGE(LOG_DUMP, "Jump to linker (#%d) nolinker=%d\n", dyn->tablei, dyn->nolinker);
|
||||
#if 0
|
||||
int j32;
|
||||
MAYUSE(j32);
|
||||
#endif
|
||||
if(dyn->nolinker==2) {
|
||||
jump_to_epilog(dyn, ip, reg, ninst);
|
||||
} else {
|
||||
@@ -300,11 +277,11 @@ void jump_to_linker(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
|
||||
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
|
||||
BXcond(cEQ, x2);
|
||||
MOV32_(x2, (uintptr_t)arm_linker);
|
||||
MOV_REG(x3, x12);
|
||||
STREXD(x12, x2, x1); // nope, putting back linker & IP in place
|
||||
// x12 now contain success / falure for write
|
||||
CMPS_IMM8(x12, 1);
|
||||
MOV_REG(x12, x3); // put back IP in place...
|
||||
MOV_REG(x3, x14);
|
||||
STREXD(x14, x2, x1); // nope, putting back linker & IP in place
|
||||
// x14 now contain success / falure for write
|
||||
CMPS_IMM8(x14, 1);
|
||||
MOV_REG(x14, x3); // put back IP in place...
|
||||
B_MARK(cEQ);
|
||||
BX(x2); // go to linker
|
||||
#else
|
||||
@@ -313,7 +290,7 @@ void jump_to_linker(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
|
||||
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
|
||||
BXcond(cEQ, x2);
|
||||
MOV32_(x2, (uintptr_t)arm_linker);
|
||||
MOV_REG(x3, x12);
|
||||
MOV_REG(x3, x14);
|
||||
STRD_IMM8(x2, x1, 0);
|
||||
BX(x2);
|
||||
#endif
|
||||
@@ -324,6 +301,26 @@ void jump_to_linker(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
|
||||
}
|
||||
}
|
||||
|
||||
void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
|
||||
{
|
||||
MESSAGE(LOG_DUMP, "Jump to next nolinker=%d\n", dyn->nolinker);
|
||||
|
||||
if(dyn->nolinker==2) {
|
||||
jump_to_epilog(dyn, ip, reg, ninst);
|
||||
} else {
|
||||
if(reg) {
|
||||
if(reg!=xEIP) {
|
||||
MOV_REG(xEIP, reg);
|
||||
}
|
||||
} else {
|
||||
MOV32_(xEIP, ip);
|
||||
}
|
||||
MOV32_(x2, (uintptr_t)arm_next);
|
||||
MOV_REG(x1, xEIP);
|
||||
BX(x2);
|
||||
}
|
||||
}
|
||||
|
||||
void ret_to_epilog(dynarec_arm_t* dyn, int ninst)
|
||||
{
|
||||
// using linker here doesn't seem to bring any significant speed improvment. To much change in the jump table probably
|
||||
@@ -332,16 +329,16 @@ void ret_to_epilog(dynarec_arm_t* dyn, int ninst)
|
||||
MAYUSE(i32);
|
||||
if(dyn->nolinker) {
|
||||
#endif
|
||||
MESSAGE(LOG_DUMP, "Ret epilog\n");
|
||||
POP(xESP, 1<<xEIP);
|
||||
MESSAGE(LOG_DUMP, "Ret next\n");
|
||||
POP1(xEIP);
|
||||
cstack_pop(dyn, ninst, xEIP, x1, x2);
|
||||
PASS3(void* epilog = arm_epilog);
|
||||
MOV32_(x2, (uintptr_t)epilog);
|
||||
MOV32_(x2, (uintptr_t)arm_next);
|
||||
MOV_REG(x1, xEIP);
|
||||
BX(x2);
|
||||
#if 0
|
||||
} else {
|
||||
MESSAGE(LOG_DUMP, "Ret epilog with linker\n");
|
||||
POP(xESP, 1<<xEIP);
|
||||
POP1(xEIP);
|
||||
uintptr_t* table = 0;
|
||||
if(dyn->tablesz) {
|
||||
table = &dyn->table[dyn->tablei];
|
||||
@@ -355,11 +352,11 @@ void ret_to_epilog(dynarec_arm_t* dyn, int ninst)
|
||||
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
|
||||
BXcond(cEQ, x2);
|
||||
MOV32_(x2, (uintptr_t)arm_linker);
|
||||
MOV_REG(x3, x12);
|
||||
STREXD(x12, x2, x1); // nope, putting back linker & IP in place
|
||||
// x12 now contain success / falure for write
|
||||
CMPS_IMM8(x12, 1);
|
||||
MOV_REG(x12, x3); // put back IP in place...
|
||||
MOV_REG(x3, x14);
|
||||
STREXD(x14, x2, x1); // nope, putting back linker & IP in place
|
||||
// x14 now contain success / falure for write
|
||||
CMPS_IMM8(x14, 1);
|
||||
MOV_REG(x14, x3); // put back IP in place...
|
||||
B_MARK(cEQ);
|
||||
BX(x2); // go to linker
|
||||
}
|
||||
@@ -374,7 +371,7 @@ void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n)
|
||||
if(dyn->nolinker) {
|
||||
#endif
|
||||
MESSAGE(LOG_DUMP, "Retn epilog\n");
|
||||
POP(xESP, 1<<xEIP);
|
||||
POP1(xEIP);
|
||||
if(n>0xff) {
|
||||
MOVW(x1, n);
|
||||
ADD_REG_LSL_IMM5(xESP, xESP, x1, 0);
|
||||
@@ -382,13 +379,13 @@ void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n)
|
||||
ADD_IMM8(xESP, xESP, n);
|
||||
}
|
||||
cstack_pop(dyn, ninst, xEIP, x1, x2);
|
||||
PASS3(void* epilog = arm_epilog);
|
||||
MOV32_(x2, (uintptr_t)epilog);
|
||||
MOV32_(x2, (uintptr_t)arm_next);
|
||||
MOV_REG(x1, xEIP);
|
||||
BX(x2);
|
||||
#if 0
|
||||
} else {
|
||||
MESSAGE(LOG_DUMP, "Retn epilog with linker\n");
|
||||
POP(xESP, 1<<xEIP);
|
||||
POP1(xEIP);
|
||||
ADD_IMM8(xESP, xESP, n);
|
||||
uintptr_t* table = 0;
|
||||
if(dyn->tablesz) {
|
||||
@@ -403,11 +400,11 @@ void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n)
|
||||
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
|
||||
BXcond(cEQ, x2);
|
||||
MOV32_(x2, (uintptr_t)arm_linker);
|
||||
MOV_REG(x3, x12);
|
||||
STREXD(x12, x2, x1); // nope, putting back linker & IP in place
|
||||
// x12 now contain success / falure for write
|
||||
CMPS_IMM8(x12, 1);
|
||||
MOV_REG(x12, x3); // put back IP in place...
|
||||
MOV_REG(x3, x14);
|
||||
STREXD(x14, x2, x1); // nope, putting back linker & IP in place
|
||||
// x14 now contain success / falure for write
|
||||
CMPS_IMM8(x14, 1);
|
||||
MOV_REG(x14, x3); // put back IP in place...
|
||||
B_MARK(cEQ);
|
||||
BX(x2); // go to linker
|
||||
}
|
||||
@@ -418,18 +415,19 @@ void iret_to_epilog(dynarec_arm_t* dyn, int ninst)
|
||||
{
|
||||
MESSAGE(LOG_DUMP, "IRet epilog\n");
|
||||
// POP IP
|
||||
POP(xESP, 1<<xEIP);
|
||||
POP1(xEIP);
|
||||
// POP CS
|
||||
MOVW(x1, offsetof(x86emu_t, segs[_CS]));
|
||||
POP(xESP, 1<<x2);
|
||||
POP1(x2);
|
||||
STRH_REG(x2, xEmu, x1);
|
||||
MOVW(x1, 0);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_CS]));
|
||||
// POP EFLAGS
|
||||
POP(xESP, (1<<x1));
|
||||
CALL(arm_popf, -1, (1<<xEIP));
|
||||
MOVW(x1, d_none);
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, df));
|
||||
POP1(xFlags);
|
||||
MOV32(x1, 0x3F7FD7);
|
||||
AND_REG_LSL_IMM5(xFlags, xFlags, x1, 0);
|
||||
ORR_IMM8(xFlags, xFlags, 2, 0);
|
||||
SET_DFNONE(x1);
|
||||
// Ret....
|
||||
cstack_pop(dyn, ninst, xEIP, x1, x2);
|
||||
PASS3(void* epilog = arm_epilog);
|
||||
@@ -437,12 +435,15 @@ void iret_to_epilog(dynarec_arm_t* dyn, int ninst)
|
||||
BX(x2);
|
||||
}
|
||||
|
||||
void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, uint32_t mask)
|
||||
void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, uint32_t mask, int saveflags)
|
||||
{
|
||||
if(ret!=-2) {
|
||||
PUSH(xSP, (1<<xEmu) | mask);
|
||||
}
|
||||
fpu_pushcache(dyn, ninst, reg);
|
||||
if(saveflags) {
|
||||
STR_IMM9(xFlags, xEmu, offsetof(x86emu_t, eflags));
|
||||
}
|
||||
MOV32(reg, (uintptr_t)fnc);
|
||||
BLX(reg);
|
||||
fpu_popcache(dyn, ninst, reg);
|
||||
@@ -452,6 +453,10 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, uint32_t
|
||||
if(ret!=-2) {
|
||||
POP(xSP, (1<<xEmu) | mask);
|
||||
}
|
||||
if(saveflags) {
|
||||
LDR_IMM9(xFlags, xEmu, offsetof(x86emu_t, eflags));
|
||||
}
|
||||
SET_NODF();
|
||||
}
|
||||
|
||||
void grab_tlsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg)
|
||||
@@ -460,13 +465,13 @@ void grab_tlsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg)
|
||||
int32_t j32;
|
||||
MAYUSE(j32);
|
||||
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, context));
|
||||
LDR_IMM9(x12, xEmu, offsetof(x86emu_t, segs_serial[_GS])); // complete check here
|
||||
LDR_IMM9(x14, xEmu, offsetof(x86emu_t, segs_serial[_GS])); // complete check here
|
||||
LDR_IMM9(x1, x1, offsetof(box86context_t, sel_serial));
|
||||
CMPS_REG_LSL_IMM5(x12, x1, 0);
|
||||
CMPS_REG_LSL_IMM5(x14, x1, 0);
|
||||
LDR_IMM9_COND(cEQ, reg, xEmu, offsetof(x86emu_t, segs_offs[_GS]));
|
||||
B_MARKSEG(cEQ);
|
||||
MOVW(x1, _GS);
|
||||
call_c(dyn, ninst, GetSegmentBaseEmu, 12, reg, 0);
|
||||
call_c(dyn, ninst, GetSegmentBaseEmu, x14, reg, 0, 1);
|
||||
MARKSEG;
|
||||
MESSAGE(LOG_DUMP, "----TLSData\n");
|
||||
}
|
||||
@@ -476,12 +481,12 @@ void grab_fsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg)
|
||||
int32_t j32;
|
||||
MAYUSE(j32);
|
||||
MESSAGE(LOG_DUMP, "Get FS: Offset\n");
|
||||
LDR_IMM9(x12, xEmu, offsetof(x86emu_t, segs_serial[_FS]));// fast check here
|
||||
CMPS_IMM8(x12, 0);
|
||||
LDR_IMM9(x14, xEmu, offsetof(x86emu_t, segs_serial[_FS]));// fast check here
|
||||
CMPS_IMM8(x14, 0);
|
||||
LDR_IMM9_COND(cNE, reg, xEmu, offsetof(x86emu_t, segs_offs[_FS]));
|
||||
B_MARKSEG(cNE);
|
||||
MOVW(x1, _FS);
|
||||
call_c(dyn, ninst, GetSegmentBaseEmu, 12, reg, 0);
|
||||
call_c(dyn, ninst, GetSegmentBaseEmu, x14, reg, 0, 1);
|
||||
MARKSEG;
|
||||
MESSAGE(LOG_DUMP, "----FS: Offset\n");
|
||||
}
|
||||
|
||||
@@ -179,18 +179,22 @@
|
||||
#define GBBACK BFI(gb1, gd, gb2*8, 8);
|
||||
|
||||
// Get Direction with size Z and based of F_DF flag, on register r ready for LDR/STR fetching
|
||||
// F_DF is 1<<10, so 1 ROR 11*2 (so F_OF)
|
||||
#define GETDIR(r, A) \
|
||||
LDR_IMM9(r, xEmu, offsetof(x86emu_t, flags[F_DF])); \
|
||||
CMPS_IMM8(r, 1); \
|
||||
MOVW(r, A); \
|
||||
RSB_COND_IMM8(cEQ, r, r, 0)
|
||||
TSTS_IMM8_ROR(xFlags, 1, 0x0b); \
|
||||
MOVW(r, A); \
|
||||
RSB_COND_IMM8(cNE, r, r, 0)
|
||||
|
||||
// CALL will use x12 for the call address. Return value can be put in ret (unless ret is -1)
|
||||
// CALL will use x14 for the call address. Return value can be put in ret (unless ret is -1)
|
||||
// R0 will not be pushed/popd if ret is -2
|
||||
#define CALL(F, ret, M) call_c(dyn, ninst, F, x12, ret, M)
|
||||
#define CALL(F, ret, M) call_c(dyn, ninst, F, x14, ret, M, 1)
|
||||
// CALL_ will use x3 for the call address. Return value can be put in ret (unless ret is -1)
|
||||
// R0 will not be pushed/popd if ret is -2
|
||||
#define CALL_(F, ret, M) call_c(dyn, ninst, F, x3, ret, M)
|
||||
#define CALL_(F, ret, M) call_c(dyn, ninst, F, x3, ret, M, 1)
|
||||
// CALL_S will use x3 for the call address. Return value can be put in ret (unless ret is -1)
|
||||
// R0 will not be pushed/popd if ret is -2. Flags are not save/restored
|
||||
#define CALL_S(F, ret, M) call_c(dyn, ninst, F, x3, ret, M, 0)
|
||||
|
||||
#define MARK if(dyn->insts) {dyn->insts[ninst].mark = (uintptr_t)dyn->arm_size;}
|
||||
#define GETMARK ((dyn->insts)?dyn->insts[ninst].mark:(dyn->arm_size+4))
|
||||
#define MARK2 if(dyn->insts) {dyn->insts[ninst].mark2 = (uintptr_t)dyn->arm_size;}
|
||||
@@ -250,36 +254,30 @@
|
||||
// Generate FCOMI with s1 and s2 scratch regs (the VCMP is already done)
|
||||
#define FCOMI(s1, s2) \
|
||||
VMRS_APSR(); /* 0b111 */ \
|
||||
XOR_REG_LSL_IMM5(s2, s2, s2, 0); \
|
||||
MOVW_COND(cVS, s1, 0b111); /* unordered */ \
|
||||
MOVW_COND(cEQ, s1, 0b100); /* zero */ \
|
||||
MOVW_COND(cGT, s1, 0b000); /* greater than */ \
|
||||
MOVW_COND(cLO, s1, 0b001); /* less than */ \
|
||||
IFX(X_CF|X_PEND) { \
|
||||
UBFX(s2, s1, 0, 1); \
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, flags[F_CF]));\
|
||||
MOVW_COND(cVS, s1, 0b1000101); /* unordered */ \
|
||||
MOVW_COND(cEQ, s1, 0b1000000); /* zero */ \
|
||||
MOVW_COND(cGT, s1, 0b0000000); /* greater than */ \
|
||||
MOVW_COND(cLO, s1, 0b0000001); /* less than */ \
|
||||
IFX(X_CF|X_PF|X_ZF|X_PEND) { \
|
||||
BIC_IMM8(xFlags, xFlags, 0b1000101, 0); \
|
||||
ORR_REG_LSL_IMM5(xFlags, xFlags, s1, 0); \
|
||||
} \
|
||||
IFX(X_PF|X_PEND) { \
|
||||
UBFX(s2, s1, 1, 1); \
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, flags[F_PF]));\
|
||||
} \
|
||||
IFX(X_ZF|X_PEND) { \
|
||||
UBFX(s2, s1, 2, 1); \
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, flags[F_ZF]));\
|
||||
} \
|
||||
MOVW(s2, d_none); \
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, df)); \
|
||||
SET_DFNONE(s1); \
|
||||
IFX(X_OF|X_PEND) { \
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, flags[F_OF]));\
|
||||
BFC(xFlags, F_OF, 1); \
|
||||
} \
|
||||
IFX(X_AF|X_PEND) { \
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, flags[F_AF]));\
|
||||
BFC(xFlags, F_AF, 1); \
|
||||
} \
|
||||
IFX(X_SF|X_PEND) { \
|
||||
STR_IMM9(s2, xEmu, offsetof(x86emu_t, flags[F_SF]));\
|
||||
BFC(xFlags, F_SF, 1); \
|
||||
} \
|
||||
|
||||
|
||||
#define SET_DFNONE(S) if(!dyn->dfnone) {MOVW(S, d_none); STR_IMM9(S, xEmu, offsetof(x86emu_t, df)); dyn->dfnone=1;}
|
||||
#define SET_DF(S, N) if(N) {MOVW(S, N); STR_IMM9(S, xEmu, offsetof(x86emu_t, df)); dyn->dfnone=0;} else SET_DFNONE(S)
|
||||
#define SET_NODF() dyn->dfnone = 0
|
||||
#define SET_DFOK() dyn->dfnone = 1
|
||||
|
||||
#ifndef READFLAGS
|
||||
#define READFLAGS(A) \
|
||||
@@ -293,6 +291,7 @@
|
||||
CALL_(UpdateFlags, -1, 0); \
|
||||
MARKF; \
|
||||
dyn->state_flags = SF_SET; \
|
||||
SET_DFOK(); \
|
||||
}
|
||||
#endif
|
||||
#ifndef SETFLAGS
|
||||
@@ -310,11 +309,11 @@
|
||||
#ifndef BARRIER_NEXT
|
||||
#define BARRIER_NEXT(A)
|
||||
#endif
|
||||
#define UFLAG_OP1(A) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {STR_IMM9(A, 0, offsetof(x86emu_t, op1));}
|
||||
#define UFLAG_OP2(A) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {STR_IMM9(A, 0, offsetof(x86emu_t, op2));}
|
||||
#define UFLAG_OP12(A1, A2) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {STR_IMM9(A1, 0, offsetof(x86emu_t, op1));STR_IMM9(A2, 0, offsetof(x86emu_t, op2));}
|
||||
#define UFLAG_RES(A) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {STR_IMM9(A, 0, offsetof(x86emu_t, res));}
|
||||
#define UFLAG_DF(r, A) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {MOVW(r, A); STR_IMM9(r, 0, offsetof(x86emu_t, df));}
|
||||
#define UFLAG_OP1(A) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {STR_IMM9(A, xEmu, offsetof(x86emu_t, op1));}
|
||||
#define UFLAG_OP2(A) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {STR_IMM9(A, xEmu, offsetof(x86emu_t, op2));}
|
||||
#define UFLAG_OP12(A1, A2) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {STR_IMM9(A1, xEmu, offsetof(x86emu_t, op1));STR_IMM9(A2, 0, offsetof(x86emu_t, op2));}
|
||||
#define UFLAG_RES(A) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {STR_IMM9(A, xEmu, offsetof(x86emu_t, res));}
|
||||
#define UFLAG_DF(r, A) if(dyn->insts && dyn->insts[ninst].x86.need_flags) {SET_DF(r, A)}
|
||||
#define UFLAG_IF if(dyn->insts && dyn->insts[ninst].x86.need_flags)
|
||||
#ifndef DEFAULT
|
||||
#define DEFAULT *ok = -1; BARRIER(2)
|
||||
@@ -333,6 +332,7 @@
|
||||
|
||||
void arm_epilog();
|
||||
void* arm_linker(x86emu_t* emu, void** table, uintptr_t addr);
|
||||
void* arm_next(x86emu_t* emu, uintptr_t addr);
|
||||
|
||||
#ifndef STEPNAME
|
||||
#define STEPNAME3(N,M) N##M
|
||||
@@ -362,10 +362,10 @@ void* arm_linker(x86emu_t* emu, void** table, uintptr_t addr);
|
||||
#define dynarecF30F STEPNAME(dynarecF30F)
|
||||
|
||||
#define geted STEPNAME(geted_)
|
||||
#define fakeed STEPNAME(fakeed_)
|
||||
#define geted16 STEPNAME(geted16_)
|
||||
#define jump_to_epilog STEPNAME(jump_to_epilog_)
|
||||
#define jump_to_linker STEPNAME(jump_to_linker_)
|
||||
#define jump_to_next STEPNAME(jump_to_next_)
|
||||
#define ret_to_epilog STEPNAME(ret_to_epilog_)
|
||||
#define retn_to_epilog STEPNAME(retn_to_epilog_)
|
||||
#define iret_to_epilog STEPNAME(iret_to_epilog_)
|
||||
@@ -437,6 +437,8 @@ void* arm_linker(x86emu_t* emu, void** table, uintptr_t addr);
|
||||
#define emit_sar32c STEPNAME(emit_sar32c)
|
||||
#define emit_rol32c STEPNAME(emit_rol32c)
|
||||
#define emit_ror32c STEPNAME(emit_ror32c)
|
||||
#define emit_shrd32c STEPNAME(emit_shrd32c)
|
||||
#define emit_shld32c STEPNAME(emit_shld32c)
|
||||
|
||||
#define x87_do_push STEPNAME(x87_do_push)
|
||||
#define x87_do_push_empty STEPNAME(x87_do_push_empty)
|
||||
@@ -473,9 +475,6 @@ void* arm_linker(x86emu_t* emu, void** table, uintptr_t addr);
|
||||
/* setup r2 to address pointed by */
|
||||
uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, int* fixedaddress, uint32_t absmax, uint32_t mask);
|
||||
|
||||
// Do the GETED, but don't emit anything...
|
||||
uintptr_t fakeed(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop);
|
||||
|
||||
/* setup r2 to address pointed by */
|
||||
uintptr_t geted16(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, int* fixedaddress, uint32_t absmax, uint32_t mask);
|
||||
|
||||
@@ -483,10 +482,11 @@ uintptr_t geted16(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
|
||||
// generic x86 helper
|
||||
void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst);
|
||||
void jump_to_linker(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst);
|
||||
void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst);
|
||||
void ret_to_epilog(dynarec_arm_t* dyn, int ninst);
|
||||
void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n);
|
||||
void iret_to_epilog(dynarec_arm_t* dyn, int ninst);
|
||||
void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, uint32_t mask);
|
||||
void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, uint32_t mask, int saveflags);
|
||||
void grab_fsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg);
|
||||
void grab_tlsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg);
|
||||
void emit_lock(dynarec_arm_t* dyn, uintptr_t addr, int ninst);
|
||||
@@ -556,6 +556,8 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s
|
||||
void emit_sar32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
|
||||
void emit_rol32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
|
||||
void emit_ror32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
|
||||
void emit_shrd32c(dynarec_arm_t* dyn, int ninst, int s1, int s2, int32_t c, int s3, int s4);
|
||||
void emit_shld32c(dynarec_arm_t* dyn, int ninst, int s1, int s2, int32_t c, int s3, int s4);
|
||||
|
||||
// x87 helper
|
||||
// cache of the local stack counter, to avoid upadte at every call
|
||||
|
||||
@@ -34,6 +34,7 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
|
||||
dyn->sons_size = 0;
|
||||
// Clean up (because there are multiple passes)
|
||||
dyn->state_flags = 0;
|
||||
dyn->dfnone = 0;
|
||||
fpu_reset(dyn, ninst);
|
||||
// ok, go now
|
||||
INIT;
|
||||
@@ -52,7 +53,7 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
|
||||
MESSAGE(LOG_DUMP, "TRACE ----\n");
|
||||
fpu_reflectcache(dyn, ninst, x1, x2, x3);
|
||||
MOV32(x1, ip);
|
||||
STM(xEmu, (1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11));
|
||||
STM(xEmu, (1<<xEAX)|(1<<xEBX)|(1<<xECX)|(1<<xEDX)|(1<<xESI)|(1<<xEDI)|(1<<xESP)|(1<<xEBP));
|
||||
STR_IMM9(x1, xEmu, offsetof(x86emu_t, ip));
|
||||
MOVW(x2, 1);
|
||||
CALL(PrintTrace, -1, 0);
|
||||
@@ -67,19 +68,24 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
|
||||
|
||||
if(dyn->insts && dyn->insts[ninst+1].x86.barrier) {
|
||||
fpu_purgecache(dyn, ninst, x1, x2, x3);
|
||||
if(dyn->insts[ninst+1].x86.barrier!=2)
|
||||
if(dyn->insts[ninst+1].x86.barrier!=2) {
|
||||
dyn->state_flags = 0;
|
||||
dyn->dfnone = 0;
|
||||
}
|
||||
}
|
||||
if(!ok && !need_epilog && dyn->insts && (addr < (dyn->start+dyn->isize))) {
|
||||
ok = 1;
|
||||
}
|
||||
if(!ok && !need_epilog && !dyn->insts) { // check if need to continue
|
||||
uintptr_t next = get_closest_next(dyn, addr);
|
||||
if(next && ((next-addr)<15) && is_nops(dyn, addr, next-addr)) {
|
||||
if(next && (
|
||||
(((next-addr)<15) && is_nops(dyn, addr, next-addr))
|
||||
||(((next-addr)<30) && is_instructions(dyn, addr, next-addr)) ))
|
||||
{
|
||||
dynarec_log(LOG_DEBUG, "Extend block %p, %p -> %p (ninst=%d)\n", dyn, (void*)addr, (void*)next, ninst);
|
||||
ok = 1;
|
||||
} else if(next && (next-addr)<15) {
|
||||
dynarec_log(LOG_DEBUG, "Cannot extend block %p -> %p (%02X %02X %02X %02X %02X)\n", (void*)addr, (void*)next, PK(0), PK(1), PK(2), PK(3), PK(4));
|
||||
} else if(next && (next-addr)<30) {
|
||||
dynarec_log(LOG_DEBUG, "Cannot extend block %p -> %p (%02X %02X %02X %02X %02X %02X %02X %02x)\n", (void*)addr, (void*)next, PK(0), PK(1), PK(2), PK(3), PK(4), PK(5), PK(6), PK(7));
|
||||
}
|
||||
}
|
||||
if(ok<0) {ok = 0; need_epilog=1;}
|
||||
|
||||
@@ -43,6 +43,7 @@ typedef struct dynarec_arm_s {
|
||||
int fpu_extra_qscratch; // some opcode need an extra quad scratch register
|
||||
int fpu_reg; // x87/sse/mmx reg counter
|
||||
int nolinker; // disable use of (smart) linker in the block
|
||||
int dfnone; // if defered flags is already set to df_none
|
||||
uintptr_t* next; // variable array of "next" jump address
|
||||
int next_sz;
|
||||
int next_cap;
|
||||
@@ -54,5 +55,6 @@ typedef struct dynarec_arm_s {
|
||||
void add_next(dynarec_arm_t *dyn, uintptr_t addr);
|
||||
uintptr_t get_closest_next(dynarec_arm_t *dyn, uintptr_t addr);
|
||||
int is_nops(dynarec_arm_t *dyn, uintptr_t addr, int n);
|
||||
int is_instructions(dynarec_arm_t *dyn, uintptr_t addr, int n);
|
||||
|
||||
#endif //__DYNAREC_ARM_PRIVATE_H_
|
||||
+14
-10
@@ -28,6 +28,7 @@
|
||||
#include "dynarec.h"
|
||||
#include "box86stack.h"
|
||||
#ifdef DYNAREC
|
||||
#include "custommem.h"
|
||||
#include "dynablock.h"
|
||||
#endif
|
||||
#include "../emu/x86emu_private.h"
|
||||
@@ -64,10 +65,10 @@ void FreeElfHeader(elfheader_t** head)
|
||||
return;
|
||||
elfheader_t *h = *head;
|
||||
#ifdef DYNAREC
|
||||
if(h->text) {
|
||||
/*if(h->text) {
|
||||
dynarec_log(LOG_INFO, "Free Dynarec block for %s\n", h->path);
|
||||
cleanDBFromAddressRange(my_context, h->text, h->textsz, 1);
|
||||
}
|
||||
}*/ // will be free at the end, no need to free it now
|
||||
#endif
|
||||
free(h->name);
|
||||
free(h->path);
|
||||
@@ -206,6 +207,7 @@ int AllocElfMemory(box86context_t* context, elfheader_t* head, int mainbin)
|
||||
printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%x/0x%x) for elf \"%s\"\n", (void*)head->multiblock_offs[i], head->multiblock_size[i], head->align, head->name);
|
||||
return 1;
|
||||
}
|
||||
updateProtection((uintptr_t)p, head->multiblock_size[i], PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
head->multiblock[i] = p;
|
||||
if(p<(void*)head->memory)
|
||||
head->memory = (char*)p;
|
||||
@@ -221,6 +223,7 @@ int AllocElfMemory(box86context_t* context, elfheader_t* head, int mainbin)
|
||||
printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%x/0x%x) for elf \"%s\"\n", (void*)offs, head->memsz, head->align, head->name);
|
||||
return 1;
|
||||
}
|
||||
updateProtection((uintptr_t)p, head->memsz, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
head->memory = p;
|
||||
memset(p, 0, head->memsz);
|
||||
head->delta = (intptr_t)p - (intptr_t)head->vaddr;
|
||||
@@ -264,13 +267,14 @@ int LoadElfMemory(FILE* f, box86context_t* context, elfheader_t* head)
|
||||
printf_log(LOG_NONE, "Fail to read PT_LOAD part #%d (size=%d)\n", i, e->p_filesz);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#ifdef DYNAREC
|
||||
if(e->p_flags & PF_X) {
|
||||
dynarec_log(LOG_DEBUG, "Add ELF eXecutable Memory %p:%p\n", dest, (void*)e->p_memsz);
|
||||
addDBFromAddressRange(context, (uintptr_t)dest, e->p_memsz, 0);
|
||||
}
|
||||
if(e->p_flags & PF_X) {
|
||||
dynarec_log(LOG_DEBUG, "Add ELF eXecutable Memory %p:%p\n", dest, (void*)e->p_memsz);
|
||||
addDBFromAddressRange((uintptr_t)dest, e->p_memsz, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// zero'd difference between filesz and memsz
|
||||
/*if(e->p_filesz != e->p_memsz)
|
||||
memset(dest+e->p_filesz, 0, e->p_memsz - e->p_filesz);*/ //block is already 0'd at creation
|
||||
@@ -581,7 +585,7 @@ int RelocateElfPlt(lib_t *maplib, lib_t *local_maplib, elfheader_t* head)
|
||||
return -1;
|
||||
}
|
||||
if(pltResolver==~0) {
|
||||
pltResolver = AddBridge(my_context->system, my_context, vFE, PltResolver, 0);
|
||||
pltResolver = AddBridge(my_context->system, vFE, PltResolver, 0);
|
||||
}
|
||||
if(head->pltgot) {
|
||||
*(uintptr_t*)(head->pltgot+head->delta+8) = pltResolver;
|
||||
@@ -1007,8 +1011,8 @@ dynablocklist_t* GetDynablocksFromAddress(box86context_t *context, uintptr_t add
|
||||
return ret;
|
||||
}*/
|
||||
if(box86_dynarec_forced) {
|
||||
addDBFromAddressRange(my_context, addr, 1, 1);
|
||||
return my_context->dynmap[addr>>DYNAMAP_SHIFT];
|
||||
addDBFromAddressRange(addr, 1, 1);
|
||||
return getDB(addr>>DYNAMAP_SHIFT);
|
||||
}
|
||||
//check if address is in an elf... if yes, grant a block (should I warn)
|
||||
Dl_info info;
|
||||
|
||||
@@ -146,5 +146,6 @@
|
||||
|
||||
// Alias
|
||||
#define GET_EW GET_ED
|
||||
#define GET_EW_OFFS GET_ED_OFFS
|
||||
#define EW ED
|
||||
#define GW GD
|
||||
+37
-6
@@ -2,16 +2,29 @@
|
||||
goto *opcodes66[opcode];
|
||||
|
||||
#define GO(B, OP) \
|
||||
_66_##B##_0: \
|
||||
nextop = F8; \
|
||||
GET_EB; \
|
||||
EB->byte[0] = OP##8(emu, EB->byte[0], GB); \
|
||||
NEXT; \
|
||||
_66_##B##_1: \
|
||||
nextop = F8; \
|
||||
GET_EW; \
|
||||
EW->word[0] = OP##16(emu, EW->word[0], GW.word[0]); \
|
||||
NEXT; \
|
||||
_66_##B##_2: \
|
||||
nextop = F8; \
|
||||
GET_EB; \
|
||||
GB = OP##8(emu, GB, EB->byte[0]); \
|
||||
NEXT; \
|
||||
_66_##B##_3: \
|
||||
nextop = F8; \
|
||||
GET_EW; \
|
||||
GW.word[0] = OP##16(emu, GW.word[0], EW->word[0]); \
|
||||
NEXT; \
|
||||
_66_##B##_4: \
|
||||
R_AL = OP##8(emu, R_AL, F8); \
|
||||
NEXT; \
|
||||
_66_##B##_5: \
|
||||
R_AX = OP##16(emu, R_AX, F16); \
|
||||
NEXT;
|
||||
@@ -41,6 +54,11 @@
|
||||
if(emu->quit) goto fini;
|
||||
STEP
|
||||
NEXT;
|
||||
|
||||
_66_0x1F: /* POP DS */
|
||||
emu->segs[_DS] = Pop16(emu); // no check, no use....
|
||||
emu->segs_serial[_DS] = 0;
|
||||
NEXT;
|
||||
|
||||
_66_0x26: /* ES: */
|
||||
// ignored
|
||||
@@ -247,15 +265,12 @@
|
||||
|
||||
_66_0x9C: /* PUSHFW */
|
||||
CHECK_FLAGS(emu);
|
||||
PackFlags(emu);
|
||||
Push16(emu, (uint16_t)emu->packed_eflags.x32);
|
||||
Push16(emu, (uint16_t)emu->eflags.x32);
|
||||
NEXT;
|
||||
_66_0x9D: /* POPFW */
|
||||
CHECK_FLAGS(emu);
|
||||
PackFlags(emu);
|
||||
emu->packed_eflags.x32 &=0xffff0000;
|
||||
emu->packed_eflags.x32 |= (Pop16(emu) & 0x3F7FD7) | 0x2;
|
||||
UnpackFlags(emu);
|
||||
emu->eflags.x32 &=0xffff0000;
|
||||
emu->eflags.x32 |= (Pop16(emu) & 0x3F7FD7) | 0x2;
|
||||
NEXT;
|
||||
|
||||
_66_0xA1: /* MOV AX,Ow */
|
||||
@@ -333,6 +348,22 @@
|
||||
EW->word[0] = F16;
|
||||
NEXT;
|
||||
|
||||
_66_0xCB: /* FAR RET */
|
||||
ip = Pop(emu);
|
||||
emu->segs[_CS] = Pop(emu); // no check, no use....
|
||||
emu->segs_serial[_CS] = 0;
|
||||
// need to check status of CS register!
|
||||
STEP
|
||||
NEXT;
|
||||
_66_0xCC: /* INT3 */
|
||||
emu->old_ip = R_EIP;
|
||||
R_EIP = ip-1;
|
||||
if(my_context->signals[SIGTRAP])
|
||||
raise(SIGTRAP);
|
||||
ip = R_EIP;
|
||||
if(emu->quit) goto fini;
|
||||
STEP
|
||||
NEXT;
|
||||
_66_0xD1: /* GRP2 Ew,1 */
|
||||
_66_0xD3: /* GRP2 Ew,CL */
|
||||
nextop = F8;
|
||||
|
||||
+8
-7
@@ -15,6 +15,9 @@
|
||||
#include "x86run.h"
|
||||
#include "x86run_private.h"
|
||||
#include "callback.h"
|
||||
#ifdef DYNAREC
|
||||
#include "custommem.h"
|
||||
#endif
|
||||
|
||||
typedef struct cleanup_s {
|
||||
void* f;
|
||||
@@ -39,7 +42,7 @@ static uint8_t EndEmuMarker[] = {0xcc, 'S', 'C', 0, 0, 0, 0};
|
||||
void DynablockEmuMarker(box86context_t* context)
|
||||
{
|
||||
dynarec_log(LOG_DUMP, "Create bridge memory map for PushExit\n");
|
||||
addDBFromAddressRange(context, (uintptr_t)&EndEmuMarker[0], sizeof(EndEmuMarker), 0);
|
||||
addDBFromAddressRange((uintptr_t)&EndEmuMarker[0], sizeof(EndEmuMarker), 0);
|
||||
}
|
||||
#endif
|
||||
void PushExit(x86emu_t* emu)
|
||||
@@ -60,8 +63,7 @@ static void internalX86Setup(x86emu_t* emu, box86context_t *context, uintptr_t s
|
||||
emu->sbiidx[i] = &emu->regs[i];
|
||||
emu->sbiidx[4] = &emu->zero;
|
||||
emu->x86emu_parity_tab = x86emu_parity_tab;
|
||||
emu->packed_eflags.x32 = 0x202; // default flags?
|
||||
UnpackFlags(emu);
|
||||
emu->eflags.x32 = 0x202; // default flags?
|
||||
// own stack?
|
||||
emu->stack2free = (ownstack)?(void*)stack:NULL;
|
||||
emu->init_stack = (void*)stack;
|
||||
@@ -177,7 +179,7 @@ void FreeX86Emu(x86emu_t **emu)
|
||||
{
|
||||
if(!emu)
|
||||
return;
|
||||
printf_log(LOG_DEBUG, "Free a X86 Emu (%p)\n", *emu);
|
||||
printf_log(LOG_DEBUG, "%04d|Free a X86 Emu (%p)\n", GetTID(), *emu);
|
||||
|
||||
internalFreeX86(*emu);
|
||||
|
||||
@@ -189,7 +191,7 @@ void FreeX86EmuFromStack(x86emu_t **emu)
|
||||
{
|
||||
if(!emu)
|
||||
return;
|
||||
printf_log(LOG_DEBUG, "Free a X86 Emu from stack (%p)\n", *emu);
|
||||
printf_log(LOG_DEBUG, "%04d|Free a X86 Emu from stack (%p)\n", GetTID(), *emu);
|
||||
|
||||
internalFreeX86(*emu);
|
||||
}
|
||||
@@ -198,8 +200,7 @@ void CloneEmu(x86emu_t *newemu, const x86emu_t* emu)
|
||||
{
|
||||
memcpy(newemu->regs, emu->regs, sizeof(emu->regs));
|
||||
memcpy(&newemu->ip, &emu->ip, sizeof(emu->ip));
|
||||
memcpy(&newemu->packed_eflags, &emu->packed_eflags, sizeof(emu->packed_eflags));
|
||||
memcpy(&newemu->flags, &emu->flags, sizeof(emu->flags));
|
||||
memcpy(&newemu->eflags, &emu->eflags, sizeof(emu->eflags));
|
||||
newemu->old_ip = emu->old_ip;
|
||||
memcpy(newemu->segs, emu->segs, sizeof(emu->segs));
|
||||
memset(newemu->segs_serial, 0, sizeof(newemu->segs_serial));
|
||||
|
||||
@@ -25,9 +25,9 @@ typedef struct forkpty_s {
|
||||
|
||||
typedef struct x86emu_s {
|
||||
// cpu
|
||||
reg32_t regs[8],ip;
|
||||
int flags[F_LAST];
|
||||
x86flags_t packed_eflags;
|
||||
reg32_t regs[8];
|
||||
x86flags_t eflags;
|
||||
reg32_t ip;
|
||||
uintptr_t old_ip;
|
||||
// fpu
|
||||
fpu_reg_t fpu[9];
|
||||
|
||||
+25
-16
@@ -9,6 +9,7 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "box86stack.h"
|
||||
@@ -155,19 +156,22 @@ void x86Int3(x86emu_t* emu)
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p(\"%s\"), %i(%c))", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+4), *(int32_t*)(R_ESP+8), *(int32_t*)(R_ESP+8));
|
||||
} else if(strstr(s, "rindex")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p(\"%s\"), %i(%c))", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+4), *(int32_t*)(R_ESP+8), *(int32_t*)(R_ESP+8));
|
||||
} else if(strstr(s, "__xstat64")==s) {
|
||||
} else if(strstr(s, "my___xstat64")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)(R_ESP), s, *(int32_t*)(R_ESP+4), *(char**)(R_ESP+8), *(char**)(R_ESP+8), *(void**)(R_ESP+12));
|
||||
perr = 1;
|
||||
} else if(strcmp(s, "__xstat")==0) {
|
||||
} else if(strcmp(s, "my___xstat")==0) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)(R_ESP), s, *(int32_t*)(R_ESP+4), *(char**)(R_ESP+8), *(char**)(R_ESP+8), *(void**)(R_ESP+12));
|
||||
perr = 1;
|
||||
} else if(strstr(s, "__lxstat64")==s) {
|
||||
} else if(strstr(s, "my___lxstat64")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)(R_ESP), s, *(int32_t*)(R_ESP+4), *(char**)(R_ESP+8), *(char**)(R_ESP+8), *(void**)(R_ESP+12));
|
||||
perr = 1;
|
||||
} else if(strstr(s, "sem_timedwait")==s) {
|
||||
pu32 = *(uint32_t**)(R_ESP+8);
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p, %p[%d sec %d ns])", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(void**)(R_ESP+8), pu32?pu32[0]:-1, pu32?pu32[1]:-1);
|
||||
perr = 1;
|
||||
} else if(strstr(s, "waitpid")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p, 0x%x)", tid, *(void**)(R_ESP), s, *(int32_t*)(R_ESP+4), *(void**)(R_ESP+8), *(uint32_t*)(R_ESP+12));
|
||||
perr = 1;
|
||||
} else if(strstr(s, "clock_gettime")==s || strstr(s, "__clock_gettime")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), *(void**)(R_ESP+8));
|
||||
post = 1;
|
||||
@@ -176,10 +180,10 @@ void x86Int3(x86emu_t* emu)
|
||||
int16_t* p16 = *(int16_t**)(R_ESP+8);
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p[%u/%d/%d], %d)", tid, *(void**)(R_ESP), s, *(int*)(R_ESP+4), p16, p16[0], p16[1], p16[2], *(int*)(R_ESP+12));
|
||||
perr = 1;
|
||||
} else if(!strcmp(s, "mmap64")) {
|
||||
} else if(!strcmp(s, "my_mmap64")) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p, 0x%x, %d, 0x%x, %d, %lld)", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(size_t*)(R_ESP+8), *(int*)(R_ESP+12), *(int*)(R_ESP+16), *(int*)(R_ESP+20), *(int64_t*)(R_ESP+24));
|
||||
perr = 1;
|
||||
} else if(!strcmp(s, "mmap")) {
|
||||
} else if(!strcmp(s, "my_mmap")) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p, 0x%x, %d, 0x%x, %d, %d)", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(size_t*)(R_ESP+8), *(int*)(R_ESP+12), *(int*)(R_ESP+16), *(int*)(R_ESP+20), *(int*)(R_ESP+24));
|
||||
perr = 1;
|
||||
} else if(strstr(s, "strcasecmp")==s || strstr(s, "__strcasecmp")==s) {
|
||||
@@ -192,40 +196,42 @@ void x86Int3(x86emu_t* emu)
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(\"%.127s\", \"%.127s\")", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
} else if(strstr(s, "strlen")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p(\"%s\"))", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), ((R_ESP+4))?(*(char**)(R_ESP+4)):"nil");
|
||||
} else if(strstr(s, "vsnprintf")==s) {
|
||||
} else if(strstr(s, "my_vsnprintf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, %u, %08X...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), *(uint32_t*)(R_ESP+8), *(uint32_t*)(R_ESP+12));
|
||||
pu32 = *(uint32_t**)(R_ESP+4);
|
||||
post = 3;
|
||||
} else if(strstr(s, "vsprintf")==s) {
|
||||
} else if(strstr(s, "my_vsprintf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, \"%s\"...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
pu32 = *(uint32_t**)(R_ESP+4);
|
||||
post = 3;
|
||||
} else if(strstr(s, "snprintf")==s) {
|
||||
} else if(strstr(s, "my_snprintf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, %u, %08X...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), *(uint32_t*)(R_ESP+8), *(uint32_t*)(R_ESP+12));
|
||||
pu32 = *(uint32_t**)(R_ESP+4);
|
||||
post = 3;
|
||||
} else if(strstr(s, "sprintf")==s) {
|
||||
} else if(strstr(s, "my_sprintf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, %08X...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), *(uint32_t*)(R_ESP+8));
|
||||
pu32 = *(uint32_t**)(R_ESP+4);
|
||||
post = 3;
|
||||
} else if(strstr(s, "printf")==s) {
|
||||
} else if(strstr(s, "my_printf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\"...)", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4));
|
||||
} else if(strstr(s, "puts")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\"...)", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4));
|
||||
} else if(strstr(s, "fputs")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, \"%s\"...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
} else if(strstr(s, "fprintf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %p...)", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(void**)(R_ESP+8));
|
||||
} else if(strstr(s, "my_fprintf")==s) {
|
||||
pu32 = *(uint32_t**)(R_ESP+8);
|
||||
if(((uintptr_t)pu32)<0x5) // probably a __fprint_chk
|
||||
pu32 = *(uint32_t**)(R_ESP+12);
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, \"%s\", ...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), pu32?((char*)(pu32)):"nil");
|
||||
} else if(strstr(s, "vfprintf")==s) {
|
||||
} else if(strstr(s, "my_vfprintf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, \"%s\", ...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
} else if(strstr(s, "vkGetInstanceProcAddr")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
} else if(strstr(s, "vkGetDeviceProcAddr")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
} else if(strstr(s, "sscanf")==s) {
|
||||
} else if(strstr(s, "my_sscanf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\", ...)", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
} else if(strstr(s, "vsscanf")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\", ...)", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
} else if(strstr(s, "XCreateWindow")==s) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p, %p, %d, %d, %u, %u, %u, %d, %u, %p, %u, %p)", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(void**)(R_ESP+8), *(int*)(R_ESP+12), *(int*)(R_ESP+16), *(uint32_t*)(R_ESP+20), *(uint32_t*)(R_ESP+24), *(uint32_t*)(R_ESP+28), *(int32_t*)(R_ESP+32), *(uint32_t*)(R_ESP+36), *(void**)(R_ESP+40), *(uint32_t*)(R_ESP+44), *(void**)(R_ESP+48));
|
||||
@@ -245,7 +251,7 @@ void x86Int3(x86emu_t* emu)
|
||||
} else if(strstr(s, "udev_monitor_new_from_netlink")==s) {
|
||||
post = 5;
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(char**)(R_ESP+8));
|
||||
} else if(!strcmp(s, "syscall")) {
|
||||
} else if(!strcmp(s, "my_syscall")) {
|
||||
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p, %p, %p...)", tid, *(void**)(R_ESP), s, *(int32_t*)(R_ESP+4), *(void**)(R_ESP+8), *(void**)(R_ESP+12), *(void**)(R_ESP+16));
|
||||
perr = 1;
|
||||
} else {
|
||||
@@ -285,7 +291,10 @@ void x86Int3(x86emu_t* emu)
|
||||
}
|
||||
return;
|
||||
}
|
||||
printf_log(LOG_INFO, "Warning, ignoring unsupported Int 3 call\n");
|
||||
if(my_context->signals[SIGTRAP])
|
||||
raise(SIGTRAP);
|
||||
else
|
||||
printf_log(LOG_INFO, "Warning, ignoring unsupported Int 3 call\n");
|
||||
//emu->quit = 1;
|
||||
}
|
||||
|
||||
|
||||
+25
-21
@@ -134,13 +134,13 @@ int Run(x86emu_t *emu, int step)
|
||||
};
|
||||
|
||||
static const void* opcodes66[256] = {
|
||||
&&_default, &&_66_0x00_1, &&_default, &&_66_0x00_3, &&_default ,&&_66_0x00_5, &&_66_0x06, &&_66_0x07, //0x00-0x07
|
||||
&&_default, &&_66_0x08_1, &&_default, &&_66_0x08_3, &&_default ,&&_66_0x08_5, &&_default, &&_66_0x0F, //0x08-0x0F
|
||||
&&_default, &&_66_0x10_1, &&_default, &&_66_0x10_3, &&_default ,&&_66_0x10_5, &&_default, &&_default, //0x10-0x17
|
||||
&&_default, &&_66_0x18_1, &&_default, &&_66_0x18_3, &&_default ,&&_66_0x18_5, &&_default, &&_default, //0x18-0x1F
|
||||
&&_default, &&_66_0x20_1, &&_default, &&_66_0x20_3, &&_default ,&&_66_0x20_5, &&_66_0x26, &&_default, //0x20-0x27
|
||||
&&_default, &&_66_0x28_1, &&_default, &&_66_0x28_3, &&_default ,&&_66_0x28_5, &&_66_0x2E, &&_default, //0x28-0x2F
|
||||
&&_default, &&_66_0x30_1, &&_default, &&_66_0x30_3, &&_default ,&&_66_0x30_5, &&_66_0x36, &&_default, //0x30-0x37
|
||||
&&_66_0x00_0, &&_66_0x00_1, &&_66_0x00_2, &&_66_0x00_3, &&_66_0x00_4 ,&&_66_0x00_5, &&_66_0x06, &&_66_0x07, //0x00-0x07
|
||||
&&_66_0x08_0, &&_66_0x08_1, &&_66_0x08_2, &&_66_0x08_3, &&_66_0x08_4 ,&&_66_0x08_5, &&_default, &&_66_0x0F, //0x08-0x0F
|
||||
&&_66_0x10_0, &&_66_0x10_1, &&_66_0x10_2, &&_66_0x10_3, &&_66_0x10_4 ,&&_66_0x10_5, &&_default, &&_default, //0x10-0x17
|
||||
&&_66_0x18_0, &&_66_0x18_1, &&_66_0x18_2, &&_66_0x18_3, &&_66_0x18_4 ,&&_66_0x18_5, &&_default, &&_66_0x1F, //0x18-0x1F
|
||||
&&_66_0x20_0, &&_66_0x20_1, &&_66_0x20_2, &&_66_0x20_3, &&_66_0x20_4 ,&&_66_0x20_5, &&_66_0x26, &&_default, //0x20-0x27
|
||||
&&_66_0x28_0, &&_66_0x28_1, &&_66_0x28_2, &&_66_0x28_3, &&_66_0x28_4 ,&&_66_0x28_5, &&_66_0x2E, &&_default, //0x28-0x2F
|
||||
&&_66_0x30_0, &&_66_0x30_1, &&_66_0x30_2, &&_66_0x30_3, &&_66_0x30_4 ,&&_66_0x30_5, &&_66_0x36, &&_default, //0x30-0x37
|
||||
&&_default, &&_66_0x39, &&_default, &&_66_0x3B, &&_default, &&_66_0x3D, &&_default, &&_default, //0x38-0x3F
|
||||
&&_66_0x40, &&_66_0x41, &&_66_0x42, &&_66_0x43, &&_66_0x44, &&_66_0x45, &&_66_0x46, &&_66_0x47,
|
||||
&&_66_0x48, &&_66_0x49, &&_66_0x4A, &&_66_0x4B, &&_66_0x4C, &&_66_0x4D, &&_66_0x4E, &&_66_0x4F,
|
||||
@@ -159,7 +159,7 @@ int Run(x86emu_t *emu, int step)
|
||||
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_default, &&_default, &&_default, //0xB0-0xB7
|
||||
&&_66_0xB8, &&_66_0xB9, &&_66_0xBA, &&_66_0xBB, &&_66_0xBC, &&_66_0xBD, &&_66_0xBE, &&_66_0xBF,
|
||||
&&_default, &&_66_0xC1, &&_default, &&_default, &&_default, &&_default, &&_default, &&_66_0xC7,
|
||||
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_default, &&_default, &&_default, //0xC8-0xCF
|
||||
&&_default, &&_default, &&_default, &&_66_0xCB, &&_66_0xCC ,&&_default, &&_default, &&_default, //0xC8-0xCF
|
||||
&&_default, &&_66_0xD1, &&_default, &&_66_0xD3, &&_default, &&_default, &&_default, &&_default, //0xD0-0xD7
|
||||
&&_default, &&_66_0xD9, &&_default, &&_default, &&_default ,&&_66_0xDD, &&_default, &&_default, //0xD8-0xDF
|
||||
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_default, &&_default, &&_default, //0xE0-0xE7
|
||||
@@ -170,7 +170,6 @@ int Run(x86emu_t *emu, int step)
|
||||
|
||||
x86emurun:
|
||||
ip = R_EIP;
|
||||
// UnpackFlags(emu);
|
||||
#ifdef HAVE_TRACE
|
||||
_trace:
|
||||
__builtin_prefetch((void*)ip, 0, 0);
|
||||
@@ -702,8 +701,15 @@ _trace:
|
||||
NEXT;
|
||||
_0x8F: /* POP Ed */
|
||||
nextop = F8;
|
||||
GET_ED;
|
||||
ED->dword[0] = Pop(emu);
|
||||
if((nextop&0xC0)==0xC0) {
|
||||
emu->regs[(nextop&7)].dword[0] = Pop(emu);
|
||||
} else {
|
||||
tmp32u = Pop(emu); // this order allows handling POP [ESP] and variant
|
||||
GET_ED;
|
||||
R_ESP -= 4; // to prevent issue with SEGFAULT
|
||||
ED->dword[0] = tmp32u;
|
||||
R_ESP += 4;
|
||||
}
|
||||
NEXT;
|
||||
_0x90: /* NOP */
|
||||
NEXT;
|
||||
@@ -730,12 +736,10 @@ _trace:
|
||||
NEXT;
|
||||
_0x9C: /* PUSHF */
|
||||
CHECK_FLAGS(emu);
|
||||
PackFlags(emu);
|
||||
Push(emu, emu->packed_eflags.x32);
|
||||
Push(emu, emu->eflags.x32);
|
||||
NEXT;
|
||||
_0x9D: /* POPF */
|
||||
emu->packed_eflags.x32 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
|
||||
UnpackFlags(emu);
|
||||
emu->eflags.x32 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
|
||||
RESET_FLAGS(emu);
|
||||
NEXT;
|
||||
_0x9E: /* SAHF */
|
||||
@@ -749,8 +753,7 @@ _trace:
|
||||
NEXT;
|
||||
_0x9F: /* LAHF */
|
||||
CHECK_FLAGS(emu);
|
||||
PackFlags(emu);
|
||||
R_AH = (uint8_t)emu->packed_eflags.x32;
|
||||
R_AH = (uint8_t)emu->eflags.x32;
|
||||
NEXT;
|
||||
|
||||
_0xA0: /* MOV AL,Ob */
|
||||
@@ -976,8 +979,7 @@ _trace:
|
||||
ip = Pop(emu);
|
||||
emu->segs[_CS] = Pop(emu);
|
||||
emu->segs_serial[_CS] = 0;
|
||||
emu->packed_eflags.x32 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
|
||||
UnpackFlags(emu);
|
||||
emu->eflags.x32 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
|
||||
RESET_FLAGS(emu);
|
||||
NEXT;
|
||||
_0xD0: /* GRP2 Eb,1 */
|
||||
@@ -1434,7 +1436,8 @@ _trace:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
case 1: /* TEST Eb,Ib */
|
||||
test8(emu, EB->byte[0], F8);
|
||||
tmp8u = F8;
|
||||
test8(emu, EB->byte[0], tmp8u);
|
||||
break;
|
||||
case 2: /* NOT Eb */
|
||||
EB->byte[0] = not8(emu, EB->byte[0]);
|
||||
@@ -1462,7 +1465,8 @@ _trace:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
case 1: /* TEST Ed,Id */
|
||||
test32(emu, ED->dword[0], F32);
|
||||
tmp32u = F32;
|
||||
test32(emu, ED->dword[0], tmp32u);
|
||||
break;
|
||||
case 2: /* NOT Ed */
|
||||
ED->dword[0] = not32(emu, ED->dword[0]);
|
||||
|
||||
+90
-16
@@ -288,16 +288,32 @@ void RunLock(x86emu_t *emu)
|
||||
nextop = F8;
|
||||
GET_ED;
|
||||
#ifdef DYNAREC
|
||||
do {
|
||||
tmp32u = arm_lock_read_d(ED);
|
||||
cmp32(emu, R_EAX, tmp32u);
|
||||
if(ACCESS_FLAG(F_ZF)) {
|
||||
tmp32s = arm_lock_write_d(ED, GD.dword[0]);
|
||||
} else {
|
||||
R_EAX = tmp32u;
|
||||
tmp32s = 0;
|
||||
}
|
||||
} while(tmp32s);
|
||||
if(((uintptr_t)ED)&3) {
|
||||
do {
|
||||
tmp32u = ED->dword[0] & ~0xff;
|
||||
tmp32u |= arm_lock_read_b(ED);
|
||||
cmp32(emu, R_EAX, tmp32u);
|
||||
if(ACCESS_FLAG(F_ZF)) {
|
||||
tmp32s = arm_lock_write_b(ED, GD.dword[0] & 0xff);
|
||||
if(!tmp32s)
|
||||
ED->dword[0] = GD.dword[0];
|
||||
} else {
|
||||
R_EAX = tmp32u;
|
||||
tmp32s = 0;
|
||||
}
|
||||
} while(tmp32s);
|
||||
} else {
|
||||
do {
|
||||
tmp32u = arm_lock_read_d(ED);
|
||||
cmp32(emu, R_EAX, tmp32u);
|
||||
if(ACCESS_FLAG(F_ZF)) {
|
||||
tmp32s = arm_lock_write_d(ED, GD.dword[0]);
|
||||
} else {
|
||||
R_EAX = tmp32u;
|
||||
tmp32s = 0;
|
||||
}
|
||||
} while(tmp32s);
|
||||
}
|
||||
#else
|
||||
pthread_mutex_lock(&emu->context->mutex_lock);
|
||||
cmp32(emu, R_EAX, ED->dword[0]);
|
||||
@@ -455,10 +471,19 @@ void RunLock(x86emu_t *emu)
|
||||
nextop = F8;
|
||||
GET_ED;
|
||||
#ifdef DYNAREC
|
||||
do {
|
||||
tmp32u = arm_lock_read_d(ED);
|
||||
tmp32u2 = add32(emu, tmp32u, GD.dword[0]);
|
||||
} while(arm_lock_write_d(ED, tmp32u2));
|
||||
if(((uintptr_t)ED)&3) {
|
||||
do {
|
||||
tmp32u = ED->dword[0] & ~0xff;
|
||||
tmp32u |= arm_lock_read_b(ED);
|
||||
tmp32u2 = add32(emu, tmp32u, GD.dword[0]);
|
||||
} while(arm_lock_write_b(ED, tmp32u2&0xff));
|
||||
ED->dword[0] = tmp32u2;
|
||||
} else {
|
||||
do {
|
||||
tmp32u = arm_lock_read_d(ED);
|
||||
tmp32u2 = add32(emu, tmp32u, GD.dword[0]);
|
||||
} while(arm_lock_write_d(ED, tmp32u2));
|
||||
}
|
||||
GD.dword[0] = tmp32u;
|
||||
#else
|
||||
pthread_mutex_lock(&emu->context->mutex_lock);
|
||||
@@ -626,11 +651,12 @@ void RunLock(x86emu_t *emu)
|
||||
|
||||
void RunLock66(x86emu_t *emu)
|
||||
{
|
||||
uintptr_t ip = R_EIP+1;
|
||||
uintptr_t ip = R_EIP+2;
|
||||
uint8_t opcode = F8;
|
||||
uint8_t nextop;
|
||||
reg32_t *oped;
|
||||
uint16_t tmp16u;
|
||||
uint16_t tmp16u, tmp16u2;
|
||||
int16_t tmp16s;
|
||||
int32_t tmp32s;
|
||||
switch(opcode) {
|
||||
case 0x0f:
|
||||
@@ -667,6 +693,41 @@ void RunLock66(x86emu_t *emu)
|
||||
UnimpOpcode(emu);
|
||||
}
|
||||
break;
|
||||
case 0x81: /* GRP Ed,Iw */
|
||||
case 0x83: /* GRP Ed,Ib */
|
||||
nextop = F8;
|
||||
GET_EW;
|
||||
if(opcode==0x83) {
|
||||
tmp16s = F8S;
|
||||
tmp16u = (uint32_t)tmp16s;
|
||||
} else
|
||||
tmp16u = F16;
|
||||
#ifdef DYNAREC
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: do { tmp16u2 = arm_lock_read_h(EW);} while(arm_lock_write_h(EW, add16(emu, tmp16u2, tmp16u))); break;
|
||||
case 1: do { tmp16u2 = arm_lock_read_h(EW);} while(arm_lock_write_h(EW, or16(emu, tmp16u2, tmp16u))); break;
|
||||
case 2: do { tmp16u2 = arm_lock_read_h(EW);} while(arm_lock_write_h(EW, adc16(emu, tmp16u2, tmp16u))); break;
|
||||
case 3: do { tmp16u2 = arm_lock_read_h(EW);} while(arm_lock_write_h(EW, sbb16(emu, tmp16u2, tmp16u))); break;
|
||||
case 4: do { tmp16u2 = arm_lock_read_h(EW);} while(arm_lock_write_h(EW, and16(emu, tmp16u2, tmp16u))); break;
|
||||
case 5: do { tmp16u2 = arm_lock_read_h(EW);} while(arm_lock_write_h(EW, sub16(emu, tmp16u2, tmp16u))); break;
|
||||
case 6: do { tmp16u2 = arm_lock_read_h(EW);} while(arm_lock_write_h(EW, xor16(emu, tmp16u2, tmp16u))); break;
|
||||
case 7: cmp16(emu, ED->dword[0], tmp16u); break;
|
||||
}
|
||||
#else
|
||||
pthread_mutex_lock(&emu->context->mutex_lock);
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: EW->word[0] = add16(emu, EW->word[0], tmp16u); break;
|
||||
case 1: EW->word[0] = or16(emu, EW->word[0], tmp16u); break;
|
||||
case 2: EW->word[0] = adc16(emu, EW->word[0], tmp16u); break;
|
||||
case 3: EW->word[0] = sbb16(emu, EW->word[0], tmp16u); break;
|
||||
case 4: EW->word[0] = and16(emu, EW->word[0], tmp16u); break;
|
||||
case 5: EW->word[0] = sub16(emu, EW->word[0], tmp16u); break;
|
||||
case 6: EW->word[0] = xor16(emu, EW->word[0], tmp16u); break;
|
||||
case 7: cmp16(emu, EW->word[0], tmp16u); break;
|
||||
}
|
||||
pthread_mutex_unlock(&emu->context->mutex_lock);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ip-=3; // unfetch nextop, F0 & 66
|
||||
UnimpOpcode(emu);
|
||||
@@ -964,6 +1025,19 @@ void RunFS(x86emu_t *emu)
|
||||
--ip; // so ignore prefix and continue
|
||||
break;
|
||||
|
||||
case 0x66:
|
||||
opcode = F8;
|
||||
switch(opcode) {
|
||||
case 0x8B: /* MOV Gw,FS:Ew */
|
||||
nextop = F8;
|
||||
GET_EW_OFFS(tlsdata);
|
||||
GW.word[0] = EW->word[0];
|
||||
break;
|
||||
default:
|
||||
ip-=2;
|
||||
UnimpOpcode(emu);
|
||||
}
|
||||
break;
|
||||
case 0x67:
|
||||
opcode = F8;
|
||||
switch(opcode) {
|
||||
|
||||
+15
-4
@@ -66,7 +66,7 @@ void Run660F(x86emu_t *emu)
|
||||
&&_default, &&_default, &&_6f_0xBA, &&_6f_0xBB, &&_6f_0xBC, &&_6f_0xBD, &&_6f_0xBE, &&_default, //0xB8-0xBF
|
||||
&&_default, &&_6f_0xC1, &&_6f_0xC2, &&_default, &&_6f_0xC4, &&_6f_0xC5, &&_6f_0xC6, &&_default,
|
||||
&&_6f_0xC8, &&_6f_0xC9, &&_6f_0xCA, &&_6f_0xCB, &&_6f_0xCC ,&&_6f_0xCD, &&_6f_0xCE, &&_6f_0xCF, //0xC8-0xCF
|
||||
&&_default, &&_6f_0xD1, &&_6f_0xD2, &&_6f_0xD3, &&_6f_0xD4, &&_6f_0xD5, &&_6f_0xD6, &&_6f_0xD7,
|
||||
&&_6f_0xD0, &&_6f_0xD1, &&_6f_0xD2, &&_6f_0xD3, &&_6f_0xD4, &&_6f_0xD5, &&_6f_0xD6, &&_6f_0xD7,
|
||||
&&_6f_0xD8, &&_6f_0xD9, &&_6f_0xDA, &&_6f_0xDB, &&_6f_0xDC, &&_6f_0xDD, &&_6f_0xDE, &&_6f_0xDF,
|
||||
&&_6f_0xE0, &&_6f_0xE1, &&_6f_0xE2, &&_6f_0xE3, &&_6f_0xE4, &&_6f_0xE5, &&_6f_0xE6, &&_6f_0xE7,
|
||||
&&_6f_0xE8, &&_6f_0xE9, &&_6f_0xEA, &&_6f_0xEB, &&_6f_0xEC, &&_6f_0xED, &&_6f_0xEE, &&_6f_0xEF,
|
||||
@@ -188,12 +188,18 @@ void Run660F(x86emu_t *emu)
|
||||
_6f_0x12: /* MOVLPD Gx, Eq */
|
||||
nextop = F8;
|
||||
GET_ED;
|
||||
GX.q[0] = *(uint64_t*)ED;
|
||||
if((uintptr_t)ED & 7)
|
||||
memcpy(&GX.q[0], ED, 8);
|
||||
else
|
||||
GX.q[0] = *(uint64_t*)ED;
|
||||
NEXT;
|
||||
_6f_0x13: /* MOVLPD Eq, Gx */
|
||||
nextop = F8;
|
||||
GET_ED;
|
||||
*(uint64_t*)ED = GX.q[0];
|
||||
if((uintptr_t)ED & 7)
|
||||
memcpy(ED, &GX.q[0], 8);
|
||||
else
|
||||
*(uint64_t*)ED = GX.q[0];
|
||||
NEXT;
|
||||
_6f_0x14: /* UNPCKLPD Gx, Ex */
|
||||
nextop = F8;
|
||||
@@ -1103,7 +1109,12 @@ void Run660F(x86emu_t *emu)
|
||||
tmp8s = opcode&7;
|
||||
emu->regs[tmp8s].word[0] = __builtin_bswap16(emu->regs[tmp8s].word[0]);
|
||||
NEXT;
|
||||
|
||||
_6f_0xD0: /* ADDSUBPD Gx, Ex */
|
||||
nextop = F8;
|
||||
GET_EX;
|
||||
GX.d[0] -= EX->d[0];
|
||||
GX.d[1] += EX->d[1];
|
||||
NEXT;
|
||||
_6f_0xD1: /* PSRLW Gx, Ex */
|
||||
nextop = F8;
|
||||
GET_EX;
|
||||
|
||||
@@ -685,64 +685,6 @@ void UpdateFlags(x86emu_t *emu)
|
||||
RESET_FLAGS(emu);
|
||||
}
|
||||
|
||||
|
||||
void PackFlags(x86emu_t* emu)
|
||||
{
|
||||
#define GO(A) emu->packed_eflags.f.F__##A = emu->flags[F_##A];
|
||||
#define GOC(A, C) emu->packed_eflags.f.F__##A = C;
|
||||
GO(CF);
|
||||
GOC(res1, 1);
|
||||
GO(PF);
|
||||
GOC(res2, 0);
|
||||
GO(AF);
|
||||
GOC(res3, 0);
|
||||
GO(ZF);
|
||||
GO(SF);
|
||||
GO(TF);
|
||||
GO(IF);
|
||||
GO(DF);
|
||||
GO(OF);
|
||||
GO(IOPL);
|
||||
GO(NT);
|
||||
GOC(dummy, 0);
|
||||
GO(RF);
|
||||
GO(VM);
|
||||
GO(AC);
|
||||
GO(VIF);
|
||||
GO(VIP);
|
||||
GO(ID);
|
||||
#undef GO
|
||||
#undef GOC
|
||||
}
|
||||
void UnpackFlags(x86emu_t* emu)
|
||||
{
|
||||
#define GO(A) emu->flags[F_##A] = emu->packed_eflags.f.F__##A;
|
||||
#define GOC(A, C) emu->flags[F_##A] = C;
|
||||
GO(CF);
|
||||
GOC(res1, 1);
|
||||
GO(PF);
|
||||
GOC(res2, 0);
|
||||
GO(AF);
|
||||
GOC(res3, 0);
|
||||
GO(ZF);
|
||||
GO(SF);
|
||||
GO(TF);
|
||||
GO(IF);
|
||||
GO(DF);
|
||||
GO(OF);
|
||||
GO(IOPL);
|
||||
GO(NT);
|
||||
GOC(dummy, 0);
|
||||
GO(RF);
|
||||
GO(VM);
|
||||
GO(AC);
|
||||
GO(VIF);
|
||||
GO(VIP);
|
||||
GO(ID);
|
||||
#undef GO
|
||||
#undef GOC
|
||||
}
|
||||
|
||||
uintptr_t GetSegmentBaseEmu(x86emu_t* emu, int seg)
|
||||
{
|
||||
if(emu->segs_serial[seg] != emu->context->sel_serial) {
|
||||
@@ -807,7 +749,6 @@ void PrintTrace(x86emu_t* emu, uintptr_t ip, int dynarec)
|
||||
my_context->trace_tid = tid;
|
||||
}
|
||||
#endif
|
||||
trace_end = 0;
|
||||
printf_log(LOG_NONE, "%s", DumpCPURegs(emu, ip));
|
||||
if(PK(0)==0xcc && PK(1)=='S' && PK(2)=='C') {
|
||||
uint32_t a = *(uint32_t*)(ip+3);
|
||||
|
||||
@@ -208,9 +208,6 @@ void x86Syscall(x86emu_t *emu);
|
||||
void x86Int3(x86emu_t* emu);
|
||||
x86emu_t* x86emu_fork(x86emu_t* e, int forktype);
|
||||
|
||||
void PackFlags(x86emu_t* emu);
|
||||
void UnpackFlags(x86emu_t* emu);
|
||||
|
||||
uintptr_t GetSegmentBaseEmu(x86emu_t* emu, int seg);
|
||||
#define GetGSBaseEmu(emu) GetSegmentBaseEmu(emu, _GS)
|
||||
#define GetFSBaseEmu(emu) GetSegmentBaseEmu(emu, _FS)
|
||||
|
||||
+33
-4
@@ -68,6 +68,10 @@ int32_t my_epoll_wait(x86emu_t* emu, int32_t epfd, void* events, int32_t maxeven
|
||||
#endif
|
||||
int my_sigaction(x86emu_t* emu, int signum, const x86_sigaction_t *act, x86_sigaction_t *oldact);
|
||||
int32_t my_execve(x86emu_t* emu, const char* path, char* const argv[], char* const envp[]);
|
||||
void* my_mmap(x86emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, int offset);
|
||||
void* my_mmap64(x86emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, int64_t offset);
|
||||
int my_munmap(x86emu_t* emu, void* addr, unsigned long length);
|
||||
int my_mprotect(x86emu_t* emu, void *addr, unsigned long len, int prot);
|
||||
|
||||
// cannot include <fcntl.h>, it conflict with some asm includes...
|
||||
#ifndef O_NONBLOCK
|
||||
@@ -129,7 +133,7 @@ scwrap_t syscallwrap[] = {
|
||||
{ 82, __NR_select, 5 },
|
||||
#endif
|
||||
{ 85, __NR_readlink, 3 },
|
||||
{ 91, __NR_munmap, 2 },
|
||||
//{ 91, __NR_munmap, 2 },
|
||||
{ 94, __NR_fchmod, 2 },
|
||||
{ 99, __NR_statfs, 2 },
|
||||
#ifdef __NR_socketcall
|
||||
@@ -166,7 +170,7 @@ scwrap_t syscallwrap[] = {
|
||||
//{ 120, __NR_clone, 5 }, // need works
|
||||
//{ 122, __NR_uname, 1 },
|
||||
//{ 123, __NR_modify_ldt },
|
||||
{ 125, __NR_mprotect, 3 },
|
||||
//{ 125, __NR_mprotect, 3 },
|
||||
{ 136, __NR_personality, 1 },
|
||||
{ 140, __NR__llseek, 5 },
|
||||
{ 141, __NR_getdents, 3 },
|
||||
@@ -190,15 +194,24 @@ scwrap_t syscallwrap[] = {
|
||||
{ 183, __NR_getcwd, 2 },
|
||||
{ 186, __NR_sigaltstack, 2 }, // neeed wrap or something?
|
||||
{ 191, __NR_ugetrlimit, 2 },
|
||||
{ 192, __NR_mmap2, 6},
|
||||
// { 192, __NR_mmap2, 6},
|
||||
//{ 195, __NR_stat64, 2 }, // need proprer wrap because of structure size change
|
||||
//{ 196, __NR_lstat64, 2 }, // need proprer wrap because of structure size change
|
||||
//{ 197, __NR_fstat64, 2 }, // need proprer wrap because of structure size change
|
||||
#ifndef POWERPCLE
|
||||
{ 199, __NR_getuid32, 0 },
|
||||
{ 200, __NR_getgid32, 0 },
|
||||
{ 201, __NR_geteuid32, 0 },
|
||||
{ 202, __NR_getegid32, 0 },
|
||||
{ 208, __NR_setresuid32, 3 },
|
||||
#else
|
||||
// PowerPC uses the same syscalls for 32/64 bit processes.
|
||||
{ 199, __NR_getuid, 0 },
|
||||
{ 200, __NR_getgid, 0 },
|
||||
{ 201, __NR_geteuid, 0 },
|
||||
{ 202, __NR_getegid, 0 },
|
||||
{ 208, __NR_setresuid, 3 },
|
||||
#endif
|
||||
{ 220, __NR_getdents64, 3 },
|
||||
//{ 221, __NR_fcntl64, 3 },
|
||||
{ 224, __NR_gettid, 0 },
|
||||
@@ -217,6 +230,7 @@ scwrap_t syscallwrap[] = {
|
||||
{ 271, __NR_utimes, 2 },
|
||||
{ 311, __NR_set_robust_list, 2 },
|
||||
{ 312, __NR_get_robust_list, 4 },
|
||||
{ 318, __NR_getcpu, 3},
|
||||
#ifdef NOALIGN
|
||||
{ 329, __NR_epoll_create1, 1 },
|
||||
#endif
|
||||
@@ -396,9 +410,12 @@ void EXPORT x86Syscall(x86emu_t *emu)
|
||||
case 90: // old_mmap
|
||||
{
|
||||
struct mmap_arg_struct *st = (struct mmap_arg_struct*)R_EBX;
|
||||
R_EAX = (uintptr_t)mmap((void*)st->addr, st->len, st->prot, st->flags, st->fd, st->offset);
|
||||
R_EAX = (uintptr_t)my_mmap(emu, (void*)st->addr, st->len, st->prot, st->flags, st->fd, st->offset);
|
||||
}
|
||||
break;
|
||||
case 91: // munmap
|
||||
R_EAX = my_munmap(emu, (void*)R_EBX, (unsigned long)R_ECX);
|
||||
break;
|
||||
#ifndef __NR_socketcall
|
||||
case 102: {
|
||||
unsigned long *args = (unsigned long *)R_ECX;
|
||||
@@ -510,6 +527,9 @@ void EXPORT x86Syscall(x86emu_t *emu)
|
||||
case 123: // SYS_modify_ldt
|
||||
R_EAX = my_modify_ldt(emu, R_EBX, (thread_area_t*)R_ECX, R_EDX);
|
||||
break;
|
||||
case 125: // mprotect
|
||||
R_EAX = my_mprotect(emu, (void*)R_EBX, (unsigned long)R_ECX, R_EDX);
|
||||
break;
|
||||
case 168: // sys_poll
|
||||
R_EAX = (uint32_t)poll((void*)R_EBX, R_ECX, (int)R_EDX);
|
||||
break;
|
||||
@@ -526,6 +546,9 @@ void EXPORT x86Syscall(x86emu_t *emu)
|
||||
R_EAX = r;
|
||||
}
|
||||
break;
|
||||
case 192: // mmap2
|
||||
R_EAX = (uint32_t)my_mmap64(emu, (void*)R_EBX, (unsigned long)R_ECX, R_EDX, R_ESI, R_EDI, R_EBP);
|
||||
break;
|
||||
case 195: // stat64
|
||||
{
|
||||
struct stat64 st;
|
||||
@@ -644,10 +667,16 @@ uint32_t EXPORT my_syscall(x86emu_t *emu)
|
||||
return (uint32_t)close(i32(4));
|
||||
case 11: // execve
|
||||
return (uint32_t)my_execve(emu, p(4), p(8), p(12));
|
||||
case 91: // munmap
|
||||
return (uint32_t)my_munmap(emu, p(4), u32(8));
|
||||
case 123: // SYS_modify_ldt
|
||||
return my_modify_ldt(emu, i32(4), (thread_area_t*)p(8), i32(12));
|
||||
case 125: // mprotect
|
||||
return (uint32_t)my_mprotect(emu, p(4), u32(8), i32(12));
|
||||
case 174: // sys_rt_sigaction
|
||||
return (uint32_t)my_sigaction(emu, i32(4), (x86_sigaction_t*)p(8), (x86_sigaction_t*)p(12));
|
||||
case 192: // mmap2
|
||||
return (uint32_t)my_mmap64(emu, p(4), u32(8), i32(12), i32(16), i32(20), u32(24));
|
||||
case 243: // set_thread_area
|
||||
return my_set_thread_area((thread_area_t*)p(4));
|
||||
#ifndef NOALIGN
|
||||
|
||||
+15
-15
@@ -92,27 +92,27 @@ static inline void fpu_fcom(x86emu_t* emu, double b)
|
||||
static inline void fpu_fcomi(x86emu_t* emu, double b)
|
||||
{
|
||||
RESET_FLAGS(emu);
|
||||
emu->flags[F_AF] = 0;
|
||||
emu->flags[F_OF] = 0;
|
||||
emu->flags[F_SF] = 0;
|
||||
CLEAR_FLAG(F_AF);
|
||||
CLEAR_FLAG(F_OF);
|
||||
CLEAR_FLAG(F_SF);
|
||||
emu->sw.f.F87_C1 = 0;
|
||||
if(isnan(ST0.d) || isnan(b)) {
|
||||
emu->flags[F_CF] = 1;
|
||||
emu->flags[F_PF] = 1;
|
||||
emu->flags[F_ZF] = 1;
|
||||
SET_FLAG(F_CF);
|
||||
SET_FLAG(F_PF);
|
||||
SET_FLAG(F_ZF);
|
||||
} else if (isgreater(ST0.d, b)) {
|
||||
emu->flags[F_CF] = 0;
|
||||
emu->flags[F_PF] = 0;
|
||||
emu->flags[F_ZF] = 0;
|
||||
CLEAR_FLAG(F_CF);
|
||||
CLEAR_FLAG(F_PF);
|
||||
CLEAR_FLAG(F_ZF);
|
||||
} else if (isless(ST0.d, b)) {
|
||||
emu->flags[F_CF] = 1;
|
||||
emu->flags[F_PF] = 0;
|
||||
emu->flags[F_ZF] = 0;
|
||||
SET_FLAG(F_CF);
|
||||
CLEAR_FLAG(F_PF);
|
||||
CLEAR_FLAG(F_ZF);
|
||||
}
|
||||
else {
|
||||
emu->flags[F_CF] = 0;
|
||||
emu->flags[F_PF] = 0;
|
||||
emu->flags[F_ZF] = 1;
|
||||
CLEAR_FLAG(F_CF);
|
||||
CLEAR_FLAG(F_PF);
|
||||
SET_FLAG(F_ZF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ typedef struct dynablock_s dynablock_t;
|
||||
typedef struct dynablocklist_s dynablocklist_t;
|
||||
typedef struct mmaplist_s mmaplist_t;
|
||||
typedef struct kh_dynablocks_s kh_dynablocks_t;
|
||||
#endif
|
||||
#define DYNAMAP_SIZE (1<<20)
|
||||
#define DYNAMAP_SHIFT 12
|
||||
#endif
|
||||
|
||||
typedef void* (*procaddess_t)(const char* name);
|
||||
typedef void* (*vkprocaddess_t)(void* instance, const char* name);
|
||||
@@ -61,16 +61,7 @@ typedef struct base_segment_s {
|
||||
} base_segment_t;
|
||||
|
||||
typedef struct box86context_s {
|
||||
#ifdef DYNAREC
|
||||
dynablocklist_t** dynmap; // 4G of memory mapped by 4K block
|
||||
int trace_dynarec;
|
||||
pthread_mutex_t mutex_dyndump;
|
||||
pthread_mutex_t mutex_blocks;
|
||||
pthread_mutex_t mutex_mmap;
|
||||
mmaplist_t *mmaplist;
|
||||
int mmapsize;
|
||||
kh_dynablocks_t *dblist_oversized; // store the list of oversized dynablocks (normal sized are inside mmaplist)
|
||||
#endif
|
||||
uint32_t* memprot; // protection flags by 4K block
|
||||
path_collection_t box86_path; // PATH env. variable
|
||||
path_collection_t box86_ld_lib; // LD_LIBRARY_PATH env. variable
|
||||
|
||||
@@ -128,6 +119,9 @@ typedef struct box86context_s {
|
||||
pthread_mutex_t mutex_trace;
|
||||
#ifndef DYNAREC
|
||||
pthread_mutex_t mutex_lock; // dynarec build will use their own mecanism
|
||||
#else
|
||||
pthread_mutex_t mutex_dyndump;
|
||||
int trace_dynarec;
|
||||
#endif
|
||||
pthread_mutex_t mutex_tls;
|
||||
pthread_mutex_t mutex_thread;
|
||||
@@ -212,13 +206,10 @@ int AddElfHeader(box86context_t* ctx, elfheader_t* head);
|
||||
// return the tlsbase (negative) for the new TLS partition created (no partition index is stored in the context)
|
||||
int AddTLSPartition(box86context_t* context, int tlssize);
|
||||
|
||||
#define PROT_DYNAREC 0x10000
|
||||
void updateProtection(uintptr_t addr, uintptr_t size, uint32_t prot);
|
||||
uint32_t getProtection(uintptr_t addr);
|
||||
#ifdef DYNAREC
|
||||
uintptr_t AllocDynarecMap(dynablock_t* db, int size);
|
||||
void FreeDynarecMap(dynablock_t* db, uintptr_t addr, uint32_t size);
|
||||
|
||||
void addDBFromAddressRange(box86context_t* context, uintptr_t addr, uintptr_t size, int nolinker);
|
||||
void cleanDBFromAddressRange(box86context_t* context, uintptr_t addr, uintptr_t size, int destroy);
|
||||
|
||||
void protectDB(uintptr_t addr, uintptr_t size);
|
||||
void unprotectDB(uintptr_t addr, uintptr_t size);
|
||||
#endif
|
||||
|
||||
@@ -10,9 +10,9 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
bridge_t *NewBridge();
|
||||
void FreeBridge(bridge_t** bridge);
|
||||
|
||||
uintptr_t AddBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void* fnc, int N);
|
||||
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N);
|
||||
uintptr_t CheckBridged(bridge_t* bridge, void* fnc);
|
||||
uintptr_t AddCheckBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void* fnc, int N);
|
||||
uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N);
|
||||
uintptr_t AddAutomaticBridge(x86emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N);
|
||||
void* GetNativeFnc(uintptr_t fnc);
|
||||
void* GetNativeFncOrFnc(uintptr_t fnc);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef __CUSTOM_MEM__H_
|
||||
#define __CUSTOM_MEM__H_
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct box86context_s box86context_t;
|
||||
|
||||
void* customMalloc(size_t size);
|
||||
void* customCalloc(size_t n, size_t size);
|
||||
void* customRealloc(void* p, size_t size);
|
||||
void customFree(void* p);
|
||||
|
||||
#define kcalloc customCalloc
|
||||
#define kmalloc customMalloc
|
||||
#define krealloc customRealloc
|
||||
#define kfree customFree
|
||||
|
||||
#ifdef DYNAREC
|
||||
typedef struct dynablock_s dynablock_t;
|
||||
typedef struct dynablocklist_s dynablocklist_t;
|
||||
// custom protection flag to mark Page that are Write protected for Dynarec purpose
|
||||
uintptr_t AllocDynarecMap(dynablock_t* db, int size);
|
||||
void FreeDynarecMap(dynablock_t* db, uintptr_t addr, uint32_t size);
|
||||
|
||||
void addDBFromAddressRange(uintptr_t addr, uintptr_t size, int nolinker);
|
||||
void cleanDBFromAddressRange(uintptr_t addr, uintptr_t size, int destroy);
|
||||
|
||||
dynablocklist_t* getDB(uintptr_t idx);
|
||||
#endif
|
||||
|
||||
void init_custommem_helper(box86context_t* ctx);
|
||||
void fini_custommem_helper(box86context_t* ctx);
|
||||
|
||||
#endif //__CUSTOM_MEM__H_
|
||||
+2
-1
@@ -26,8 +26,9 @@ extern int trace_xmm; // include XMM reg in trace?
|
||||
extern int trace_emm; // include EMM reg in trace?
|
||||
extern int allow_missing_libs;
|
||||
extern int box86_steam;
|
||||
extern int box86_nopulse; // diabling the use of wrapped pulseaudio
|
||||
extern int box86_nopulse; // disabling the use of wrapped pulseaudio
|
||||
extern int box86_nogtk; // disabling the use of wrapped gtk
|
||||
extern int box86_novulkan; // disabling the use of wrapped vulkan
|
||||
extern uintptr_t trace_start, trace_end;
|
||||
extern char* trace_func;
|
||||
extern uintptr_t fmod_smc_start, fmod_smc_end; // to handle libfmod (from Unreal) SMC (self modifying code)
|
||||
|
||||
@@ -7,7 +7,7 @@ typedef struct dynablocklist_s dynablocklist_t;
|
||||
typedef struct kh_dynablocks_s kh_dynablocks_t;
|
||||
|
||||
uint32_t X31_hash_code(void* addr, int len);
|
||||
dynablocklist_t* NewDynablockList(uintptr_t base, uintptr_t text, int textsz, int nolinker, int direct);
|
||||
dynablocklist_t* NewDynablockList(uintptr_t text, int textsz, int nolinker, int direct);
|
||||
void FreeDynablockList(dynablocklist_t** dynablocks);
|
||||
void FreeDynablock(dynablock_t* db);
|
||||
void MarkDynablock(dynablock_t* db);
|
||||
|
||||
@@ -16,7 +16,7 @@ char* ResolveFile(const char* filename, path_collection_t* paths);
|
||||
// 1: if file is an x86 elf, 0: if not (or not found)
|
||||
int FileIsX86ELF(const char* filename);
|
||||
|
||||
#ifdef RPI
|
||||
#if defined(RPI) || defined(RK3399)
|
||||
void sanitize_mojosetup_gtk_background();
|
||||
#endif
|
||||
|
||||
|
||||
+20
-1
@@ -1,5 +1,24 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#define CREATE_SYSV_VALIST(A) \
|
||||
va_list sysv_varargs; \
|
||||
sysv_varargs->gpr=8; \
|
||||
sysv_varargs->fpr=8; \
|
||||
sysv_varargs->overflow_arg_area=A;
|
||||
|
||||
#ifdef SYSV_VARARG
|
||||
#define VARARGS sysv_varargs
|
||||
#define PREPARE_VALIST CREATE_SYSV_VALIST(emu->scratch)
|
||||
#define VARARGS_(A) sysv_varargs
|
||||
#define PREPARE_VALIST_(A) CREATE_SYSV_VALIST(A)
|
||||
#else
|
||||
#define VARARGS emu->scratch
|
||||
#define PREPARE_VALIST do {} while(0)
|
||||
#define VARARGS_(A) A
|
||||
#define PREPARE_VALIST_(A) do {} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
void myStackAlign(const char* fmt, uint32_t* st, uint32_t* mystack);
|
||||
void myStackAlignGVariantNew(const char* fmt, uint32_t* st, uint32_t* mystack);
|
||||
void myStackAlignW(const char* fmt, uint32_t* st, uint32_t* mystack);
|
||||
@@ -306,4 +325,4 @@ void AlignFlock64(void* dest, void* source); // x86 -> Arm
|
||||
|
||||
// defined in wrapperlibc.c
|
||||
int of_convert(int); // x86->arm
|
||||
int of_unconvert(int); // arm->x86
|
||||
int of_unconvert(int); // arm->x86
|
||||
+25
-32
@@ -138,27 +138,27 @@ typedef struct {
|
||||
|
||||
typedef union {
|
||||
struct __attribute__ ((__packed__)) {
|
||||
unsigned int F__CF:1;
|
||||
unsigned int F__res1:1;
|
||||
unsigned int F__PF:1;
|
||||
unsigned int F__res2:1;
|
||||
unsigned int F__AF:1;
|
||||
unsigned int F__res3:1;
|
||||
unsigned int F__ZF:1;
|
||||
unsigned int F__SF:1;
|
||||
unsigned int F__TF:1;
|
||||
unsigned int F__IF:1;
|
||||
unsigned int F__DF:1;
|
||||
unsigned int F__OF:1;
|
||||
unsigned int F__IOPL:2;
|
||||
unsigned int F__NT:1;
|
||||
unsigned int F__dummy:1;
|
||||
unsigned int F__RF:1;
|
||||
unsigned int F__VM:1;
|
||||
unsigned int F__AC:1;
|
||||
unsigned int F__VIF:1;
|
||||
unsigned int F__VIP:1;
|
||||
unsigned int F__ID:1;
|
||||
unsigned int _F_CF:1;
|
||||
unsigned int _F_res1:1;
|
||||
unsigned int _F_PF:1;
|
||||
unsigned int _F_res2:1;
|
||||
unsigned int _F_AF:1;
|
||||
unsigned int _F_res3:1;
|
||||
unsigned int _F_ZF:1;
|
||||
unsigned int _F_SF:1;
|
||||
unsigned int _F_TF:1;
|
||||
unsigned int _F_IF:1;
|
||||
unsigned int _F_DF:1;
|
||||
unsigned int _F_OF:1;
|
||||
unsigned int _F_IOPL:2;
|
||||
unsigned int _F_NT:1;
|
||||
unsigned int _F_dummy:1;
|
||||
unsigned int _F_RF:1;
|
||||
unsigned int _F_VM:1;
|
||||
unsigned int _F_AC:1;
|
||||
unsigned int _F_VIF:1;
|
||||
unsigned int _F_VIP:1;
|
||||
unsigned int _F_ID:1;
|
||||
} f;
|
||||
uint32_t x32;
|
||||
} x86flags_t;
|
||||
@@ -262,16 +262,9 @@ typedef union {
|
||||
#define R_FS emu->segs[_FS]
|
||||
#define R_GS emu->segs[_GS]
|
||||
|
||||
#if 0
|
||||
#define ACCESS_FLAG(F) emu->eflags.f.F
|
||||
#define SET_FLAG(F) emu->eflags.f.F = 1
|
||||
#define CLEAR_FLAG(F) emu->eflags.f.F = 0
|
||||
#define CONDITIONAL_SET_FLAG(COND, F) emu->eflags.f.F = (COND)?1:0
|
||||
#else
|
||||
#define ACCESS_FLAG(F) emu->flags[F]
|
||||
#define SET_FLAG(F) emu->flags[F] = 1
|
||||
#define CLEAR_FLAG(F) emu->flags[F] = 0
|
||||
#define CONDITIONAL_SET_FLAG(COND, F) emu->flags[F] = (COND)?1:0
|
||||
#endif
|
||||
#define ACCESS_FLAG(F) emu->eflags.f._##F
|
||||
#define SET_FLAG(F) emu->eflags.f._##F = 1
|
||||
#define CLEAR_FLAG(F) emu->eflags.f._##F = 0
|
||||
#define CONDITIONAL_SET_FLAG(COND, F) emu->eflags.f._##F = (COND)?1:0
|
||||
|
||||
#endif //__REGS_H_
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef __LIBRARIAN_PRIVATE_H_
|
||||
#define __LIBRARIAN_PRIVATE_H_
|
||||
#include <stdint.h>
|
||||
|
||||
#include "custommem.h"
|
||||
#include "khash.h"
|
||||
|
||||
typedef struct box86context_s box86context_t;
|
||||
|
||||
+11
-5
@@ -250,6 +250,12 @@ library_t *NewLibrary(const char* path, box86context_t* context)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(box86_novulkan) {
|
||||
if(strstr(lib->name, "libvulkan.so")==lib->name) {
|
||||
Free1Library(&lib);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
int notwrapped = FindInCollection(lib->name, &context->box86_emulated_libs);
|
||||
// And now, actually loading a library
|
||||
// look for native(wrapped) libs first
|
||||
@@ -581,7 +587,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
|
||||
printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
|
||||
} else
|
||||
AddOffsetSymbol(lib->context->maplib, symbol, name);
|
||||
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->mysymbolmap, k), symbol, 0);
|
||||
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->mysymbolmap, k), symbol, 0);
|
||||
*size = sizeof(void*);
|
||||
return 1;
|
||||
}
|
||||
@@ -599,7 +605,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
|
||||
printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
|
||||
} else
|
||||
AddOffsetSymbol(lib->context->maplib, symbol, name);
|
||||
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->stsymbolmap, k), symbol, 4); // all of this for this little "4"
|
||||
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->stsymbolmap, k), symbol, 4); // all of this for this little "4"
|
||||
*size = sizeof(void*);
|
||||
return 1;
|
||||
}
|
||||
@@ -618,7 +624,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
|
||||
return 0;
|
||||
} else
|
||||
AddOffsetSymbol(lib->context->maplib, symbol, name);
|
||||
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->symbolmap, k), symbol, 0);
|
||||
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->symbolmap, k), symbol, 0);
|
||||
*size = sizeof(void*);
|
||||
return 1;
|
||||
}
|
||||
@@ -637,7 +643,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
|
||||
return 0;
|
||||
} else
|
||||
AddOffsetSymbol(lib->context->maplib, symbol, name);
|
||||
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->wsymbolmap, k), symbol, 0);
|
||||
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->wsymbolmap, k), symbol, 0);
|
||||
*size = sizeof(void*);
|
||||
return 1;
|
||||
}
|
||||
@@ -655,7 +661,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
|
||||
return 0;
|
||||
} else
|
||||
AddOffsetSymbol(lib->context->maplib, symbol, name);
|
||||
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->symbol2map, k).w, symbol, 0);
|
||||
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->symbol2map, k).w, symbol, 0);
|
||||
*size = sizeof(void*);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __LIBRARY_PRIVATE_H_
|
||||
#include <stdint.h>
|
||||
|
||||
#include "custommem.h"
|
||||
#include "khash.h"
|
||||
#include "wrappedlibs.h"
|
||||
#include "box86context.h"
|
||||
|
||||
@@ -136,5 +136,7 @@ GO("libldap_r-2.4.so.2", ldapr)
|
||||
GO("liblber-2.4.so.2", lber)
|
||||
GO("libnsl.so.1", nsl)
|
||||
GO("liblcms2.so.2", lcms2)
|
||||
GO("libkrb5.so.3", krb5)
|
||||
GO("libgssapi_krb5.so.2", gssapikrb5)
|
||||
|
||||
GO("ld-linux.so.2", ldlinux)
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "myalign.h"
|
||||
|
||||
|
||||
void myStackAlign(const char* fmt, uint32_t* st, uint32_t* mystack)
|
||||
{
|
||||
if(!fmt)
|
||||
|
||||
@@ -20,7 +20,12 @@ void UnalignStat64(const void* source, void* dest)
|
||||
memset(i386st->__pad0, 0, sizeof(i386st->__pad0));
|
||||
memset(i386st->__pad3, 0, sizeof(i386st->__pad3));
|
||||
i386st->st_dev = st->st_dev;
|
||||
#ifndef POWERPCLE
|
||||
i386st->__st_ino = st->__st_ino;
|
||||
#else
|
||||
i386st->__st_ino = st->st_ino; // Separate __st_ino doesn't
|
||||
// exist on powerpc
|
||||
#endif
|
||||
i386st->st_mode = st->st_mode;
|
||||
i386st->st_nlink = st->st_nlink;
|
||||
i386st->st_uid = st->st_uid;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "callback.h"
|
||||
#include "myalign.h"
|
||||
#include "bridge.h"
|
||||
#include "custommem.h"
|
||||
#include "khash.h"
|
||||
|
||||
// kh_ftsent_t store each ftsent conversion from native -> x86
|
||||
|
||||
@@ -70,7 +70,7 @@ static void* reverse_chunkfunFct(library_t* lib, void* fct)
|
||||
#define GO(A) if(my_chunkfun_##A == fct) return (void*)my_chunkfun_fct_##A;
|
||||
SUPER()
|
||||
#undef GO
|
||||
return (void*)AddBridge(lib->priv.w.bridge, lib->context, pFL, fct, 0);
|
||||
return (void*)AddBridge(lib->priv.w.bridge, pFL, fct, 0);
|
||||
}
|
||||
// freefun
|
||||
#define GO(A) \
|
||||
@@ -103,7 +103,7 @@ static void* reverse_freefunFct(library_t* lib, void* fct)
|
||||
#define GO(A) if(my_freefun_##A == fct) return (void*)my_freefun_fct_##A;
|
||||
SUPER()
|
||||
#undef GO
|
||||
return (void*)AddBridge(lib->priv.w.bridge, lib->context, vFp, fct, 0);
|
||||
return (void*)AddBridge(lib->priv.w.bridge, vFp, fct, 0);
|
||||
}
|
||||
|
||||
#undef SUPER
|
||||
@@ -217,7 +217,7 @@ void obstackSetup()
|
||||
// save the real function
|
||||
real_obstack_alloc_failed_handler = obstack_alloc_failed_handler;
|
||||
// bridge the real function for x86 world
|
||||
my_obstack_alloc_failed_handler = (void*)AddCheckBridge(my_context->system, my_context, vFv, real_obstack_alloc_failed_handler, 0);
|
||||
my_obstack_alloc_failed_handler = (void*)AddCheckBridge(my_context->system, vFv, real_obstack_alloc_failed_handler, 0);
|
||||
ref_obstack_alloc_failed_handler = my_obstack_alloc_failed_handler;
|
||||
// setup our version of the function
|
||||
obstack_alloc_failed_handler = actual_obstack_alloc_failed_handler;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "librarian/library_private.h"
|
||||
#include "bridge.h"
|
||||
#include "callback.h"
|
||||
#include "khash.h"
|
||||
|
||||
typedef struct SDL1_RWops_s SDL1_RWops_t;
|
||||
|
||||
@@ -107,7 +106,7 @@ SDL1_RWops_t* AddNativeRW(x86emu_t* emu, SDL1_RWops_t* ops)
|
||||
|
||||
// get or create wrapper, add it to map and change to the emulated one if rw
|
||||
#define GO(A, W) \
|
||||
fnc = AddCheckBridge(system, my_context, W, my_native_##A, 0); \
|
||||
fnc = AddCheckBridge(system, W, my_native_##A, 0); \
|
||||
newrw->A = (sdl1_##A)fnc;
|
||||
|
||||
GO(seek, iFpii)
|
||||
|
||||
@@ -117,7 +117,7 @@ SDL2_RWops_t* AddNativeRW2(x86emu_t* emu, SDL2_RWops_t* ops)
|
||||
|
||||
// get or create wrapper, add it to map and change to the emulated one if rw
|
||||
#define GO(A, W) \
|
||||
fnc = AddCheckBridge(system, my_context, W, my2_native_##A, 0); \
|
||||
fnc = AddCheckBridge(system, W, my2_native_##A, 0); \
|
||||
newrw->A = (sdl2_##A)fnc;
|
||||
|
||||
GO(size, IFp)
|
||||
|
||||
+45
-29
@@ -10,6 +10,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <ucontext.h>
|
||||
#include <setjmp.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "box86context.h"
|
||||
#include "debug.h"
|
||||
@@ -25,6 +26,7 @@
|
||||
#include "threads.h"
|
||||
#include "emu/x87emu_private.h"
|
||||
#ifdef DYNAREC
|
||||
#include "custommem.h"
|
||||
#include "dynablock.h"
|
||||
#include "../dynarec/dynablock_private.h"
|
||||
#endif
|
||||
@@ -446,7 +448,7 @@ void my_sigactionhandler_oldpc(int32_t sig, siginfo_t* info, void * ucntx, void*
|
||||
sigcontext->uc_mcontext.gregs[REG_ESP] = R_ESP;
|
||||
sigcontext->uc_mcontext.gregs[REG_EBX] = R_EBX;
|
||||
// flags
|
||||
sigcontext->uc_mcontext.gregs[REG_EFL] = emu->packed_eflags.x32;
|
||||
sigcontext->uc_mcontext.gregs[REG_EFL] = emu->eflags.x32;
|
||||
// get segments
|
||||
sigcontext->uc_mcontext.gregs[REG_GS] = R_GS;
|
||||
sigcontext->uc_mcontext.gregs[REG_FS] = R_FS;
|
||||
@@ -505,17 +507,28 @@ void my_sigactionhandler_oldpc(int32_t sig, siginfo_t* info, void * ucntx, void*
|
||||
TRAP_x86_MCHK = 18, // Machine check exception
|
||||
TRAP_x86_CACHEFLT = 19 // SIMD exception (via SIGFPE) if CPU is SSE capable otherwise Cache flush exception (via SIGSEV)
|
||||
*/
|
||||
|
||||
uint32_t prot = getProtection((uintptr_t)info->si_addr);
|
||||
if(sig==SIGBUS)
|
||||
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = 17;
|
||||
else if(sig==SIGSEGV) {
|
||||
sigcontext->uc_mcontext.gregs[REG_TRAPNO] =
|
||||
(info->si_code == SEGV_ACCERR)?((abs((intptr_t)info->si_addr-(intptr_t)sigcontext->uc_mcontext.gregs[REG_ESP])<16)?12:13):14; // how to differenciate between a STACKFLT and a PAGEFAULT?
|
||||
if((uintptr_t)info->si_addr == sigcontext->uc_mcontext.gregs[REG_EIP]) {
|
||||
sigcontext->uc_mcontext.gregs[REG_ERR] = 0x0010; // execution flag issue (probably)
|
||||
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = (info->si_code == SEGV_ACCERR)?14:13;
|
||||
} else if(info->si_code==SEGV_ACCERR && !(prot&PROT_WRITE)) {
|
||||
sigcontext->uc_mcontext.gregs[REG_ERR] = 0x0002; // write flag issue
|
||||
if(abs((intptr_t)info->si_addr-(intptr_t)sigcontext->uc_mcontext.gregs[REG_ESP])<16)
|
||||
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = 12; // stack overflow probably
|
||||
else
|
||||
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = 14; // PAGE_FAULT
|
||||
} else {
|
||||
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = (info->si_code == SEGV_ACCERR)?14:13;
|
||||
//REG_ERR seems to be INT:8 CODE:8. So for write access segfault it's 0x0002 For a read it's 0x0004 (and 8 for exec). For an int 2d it could be 0x2D01 for example
|
||||
sigcontext->uc_mcontext.gregs[REG_ERR] = 0x0004; // read error? there is no execute control in box86 anyway
|
||||
}
|
||||
} else if(sig==SIGFPE)
|
||||
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = 19;
|
||||
else if(sig==SIGILL)
|
||||
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = 6;
|
||||
|
||||
// call the signal handler
|
||||
i386_ucontext_t sigcontext_copy = *sigcontext;
|
||||
|
||||
@@ -544,7 +557,7 @@ void my_sigactionhandler_oldpc(int32_t sig, siginfo_t* info, void * ucntx, void*
|
||||
if(sigcontext->uc_mcontext.gregs[REG_EIP]!=sigcontext_copy.uc_mcontext.gregs[REG_EIP]) ejb->emu->ip.dword[0]=sigcontext->uc_mcontext.gregs[REG_EIP];
|
||||
sigcontext->uc_mcontext.gregs[REG_EIP] = R_EIP;
|
||||
// flags
|
||||
if(sigcontext->uc_mcontext.gregs[REG_EFL]!=sigcontext_copy.uc_mcontext.gregs[REG_EFL]) ejb->emu->packed_eflags.x32=sigcontext->uc_mcontext.gregs[REG_EFL];
|
||||
if(sigcontext->uc_mcontext.gregs[REG_EFL]!=sigcontext_copy.uc_mcontext.gregs[REG_EFL]) ejb->emu->eflags.x32=sigcontext->uc_mcontext.gregs[REG_EFL];
|
||||
// get segments
|
||||
#define GO(S) if(sigcontext->uc_mcontext.gregs[REG_##S]!=sigcontext_copy.uc_mcontext.gregs[REG_##S]) {ejb->emu->segs[_##S]=sigcontext->uc_mcontext.gregs[REG_##S]; ejb->emu->segs_serial[_##S] = 0;}
|
||||
GO(GS);
|
||||
@@ -572,30 +585,26 @@ void my_sigactionhandler_oldpc(int32_t sig, siginfo_t* info, void * ucntx, void*
|
||||
new_ss->ss_flags = 0;
|
||||
}
|
||||
|
||||
#ifdef DYNAREC
|
||||
static int hasDBFromAddress(uintptr_t addr)
|
||||
{
|
||||
int idx = (addr>>DYNAMAP_SHIFT);
|
||||
return my_context->dynmap[idx]?1:0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
{
|
||||
// sig==SIGSEGV || sig==SIGBUS || sig==SIGILL here!
|
||||
int log_minimum = (my_context->is_sigaction[sig] && sig==SIGSEGV)?LOG_INFO:LOG_NONE;
|
||||
ucontext_t *p = (ucontext_t *)ucntx;
|
||||
void* addr = (void*)info->si_addr; // address that triggered the issue
|
||||
uint32_t prot = getProtection((uintptr_t)addr);
|
||||
void* esp = NULL;
|
||||
#ifdef __arm__
|
||||
void * pc = (void*)p->uc_mcontext.arm_pc;
|
||||
#elif defined __i386
|
||||
void * pc = (void*)p->uc_mcontext.gregs[REG_EIP];
|
||||
#elif defined PPC
|
||||
void * pc = (void*)p->uc_mcontext.uc_regs->gregs[PT_NIP];
|
||||
#else
|
||||
void * pc = NULL; // unknow arch...
|
||||
#warning Unhandled architecture
|
||||
#endif
|
||||
#ifdef DYNAREC
|
||||
if(sig==SIGSEGV && addr && info->si_code == SEGV_ACCERR && hasDBFromAddress((uintptr_t)addr)) {
|
||||
if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_WRITE)) {
|
||||
if(box86_dynarec_smc) {
|
||||
dynablock_t* db_pc = NULL;
|
||||
dynablock_t* db_addr = NULL;
|
||||
@@ -611,9 +620,10 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
dynarec_log(LOG_NONE, "Warning: Access to protected %p from %p, inside a dynablock with linker\n", addr, pc);
|
||||
}
|
||||
}
|
||||
dynarec_log(LOG_DEBUG, "Access to protected %p from %p, unprotecting memory\n", addr, pc);
|
||||
// access error
|
||||
unprotectDB((uintptr_t)addr, 1); // unprotect 1 byte... But then, the whole page will be unprotected
|
||||
dynarec_log(LOG_DEBUG, "Access to protected %p from %p, unprotecting memory (prot=%x)\n", addr, pc, prot);
|
||||
// access error, unprotect the block (and mark them dirty)
|
||||
if(prot&PROT_DYNAREC) // on heavy multi-thread program, the protection can already be gone...
|
||||
unprotectDB((uintptr_t)addr, 1); // unprotect 1 byte... But then, the whole page will be unprotected
|
||||
// done
|
||||
return;
|
||||
}
|
||||
@@ -623,7 +633,8 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
static void* old_addr = 0;
|
||||
const char* signame = (sig==SIGSEGV)?"SIGSEGV":((sig==SIGBUS)?"SIGBUS":"SIGILL");
|
||||
if(old_code==info->si_code && old_pc==pc && old_addr==addr) {
|
||||
printf_log(LOG_NONE, "%04d|Double %s!\n", GetTID(), signame);
|
||||
printf_log(log_minimum, "%04d|Double %s!\n", GetTID(), signame);
|
||||
exit(-1);
|
||||
} else {
|
||||
#ifdef DYNAREC
|
||||
dynablock_t* db = FindDynablockFromNativeAddress(pc);
|
||||
@@ -657,7 +668,7 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
if(v) {
|
||||
// parent process, the one that have the segfault
|
||||
volatile int waiting = 1;
|
||||
printf_log(LOG_NONE, "Waiting for gdb...\n");
|
||||
printf_log(LOG_NONE, "Waiting for %s (pid %d)...\n", (jit_gdb==2)?"gdbserver":"gdb", pid);
|
||||
while(waiting) {
|
||||
// using gdb, use "set waiting=0" to stop waiting...
|
||||
usleep(1000);
|
||||
@@ -665,23 +676,28 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
} else {
|
||||
char myarg[50] = {0};
|
||||
sprintf(myarg, "%d", pid);
|
||||
execlp("gdb", "gdb", "-pid", myarg, (char*)NULL);
|
||||
//execlp("gdbserver", "gdbserver", "127.0.0.1:1234", "--attach", myarg, (char*)NULL);
|
||||
if(jit_gdb==2)
|
||||
execlp("gdbserver", "gdbserver", "127.0.0.1:1234", "--attach", myarg, (char*)NULL);
|
||||
else
|
||||
execlp("gdb", "gdb", "-pid", myarg, (char*)NULL);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
#ifdef DYNAREC
|
||||
printf_log(LOG_NONE, "%04d|%s @%p (%s) (x86pc=%p/%s:\"%s\", esp=%p), for accessing %p (code=%d), db=%p(%p:%p/%p:%p/%s)",
|
||||
printf_log(log_minimum, "%04d|%s @%p (%s) (x86pc=%p/%s:\"%s\", esp=%p), for accessing %p (code=%d/prot=%x), db=%p(%p:%p/%p:%p/%s:%s)",
|
||||
GetTID(), signame, pc, name, (void*)x86pc, elfname?elfname:"???", x86name?x86name:"???", esp, addr, info->si_code,
|
||||
db, db?db->block:0, db?(db->block+db->size):0, db?db->x86_addr:0, db?(db->x86_addr+db->x86_size):0,
|
||||
getAddrFunctionName((uintptr_t)(db?db->x86_addr:0)));
|
||||
prot, db, db?db->block:0, db?(db->block+db->size):0,
|
||||
db?db->x86_addr:0, db?(db->x86_addr+db->x86_size):0,
|
||||
getAddrFunctionName((uintptr_t)(db?db->x86_addr:0)), (db?db->need_test:0)?"need_stest":"clean");
|
||||
#else
|
||||
printf_log(LOG_NONE, "%04d|%s @%p (%s) (x86pc=%p/%s:\"%s\", esp=%p), for accessing %p (code=%d)", GetTID(), signame, pc, name, (void*)x86pc, elfname?elfname:"???", x86name?x86name:"???", esp, addr, info->si_code);
|
||||
printf_log(log_minimum, "%04d|%s @%p (%s) (x86pc=%p/%s:\"%s\", esp=%p), for accessing %p (code=%d)", GetTID(), signame, pc, name, (void*)x86pc, elfname?elfname:"???", x86name?x86name:"???", esp, addr, info->si_code);
|
||||
#endif
|
||||
if(sig==SIGILL)
|
||||
printf_log(LOG_NONE, " opcode=%02X %02X %02X %02X %02X %02X %02X %02X\n", ((uint8_t*)pc)[0], ((uint8_t*)pc)[1], ((uint8_t*)pc)[2], ((uint8_t*)pc)[3], ((uint8_t*)pc)[4], ((uint8_t*)pc)[5], ((uint8_t*)pc)[6], ((uint8_t*)pc)[7]);
|
||||
printf_log(log_minimum, " opcode=%02X %02X %02X %02X %02X %02X %02X %02X\n", ((uint8_t*)pc)[0], ((uint8_t*)pc)[1], ((uint8_t*)pc)[2], ((uint8_t*)pc)[3], ((uint8_t*)pc)[4], ((uint8_t*)pc)[5], ((uint8_t*)pc)[6], ((uint8_t*)pc)[7]);
|
||||
else if(sig==SIGBUS)
|
||||
printf_log(log_minimum, " x86opcode=%02X %02X %02X %02X %02X %02X %02X %02X\n", ((uint8_t*)x86pc)[0], ((uint8_t*)x86pc)[1], ((uint8_t*)x86pc)[2], ((uint8_t*)x86pc)[3], ((uint8_t*)x86pc)[4], ((uint8_t*)x86pc)[5], ((uint8_t*)x86pc)[6], ((uint8_t*)x86pc)[7]);
|
||||
else
|
||||
printf_log(LOG_NONE, "\n");
|
||||
printf_log(log_minimum, "\n");
|
||||
}
|
||||
if(my_context->signals[sig] && my_context->signals[sig]!=1) {
|
||||
if(my_context->is_sigaction[sig])
|
||||
@@ -692,7 +708,7 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
}
|
||||
// no handler (or double identical segfault)
|
||||
// set default and that's it, instruction will restart and default segfault handler will be called...
|
||||
if(my_context->signals[sig]==1)
|
||||
if(my_context->signals[sig]!=1)
|
||||
signal(sig, SIG_DFL);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "x86emu.h"
|
||||
#include "box86stack.h"
|
||||
#include "callback.h"
|
||||
#include "custommem.h"
|
||||
#include "khash.h"
|
||||
#include "emu/x86run_private.h"
|
||||
#include "x86trace.h"
|
||||
@@ -201,6 +202,15 @@ x86emu_t* thread_get_emu()
|
||||
emuthread_t *et = (emuthread_t*)pthread_getspecific(thread_key);
|
||||
if(!et) {
|
||||
int stacksize = 2*1024*1024;
|
||||
// try to get stack size of the thread
|
||||
pthread_attr_t attr;
|
||||
if(!pthread_getattr_np(pthread_self(), &attr)) {
|
||||
size_t stack_size;
|
||||
void *stack_addr;
|
||||
if(!pthread_attr_getstack(&attr, &stack_addr, &stack_size))
|
||||
stacksize = stack_size;
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
void* stack = calloc(1, stacksize);
|
||||
x86emu_t *emu = NewX86Emu(my_context, 0, (uintptr_t)stack, stacksize, 1);
|
||||
SetupX86Emu(emu);
|
||||
|
||||
+17
-6
@@ -85,6 +85,7 @@ int fix_64bit_inodes = 0;
|
||||
int box86_steam = 0;
|
||||
int box86_nopulse = 0;
|
||||
int box86_nogtk = 0;
|
||||
int box86_novulkan = 0;
|
||||
char* libGL = NULL;
|
||||
uintptr_t trace_start = 0, trace_end = 0;
|
||||
char* trace_func = NULL;
|
||||
@@ -400,7 +401,16 @@ void LoadLogEnv()
|
||||
box86_nogtk = p[0]-'0';
|
||||
}
|
||||
if(box86_nogtk)
|
||||
printf_log(LOG_INFO, "Disable the use of wraped gtk libs\n");
|
||||
printf_log(LOG_INFO, "Disable the use of wrapped gtk libs\n");
|
||||
}
|
||||
p = getenv("BOX86_NOVULKAN");
|
||||
if(p) {
|
||||
if(strlen(p)==1) {
|
||||
if(p[0]>='0' && p[1]<='0'+1)
|
||||
box86_novulkan = p[0]-'0';
|
||||
}
|
||||
if(box86_novulkan)
|
||||
printf_log(LOG_INFO, "Disable the use of wrapped vulkan libs\n");
|
||||
}
|
||||
p = getenv("BOX86_FIX_64BIT_INODES");
|
||||
if(p) {
|
||||
@@ -418,7 +428,7 @@ void LoadLogEnv()
|
||||
jit_gdb = p[0]-'0';
|
||||
}
|
||||
if(jit_gdb)
|
||||
printf_log(LOG_INFO, "Launch gdb on segfault\n");
|
||||
printf_log(LOG_INFO, "Launch %s on segfault\n", (jit_gdb==2)?"gdbserver":"gdb");
|
||||
}
|
||||
box86_pagesize = sysconf(_SC_PAGESIZE);
|
||||
if(!box86_pagesize)
|
||||
@@ -553,6 +563,7 @@ void PrintHelp() {
|
||||
printf(" BOX86_ALLOWMISSINGLIBS with 1 to allow to continue even if a lib is missing (unadvised, will probably crash later)\n");
|
||||
printf(" BOX86_NOPULSE=1 to disable the loading of pulseaudio libs\n");
|
||||
printf(" BOX86_NOGTK=1 to disable the loading of wrapped gtk libs\n");
|
||||
printf(" BOX86_NOVULKAN=1 to disable the loading of wrapped vulkan libs\n");
|
||||
printf(" BOX86_JITGDB with 1 to launch \"gdb\" when a segfault is trapped, attached to the offending process\n");
|
||||
}
|
||||
|
||||
@@ -646,7 +657,7 @@ void setupTraceInit(box86context_t* context)
|
||||
if(sscanf(p, "0x%X-0x%X", &trace_start, &trace_end)!=2)
|
||||
sscanf(p, "%x-%x", &trace_start, &trace_end);
|
||||
}
|
||||
if(trace_start)
|
||||
if(trace_start || trace_end)
|
||||
SetTraceEmu(trace_start, trace_end);
|
||||
} else {
|
||||
if (GetSymbolStartEnd(GetMapSymbol(my_context->maplib), p, &trace_start, &trace_end)) {
|
||||
@@ -859,7 +870,7 @@ int main(int argc, const char **argv, const char **env) {
|
||||
if(!strcmp(prog, "wine") || (strlen(prog)>5 && !strcmp(prog+strlen(prog)-strlen("/wine"), "/wine"))) {
|
||||
const char* prereserve = getenv("WINEPRELOADRESERVE");
|
||||
printf_log(LOG_INFO, "BOX86: Wine detected, WINEPRELOADRESERVE=\"%s\"\n", prereserve?prereserve:"");
|
||||
wine_prereserve(prereserve);
|
||||
//wine_prereserve(prereserve);
|
||||
// special case for winedbg, doesn't work anyway
|
||||
if(argv[nextarg+1] && strstr(argv[nextarg+1], "winedbg")==argv[nextarg+1]) {
|
||||
printf_log(LOG_NONE, "winedbg detected, not launching it!\n");
|
||||
@@ -1118,7 +1129,7 @@ int main(int argc, const char **argv, const char **env) {
|
||||
setupTraceInit(my_context);
|
||||
// export symbols
|
||||
AddSymbols(my_context->maplib, GetMapSymbol(my_context->maplib), GetWeakSymbol(my_context->maplib), GetLocalSymbol(my_context->maplib), elf_header);
|
||||
if(wine_preloaded) {
|
||||
/*if(wine_preloaded) {
|
||||
uintptr_t wineinfo = FindSymbol(GetMapSymbol(my_context->maplib), "wine_main_preload_info");
|
||||
if(!wineinfo) wineinfo = FindSymbol(GetWeakSymbol(my_context->maplib), "wine_main_preload_info");
|
||||
if(!wineinfo) wineinfo = FindSymbol(GetLocalSymbol(my_context->maplib), "wine_main_preload_info");
|
||||
@@ -1130,7 +1141,7 @@ int main(int argc, const char **argv, const char **env) {
|
||||
#ifdef DYNAREC
|
||||
dynarec_wine_prereserve();
|
||||
#endif
|
||||
}
|
||||
}*/
|
||||
// pre-load lib if needed
|
||||
if(ld_preload.size) {
|
||||
for (int i=0; i<ld_preload.size; ++i) {
|
||||
|
||||
+6
-5
@@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "custommem.h"
|
||||
#include "bridge.h"
|
||||
#include "bridge_private.h"
|
||||
#include "wrapper.h"
|
||||
@@ -54,7 +55,7 @@ void FreeBridge(bridge_t** bridge)
|
||||
*bridge = NULL;
|
||||
}
|
||||
|
||||
uintptr_t AddBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void* fnc, int N)
|
||||
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N)
|
||||
{
|
||||
brick_t *b = bridge->last;
|
||||
if(b->sz == NBRICK) {
|
||||
@@ -74,7 +75,7 @@ uintptr_t AddBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void
|
||||
kh_value(bridge->bridgemap, k) = (uintptr_t)&b->b[b->sz].CC;
|
||||
#ifdef DYNAREC
|
||||
if(box86_dynarec)
|
||||
addDBFromAddressRange(context, (uintptr_t)&b->b[b->sz].CC, sizeof(onebridge_t), 0);
|
||||
addDBFromAddressRange((uintptr_t)&b->b[b->sz].CC, sizeof(onebridge_t), 0);
|
||||
#endif
|
||||
|
||||
return (uintptr_t)&b->b[b->sz++].CC;
|
||||
@@ -89,13 +90,13 @@ uintptr_t CheckBridged(bridge_t* bridge, void* fnc)
|
||||
return kh_value(bridge->bridgemap, k);
|
||||
}
|
||||
|
||||
uintptr_t AddCheckBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void* fnc, int N)
|
||||
uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N)
|
||||
{
|
||||
if(!fnc)
|
||||
return 0;
|
||||
uintptr_t ret = CheckBridged(bridge, fnc);
|
||||
if(!ret)
|
||||
ret = AddBridge(bridge, context, w, fnc, N);
|
||||
ret = AddBridge(bridge, w, fnc, N);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -105,7 +106,7 @@ uintptr_t AddAutomaticBridge(x86emu_t* emu, bridge_t* bridge, wrapper_t w, void*
|
||||
return 0;
|
||||
uintptr_t ret = CheckBridged(bridge, fnc);
|
||||
if(!ret)
|
||||
ret = AddBridge(bridge, GetEmuContext(emu), w, fnc, N);
|
||||
ret = AddBridge(bridge, w, fnc, N);
|
||||
if(!hasAlternate(fnc)) {
|
||||
printf_log(LOG_DEBUG, "Adding AutomaticBridge for %p to %p\n", fnc, (void*)ret);
|
||||
addAlternate(fnc, (void*)ret);
|
||||
|
||||
@@ -28,10 +28,9 @@ int FileExist(const char* filename, int flags)
|
||||
if(flags&IS_FILE) {
|
||||
if(!S_ISREG(sb.st_mode))
|
||||
return 0;
|
||||
} else {
|
||||
if(!S_ISDIR(sb.st_mode))
|
||||
} else if(!S_ISDIR(sb.st_mode))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(flags&IS_EXECUTABLE) {
|
||||
if((sb.st_mode&S_IXUSR)!=S_IXUSR)
|
||||
return 0; // nope
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "librarian.h"
|
||||
#include "gtkclass.h"
|
||||
#include "library.h"
|
||||
#include "custommem.h"
|
||||
#include "khash.h"
|
||||
|
||||
static bridge_t* my_bridge = NULL;
|
||||
@@ -84,7 +85,7 @@ static void* reverse_##NAME##_##A(wrapper_t W, void* fct)
|
||||
if((void*)my_##NAME##_##A##_7 == fct) return (void*)my_##NAME##_##A##_fct_7;\
|
||||
Dl_info info; \
|
||||
if(dladdr(fct, &info)) \
|
||||
return (void*)AddCheckBridge(my_bridge, my_context, W, fct, 0); \
|
||||
return (void*)AddCheckBridge(my_bridge, W, fct, 0); \
|
||||
return fct; \
|
||||
}
|
||||
|
||||
@@ -361,7 +362,7 @@ static void bridgeGtkWidgetClass(my_GtkWidgetClass_t* class)
|
||||
WRAPPER(GtkContainer, add, void, (void* container, void* widget), 2, container, widget);
|
||||
WRAPPER(GtkContainer, remove, void, (void* container, void* widget), 2, container, widget);
|
||||
WRAPPER(GtkContainer, check_resize, void, (void* container), 1, container);
|
||||
WRAPPER(GtkContainer, forall, void, (void* container, int include_internals, void* callback, void* callback_data), 4, container, include_internals, AddCheckBridge(my_bridge, my_context, vFpp, callback, 0), callback_data);
|
||||
WRAPPER(GtkContainer, forall, void, (void* container, int include_internals, void* callback, void* callback_data), 4, container, include_internals, AddCheckBridge(my_bridge, vFpp, callback, 0), callback_data);
|
||||
WRAPPER(GtkContainer, set_focus_child, void, (void* container, void* widget), 2, container, widget);
|
||||
WRAPPER(GtkContainer, child_type, int, (void* container), 1, container);
|
||||
WRAPPER(GtkContainer, composite_name, void*, (void* container, void* child), 2, container, child);
|
||||
|
||||
@@ -38,6 +38,7 @@ void my_cpuid(x86emu_t* emu, uint32_t tmp32u)
|
||||
R_EAX = 0x00000601; // familly and all
|
||||
R_EBX = 0; // Brand indexe, CLFlush, Max APIC ID, Local APIC ID
|
||||
R_EDX = 1 // fpu
|
||||
| 1<<4 // rdtsc
|
||||
| 1<<8 // cmpxchg8
|
||||
| 1<<11 // sep (sysenter & sysexit)
|
||||
| 1<<15 // cmov
|
||||
|
||||
@@ -16,7 +16,7 @@ typedef struct wine_prereserve_s
|
||||
} wine_prereserve_t;
|
||||
|
||||
// only the prereseve argument is reserved, not the other zone that wine-preloader reserve
|
||||
static wine_prereserve_t my_wine_reserve[3] = {{(void*)0x0010000, 0x00008000}, {0, 0}, {0, 0}};
|
||||
static wine_prereserve_t my_wine_reserve[] = {{(void*)0x0010000, 0x00008000}, {0, 0}, {0, 0}};
|
||||
|
||||
int wine_preloaded = 0;
|
||||
|
||||
@@ -93,7 +93,7 @@ void* get_wine_prereserve()
|
||||
void dynarec_wine_prereserve()
|
||||
{
|
||||
#if 0
|
||||
// disable for now, as it brack some installer
|
||||
// disable for now, as it break some installer
|
||||
if(!wine_preloaded)
|
||||
wine_prereserve(NULL);
|
||||
// don't reserve the initial arbritrary block as "with linker", it's not true
|
||||
|
||||
@@ -330,8 +330,10 @@
|
||||
#() iFiII
|
||||
#() iFiuu
|
||||
#() iFiup
|
||||
#() iFiLN
|
||||
#() iFipi
|
||||
#() iFipu
|
||||
#() iFipL
|
||||
#() iFipp
|
||||
#() iFCiW
|
||||
#() iFuii
|
||||
@@ -498,6 +500,7 @@
|
||||
#() pFSpp
|
||||
#() vFEiip
|
||||
#() vFEipV
|
||||
#() vFEpii
|
||||
#() vFEpiL
|
||||
#() vFEpip
|
||||
#() vFEpuu
|
||||
@@ -603,6 +606,7 @@
|
||||
#() vFSppi
|
||||
#() cFpiii
|
||||
#() iFEiip
|
||||
#() iFEiiN
|
||||
#() iFEipp
|
||||
#() iFEupp
|
||||
#() iFELup
|
||||
@@ -629,7 +633,6 @@
|
||||
#() iFiiII
|
||||
#() iFiiLi
|
||||
#() iFiipi
|
||||
#() iFiipu
|
||||
#() iFiipp
|
||||
#() iFiuii
|
||||
#() iFiuui
|
||||
@@ -738,12 +741,14 @@
|
||||
#() uFppLp
|
||||
#() uFpppi
|
||||
#() uFpppp
|
||||
#() UFpipp
|
||||
#() UFppii
|
||||
#() UFppip
|
||||
#() UFpppp
|
||||
#() UFSUii
|
||||
#() dFpppp
|
||||
#() lFEpip
|
||||
#() lFiipL
|
||||
#() lFipLi
|
||||
#() lFipLI
|
||||
#() lFipLl
|
||||
@@ -801,6 +806,7 @@
|
||||
#() pFppip
|
||||
#() pFppuu
|
||||
#() pFppup
|
||||
#() pFppLL
|
||||
#() pFppLp
|
||||
#() pFpppi
|
||||
#() pFpppu
|
||||
@@ -809,6 +815,7 @@
|
||||
#() pFpppV
|
||||
#() pFSppi
|
||||
#() vFEippp
|
||||
#() vFEpipu
|
||||
#() vFEpuup
|
||||
#() vFEpupp
|
||||
#() vFEpLLp
|
||||
@@ -934,7 +941,7 @@
|
||||
#() iFiiipp
|
||||
#() iFiiupp
|
||||
#() iFiipip
|
||||
#() iFiuuuu
|
||||
#() iFiLLLL
|
||||
#() iFipiii
|
||||
#() iFipipi
|
||||
#() iFipipu
|
||||
@@ -1017,8 +1024,10 @@
|
||||
#() uFppiip
|
||||
#() uFppipp
|
||||
#() uFppuup
|
||||
#() uFppupp
|
||||
#() uFpplip
|
||||
#() uFppLpp
|
||||
#() uFppppu
|
||||
#() uFppppp
|
||||
#() lFEipiI
|
||||
#() lFipLli
|
||||
@@ -1026,6 +1035,7 @@
|
||||
#() LFEpppp
|
||||
#() LFpuppi
|
||||
#() LFpLppp
|
||||
#() LFppLLp
|
||||
#() LFpppii
|
||||
#() LFppppp
|
||||
#() pFEpiii
|
||||
@@ -1195,7 +1205,6 @@
|
||||
#() iFiuiipi
|
||||
#() iFipipuu
|
||||
#() iFipuipu
|
||||
#() iFipuipp
|
||||
#() iFipupup
|
||||
#() iFipuppp
|
||||
#() iFipppup
|
||||
@@ -1258,9 +1267,13 @@
|
||||
#() uFEiippp
|
||||
#() uFEiuppp
|
||||
#() uFpippup
|
||||
#() uFpuippp
|
||||
#() uFppippp
|
||||
#() uFpppppi
|
||||
#() uFpppppp
|
||||
#() uFSpuiip
|
||||
#() UFpippup
|
||||
#() lFipLipp
|
||||
#() LFEupppp
|
||||
#() LFpipipi
|
||||
#() LFpLippp
|
||||
@@ -1379,7 +1392,6 @@
|
||||
#() iFEpppiiu
|
||||
#() iFEpppppp
|
||||
#() iFiiiiiip
|
||||
#() iFiuppppp
|
||||
#() iFpiiiiii
|
||||
#() iFpiiiiip
|
||||
#() iFpiiiLwp
|
||||
@@ -1405,6 +1417,7 @@
|
||||
#() iFppiiuui
|
||||
#() iFppiipii
|
||||
#() iFppiipiL
|
||||
#() iFppiuppi
|
||||
#() iFppipiip
|
||||
#() iFppipipi
|
||||
#() iFppipipp
|
||||
@@ -1431,6 +1444,7 @@
|
||||
#() iFppppppp
|
||||
#() uFEpiippp
|
||||
#() uFuippppp
|
||||
#() uFppiuppp
|
||||
#() LFEpppppu
|
||||
#() pFEpLiiii
|
||||
#() pFEpLiiiI
|
||||
@@ -1520,7 +1534,6 @@
|
||||
#() iFEpuuLppp
|
||||
#() iFEppppipp
|
||||
#() iFiiiiiiip
|
||||
#() iFiiippppp
|
||||
#() iFiiupiupi
|
||||
#() iFipOuuuuu
|
||||
#() iFuiifpppp
|
||||
@@ -1548,6 +1561,7 @@
|
||||
#() uFEppipppp
|
||||
#() uFEppppppp
|
||||
#() uFuipppppp
|
||||
#() uFppuppppp
|
||||
#() LFEpiupppp
|
||||
#() pFEppCuuCC
|
||||
#() pFEppCuuWW
|
||||
@@ -1605,7 +1619,6 @@
|
||||
#() vFppppipiip
|
||||
#() vFpppppippp
|
||||
#() vFppppppppp
|
||||
#() iFEiiuuuuuu
|
||||
#() iFEpiiiiipi
|
||||
#() iFEpuuiippu
|
||||
#() iFEpuuuiipp
|
||||
@@ -1683,6 +1696,7 @@
|
||||
#() iFEpuipupppp
|
||||
#() iFEpuuiiuipp
|
||||
#() iFEpuuuuiipp
|
||||
#() iFEppppppipp
|
||||
#() iFiiiiiiiiip
|
||||
#() iFpuipuppppp
|
||||
#() iFpuupiuiipp
|
||||
@@ -1735,6 +1749,7 @@
|
||||
#() uFEpiiupppiuV
|
||||
#() uFEpiippppiup
|
||||
#() uFEppppppippp
|
||||
#() uFppppppppppp
|
||||
#() pFEpipppppppi
|
||||
#() pFEppiiLpppip
|
||||
#() pFEppCuWCCuuu
|
||||
@@ -1784,6 +1799,7 @@
|
||||
#() iFpupiiiipppppp
|
||||
#() iFpuppppppppppp
|
||||
#() iFppppppppppppp
|
||||
#() uFppppuuupppppp
|
||||
#() pFppppppppppppp
|
||||
#() vFuffiiffiiffiip
|
||||
#() vFuddiiddiiddiip
|
||||
@@ -1828,6 +1844,7 @@
|
||||
#defined(NOALIGN) dFpi
|
||||
#defined(NOALIGN) iFppiiiip
|
||||
#!defined(NOALIGN) iFEi
|
||||
#!defined(NOALIGN) iFEO
|
||||
#!defined(NOALIGN) dFEp
|
||||
#!defined(NOALIGN) iFEpI
|
||||
#!defined(NOALIGN) iFEpd
|
||||
@@ -1837,6 +1854,8 @@
|
||||
#!defined(NOALIGN) iFEipii
|
||||
#!defined(NOALIGN) iFEpppi
|
||||
#!defined(NOALIGN) iFEppiiiip
|
||||
#defined(POWERPCLE) iFEiiiN
|
||||
#!defined(POWERPCLE) iFiiiN
|
||||
#defined(HAVE_LD80BITS) DFD
|
||||
#defined(HAVE_LD80BITS) DFDD
|
||||
#defined(HAVE_LD80BITS) DFDp
|
||||
|
||||
@@ -401,8 +401,10 @@ typedef int32_t (*iFiiO_t)(int32_t, int32_t, int32_t);
|
||||
typedef int32_t (*iFiII_t)(int32_t, int64_t, int64_t);
|
||||
typedef int32_t (*iFiuu_t)(int32_t, uint32_t, uint32_t);
|
||||
typedef int32_t (*iFiup_t)(int32_t, uint32_t, void*);
|
||||
typedef int32_t (*iFiLN_t)(int32_t, uintptr_t, ...);
|
||||
typedef int32_t (*iFipi_t)(int32_t, void*, int32_t);
|
||||
typedef int32_t (*iFipu_t)(int32_t, void*, uint32_t);
|
||||
typedef int32_t (*iFipL_t)(int32_t, void*, uintptr_t);
|
||||
typedef int32_t (*iFipp_t)(int32_t, void*, void*);
|
||||
typedef int32_t (*iFCiW_t)(uint8_t, int32_t, uint16_t);
|
||||
typedef int32_t (*iFuii_t)(uint32_t, int32_t, int32_t);
|
||||
@@ -569,6 +571,7 @@ typedef void* (*pFSpi_t)(void*, void*, int32_t);
|
||||
typedef void* (*pFSpp_t)(void*, void*, void*);
|
||||
typedef void (*vFEiip_t)(x86emu_t*, int32_t, int32_t, void*);
|
||||
typedef void (*vFEipV_t)(x86emu_t*, int32_t, void*, void*);
|
||||
typedef void (*vFEpii_t)(x86emu_t*, void*, int32_t, int32_t);
|
||||
typedef void (*vFEpiL_t)(x86emu_t*, void*, int32_t, uintptr_t);
|
||||
typedef void (*vFEpip_t)(x86emu_t*, void*, int32_t, void*);
|
||||
typedef void (*vFEpuu_t)(x86emu_t*, void*, uint32_t, uint32_t);
|
||||
@@ -674,6 +677,7 @@ typedef void (*vFpPpp_t)(void*, void*, void*, void*);
|
||||
typedef void (*vFSppi_t)(void*, void*, void*, int32_t);
|
||||
typedef int8_t (*cFpiii_t)(void*, int32_t, int32_t, int32_t);
|
||||
typedef int32_t (*iFEiip_t)(x86emu_t*, int32_t, int32_t, void*);
|
||||
typedef int32_t (*iFEiiN_t)(x86emu_t*, int32_t, int32_t, ...);
|
||||
typedef int32_t (*iFEipp_t)(x86emu_t*, int32_t, void*, void*);
|
||||
typedef int32_t (*iFEupp_t)(x86emu_t*, uint32_t, void*, void*);
|
||||
typedef int32_t (*iFELup_t)(x86emu_t*, uintptr_t, uint32_t, void*);
|
||||
@@ -700,7 +704,6 @@ typedef int32_t (*iFiiip_t)(int32_t, int32_t, int32_t, void*);
|
||||
typedef int32_t (*iFiiII_t)(int32_t, int32_t, int64_t, int64_t);
|
||||
typedef int32_t (*iFiiLi_t)(int32_t, int32_t, uintptr_t, int32_t);
|
||||
typedef int32_t (*iFiipi_t)(int32_t, int32_t, void*, int32_t);
|
||||
typedef int32_t (*iFiipu_t)(int32_t, int32_t, void*, uint32_t);
|
||||
typedef int32_t (*iFiipp_t)(int32_t, int32_t, void*, void*);
|
||||
typedef int32_t (*iFiuii_t)(int32_t, uint32_t, int32_t, int32_t);
|
||||
typedef int32_t (*iFiuui_t)(int32_t, uint32_t, uint32_t, int32_t);
|
||||
@@ -809,12 +812,14 @@ typedef uint32_t (*uFppup_t)(void*, void*, uint32_t, void*);
|
||||
typedef uint32_t (*uFppLp_t)(void*, void*, uintptr_t, void*);
|
||||
typedef uint32_t (*uFpppi_t)(void*, void*, void*, int32_t);
|
||||
typedef uint32_t (*uFpppp_t)(void*, void*, void*, void*);
|
||||
typedef uint64_t (*UFpipp_t)(void*, int32_t, void*, void*);
|
||||
typedef uint64_t (*UFppii_t)(void*, void*, int32_t, int32_t);
|
||||
typedef uint64_t (*UFppip_t)(void*, void*, int32_t, void*);
|
||||
typedef uint64_t (*UFpppp_t)(void*, void*, void*, void*);
|
||||
typedef uint64_t (*UFSUii_t)(void*, uint64_t, int32_t, int32_t);
|
||||
typedef double (*dFpppp_t)(void*, void*, void*, void*);
|
||||
typedef intptr_t (*lFEpip_t)(x86emu_t*, void*, int32_t, void*);
|
||||
typedef intptr_t (*lFiipL_t)(int32_t, int32_t, void*, uintptr_t);
|
||||
typedef intptr_t (*lFipLi_t)(int32_t, void*, uintptr_t, int32_t);
|
||||
typedef intptr_t (*lFipLI_t)(int32_t, void*, uintptr_t, int64_t);
|
||||
typedef intptr_t (*lFipLl_t)(int32_t, void*, uintptr_t, intptr_t);
|
||||
@@ -872,6 +877,7 @@ typedef void* (*pFppiL_t)(void*, void*, int32_t, uintptr_t);
|
||||
typedef void* (*pFppip_t)(void*, void*, int32_t, void*);
|
||||
typedef void* (*pFppuu_t)(void*, void*, uint32_t, uint32_t);
|
||||
typedef void* (*pFppup_t)(void*, void*, uint32_t, void*);
|
||||
typedef void* (*pFppLL_t)(void*, void*, uintptr_t, uintptr_t);
|
||||
typedef void* (*pFppLp_t)(void*, void*, uintptr_t, void*);
|
||||
typedef void* (*pFpppi_t)(void*, void*, void*, int32_t);
|
||||
typedef void* (*pFpppu_t)(void*, void*, void*, uint32_t);
|
||||
@@ -880,6 +886,7 @@ typedef void* (*pFpppp_t)(void*, void*, void*, void*);
|
||||
typedef void* (*pFpppV_t)(void*, void*, void*, void*);
|
||||
typedef void* (*pFSppi_t)(void*, void*, void*, int32_t);
|
||||
typedef void (*vFEippp_t)(x86emu_t*, int32_t, void*, void*, void*);
|
||||
typedef void (*vFEpipu_t)(x86emu_t*, void*, int32_t, void*, uint32_t);
|
||||
typedef void (*vFEpuup_t)(x86emu_t*, void*, uint32_t, uint32_t, void*);
|
||||
typedef void (*vFEpupp_t)(x86emu_t*, void*, uint32_t, void*, void*);
|
||||
typedef void (*vFEpLLp_t)(x86emu_t*, void*, uintptr_t, uintptr_t, void*);
|
||||
@@ -1005,7 +1012,7 @@ typedef int32_t (*iFiiipu_t)(int32_t, int32_t, int32_t, void*, uint32_t);
|
||||
typedef int32_t (*iFiiipp_t)(int32_t, int32_t, int32_t, void*, void*);
|
||||
typedef int32_t (*iFiiupp_t)(int32_t, int32_t, uint32_t, void*, void*);
|
||||
typedef int32_t (*iFiipip_t)(int32_t, int32_t, void*, int32_t, void*);
|
||||
typedef int32_t (*iFiuuuu_t)(int32_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
typedef int32_t (*iFiLLLL_t)(int32_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
||||
typedef int32_t (*iFipiii_t)(int32_t, void*, int32_t, int32_t, int32_t);
|
||||
typedef int32_t (*iFipipi_t)(int32_t, void*, int32_t, void*, int32_t);
|
||||
typedef int32_t (*iFipipu_t)(int32_t, void*, int32_t, void*, uint32_t);
|
||||
@@ -1088,8 +1095,10 @@ typedef uint32_t (*uFpuuup_t)(void*, uint32_t, uint32_t, uint32_t, void*);
|
||||
typedef uint32_t (*uFppiip_t)(void*, void*, int32_t, int32_t, void*);
|
||||
typedef uint32_t (*uFppipp_t)(void*, void*, int32_t, void*, void*);
|
||||
typedef uint32_t (*uFppuup_t)(void*, void*, uint32_t, uint32_t, void*);
|
||||
typedef uint32_t (*uFppupp_t)(void*, void*, uint32_t, void*, void*);
|
||||
typedef uint32_t (*uFpplip_t)(void*, void*, intptr_t, int32_t, void*);
|
||||
typedef uint32_t (*uFppLpp_t)(void*, void*, uintptr_t, void*, void*);
|
||||
typedef uint32_t (*uFppppu_t)(void*, void*, void*, void*, uint32_t);
|
||||
typedef uint32_t (*uFppppp_t)(void*, void*, void*, void*, void*);
|
||||
typedef intptr_t (*lFEipiI_t)(x86emu_t*, int32_t, void*, int32_t, int64_t);
|
||||
typedef intptr_t (*lFipLli_t)(int32_t, void*, uintptr_t, intptr_t, int32_t);
|
||||
@@ -1097,6 +1106,7 @@ typedef intptr_t (*lFppiip_t)(void*, void*, int32_t, int32_t, void*);
|
||||
typedef uintptr_t (*LFEpppp_t)(x86emu_t*, void*, void*, void*, void*);
|
||||
typedef uintptr_t (*LFpuppi_t)(void*, uint32_t, void*, void*, int32_t);
|
||||
typedef uintptr_t (*LFpLppp_t)(void*, uintptr_t, void*, void*, void*);
|
||||
typedef uintptr_t (*LFppLLp_t)(void*, void*, uintptr_t, uintptr_t, void*);
|
||||
typedef uintptr_t (*LFpppii_t)(void*, void*, void*, int32_t, int32_t);
|
||||
typedef uintptr_t (*LFppppp_t)(void*, void*, void*, void*, void*);
|
||||
typedef void* (*pFEpiii_t)(x86emu_t*, void*, int32_t, int32_t, int32_t);
|
||||
@@ -1266,7 +1276,6 @@ typedef int32_t (*iFiiiLwp_t)(int32_t, int32_t, int32_t, uintptr_t, int16_t, voi
|
||||
typedef int32_t (*iFiuiipi_t)(int32_t, uint32_t, int32_t, int32_t, void*, int32_t);
|
||||
typedef int32_t (*iFipipuu_t)(int32_t, void*, int32_t, void*, uint32_t, uint32_t);
|
||||
typedef int32_t (*iFipuipu_t)(int32_t, void*, uint32_t, int32_t, void*, uint32_t);
|
||||
typedef int32_t (*iFipuipp_t)(int32_t, void*, uint32_t, int32_t, void*, void*);
|
||||
typedef int32_t (*iFipupup_t)(int32_t, void*, uint32_t, void*, uint32_t, void*);
|
||||
typedef int32_t (*iFipuppp_t)(int32_t, void*, uint32_t, void*, void*, void*);
|
||||
typedef int32_t (*iFipppup_t)(int32_t, void*, void*, void*, uint32_t, void*);
|
||||
@@ -1329,9 +1338,13 @@ typedef int32_t (*iFpppppp_t)(void*, void*, void*, void*, void*, void*);
|
||||
typedef uint32_t (*uFEiippp_t)(x86emu_t*, int32_t, int32_t, void*, void*, void*);
|
||||
typedef uint32_t (*uFEiuppp_t)(x86emu_t*, int32_t, uint32_t, void*, void*, void*);
|
||||
typedef uint32_t (*uFpippup_t)(void*, int32_t, void*, void*, uint32_t, void*);
|
||||
typedef uint32_t (*uFpuippp_t)(void*, uint32_t, int32_t, void*, void*, void*);
|
||||
typedef uint32_t (*uFppippp_t)(void*, void*, int32_t, void*, void*, void*);
|
||||
typedef uint32_t (*uFpppppi_t)(void*, void*, void*, void*, void*, int32_t);
|
||||
typedef uint32_t (*uFpppppp_t)(void*, void*, void*, void*, void*, void*);
|
||||
typedef uint32_t (*uFSpuiip_t)(void*, void*, uint32_t, int32_t, int32_t, void*);
|
||||
typedef uint64_t (*UFpippup_t)(void*, int32_t, void*, void*, uint32_t, void*);
|
||||
typedef intptr_t (*lFipLipp_t)(int32_t, void*, uintptr_t, int32_t, void*, void*);
|
||||
typedef uintptr_t (*LFEupppp_t)(x86emu_t*, uint32_t, void*, void*, void*, void*);
|
||||
typedef uintptr_t (*LFpipipi_t)(void*, int32_t, void*, int32_t, void*, int32_t);
|
||||
typedef uintptr_t (*LFpLippp_t)(void*, uintptr_t, int32_t, void*, void*, void*);
|
||||
@@ -1450,7 +1463,6 @@ typedef int32_t (*iFEppuppp_t)(x86emu_t*, void*, void*, uint32_t, void*, void*,
|
||||
typedef int32_t (*iFEpppiiu_t)(x86emu_t*, void*, void*, void*, int32_t, int32_t, uint32_t);
|
||||
typedef int32_t (*iFEpppppp_t)(x86emu_t*, void*, void*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFiiiiiip_t)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, void*);
|
||||
typedef int32_t (*iFiuppppp_t)(int32_t, uint32_t, void*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFpiiiiii_t)(void*, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t);
|
||||
typedef int32_t (*iFpiiiiip_t)(void*, int32_t, int32_t, int32_t, int32_t, int32_t, void*);
|
||||
typedef int32_t (*iFpiiiLwp_t)(void*, int32_t, int32_t, int32_t, uintptr_t, int16_t, void*);
|
||||
@@ -1476,6 +1488,7 @@ typedef int32_t (*iFpLipipi_t)(void*, uintptr_t, int32_t, void*, int32_t, void*,
|
||||
typedef int32_t (*iFppiiuui_t)(void*, void*, int32_t, int32_t, uint32_t, uint32_t, int32_t);
|
||||
typedef int32_t (*iFppiipii_t)(void*, void*, int32_t, int32_t, void*, int32_t, int32_t);
|
||||
typedef int32_t (*iFppiipiL_t)(void*, void*, int32_t, int32_t, void*, int32_t, uintptr_t);
|
||||
typedef int32_t (*iFppiuppi_t)(void*, void*, int32_t, uint32_t, void*, void*, int32_t);
|
||||
typedef int32_t (*iFppipiip_t)(void*, void*, int32_t, void*, int32_t, int32_t, void*);
|
||||
typedef int32_t (*iFppipipi_t)(void*, void*, int32_t, void*, int32_t, void*, int32_t);
|
||||
typedef int32_t (*iFppipipp_t)(void*, void*, int32_t, void*, int32_t, void*, void*);
|
||||
@@ -1502,6 +1515,7 @@ typedef int32_t (*iFppppppi_t)(void*, void*, void*, void*, void*, void*, int32_t
|
||||
typedef int32_t (*iFppppppp_t)(void*, void*, void*, void*, void*, void*, void*);
|
||||
typedef uint32_t (*uFEpiippp_t)(x86emu_t*, void*, int32_t, int32_t, void*, void*, void*);
|
||||
typedef uint32_t (*uFuippppp_t)(uint32_t, int32_t, void*, void*, void*, void*, void*);
|
||||
typedef uint32_t (*uFppiuppp_t)(void*, void*, int32_t, uint32_t, void*, void*, void*);
|
||||
typedef uintptr_t (*LFEpppppu_t)(x86emu_t*, void*, void*, void*, void*, void*, uint32_t);
|
||||
typedef void* (*pFEpLiiii_t)(x86emu_t*, void*, uintptr_t, int32_t, int32_t, int32_t, int32_t);
|
||||
typedef void* (*pFEpLiiiI_t)(x86emu_t*, void*, uintptr_t, int32_t, int32_t, int32_t, int64_t);
|
||||
@@ -1591,7 +1605,6 @@ typedef int32_t (*iFEpuuuipp_t)(x86emu_t*, void*, uint32_t, uint32_t, uint32_t,
|
||||
typedef int32_t (*iFEpuuLppp_t)(x86emu_t*, void*, uint32_t, uint32_t, uintptr_t, void*, void*, void*);
|
||||
typedef int32_t (*iFEppppipp_t)(x86emu_t*, void*, void*, void*, void*, int32_t, void*, void*);
|
||||
typedef int32_t (*iFiiiiiiip_t)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, void*);
|
||||
typedef int32_t (*iFiiippppp_t)(int32_t, int32_t, int32_t, void*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFiiupiupi_t)(int32_t, int32_t, uint32_t, void*, int32_t, uint32_t, void*, int32_t);
|
||||
typedef int32_t (*iFipOuuuuu_t)(int32_t, void*, int32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
typedef int32_t (*iFuiifpppp_t)(uint32_t, int32_t, int32_t, float, void*, void*, void*, void*);
|
||||
@@ -1619,6 +1632,7 @@ typedef uint32_t (*uFEpiupppp_t)(x86emu_t*, void*, int32_t, uint32_t, void*, voi
|
||||
typedef uint32_t (*uFEppipppp_t)(x86emu_t*, void*, void*, int32_t, void*, void*, void*, void*);
|
||||
typedef uint32_t (*uFEppppppp_t)(x86emu_t*, void*, void*, void*, void*, void*, void*, void*);
|
||||
typedef uint32_t (*uFuipppppp_t)(uint32_t, int32_t, void*, void*, void*, void*, void*, void*);
|
||||
typedef uint32_t (*uFppuppppp_t)(void*, void*, uint32_t, void*, void*, void*, void*, void*);
|
||||
typedef uintptr_t (*LFEpiupppp_t)(x86emu_t*, void*, int32_t, uint32_t, void*, void*, void*, void*);
|
||||
typedef void* (*pFEppCuuCC_t)(x86emu_t*, void*, void*, uint8_t, uint32_t, uint32_t, uint8_t, uint8_t);
|
||||
typedef void* (*pFEppCuuWW_t)(x86emu_t*, void*, void*, uint8_t, uint32_t, uint32_t, uint16_t, uint16_t);
|
||||
@@ -1676,7 +1690,6 @@ typedef void (*vFpppiiiiii_t)(void*, void*, void*, int32_t, int32_t, int32_t, in
|
||||
typedef void (*vFppppipiip_t)(void*, void*, void*, void*, int32_t, void*, int32_t, int32_t, void*);
|
||||
typedef void (*vFpppppippp_t)(void*, void*, void*, void*, void*, int32_t, void*, void*, void*);
|
||||
typedef void (*vFppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFEiiuuuuuu_t)(x86emu_t*, int32_t, int32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
typedef int32_t (*iFEpiiiiipi_t)(x86emu_t*, void*, int32_t, int32_t, int32_t, int32_t, int32_t, void*, int32_t);
|
||||
typedef int32_t (*iFEpuuiippu_t)(x86emu_t*, void*, uint32_t, uint32_t, int32_t, int32_t, void*, void*, uint32_t);
|
||||
typedef int32_t (*iFEpuuuiipp_t)(x86emu_t*, void*, uint32_t, uint32_t, uint32_t, int32_t, int32_t, void*, void*);
|
||||
@@ -1754,6 +1767,7 @@ typedef int32_t (*iFEpiiiiippp_t)(x86emu_t*, void*, int32_t, int32_t, int32_t, i
|
||||
typedef int32_t (*iFEpuipupppp_t)(x86emu_t*, void*, uint32_t, int32_t, void*, uint32_t, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFEpuuiiuipp_t)(x86emu_t*, void*, uint32_t, uint32_t, int32_t, int32_t, uint32_t, int32_t, void*, void*);
|
||||
typedef int32_t (*iFEpuuuuiipp_t)(x86emu_t*, void*, uint32_t, uint32_t, uint32_t, uint32_t, int32_t, int32_t, void*, void*);
|
||||
typedef int32_t (*iFEppppppipp_t)(x86emu_t*, void*, void*, void*, void*, void*, void*, int32_t, void*, void*);
|
||||
typedef int32_t (*iFiiiiiiiiip_t)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, void*);
|
||||
typedef int32_t (*iFpuipuppppp_t)(void*, uint32_t, int32_t, void*, uint32_t, void*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFpuupiuiipp_t)(void*, uint32_t, uint32_t, void*, int32_t, uint32_t, int32_t, int32_t, void*, void*);
|
||||
@@ -1806,6 +1820,7 @@ typedef int32_t (*iFppppiiuuiiu_t)(void*, void*, void*, void*, int32_t, int32_t,
|
||||
typedef uint32_t (*uFEpiiupppiuV_t)(x86emu_t*, void*, int32_t, int32_t, uint32_t, void*, void*, void*, int32_t, uint32_t, void*);
|
||||
typedef uint32_t (*uFEpiippppiup_t)(x86emu_t*, void*, int32_t, int32_t, void*, void*, void*, void*, int32_t, uint32_t, void*);
|
||||
typedef uint32_t (*uFEppppppippp_t)(x86emu_t*, void*, void*, void*, void*, void*, void*, int32_t, void*, void*, void*);
|
||||
typedef uint32_t (*uFppppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
|
||||
typedef void* (*pFEpipppppppi_t)(x86emu_t*, void*, int32_t, void*, void*, void*, void*, void*, void*, void*, int32_t);
|
||||
typedef void* (*pFEppiiLpppip_t)(x86emu_t*, void*, void*, int32_t, int32_t, uintptr_t, void*, void*, void*, int32_t, void*);
|
||||
typedef void* (*pFEppCuWCCuuu_t)(x86emu_t*, void*, void*, uint8_t, uint32_t, uint16_t, uint8_t, uint8_t, uint32_t, uint32_t, uint32_t);
|
||||
@@ -1855,6 +1870,7 @@ typedef int32_t (*iFpippppppppppp_t)(void*, int32_t, void*, void*, void*, void*,
|
||||
typedef int32_t (*iFpupiiiipppppp_t)(void*, uint32_t, void*, int32_t, int32_t, int32_t, int32_t, void*, void*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFpuppppppppppp_t)(void*, uint32_t, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFppppppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
|
||||
typedef uint32_t (*uFppppuuupppppp_t)(void*, void*, void*, void*, uint32_t, uint32_t, uint32_t, void*, void*, void*, void*, void*, void*);
|
||||
typedef void* (*pFppppppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
|
||||
typedef void (*vFuffiiffiiffiip_t)(uint32_t, float, float, int32_t, int32_t, float, float, int32_t, int32_t, float, float, int32_t, int32_t, void*);
|
||||
typedef void (*vFuddiiddiiddiip_t)(uint32_t, double, double, int32_t, int32_t, double, double, int32_t, int32_t, double, double, int32_t, int32_t, void*);
|
||||
@@ -1904,6 +1920,7 @@ typedef int32_t (*iFppiiiip_t)(void*, void*, int32_t, int32_t, int32_t, int32_t,
|
||||
|
||||
#if !defined(NOALIGN)
|
||||
typedef int32_t (*iFEi_t)(x86emu_t*, int32_t);
|
||||
typedef int32_t (*iFEO_t)(x86emu_t*, int32_t);
|
||||
typedef double (*dFEp_t)(x86emu_t*, void*);
|
||||
typedef int32_t (*iFEpI_t)(x86emu_t*, void*, int64_t);
|
||||
typedef int32_t (*iFEpd_t)(x86emu_t*, void*, double);
|
||||
@@ -1915,6 +1932,14 @@ typedef int32_t (*iFEpppi_t)(x86emu_t*, void*, void*, void*, int32_t);
|
||||
typedef int32_t (*iFEppiiiip_t)(x86emu_t*, void*, void*, int32_t, int32_t, int32_t, int32_t, void*);
|
||||
#endif
|
||||
|
||||
#if defined(POWERPCLE)
|
||||
typedef int32_t (*iFEiiiN_t)(x86emu_t*, int32_t, int32_t, int32_t, ...);
|
||||
#endif
|
||||
|
||||
#if !defined(POWERPCLE)
|
||||
typedef int32_t (*iFiiiN_t)(int32_t, int32_t, int32_t, ...);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LD80BITS)
|
||||
typedef long double (*DFD_t)(long double);
|
||||
typedef long double (*DFDD_t)(long double, long double);
|
||||
@@ -2269,8 +2294,10 @@ void iFiiO(x86emu_t *emu, uintptr_t fcn) { iFiiO_t fn = (iFiiO_t)fcn; R_EAX=fn(*
|
||||
void iFiII(x86emu_t *emu, uintptr_t fcn) { iFiII_t fn = (iFiII_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int64_t*)(R_ESP + 8), *(int64_t*)(R_ESP + 16)); }
|
||||
void iFiuu(x86emu_t *emu, uintptr_t fcn) { iFiuu_t fn = (iFiuu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); }
|
||||
void iFiup(x86emu_t *emu, uintptr_t fcn) { iFiup_t fn = (iFiup_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void iFiLN(x86emu_t *emu, uintptr_t fcn) { iFiLN_t fn = (iFiLN_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uintptr_t*)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void iFipi(x86emu_t *emu, uintptr_t fcn) { iFipi_t fn = (iFipi_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12)); }
|
||||
void iFipu(x86emu_t *emu, uintptr_t fcn) { iFipu_t fn = (iFipu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); }
|
||||
void iFipL(x86emu_t *emu, uintptr_t fcn) { iFipL_t fn = (iFipL_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12)); }
|
||||
void iFipp(x86emu_t *emu, uintptr_t fcn) { iFipp_t fn = (iFipp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void iFCiW(x86emu_t *emu, uintptr_t fcn) { iFCiW_t fn = (iFCiW_t)fcn; R_EAX=fn(*(uint8_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(uint16_t*)(R_ESP + 12)); }
|
||||
void iFuii(x86emu_t *emu, uintptr_t fcn) { iFuii_t fn = (iFuii_t)fcn; R_EAX=fn(*(uint32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12)); }
|
||||
@@ -2437,6 +2464,7 @@ void pFSpi(x86emu_t *emu, uintptr_t fcn) { pFSpi_t fn = (pFSpi_t)fcn; R_EAX=(uin
|
||||
void pFSpp(x86emu_t *emu, uintptr_t fcn) { pFSpp_t fn = (pFSpp_t)fcn; R_EAX=(uintptr_t)fn(io_convert(*(void**)(R_ESP + 4)), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void vFEiip(x86emu_t *emu, uintptr_t fcn) { vFEiip_t fn = (vFEiip_t)fcn; fn(emu, *(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void vFEipV(x86emu_t *emu, uintptr_t fcn) { vFEipV_t fn = (vFEipV_t)fcn; fn(emu, *(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), (void*)(R_ESP + 12)); }
|
||||
void vFEpii(x86emu_t *emu, uintptr_t fcn) { vFEpii_t fn = (vFEpii_t)fcn; fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12)); }
|
||||
void vFEpiL(x86emu_t *emu, uintptr_t fcn) { vFEpiL_t fn = (vFEpiL_t)fcn; fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12)); }
|
||||
void vFEpip(x86emu_t *emu, uintptr_t fcn) { vFEpip_t fn = (vFEpip_t)fcn; fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void vFEpuu(x86emu_t *emu, uintptr_t fcn) { vFEpuu_t fn = (vFEpuu_t)fcn; fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); }
|
||||
@@ -2542,6 +2570,7 @@ void vFpPpp(x86emu_t *emu, uintptr_t fcn) { vFpPpp_t fn = (vFpPpp_t)fcn; void* s
|
||||
void vFSppi(x86emu_t *emu, uintptr_t fcn) { vFSppi_t fn = (vFSppi_t)fcn; fn(io_convert(*(void**)(R_ESP + 4)), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void cFpiii(x86emu_t *emu, uintptr_t fcn) { cFpiii_t fn = (cFpiii_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void iFEiip(x86emu_t *emu, uintptr_t fcn) { iFEiip_t fn = (iFEiip_t)fcn; R_EAX=fn(emu, *(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void iFEiiN(x86emu_t *emu, uintptr_t fcn) { iFEiiN_t fn = (iFEiiN_t)fcn; R_EAX=fn(emu, *(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void iFEipp(x86emu_t *emu, uintptr_t fcn) { iFEipp_t fn = (iFEipp_t)fcn; R_EAX=fn(emu, *(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void iFEupp(x86emu_t *emu, uintptr_t fcn) { iFEupp_t fn = (iFEupp_t)fcn; R_EAX=fn(emu, *(uint32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void iFELup(x86emu_t *emu, uintptr_t fcn) { iFELup_t fn = (iFELup_t)fcn; R_EAX=fn(emu, *(uintptr_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
@@ -2568,7 +2597,6 @@ void iFiiip(x86emu_t *emu, uintptr_t fcn) { iFiiip_t fn = (iFiiip_t)fcn; R_EAX=f
|
||||
void iFiiII(x86emu_t *emu, uintptr_t fcn) { iFiiII_t fn = (iFiiII_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int64_t*)(R_ESP + 12), *(int64_t*)(R_ESP + 20)); }
|
||||
void iFiiLi(x86emu_t *emu, uintptr_t fcn) { iFiiLi_t fn = (iFiiLi_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void iFiipi(x86emu_t *emu, uintptr_t fcn) { iFiipi_t fn = (iFiipi_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void iFiipu(x86emu_t *emu, uintptr_t fcn) { iFiipu_t fn = (iFiipu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(uint32_t*)(R_ESP + 16)); }
|
||||
void iFiipp(x86emu_t *emu, uintptr_t fcn) { iFiipp_t fn = (iFiipp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void iFiuii(x86emu_t *emu, uintptr_t fcn) { iFiuii_t fn = (iFiuii_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void iFiuui(x86emu_t *emu, uintptr_t fcn) { iFiuui_t fn = (iFiuui_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
@@ -2677,12 +2705,14 @@ void uFppup(x86emu_t *emu, uintptr_t fcn) { uFppup_t fn = (uFppup_t)fcn; R_EAX=(
|
||||
void uFppLp(x86emu_t *emu, uintptr_t fcn) { uFppLp_t fn = (uFppLp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void uFpppi(x86emu_t *emu, uintptr_t fcn) { uFpppi_t fn = (uFpppi_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void uFpppp(x86emu_t *emu, uintptr_t fcn) { uFpppp_t fn = (uFpppp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void UFpipp(x86emu_t *emu, uintptr_t fcn) { UFpipp_t fn = (UFpipp_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void UFppii(x86emu_t *emu, uintptr_t fcn) { UFppii_t fn = (UFppii_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void UFppip(x86emu_t *emu, uintptr_t fcn) { UFppip_t fn = (UFppip_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void UFpppp(x86emu_t *emu, uintptr_t fcn) { UFpppp_t fn = (UFpppp_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void UFSUii(x86emu_t *emu, uintptr_t fcn) { UFSUii_t fn = (UFSUii_t)fcn; ui64_t r; r.u=(uint64_t)fn(io_convert(*(void**)(R_ESP + 4)), *(uint64_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void dFpppp(x86emu_t *emu, uintptr_t fcn) { dFpppp_t fn = (dFpppp_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); fpu_do_push(emu); ST0val = db; }
|
||||
void lFEpip(x86emu_t *emu, uintptr_t fcn) { lFEpip_t fn = (lFEpip_t)fcn; R_EAX=(intptr_t)fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void lFiipL(x86emu_t *emu, uintptr_t fcn) { lFiipL_t fn = (lFiipL_t)fcn; R_EAX=(intptr_t)fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(uintptr_t*)(R_ESP + 16)); }
|
||||
void lFipLi(x86emu_t *emu, uintptr_t fcn) { lFipLi_t fn = (lFipLi_t)fcn; R_EAX=(intptr_t)fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void lFipLI(x86emu_t *emu, uintptr_t fcn) { lFipLI_t fn = (lFipLI_t)fcn; R_EAX=(intptr_t)fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(int64_t*)(R_ESP + 16)); }
|
||||
void lFipLl(x86emu_t *emu, uintptr_t fcn) { lFipLl_t fn = (lFipLl_t)fcn; R_EAX=(intptr_t)fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(intptr_t*)(R_ESP + 16)); }
|
||||
@@ -2740,6 +2770,7 @@ void pFppiL(x86emu_t *emu, uintptr_t fcn) { pFppiL_t fn = (pFppiL_t)fcn; R_EAX=(
|
||||
void pFppip(x86emu_t *emu, uintptr_t fcn) { pFppip_t fn = (pFppip_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void pFppuu(x86emu_t *emu, uintptr_t fcn) { pFppuu_t fn = (pFppuu_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16)); }
|
||||
void pFppup(x86emu_t *emu, uintptr_t fcn) { pFppup_t fn = (pFppup_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void pFppLL(x86emu_t *emu, uintptr_t fcn) { pFppLL_t fn = (pFppLL_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(uintptr_t*)(R_ESP + 16)); }
|
||||
void pFppLp(x86emu_t *emu, uintptr_t fcn) { pFppLp_t fn = (pFppLp_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void pFpppi(x86emu_t *emu, uintptr_t fcn) { pFpppi_t fn = (pFpppi_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void pFpppu(x86emu_t *emu, uintptr_t fcn) { pFpppu_t fn = (pFpppu_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(uint32_t*)(R_ESP + 16)); }
|
||||
@@ -2748,6 +2779,7 @@ void pFpppp(x86emu_t *emu, uintptr_t fcn) { pFpppp_t fn = (pFpppp_t)fcn; R_EAX=(
|
||||
void pFpppV(x86emu_t *emu, uintptr_t fcn) { pFpppV_t fn = (pFpppV_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), (void*)(R_ESP + 16)); }
|
||||
void pFSppi(x86emu_t *emu, uintptr_t fcn) { pFSppi_t fn = (pFSppi_t)fcn; R_EAX=(uintptr_t)fn(io_convert(*(void**)(R_ESP + 4)), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void vFEippp(x86emu_t *emu, uintptr_t fcn) { vFEippp_t fn = (vFEippp_t)fcn; fn(emu, *(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void vFEpipu(x86emu_t *emu, uintptr_t fcn) { vFEpipu_t fn = (vFEpipu_t)fcn; fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(uint32_t*)(R_ESP + 16)); }
|
||||
void vFEpuup(x86emu_t *emu, uintptr_t fcn) { vFEpuup_t fn = (vFEpuup_t)fcn; fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void vFEpupp(x86emu_t *emu, uintptr_t fcn) { vFEpupp_t fn = (vFEpupp_t)fcn; fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void vFEpLLp(x86emu_t *emu, uintptr_t fcn) { vFEpLLp_t fn = (vFEpLLp_t)fcn; fn(emu, *(void**)(R_ESP + 4), *(uintptr_t*)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
@@ -2873,7 +2905,7 @@ void iFiiipu(x86emu_t *emu, uintptr_t fcn) { iFiiipu_t fn = (iFiiipu_t)fcn; R_EA
|
||||
void iFiiipp(x86emu_t *emu, uintptr_t fcn) { iFiiipp_t fn = (iFiiipp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void iFiiupp(x86emu_t *emu, uintptr_t fcn) { iFiiupp_t fn = (iFiiupp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void iFiipip(x86emu_t *emu, uintptr_t fcn) { iFiipip_t fn = (iFiipip_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void iFiuuuu(x86emu_t *emu, uintptr_t fcn) { iFiuuuu_t fn = (iFiuuuu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(uint32_t*)(R_ESP + 20)); }
|
||||
void iFiLLLL(x86emu_t *emu, uintptr_t fcn) { iFiLLLL_t fn = (iFiLLLL_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uintptr_t*)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(uintptr_t*)(R_ESP + 16), *(uintptr_t*)(R_ESP + 20)); }
|
||||
void iFipiii(x86emu_t *emu, uintptr_t fcn) { iFipiii_t fn = (iFipiii_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20)); }
|
||||
void iFipipi(x86emu_t *emu, uintptr_t fcn) { iFipipi_t fn = (iFipipi_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20)); }
|
||||
void iFipipu(x86emu_t *emu, uintptr_t fcn) { iFipipu_t fn = (iFipipu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20)); }
|
||||
@@ -2956,8 +2988,10 @@ void uFpuuup(x86emu_t *emu, uintptr_t fcn) { uFpuuup_t fn = (uFpuuup_t)fcn; R_EA
|
||||
void uFppiip(x86emu_t *emu, uintptr_t fcn) { uFppiip_t fn = (uFppiip_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void uFppipp(x86emu_t *emu, uintptr_t fcn) { uFppipp_t fn = (uFppipp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void uFppuup(x86emu_t *emu, uintptr_t fcn) { uFppuup_t fn = (uFppuup_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void uFppupp(x86emu_t *emu, uintptr_t fcn) { uFppupp_t fn = (uFppupp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void uFpplip(x86emu_t *emu, uintptr_t fcn) { uFpplip_t fn = (uFpplip_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(intptr_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void uFppLpp(x86emu_t *emu, uintptr_t fcn) { uFppLpp_t fn = (uFppLpp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void uFppppu(x86emu_t *emu, uintptr_t fcn) { uFppppu_t fn = (uFppppu_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20)); }
|
||||
void uFppppp(x86emu_t *emu, uintptr_t fcn) { uFppppp_t fn = (uFppppp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void lFEipiI(x86emu_t *emu, uintptr_t fcn) { lFEipiI_t fn = (lFEipiI_t)fcn; R_EAX=(intptr_t)fn(emu, *(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int64_t*)(R_ESP + 16)); }
|
||||
void lFipLli(x86emu_t *emu, uintptr_t fcn) { lFipLli_t fn = (lFipLli_t)fcn; R_EAX=(intptr_t)fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(intptr_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20)); }
|
||||
@@ -2965,6 +2999,7 @@ void lFppiip(x86emu_t *emu, uintptr_t fcn) { lFppiip_t fn = (lFppiip_t)fcn; R_EA
|
||||
void LFEpppp(x86emu_t *emu, uintptr_t fcn) { LFEpppp_t fn = (LFEpppp_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void LFpuppi(x86emu_t *emu, uintptr_t fcn) { LFpuppi_t fn = (LFpuppi_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20)); }
|
||||
void LFpLppp(x86emu_t *emu, uintptr_t fcn) { LFpLppp_t fn = (LFpLppp_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(uintptr_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void LFppLLp(x86emu_t *emu, uintptr_t fcn) { LFppLLp_t fn = (LFppLLp_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(uintptr_t*)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void LFpppii(x86emu_t *emu, uintptr_t fcn) { LFpppii_t fn = (LFpppii_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20)); }
|
||||
void LFppppp(x86emu_t *emu, uintptr_t fcn) { LFppppp_t fn = (LFppppp_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void pFEpiii(x86emu_t *emu, uintptr_t fcn) { pFEpiii_t fn = (pFEpiii_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
@@ -3134,7 +3169,6 @@ void iFiiiLwp(x86emu_t *emu, uintptr_t fcn) { iFiiiLwp_t fn = (iFiiiLwp_t)fcn; R
|
||||
void iFiuiipi(x86emu_t *emu, uintptr_t fcn) { iFiuiipi_t fn = (iFiuiipi_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(int32_t*)(R_ESP + 24)); }
|
||||
void iFipipuu(x86emu_t *emu, uintptr_t fcn) { iFipipuu_t fn = (iFipipuu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24)); }
|
||||
void iFipuipu(x86emu_t *emu, uintptr_t fcn) { iFipuipu_t fn = (iFipuipu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(uint32_t*)(R_ESP + 24)); }
|
||||
void iFipuipp(x86emu_t *emu, uintptr_t fcn) { iFipuipp_t fn = (iFipuipp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void iFipupup(x86emu_t *emu, uintptr_t fcn) { iFipupup_t fn = (iFipupup_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void iFipuppp(x86emu_t *emu, uintptr_t fcn) { iFipuppp_t fn = (iFipuppp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void iFipppup(x86emu_t *emu, uintptr_t fcn) { iFipppup_t fn = (iFipppup_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
@@ -3197,9 +3231,13 @@ void iFpppppp(x86emu_t *emu, uintptr_t fcn) { iFpppppp_t fn = (iFpppppp_t)fcn; R
|
||||
void uFEiippp(x86emu_t *emu, uintptr_t fcn) { uFEiippp_t fn = (uFEiippp_t)fcn; R_EAX=(uint32_t)fn(emu, *(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void uFEiuppp(x86emu_t *emu, uintptr_t fcn) { uFEiuppp_t fn = (uFEiuppp_t)fcn; R_EAX=(uint32_t)fn(emu, *(int32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void uFpippup(x86emu_t *emu, uintptr_t fcn) { uFpippup_t fn = (uFpippup_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void uFpuippp(x86emu_t *emu, uintptr_t fcn) { uFpuippp_t fn = (uFpuippp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void uFppippp(x86emu_t *emu, uintptr_t fcn) { uFppippp_t fn = (uFppippp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void uFpppppi(x86emu_t *emu, uintptr_t fcn) { uFpppppi_t fn = (uFpppppi_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(int32_t*)(R_ESP + 24)); }
|
||||
void uFpppppp(x86emu_t *emu, uintptr_t fcn) { uFpppppp_t fn = (uFpppppp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void uFSpuiip(x86emu_t *emu, uintptr_t fcn) { uFSpuiip_t fn = (uFSpuiip_t)fcn; R_EAX=(uint32_t)fn(io_convert(*(void**)(R_ESP + 4)), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void UFpippup(x86emu_t *emu, uintptr_t fcn) { UFpippup_t fn = (UFpippup_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(void**)(R_ESP + 24)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void lFipLipp(x86emu_t *emu, uintptr_t fcn) { lFipLipp_t fn = (lFipLipp_t)fcn; R_EAX=(intptr_t)fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(uintptr_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void LFEupppp(x86emu_t *emu, uintptr_t fcn) { LFEupppp_t fn = (LFEupppp_t)fcn; R_EAX=(uintptr_t)fn(emu, *(uint32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
void LFpipipi(x86emu_t *emu, uintptr_t fcn) { LFpipipi_t fn = (LFpipipi_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(int32_t*)(R_ESP + 24)); }
|
||||
void LFpLippp(x86emu_t *emu, uintptr_t fcn) { LFpLippp_t fn = (LFpLippp_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(uintptr_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
@@ -3318,7 +3356,6 @@ void iFEppuppp(x86emu_t *emu, uintptr_t fcn) { iFEppuppp_t fn = (iFEppuppp_t)fcn
|
||||
void iFEpppiiu(x86emu_t *emu, uintptr_t fcn) { iFEpppiiu_t fn = (iFEpppiiu_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24)); }
|
||||
void iFEpppppp(x86emu_t *emu, uintptr_t fcn) { iFEpppppp_t fn = (iFEpppppp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void iFiiiiiip(x86emu_t *emu, uintptr_t fcn) { iFiiiiiip_t fn = (iFiiiiiip_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void iFiuppppp(x86emu_t *emu, uintptr_t fcn) { iFiuppppp_t fn = (iFiuppppp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void iFpiiiiii(x86emu_t *emu, uintptr_t fcn) { iFpiiiiii_t fn = (iFpiiiiii_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28)); }
|
||||
void iFpiiiiip(x86emu_t *emu, uintptr_t fcn) { iFpiiiiip_t fn = (iFpiiiiip_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void iFpiiiLwp(x86emu_t *emu, uintptr_t fcn) { iFpiiiLwp_t fn = (iFpiiiLwp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(uintptr_t*)(R_ESP + 20), *(int16_t*)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
@@ -3344,6 +3381,7 @@ void iFpLipipi(x86emu_t *emu, uintptr_t fcn) { iFpLipipi_t fn = (iFpLipipi_t)fcn
|
||||
void iFppiiuui(x86emu_t *emu, uintptr_t fcn) { iFppiiuui_t fn = (iFppiiuui_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28)); }
|
||||
void iFppiipii(x86emu_t *emu, uintptr_t fcn) { iFppiipii_t fn = (iFppiipii_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28)); }
|
||||
void iFppiipiL(x86emu_t *emu, uintptr_t fcn) { iFppiipiL_t fn = (iFppiipiL_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(uintptr_t*)(R_ESP + 28)); }
|
||||
void iFppiuppi(x86emu_t *emu, uintptr_t fcn) { iFppiuppi_t fn = (iFppiuppi_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(int32_t*)(R_ESP + 28)); }
|
||||
void iFppipiip(x86emu_t *emu, uintptr_t fcn) { iFppipiip_t fn = (iFppipiip_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void iFppipipi(x86emu_t *emu, uintptr_t fcn) { iFppipipi_t fn = (iFppipipi_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(void**)(R_ESP + 24), *(int32_t*)(R_ESP + 28)); }
|
||||
void iFppipipp(x86emu_t *emu, uintptr_t fcn) { iFppipipp_t fn = (iFppipipp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
@@ -3370,6 +3408,7 @@ void iFppppppi(x86emu_t *emu, uintptr_t fcn) { iFppppppi_t fn = (iFppppppi_t)fcn
|
||||
void iFppppppp(x86emu_t *emu, uintptr_t fcn) { iFppppppp_t fn = (iFppppppp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void uFEpiippp(x86emu_t *emu, uintptr_t fcn) { uFEpiippp_t fn = (uFEpiippp_t)fcn; R_EAX=(uint32_t)fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24)); }
|
||||
void uFuippppp(x86emu_t *emu, uintptr_t fcn) { uFuippppp_t fn = (uFuippppp_t)fcn; R_EAX=(uint32_t)fn(*(uint32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void uFppiuppp(x86emu_t *emu, uintptr_t fcn) { uFppiuppp_t fn = (uFppiuppp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void LFEpppppu(x86emu_t *emu, uintptr_t fcn) { LFEpppppu_t fn = (LFEpppppu_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(uint32_t*)(R_ESP + 24)); }
|
||||
void pFEpLiiii(x86emu_t *emu, uintptr_t fcn) { pFEpLiiii_t fn = (pFEpLiiii_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(uintptr_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24)); }
|
||||
void pFEpLiiiI(x86emu_t *emu, uintptr_t fcn) { pFEpLiiiI_t fn = (pFEpLiiiI_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(uintptr_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int64_t*)(R_ESP + 24)); }
|
||||
@@ -3459,7 +3498,6 @@ void iFEpuuuipp(x86emu_t *emu, uintptr_t fcn) { iFEpuuuipp_t fn = (iFEpuuuipp_t)
|
||||
void iFEpuuLppp(x86emu_t *emu, uintptr_t fcn) { iFEpuuLppp_t fn = (iFEpuuLppp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(uintptr_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void iFEppppipp(x86emu_t *emu, uintptr_t fcn) { iFEppppipp_t fn = (iFEppppipp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void iFiiiiiiip(x86emu_t *emu, uintptr_t fcn) { iFiiiiiiip_t fn = (iFiiiiiiip_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(void**)(R_ESP + 32)); }
|
||||
void iFiiippppp(x86emu_t *emu, uintptr_t fcn) { iFiiippppp_t fn = (iFiiippppp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32)); }
|
||||
void iFiiupiupi(x86emu_t *emu, uintptr_t fcn) { iFiiupiupi_t fn = (iFiiupiupi_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24), *(void**)(R_ESP + 28), *(int32_t*)(R_ESP + 32)); }
|
||||
void iFipOuuuuu(x86emu_t *emu, uintptr_t fcn) { iFipOuuuuu_t fn = (iFipOuuuuu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8), of_convert(*(int32_t*)(R_ESP + 12)), *(uint32_t*)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24), *(uint32_t*)(R_ESP + 28), *(uint32_t*)(R_ESP + 32)); }
|
||||
void iFuiifpppp(x86emu_t *emu, uintptr_t fcn) { iFuiifpppp_t fn = (iFuiifpppp_t)fcn; R_EAX=fn(*(uint32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(float*)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32)); }
|
||||
@@ -3487,6 +3525,7 @@ void uFEpiupppp(x86emu_t *emu, uintptr_t fcn) { uFEpiupppp_t fn = (uFEpiupppp_t)
|
||||
void uFEppipppp(x86emu_t *emu, uintptr_t fcn) { uFEppipppp_t fn = (uFEppipppp_t)fcn; R_EAX=(uint32_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void uFEppppppp(x86emu_t *emu, uintptr_t fcn) { uFEppppppp_t fn = (uFEppppppp_t)fcn; R_EAX=(uint32_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void uFuipppppp(x86emu_t *emu, uintptr_t fcn) { uFuipppppp_t fn = (uFuipppppp_t)fcn; R_EAX=(uint32_t)fn(*(uint32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32)); }
|
||||
void uFppuppppp(x86emu_t *emu, uintptr_t fcn) { uFppuppppp_t fn = (uFppuppppp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32)); }
|
||||
void LFEpiupppp(x86emu_t *emu, uintptr_t fcn) { LFEpiupppp_t fn = (LFEpiupppp_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
void pFEppCuuCC(x86emu_t *emu, uintptr_t fcn) { pFEppCuuCC_t fn = (pFEppCuuCC_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint8_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(uint8_t*)(R_ESP + 24), *(uint8_t*)(R_ESP + 28)); }
|
||||
void pFEppCuuWW(x86emu_t *emu, uintptr_t fcn) { pFEppCuuWW_t fn = (pFEppCuuWW_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint8_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(uint16_t*)(R_ESP + 24), *(uint16_t*)(R_ESP + 28)); }
|
||||
@@ -3544,7 +3583,6 @@ void vFpppiiiiii(x86emu_t *emu, uintptr_t fcn) { vFpppiiiiii_t fn = (vFpppiiiiii
|
||||
void vFppppipiip(x86emu_t *emu, uintptr_t fcn) { vFppppipiip_t fn = (vFppppipiip_t)fcn; fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(void**)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(int32_t*)(R_ESP + 32), *(void**)(R_ESP + 36)); }
|
||||
void vFpppppippp(x86emu_t *emu, uintptr_t fcn) { vFpppppippp_t fn = (vFpppppippp_t)fcn; fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36)); }
|
||||
void vFppppppppp(x86emu_t *emu, uintptr_t fcn) { vFppppppppp_t fn = (vFppppppppp_t)fcn; fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36)); }
|
||||
void iFEiiuuuuuu(x86emu_t *emu, uintptr_t fcn) { iFEiiuuuuuu_t fn = (iFEiiuuuuuu_t)fcn; R_EAX=fn(emu, *(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24), *(uint32_t*)(R_ESP + 28), *(uint32_t*)(R_ESP + 32)); }
|
||||
void iFEpiiiiipi(x86emu_t *emu, uintptr_t fcn) { iFEpiiiiipi_t fn = (iFEpiiiiipi_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(void**)(R_ESP + 28), *(int32_t*)(R_ESP + 32)); }
|
||||
void iFEpuuiippu(x86emu_t *emu, uintptr_t fcn) { iFEpuuiippu_t fn = (iFEpuuiippu_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(uint32_t*)(R_ESP + 32)); }
|
||||
void iFEpuuuiipp(x86emu_t *emu, uintptr_t fcn) { iFEpuuuiipp_t fn = (iFEpuuuiipp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32)); }
|
||||
@@ -3622,6 +3660,7 @@ void iFEpiiiiippp(x86emu_t *emu, uintptr_t fcn) { iFEpiiiiippp_t fn = (iFEpiiiii
|
||||
void iFEpuipupppp(x86emu_t *emu, uintptr_t fcn) { iFEpuipupppp_t fn = (iFEpuipupppp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36)); }
|
||||
void iFEpuuiiuipp(x86emu_t *emu, uintptr_t fcn) { iFEpuuiiuipp_t fn = (iFEpuuiiuipp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36)); }
|
||||
void iFEpuuuuiipp(x86emu_t *emu, uintptr_t fcn) { iFEpuuuuiipp_t fn = (iFEpuuuuiipp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36)); }
|
||||
void iFEppppppipp(x86emu_t *emu, uintptr_t fcn) { iFEppppppipp_t fn = (iFEppppppipp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36)); }
|
||||
void iFiiiiiiiiip(x86emu_t *emu, uintptr_t fcn) { iFiiiiiiiiip_t fn = (iFiiiiiiiiip_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(int32_t*)(R_ESP + 32), *(int32_t*)(R_ESP + 36), *(void**)(R_ESP + 40)); }
|
||||
void iFpuipuppppp(x86emu_t *emu, uintptr_t fcn) { iFpuipuppppp_t fn = (iFpuipuppppp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40)); }
|
||||
void iFpuupiuiipp(x86emu_t *emu, uintptr_t fcn) { iFpuupiuiipp_t fn = (iFpuupiuiipp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(uint32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(int32_t*)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40)); }
|
||||
@@ -3674,6 +3713,7 @@ void iFppppiiuuiiu(x86emu_t *emu, uintptr_t fcn) { iFppppiiuuiiu_t fn = (iFppppi
|
||||
void uFEpiiupppiuV(x86emu_t *emu, uintptr_t fcn) { uFEpiiupppiuV_t fn = (uFEpiiupppiuV_t)fcn; R_EAX=(uint32_t)fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(int32_t*)(R_ESP + 32), *(uint32_t*)(R_ESP + 36), (void*)(R_ESP + 40)); }
|
||||
void uFEpiippppiup(x86emu_t *emu, uintptr_t fcn) { uFEpiippppiup_t fn = (uFEpiippppiup_t)fcn; R_EAX=(uint32_t)fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(int32_t*)(R_ESP + 32), *(uint32_t*)(R_ESP + 36), *(void**)(R_ESP + 40)); }
|
||||
void uFEppppppippp(x86emu_t *emu, uintptr_t fcn) { uFEppppppippp_t fn = (uFEppppppippp_t)fcn; R_EAX=(uint32_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40)); }
|
||||
void uFppppppppppp(x86emu_t *emu, uintptr_t fcn) { uFppppppppppp_t fn = (uFppppppppppp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40), *(void**)(R_ESP + 44)); }
|
||||
void pFEpipppppppi(x86emu_t *emu, uintptr_t fcn) { pFEpipppppppi_t fn = (pFEpipppppppi_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(int32_t*)(R_ESP + 40)); }
|
||||
void pFEppiiLpppip(x86emu_t *emu, uintptr_t fcn) { pFEppiiLpppip_t fn = (pFEppiiLpppip_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(uintptr_t*)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(int32_t*)(R_ESP + 36), *(void**)(R_ESP + 40)); }
|
||||
void pFEppCuWCCuuu(x86emu_t *emu, uintptr_t fcn) { pFEppCuWCCuuu_t fn = (pFEppCuWCCuuu_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint8_t*)(R_ESP + 12), *(uint32_t*)(R_ESP + 16), *(uint16_t*)(R_ESP + 20), *(uint8_t*)(R_ESP + 24), *(uint8_t*)(R_ESP + 28), *(uint32_t*)(R_ESP + 32), *(uint32_t*)(R_ESP + 36), *(uint32_t*)(R_ESP + 40)); }
|
||||
@@ -3723,6 +3763,7 @@ void iFpippppppppppp(x86emu_t *emu, uintptr_t fcn) { iFpippppppppppp_t fn = (iFp
|
||||
void iFpupiiiipppppp(x86emu_t *emu, uintptr_t fcn) { iFpupiiiipppppp_t fn = (iFpupiiiipppppp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40), *(void**)(R_ESP + 44), *(void**)(R_ESP + 48), *(void**)(R_ESP + 52)); }
|
||||
void iFpuppppppppppp(x86emu_t *emu, uintptr_t fcn) { iFpuppppppppppp_t fn = (iFpuppppppppppp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40), *(void**)(R_ESP + 44), *(void**)(R_ESP + 48), *(void**)(R_ESP + 52)); }
|
||||
void iFppppppppppppp(x86emu_t *emu, uintptr_t fcn) { iFppppppppppppp_t fn = (iFppppppppppppp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40), *(void**)(R_ESP + 44), *(void**)(R_ESP + 48), *(void**)(R_ESP + 52)); }
|
||||
void uFppppuuupppppp(x86emu_t *emu, uintptr_t fcn) { uFppppuuupppppp_t fn = (uFppppuuupppppp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20), *(uint32_t*)(R_ESP + 24), *(uint32_t*)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40), *(void**)(R_ESP + 44), *(void**)(R_ESP + 48), *(void**)(R_ESP + 52)); }
|
||||
void pFppppppppppppp(x86emu_t *emu, uintptr_t fcn) { pFppppppppppppp_t fn = (pFppppppppppppp_t)fcn; R_EAX=(uintptr_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20), *(void**)(R_ESP + 24), *(void**)(R_ESP + 28), *(void**)(R_ESP + 32), *(void**)(R_ESP + 36), *(void**)(R_ESP + 40), *(void**)(R_ESP + 44), *(void**)(R_ESP + 48), *(void**)(R_ESP + 52)); }
|
||||
void vFuffiiffiiffiip(x86emu_t *emu, uintptr_t fcn) { vFuffiiffiiffiip_t fn = (vFuffiiffiiffiip_t)fcn; fn(*(uint32_t*)(R_ESP + 4), *(float*)(R_ESP + 8), *(float*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(float*)(R_ESP + 24), *(float*)(R_ESP + 28), *(int32_t*)(R_ESP + 32), *(int32_t*)(R_ESP + 36), *(float*)(R_ESP + 40), *(float*)(R_ESP + 44), *(int32_t*)(R_ESP + 48), *(int32_t*)(R_ESP + 52), *(void**)(R_ESP + 56)); }
|
||||
void vFuddiiddiiddiip(x86emu_t *emu, uintptr_t fcn) { vFuddiiddiiddiip_t fn = (vFuddiiddiiddiip_t)fcn; fn(*(uint32_t*)(R_ESP + 4), *(double*)(R_ESP + 8), *(double*)(R_ESP + 16), *(int32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(double*)(R_ESP + 32), *(double*)(R_ESP + 40), *(int32_t*)(R_ESP + 48), *(int32_t*)(R_ESP + 52), *(double*)(R_ESP + 56), *(double*)(R_ESP + 64), *(int32_t*)(R_ESP + 72), *(int32_t*)(R_ESP + 76), *(void**)(R_ESP + 80)); }
|
||||
@@ -3772,6 +3813,7 @@ void iFppiiiip(x86emu_t *emu, uintptr_t fcn) { iFppiiiip_t fn = (iFppiiiip_t)fcn
|
||||
|
||||
#if !defined(NOALIGN)
|
||||
void iFEi(x86emu_t *emu, uintptr_t fcn) { iFEi_t fn = (iFEi_t)fcn; R_EAX=fn(emu, *(int32_t*)(R_ESP + 4)); }
|
||||
void iFEO(x86emu_t *emu, uintptr_t fcn) { iFEO_t fn = (iFEO_t)fcn; R_EAX=fn(emu, of_convert(*(int32_t*)(R_ESP + 4))); }
|
||||
void dFEp(x86emu_t *emu, uintptr_t fcn) { dFEp_t fn = (dFEp_t)fcn; double db=fn(emu, *(void**)(R_ESP + 4)); fpu_do_push(emu); ST0val = db; }
|
||||
void iFEpI(x86emu_t *emu, uintptr_t fcn) { iFEpI_t fn = (iFEpI_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(int64_t*)(R_ESP + 8)); }
|
||||
void iFEpd(x86emu_t *emu, uintptr_t fcn) { iFEpd_t fn = (iFEpd_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(double*)(R_ESP + 8)); }
|
||||
@@ -3783,6 +3825,14 @@ void iFEpppi(x86emu_t *emu, uintptr_t fcn) { iFEpppi_t fn = (iFEpppi_t)fcn; R_EA
|
||||
void iFEppiiiip(x86emu_t *emu, uintptr_t fcn) { iFEppiiiip_t fn = (iFEppiiiip_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(void**)(R_ESP + 28)); }
|
||||
#endif
|
||||
|
||||
#if defined(POWERPCLE)
|
||||
void iFEiiiN(x86emu_t *emu, uintptr_t fcn) { iFEiiiN_t fn = (iFEiiiN_t)fcn; R_EAX=fn(emu, *(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
#endif
|
||||
|
||||
#if !defined(POWERPCLE)
|
||||
void iFiiiN(x86emu_t *emu, uintptr_t fcn) { iFiiiN_t fn = (iFiiiN_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LD80BITS)
|
||||
void DFD(x86emu_t *emu, uintptr_t fcn) { DFD_t fn = (DFD_t)fcn; long double ld=fn(*(long double*)(R_ESP + 4)); fpu_do_push(emu); ST0val = ld; }
|
||||
void DFDD(x86emu_t *emu, uintptr_t fcn) { DFDD_t fn = (DFDD_t)fcn; long double ld=fn(*(long double*)(R_ESP + 4), *(long double*)(R_ESP + 16)); fpu_do_push(emu); ST0val = ld; }
|
||||
|
||||
@@ -27,6 +27,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
// 2 = struct of 2 uint
|
||||
// P = Vulkan struture pointer
|
||||
// G = a single GValue pointer
|
||||
// N = ... automatically sending 1 arg
|
||||
// M = ... automatically sending 2 args
|
||||
|
||||
void iF(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFE(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -360,8 +362,10 @@ void iFiiO(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiII(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiuu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiup(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiLN(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipL(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFCiW(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFuii(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -528,6 +532,7 @@ void pFSpi(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFSpp(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEipV(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEpii(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEpiL(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEpip(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEpuu(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -633,6 +638,7 @@ void vFpPpp(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFSppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void cFpiii(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEiiN(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEupp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFELup(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -659,7 +665,6 @@ void iFiiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiII(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiLi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiipi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiipu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiuii(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiuui(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -768,12 +773,14 @@ void uFppup(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppLp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFpppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFpppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void UFpipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void UFppii(x86emu_t *emu, uintptr_t fnc);
|
||||
void UFppip(x86emu_t *emu, uintptr_t fnc);
|
||||
void UFpppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void UFSUii(x86emu_t *emu, uintptr_t fnc);
|
||||
void dFpppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void lFEpip(x86emu_t *emu, uintptr_t fnc);
|
||||
void lFiipL(x86emu_t *emu, uintptr_t fnc);
|
||||
void lFipLi(x86emu_t *emu, uintptr_t fnc);
|
||||
void lFipLI(x86emu_t *emu, uintptr_t fnc);
|
||||
void lFipLl(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -831,6 +838,7 @@ void pFppiL(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFppip(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFppuu(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFppup(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFppLL(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFppLp(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFpppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFpppu(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -839,6 +847,7 @@ void pFpppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFpppV(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFSppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEpipu(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEpuup(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEpupp(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFEpLLp(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -964,7 +973,7 @@ void iFiiipu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiupp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiipip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiuuuu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiLLLL(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipiii(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipipi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipipu(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1047,8 +1056,10 @@ void uFpuuup(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppuup(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppupp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFpplip(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppLpp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppppu(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void lFEipiI(x86emu_t *emu, uintptr_t fnc);
|
||||
void lFipLli(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1056,6 +1067,7 @@ void lFppiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFEpppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFpuppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFpLppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFppLLp(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFpppii(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEpiii(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1225,7 +1237,6 @@ void iFiiiLwp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiuiipi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipipuu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipuipu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipuipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipupup(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipuppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipppup(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1288,9 +1299,13 @@ void iFpppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFEiippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFEiuppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFpippup(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFpuippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFpppppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFpppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFSpuiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void UFpippup(x86emu_t *emu, uintptr_t fnc);
|
||||
void lFipLipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFEupppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFpipipi(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFpLippp(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1409,7 +1424,6 @@ void iFEppuppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpppiiu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiiiiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiuppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpiiiiii(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpiiiiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpiiiLwp(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1435,6 +1449,7 @@ void iFpLipipi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppiiuui(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppiipii(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppiipiL(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppiuppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppipiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppipipi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppipipp(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1461,6 +1476,7 @@ void iFppppppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFEpiippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFuippppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppiuppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFEpppppu(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEpLiiii(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEpLiiiI(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1550,7 +1566,6 @@ void iFEpuuuipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpuuLppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEppppipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiiiiiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiippppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiupiupi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFipOuuuuu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFuiifpppp(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1578,6 +1593,7 @@ void uFEpiupppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFEppipppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFEppppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFuipppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppuppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void LFEpiupppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEppCuuCC(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEppCuuWW(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1635,7 +1651,6 @@ void vFpppiiiiii(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFppppipiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFpppppippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFppppppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEiiuuuuuu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpiiiiipi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpuuiippu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpuuuiipp(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1713,6 +1728,7 @@ void iFEpiiiiippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpuipupppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpuuiiuipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpuuuuiipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEppppppipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiiiiiiiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpuipuppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpuupiuiipp(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1765,6 +1781,7 @@ void iFppppiiuuiiu(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFEpiiupppiuV(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFEpiippppiup(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFEppppppippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppppppppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEpipppppppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEppiiLpppip(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEppCuWCCuuu(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1814,6 +1831,7 @@ void iFpippppppppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpupiiiipppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFpuppppppppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFppppppppppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void uFppppuuupppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFppppppppppppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFuffiiffiiffiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFuddiiddiiddiip(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1863,6 +1881,7 @@ void iFppiiiip(x86emu_t *emu, uintptr_t fnc);
|
||||
|
||||
#if !defined(NOALIGN)
|
||||
void iFEi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEO(x86emu_t *emu, uintptr_t fnc);
|
||||
void dFEp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpI(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpd(x86emu_t *emu, uintptr_t fnc);
|
||||
@@ -1874,6 +1893,14 @@ void iFEpppi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEppiiiip(x86emu_t *emu, uintptr_t fnc);
|
||||
#endif
|
||||
|
||||
#if defined(POWERPCLE)
|
||||
void iFEiiiN(x86emu_t *emu, uintptr_t fnc);
|
||||
#endif
|
||||
|
||||
#if !defined(POWERPCLE)
|
||||
void iFiiiN(x86emu_t *emu, uintptr_t fnc);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LD80BITS)
|
||||
void DFD(x86emu_t *emu, uintptr_t fnc);
|
||||
void DFDD(x86emu_t *emu, uintptr_t fnc);
|
||||
|
||||
@@ -94,7 +94,7 @@ static void* reverse_alloc_Fct(void* fct)
|
||||
#define GO(A) if(my_alloc_##A == fct) return (void*)my_alloc_fct_##A;
|
||||
SUPER()
|
||||
#undef GO
|
||||
return (void*)AddBridge(my_lib->priv.w.bridge, my_lib->context, pFpii, fct, 0);
|
||||
return (void*)AddBridge(my_lib->priv.w.bridge, pFpii, fct, 0);
|
||||
}
|
||||
// free ...
|
||||
#define GO(A) \
|
||||
@@ -126,7 +126,7 @@ static void* reverse_free_Fct(void* fct)
|
||||
#define GO(A) if(my_free_##A == fct) return (void*)my_free_fct_##A;
|
||||
SUPER()
|
||||
#undef GO
|
||||
return (void*)AddBridge(my_lib->priv.w.bridge, my_lib->context, vFpp, fct, 0);
|
||||
return (void*)AddBridge(my_lib->priv.w.bridge, vFpp, fct, 0);
|
||||
}
|
||||
#undef SUPER
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#include "emu/x86emu_private.h"
|
||||
#include "callback.h"
|
||||
|
||||
#include "khash.h"
|
||||
|
||||
const char* curlName = "libcurl.so.4";
|
||||
#define ALTNAME "libcurl-gnutls.so.4"
|
||||
#define LIBNAME curl
|
||||
|
||||
@@ -79,15 +79,15 @@ static int my_GetDirect3D(x86emu_t* emu, void* This, void*** ppD3D9);
|
||||
#define UNPACK(...) __VA_ARGS__
|
||||
|
||||
#define GO(name, type, size) \
|
||||
new->name = (void*)AddBridge(emu->context->system, emu->context, type, real->name, size*4)
|
||||
new->name = (void*)AddBridge(emu->context->system, type, real->name, size*4)
|
||||
|
||||
#define GOM(name, type, size) \
|
||||
my_##name##_real = (void*)real->name; \
|
||||
new->name = (void*)AddBridge(emu->context->system, emu->context, type, my_##name, size*4)
|
||||
new->name = (void*)AddBridge(emu->context->system, type, my_##name, size*4)
|
||||
|
||||
#define GO2(name, type, size) \
|
||||
my_##name##_real2 = (void*)real->name; \
|
||||
new->name = (void*)AddBridge(emu->context->system, emu->context, type, my_##name2, size*4)
|
||||
new->name = (void*)AddBridge(emu->context->system, type, my_##name2, size*4)
|
||||
|
||||
#include "wrappedd3dadapter9_gen.h"
|
||||
|
||||
@@ -407,7 +407,7 @@ EXPORT void* my_D3DAdapter9GetProc(x86emu_t* emu, void *ptr)
|
||||
|
||||
my->adapter.major_version = adapter->major_version;
|
||||
my->adapter.minor_version = adapter->minor_version;
|
||||
my->adapter.create_adapter = (void*)AddBridge(emu->context->system, emu->context, iFEip, my_create_adapter, 8);
|
||||
my->adapter.create_adapter = (void*)AddBridge(emu->context->system, iFEip, my_create_adapter, 8);
|
||||
|
||||
return &my->adapter;
|
||||
}
|
||||
|
||||
+27
-14
@@ -165,7 +165,8 @@ EXPORT void* my_g_markup_vprintf_escaped(x86emu_t *emu, void* fmt, void* b) {
|
||||
#ifndef NOALIGN
|
||||
// need to align on arm
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_markup_vprintf_escaped(fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_markup_vprintf_escaped(fmt, VARARGS);
|
||||
#else
|
||||
// other platform don't need that
|
||||
return my->g_markup_vprintf_escaped(fmt, b);
|
||||
@@ -775,7 +776,8 @@ EXPORT void* my_g_markup_printf_escaped(x86emu_t *emu, void* fmt, void* b) {
|
||||
#ifndef NOALIGN
|
||||
// need to align on arm
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_markup_vprintf_escaped(fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_markup_vprintf_escaped(fmt, VARARGS);
|
||||
#else
|
||||
// other platform don't need that
|
||||
return my->g_markup_vprintf_escaped(fmt, b);
|
||||
@@ -817,7 +819,8 @@ EXPORT void* my_g_variant_new_parsed_va(x86emu_t* emu, void* fmt, void* b)
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
#ifndef NOALIGN
|
||||
myStackAlignGVariantNew((const char*)fmt, b, emu->scratch);
|
||||
uint32_t *aligned = emu->scratch;
|
||||
PREPARE_VALIST;
|
||||
uint32_t *aligned = VARARGS;
|
||||
return my->g_variant_new_parsed_va(fmt, &aligned);
|
||||
#else
|
||||
return my->g_variant_new_parsed_va(fmt, b);
|
||||
@@ -835,7 +838,8 @@ EXPORT void* my_g_strdup_vprintf(x86emu_t* emu, void* fmt, void* b)
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_strdup_vprintf(fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_strdup_vprintf(fmt, VARARGS);
|
||||
#else
|
||||
return my->g_strdup_vprintf(fmt, b);
|
||||
#endif
|
||||
@@ -846,7 +850,8 @@ EXPORT int my_g_vprintf(x86emu_t* emu, void* fmt, void* b)
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_vprintf(fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_vprintf(fmt, VARARGS);
|
||||
#else
|
||||
return my->g_vprintf(fmt, b);
|
||||
#endif
|
||||
@@ -857,7 +862,8 @@ EXPORT int my_g_vfprintf(x86emu_t* emu, void* F, void* fmt, void* b)
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_vfprintf(F, fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_vfprintf(F, fmt, VARARGS);
|
||||
#else
|
||||
return my->g_vfprintf(F, fmt, b);
|
||||
#endif
|
||||
@@ -868,7 +874,8 @@ EXPORT int my_g_vsprintf(x86emu_t* emu, void* s, void* fmt, void* b)
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_vsprintf(s, fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_vsprintf(s, fmt, VARARGS);
|
||||
#else
|
||||
return my->g_vsprintf(s, fmt, b);
|
||||
#endif
|
||||
@@ -879,7 +886,8 @@ EXPORT int my_g_vsnprintf(x86emu_t* emu, void* s, unsigned long n, void* fmt, vo
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_vsnprintf(s, n, fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_vsnprintf(s, n, fmt, VARARGS);
|
||||
#else
|
||||
return my->g_vsnprintf(s, n, fmt, b);
|
||||
#endif
|
||||
@@ -890,7 +898,8 @@ EXPORT int my_g_vasprintf(x86emu_t* emu, void* s, void* fmt, void* b)
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_vasprintf(s, fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_vasprintf(s, fmt, VARARGS);
|
||||
#else
|
||||
return my->g_vasprintf(s, fmt, b);
|
||||
#endif
|
||||
@@ -901,7 +910,8 @@ EXPORT uint32_t my_g_printf_string_upper_bound(x86emu_t* emu, void* fmt, void* b
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
return my->g_printf_string_upper_bound(fmt, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
return my->g_printf_string_upper_bound(fmt, VARARGS);
|
||||
#else
|
||||
return my->g_printf_string_upper_bound(fmt, b);
|
||||
#endif
|
||||
@@ -914,8 +924,9 @@ EXPORT void my_g_print(x86emu_t* emu, void* fmt, void* b)
|
||||
char* buf = NULL;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
iFppp_t f = (iFppp_t)vasprintf;
|
||||
f(&buf, fmt, emu->scratch);
|
||||
f(&buf, fmt, VARARGS);
|
||||
#else
|
||||
iFppp_t f = (iFppp_t)vasprintf;
|
||||
f(&buf, fmt, b);
|
||||
@@ -931,8 +942,9 @@ EXPORT void my_g_printerr(x86emu_t* emu, void* fmt, void* b)
|
||||
char* buf = NULL;
|
||||
#ifndef NOALIGN
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
PREPARE_VALIST;
|
||||
iFppp_t f = (iFppp_t)vasprintf;
|
||||
f(&buf, fmt, emu->scratch);
|
||||
f(&buf, fmt, VARARGS);
|
||||
#else
|
||||
iFppp_t f = (iFppp_t)vasprintf;
|
||||
f(&buf, fmt, b);
|
||||
@@ -972,7 +984,7 @@ EXPORT void* my_g_main_context_get_poll_func(x86emu_t* emu, void* context)
|
||||
void* r = reversePollFct(ret);
|
||||
if(r) return r;
|
||||
// needs to bridge....
|
||||
return (void*)AddCheckBridge(my_lib->priv.w.bridge, my_lib->context, iFpui, ret, 0);
|
||||
return (void*)AddCheckBridge(my_lib->priv.w.bridge, iFpui, ret, 0);
|
||||
}
|
||||
|
||||
EXPORT void my_g_main_context_set_poll_func(x86emu_t* emu, void* context, void* func)
|
||||
@@ -1222,7 +1234,8 @@ EXPORT void* my_g_variant_new_va(x86emu_t* emu, char* fmt, void* endptr, uint32_
|
||||
glib2_my_t *my = (glib2_my_t*)my_lib->priv.w.p2;
|
||||
|
||||
myStackAlignGVariantNew(fmt, *b, emu->scratch);
|
||||
uint32_t* aligned = emu->scratch;
|
||||
PREPARE_VALIST;
|
||||
uint32_t* aligned = VARARGS;
|
||||
return my->g_variant_new_va(fmt, endptr, &aligned);
|
||||
}
|
||||
|
||||
|
||||
@@ -570,7 +570,7 @@ GO(g_key_file_set_uint64, vFpppU)
|
||||
GO(g_key_file_set_value, vFpppp)
|
||||
GO(g_key_file_to_data, pFppp)
|
||||
GO(g_key_file_unref, vFp)
|
||||
//GO(glib_check_version,
|
||||
GO(glib_check_version, pFuuu)
|
||||
//GO(glib_gettext,
|
||||
//GO(glib_pgettext,
|
||||
//GO(glib__private__,
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "wrappedlibs.h"
|
||||
|
||||
#include "wrapper.h"
|
||||
#include "bridge.h"
|
||||
#include "librarian/library_private.h"
|
||||
#include "x86emu.h"
|
||||
|
||||
const char* gssapikrb5Name = "libgssapi_krb5.so.2";
|
||||
#define LIBNAME gssapikrb5
|
||||
|
||||
#include "wrappedlib_init.h"
|
||||
|
||||
Executable
+165
@@ -0,0 +1,165 @@
|
||||
#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
|
||||
#error Meh....
|
||||
#endif
|
||||
|
||||
GO(gss_accept_sec_context, uFppppppppppp)
|
||||
GO(gss_acquire_cred, uFppuppppp)
|
||||
//GO(gss_acquire_cred_from,
|
||||
//GO(gss_acquire_cred_impersonate_name,
|
||||
//GO(gss_acquire_cred_with_password,
|
||||
//GO(gss_add_buffer_set_member,
|
||||
//GO(gss_add_cred,
|
||||
//GO(gss_add_cred_from,
|
||||
//GO(gss_add_cred_impersonate_name,
|
||||
//GO(gss_add_cred_with_password,
|
||||
//GO(gss_add_oid_set_member,
|
||||
//GO(gss_authorize_localname,
|
||||
//GO(gss_canonicalize_name,
|
||||
//DATA(GSS_C_ATTR_LOCAL_LOGIN_USER,
|
||||
//DATA(GSS_C_INQ_SSPI_SESSION_KEY,
|
||||
//DATA(GSS_C_MA_AUTH_INIT,
|
||||
//DATA(GSS_C_MA_AUTH_INIT_ANON,
|
||||
//DATA(GSS_C_MA_AUTH_INIT_INIT,
|
||||
//DATA(GSS_C_MA_AUTH_TARG,
|
||||
//DATA(GSS_C_MA_AUTH_TARG_ANON,
|
||||
//DATA(GSS_C_MA_AUTH_TARG_INIT,
|
||||
//DATA(GSS_C_MA_CBINDINGS,
|
||||
//DATA(GSS_C_MA_COMPRESS,
|
||||
//DATA(GSS_C_MA_CONF_PROT,
|
||||
//DATA(GSS_C_MA_CTX_TRANS,
|
||||
//DATA(GSS_C_MA_DELEG_CRED,
|
||||
//DATA(GSS_C_MA_DEPRECATED,
|
||||
//DATA(GSS_C_MA_INTEG_PROT,
|
||||
//DATA(GSS_C_MA_ITOK_FRAMED,
|
||||
//DATA(GSS_C_MA_MECH_COMPOSITE,
|
||||
//DATA(GSS_C_MA_MECH_CONCRETE,
|
||||
//DATA(GSS_C_MA_MECH_GLUE,
|
||||
//DATA(GSS_C_MA_MECH_NEGO,
|
||||
//DATA(GSS_C_MA_MECH_PSEUDO,
|
||||
//DATA(GSS_C_MA_MIC,
|
||||
//DATA(GSS_C_MA_NOT_DFLT_MECH,
|
||||
//DATA(GSS_C_MA_NOT_MECH,
|
||||
//DATA(GSS_C_MA_OOS_DET,
|
||||
//DATA(GSS_C_MA_PFS,
|
||||
//DATA(GSS_C_MA_PROT_READY,
|
||||
//DATA(GSS_C_MA_REPLAY_DET,
|
||||
//DATA(GSS_C_MA_WRAP,
|
||||
//DATA(GSS_C_NT_ANONYMOUS,
|
||||
//DATA(GSS_C_NT_COMPOSITE_EXPORT,
|
||||
//DATA(GSS_C_NT_EXPORT_NAME,
|
||||
//DATA(GSS_C_NT_HOSTBASED_SERVICE,
|
||||
//DATA(GSS_C_NT_HOSTBASED_SERVICE_X,
|
||||
//DATA(GSS_C_NT_MACHINE_UID_NAME,
|
||||
//DATA(GSS_C_NT_STRING_UID_NAME,
|
||||
//DATA(GSS_C_NT_USER_NAME,
|
||||
//GO(gss_compare_name,
|
||||
//GO(gss_complete_auth_token,
|
||||
//GO(gss_context_time,
|
||||
//GO(gss_create_empty_buffer_set,
|
||||
//GO(gss_create_empty_oid_set,
|
||||
//GO(gss_decapsulate_token,
|
||||
//GO(gss_delete_name_attribute,
|
||||
GO(gss_delete_sec_context, uFppp)
|
||||
//GO(gss_display_mech_attr,
|
||||
//GO(gss_display_name,
|
||||
//GO(gss_display_name_ext,
|
||||
GO(gss_display_status, uFpuippp)
|
||||
//GO(gss_duplicate_name,
|
||||
//GO(gss_encapsulate_token,
|
||||
//GO(gss_export_cred,
|
||||
//GO(gss_export_name,
|
||||
//GO(gss_export_name_composite,
|
||||
//GO(gss_export_sec_context,
|
||||
GO(gss_get_mic, uFppupp)
|
||||
//GO(gss_get_mic_iov,
|
||||
//GO(gss_get_mic_iov_length,
|
||||
//GO(gss_get_name_attribute,
|
||||
//GO(gss_import_cred,
|
||||
GO(gss_import_name, uFpppp)
|
||||
//GO(gss_import_sec_context,
|
||||
//GO(gss_indicate_mechs,
|
||||
//GO(gss_indicate_mechs_by_attrs,
|
||||
GO(gss_init_sec_context, uFppppuuupppppp)
|
||||
//GO(gss_inquire_attrs_for_mech,
|
||||
GO(gss_inquire_context, uFppppppppp)
|
||||
//GO(gss_inquire_cred,
|
||||
//GO(gss_inquire_cred_by_mech,
|
||||
//GO(gss_inquire_cred_by_oid,
|
||||
//GO(gss_inquire_mech_for_saslname,
|
||||
//GO(gss_inquire_mechs_for_name,
|
||||
//GO(gss_inquire_name,
|
||||
//GO(gss_inquire_names_for_mech,
|
||||
//GO(gss_inquire_saslname_for_mech,
|
||||
//GO(gss_inquire_sec_context_by_oid,
|
||||
//GO(gssint_g_seqstate_init,
|
||||
//GO(gss_krb5_ccache_name,
|
||||
//GO(gss_krb5_copy_ccache,
|
||||
//GO(gss_krb5_export_lucid_sec_context,
|
||||
//GO(gsskrb5_extract_authtime_from_sec_context,
|
||||
//GO(gsskrb5_extract_authz_data_from_sec_context,
|
||||
//GO(gss_krb5_free_lucid_sec_context,
|
||||
//GO(gss_krb5_get_tkt_flags,
|
||||
//GO(gss_krb5_import_cred,
|
||||
//GO(gss_krb5int_make_seal_token_v3,
|
||||
//GO(gss_krb5int_unseal_token_v3,
|
||||
//DATA(GSS_KRB5_NT_PRINCIPAL_NAME,
|
||||
//GO(gss_krb5_set_allowable_enctypes,
|
||||
//GO(gss_krb5_set_cred_rcache,
|
||||
//GO(gss_localname,
|
||||
//GO(gss_map_name_to_any,
|
||||
//DATA(gss_mech_iakerb,
|
||||
//DATA(gss_mech_krb5,
|
||||
//DATA(gss_mech_krb5_old,
|
||||
//DATA(gss_mech_krb5_wrong,
|
||||
//DATA(gss_mech_set_krb5,
|
||||
//DATA(gss_mech_set_krb5_both,
|
||||
//DATA(gss_mech_set_krb5_old,
|
||||
//DATA(gss_nt_exported_name,
|
||||
//DATA(gss_nt_krb5_name,
|
||||
//DATA(gss_nt_krb5_principal,
|
||||
//DATA(gss_nt_machine_uid_name,
|
||||
//DATA(gss_nt_service_name,
|
||||
//DATA(gss_nt_service_name_v2,
|
||||
//DATA(gss_nt_string_uid_name,
|
||||
//DATA(gss_nt_user_name,
|
||||
//GO(gss_oid_equal,
|
||||
//GO(gss_oid_to_str,
|
||||
//GO(gss_pname_to_uid,
|
||||
//GO(gss_process_context_token,
|
||||
//GO(gss_pseudo_random,
|
||||
//GO(gss_release_any_name_mapping,
|
||||
GO(gss_release_buffer, uFpp)
|
||||
//GO(gss_release_buffer_set,
|
||||
GO(gss_release_cred, uFpp)
|
||||
GO(gss_release_iov_buffer, uFppi)
|
||||
GO(gss_release_name, uFpp)
|
||||
//GO(gss_release_oid,
|
||||
//GO(gss_release_oid_set,
|
||||
//GO(gss_seal,
|
||||
//GO(gss_set_cred_option,
|
||||
//GO(gss_set_name_attribute,
|
||||
//GO(gss_set_neg_mechs,
|
||||
//GO(gss_set_sec_context_option,
|
||||
//GO(gss_sign,
|
||||
//GO(gssspi_mech_invoke,
|
||||
//GO(gssspi_set_cred_option,
|
||||
//GO(gss_store_cred,
|
||||
//GO(gss_store_cred_into,
|
||||
//GO(gss_str_to_oid,
|
||||
//GO(gss_test_oid_set_member,
|
||||
//GO(gss_unseal,
|
||||
GO(gss_unwrap, uFpppppp)
|
||||
//GO(gss_unwrap_aead,
|
||||
GO(gss_unwrap_iov, uFpppppi)
|
||||
//GO(gss_userok,
|
||||
//GO(gss_verify,
|
||||
GO(gss_verify_mic, uFppppu)
|
||||
//GO(gss_verify_mic_iov,
|
||||
GO(gss_wrap, uFppiuppp)
|
||||
//GO(gss_wrap_aead,
|
||||
GO(gss_wrap_iov, iFppiuppi)
|
||||
//GO(gss_wrap_iov_length,
|
||||
//GO(gss_wrap_size_limit,
|
||||
//DATAB(krb5_gss_dbg_client_expcreds,
|
||||
//GO(krb5_gss_register_acceptor_identity,
|
||||
//GO(krb5_gss_use_kdc_context,
|
||||
Loaded 100 of 129 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user