mirror of
https://github.com/ptitSeb/box64.git
synced 2026-11-10 04:01:33 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2345d735a | ||
|
|
7a52697f9a | ||
|
|
7f1cae956c | ||
|
|
5ab21087dd | ||
|
|
58a8629135 | ||
|
|
ae53c4c8ae | ||
|
|
c0aed34f41 | ||
|
|
e694f2ca8b | ||
|
|
93abdcf317 | ||
|
|
cad3b16525 | ||
|
|
b7bf42c8b7 | ||
|
|
a49be7e78d | ||
|
|
7468d58af2 | ||
|
|
c6c5e4f797 | ||
|
|
09bce33a45 | ||
|
|
dab3fdc351 | ||
|
|
1a2ad946cb | ||
|
|
00cbf50c98 | ||
|
|
8182d2b7c0 | ||
|
|
f7cede9878 | ||
|
|
419e095ea0 | ||
|
|
7fb417db98 | ||
|
|
3583d9c90e | ||
|
|
194d577d51 | ||
|
|
87f896e85b | ||
|
|
ea33518f47 | ||
|
|
5b7308fecf | ||
|
|
5c84eb6f3a | ||
|
|
239fb1ccb3 | ||
|
|
e2186c1e8e | ||
|
|
b77a21b1e1 | ||
|
|
2d14666f3d | ||
|
|
ba3b80e3f1 | ||
|
|
2e718b464d | ||
|
|
4feb8b1863 | ||
|
|
d39062d3d7 | ||
|
|
f05bdb1f93 | ||
|
|
df37f6acf0 | ||
|
|
1299966a02 | ||
|
|
5687b460b9 | ||
|
|
1867645ef0 | ||
|
|
113b8b427e | ||
|
|
86c7d13769 | ||
|
|
174a9496fa | ||
|
|
b946deaeea | ||
|
|
ce8ae476b8 | ||
|
|
0bce9e5612 | ||
|
|
de3c2a2e60 | ||
|
|
c1d2de4538 | ||
|
|
5873363e4c | ||
|
|
ef7852773b | ||
|
|
8707b8d1ed | ||
|
|
e7a0dc92d7 | ||
|
|
86ff049f6b | ||
|
|
0e8124e7e8 | ||
|
|
7ccab5ef92 | ||
|
|
02d26a8038 | ||
|
|
8b5cc0888a | ||
|
|
cc3f0997dc | ||
|
|
419a5b22da | ||
|
|
8efb1f09bd | ||
|
|
6f30f20a47 | ||
|
|
ee42c716c8 | ||
|
|
036978bffc | ||
|
|
97a18aa6ff | ||
|
|
d0695df48d | ||
|
|
024717cb03 | ||
|
|
129fc83e8d | ||
|
|
d4f439ea26 | ||
|
|
0a7b7d4f6b | ||
|
|
7d3b1dfbfb | ||
|
|
5e472e3963 | ||
|
|
367c7aed3d | ||
|
|
b6b23e63f4 | ||
|
|
ae6fec30a4 | ||
|
|
3698195c49 | ||
|
|
f9fc55cf36 | ||
|
|
6ccba477de | ||
|
|
75721e4f97 | ||
|
|
cae00ca8b7 | ||
|
|
d32df979a4 | ||
|
|
37284f9720 | ||
|
|
8319f389bb | ||
|
|
238ed34fa9 | ||
|
|
ce3af2bd7a | ||
|
|
3b82d5a2c2 | ||
|
|
57ce5c388e | ||
|
|
cf040876be | ||
|
|
aec26f67c3 | ||
|
|
5dffedfa0f | ||
|
|
03e81c33b3 | ||
|
|
39d1cb4e33 | ||
|
|
874bee26cd | ||
|
|
1b3382d5ff | ||
|
|
740d39c6d1 | ||
|
|
a77b47b5ed | ||
|
|
36003fd14a | ||
|
|
027c7e9c05 | ||
|
|
56cdd9f732 | ||
|
|
ca432c6ff4 | ||
|
|
08022c5110 | ||
|
|
a15036f442 | ||
|
|
d6810e832c | ||
|
|
70b6068ecb | ||
|
|
84a6eba99f | ||
|
|
469c420626 | ||
|
|
705877e704 | ||
|
|
961dc21f69 | ||
|
|
ae18999411 | ||
|
|
9f1cc32015 | ||
|
|
19c9af4dd0 | ||
|
|
7ad988fd0f | ||
|
|
73787e54b3 | ||
|
|
05b8d97823 | ||
|
|
b619090f1d | ||
|
|
e5df85b625 | ||
|
|
ca70fa1b1e | ||
|
|
dfaabd0187 | ||
|
|
234105ff8d | ||
|
|
c6418bc3fd | ||
|
|
2e7d01ec46 | ||
|
|
2c72942fae | ||
|
|
42ae8b818c | ||
|
|
41054e4599 | ||
|
|
55e39c3c1f | ||
|
|
e11c10c1fa | ||
|
|
b579d23114 | ||
|
|
790baf4460 | ||
|
|
ce161a38f5 | ||
|
|
fb7cdd2c53 | ||
|
|
d118d6ac1a | ||
|
|
d021839d1d | ||
|
|
2b2f3043bf | ||
|
|
f636f7e765 | ||
|
|
96fc30b100 | ||
|
|
2deb99ae4a | ||
|
|
5c6200059d | ||
|
|
b85b7e5e2f |
No files matched your search
@@ -58,6 +58,7 @@ build*/
|
||||
.cache
|
||||
.gdb_history
|
||||
src/git_head.h
|
||||
src/dynacache_hashes.h
|
||||
backup/
|
||||
|
||||
# Wrapper helper
|
||||
|
||||
+54
-9
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
cmake_policy(SET CMP0065 NEW)
|
||||
|
||||
@@ -158,6 +158,10 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
include(CheckLinkerFlag)
|
||||
enable_language(C)
|
||||
check_linker_flag(C "-fuse-ld=gold" HAS_FUSE_LD_GOLD)
|
||||
|
||||
if(RPI3ARM64)
|
||||
add_definitions(-DRPI)
|
||||
add_definitions(-DRPI3ARM64)
|
||||
@@ -241,7 +245,11 @@ elseif(SDORYON1)
|
||||
set(CFLAGS -pipe -march=armv8.6-a+crypto+sm4+sha3+fp16 -mtune=cortex-a57)
|
||||
elseif(ADLINK)
|
||||
add_definitions(-DADLINK)
|
||||
set(CFLAGS -pipe -mcpu=neoverse-n1 -fuse-ld=gold -fuse-linker-plugin)
|
||||
set(CFLAGS -pipe -mcpu=neoverse-n1)
|
||||
if(HAS_FUSE_LD_GOLD)
|
||||
list(APPEND CFLAGS "-fuse-ld=gold")
|
||||
list(APPEND CFLAGS "-fuse-linker-plugin")
|
||||
endif()
|
||||
elseif(M1)
|
||||
add_definitions(-DM1)
|
||||
set(CFLAGS -pipe -march=armv8.5-a+simd+crypto)
|
||||
@@ -393,9 +401,19 @@ if(BOX32)
|
||||
)
|
||||
endif()
|
||||
|
||||
# git_head.h is a generated file
|
||||
set(DYNACACHE_HASH_HEADER "${BOX64_ROOT}/src/dynacache_hashes.h")
|
||||
add_custom_target(generate_dynacache_hashes
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${BOX64_ROOT}/tools/gen_dynacache_hashes.py"
|
||||
--root "${BOX64_ROOT}"
|
||||
--output "${DYNACACHE_HASH_HEADER}"
|
||||
BYPRODUCTS "${DYNACACHE_HASH_HEADER}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# generated files
|
||||
set_source_files_properties(
|
||||
"${BOX64_ROOT}/src/git_head.h"
|
||||
"${BOX64_ROOT}/src/dynacache_hashes.h"
|
||||
PROPERTIES GENERATED TRUE
|
||||
HEADER_FILE_ONLY TRUE)
|
||||
|
||||
@@ -448,6 +466,7 @@ set(ELFLOADER_SRC
|
||||
"${BOX64_ROOT}/src/libtools/myalign.c"
|
||||
"${BOX64_ROOT}/src/libtools/signals.c"
|
||||
"${BOX64_ROOT}/src/libtools/sigtools.c"
|
||||
"${BOX64_ROOT}/src/libtools/syscall_user_dispatch.c"
|
||||
"${BOX64_ROOT}/src/libtools/decopcode.c"
|
||||
"${BOX64_ROOT}/src/libtools/threads.c"
|
||||
"${BOX64_ROOT}/src/tools/bitutils.c"
|
||||
@@ -461,6 +480,7 @@ set(ELFLOADER_SRC
|
||||
"${BOX64_ROOT}/src/tools/pathcoll.c"
|
||||
"${BOX64_ROOT}/src/tools/rbtree.c"
|
||||
"${BOX64_ROOT}/src/tools/env.c"
|
||||
"${BOX64_ROOT}/src/tools/dynacache.c"
|
||||
"${BOX64_ROOT}/src/tools/wine_tools.c"
|
||||
"${BOX64_ROOT}/src/tools/pe_tools.c"
|
||||
"${BOX64_ROOT}/src/wrapped/generated/wrapper.c"
|
||||
@@ -759,6 +779,7 @@ set(WRAPPEDS
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedpcap.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedplc4.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedplds4.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedpipewire03.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedpng16.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedpulse.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedpulsemainloopglib.c"
|
||||
@@ -842,6 +863,7 @@ set(WRAPPEDS
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedproxy.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedssh4.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedsmbclient.c"
|
||||
"${BOX64_ROOT}/src/wrapped/wrappedpixman1.c"
|
||||
)
|
||||
endif()
|
||||
if(ANDROID)
|
||||
@@ -1000,6 +1022,7 @@ if(DYNAREC)
|
||||
"${BOX64_ROOT}/src/dynarec/dynarec_native.c"
|
||||
"${BOX64_ROOT}/src/dynarec/dynarec_native_functions.c"
|
||||
"${BOX64_ROOT}/src/dynarec/dynacache_reloc.c"
|
||||
"${BOX64_ROOT}/src/dynarec/dynacache_compress.c"
|
||||
"${BOX64_ROOT}/src/emu/x64test.c"
|
||||
)
|
||||
endif()
|
||||
@@ -1133,6 +1156,7 @@ if(LARCH64_DYNAREC)
|
||||
"${BOX64_ROOT}/src/dynarec/la64/la64_printer.c"
|
||||
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_jmpnext.c"
|
||||
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_consts.c"
|
||||
"${BOX64_ROOT}/src/dynarec/la64/updateflags_la64.c"
|
||||
)
|
||||
set(DYNAREC_ASM
|
||||
${DYNAREC_ASM}
|
||||
@@ -1177,6 +1201,7 @@ if(LARCH64_DYNAREC)
|
||||
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_dd.c"
|
||||
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_de.c"
|
||||
"${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_df.c"
|
||||
"${BOX64_ROOT}/src/dynarec/la64/updateflags_la64_pass.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -1296,6 +1321,7 @@ add_library(interpreter OBJECT ${INTERPRETER})
|
||||
|
||||
add_library(mainobj OBJECT ${OS_LINUX_SRC} ${ELFLOADER_SRC} ${WRAPPEDS} ${WRAPPEDS32})
|
||||
add_dependencies(mainobj generate_git_head_target)
|
||||
add_dependencies(mainobj generate_dynacache_hashes)
|
||||
|
||||
add_executable(${BOX64})
|
||||
target_link_libraries(${BOX64} mainobj)
|
||||
@@ -1362,16 +1388,30 @@ if(_x86_64 OR _aarch64 OR _ppc64le)
|
||||
endif()
|
||||
|
||||
if(NOT _x86 AND NOT _x86_64)
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/share/box64)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/tests/box64-bash ${CMAKE_BINARY_DIR}/bin/box64-bash COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/system/box64-python ${CMAKE_BINARY_DIR}/bin/box64-python COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/system/sitecustomize.py ${CMAKE_BINARY_DIR}/share/box64/sitecustomize.py COPYONLY)
|
||||
file(CHMOD ${CMAKE_BINARY_DIR}/bin/box64-python
|
||||
FILE_PERMISSIONS
|
||||
OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||
GROUP_READ GROUP_EXECUTE
|
||||
WORLD_READ WORLD_EXECUTE)
|
||||
if(NOT TERMUX)
|
||||
install(TARGETS ${BOX64} RUNTIME DESTINATION bin)
|
||||
if(NOT NO_LIB_INSTALL)
|
||||
install(PROGRAMS ${CMAKE_SOURCE_DIR}/tests/box64-bash DESTINATION bin)
|
||||
endif()
|
||||
if(NOT NO_LIB_INSTALL)
|
||||
install(PROGRAMS ${CMAKE_SOURCE_DIR}/tests/box64-bash DESTINATION bin)
|
||||
install(PROGRAMS ${CMAKE_SOURCE_DIR}/system/box64-python DESTINATION bin)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/system/sitecustomize.py DESTINATION share/box64)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${BOX64} RUNTIME DESTINATION ${TERMUX_PATH}/usr/bin)
|
||||
if(NOT NO_LIB_INSTALL)
|
||||
install(PROGRAMS ${CMAKE_SOURCE_DIR}/tests/box64-bash DESTINATION ${TERMUX_PATH}/usr/bin)
|
||||
endif()
|
||||
if(NOT NO_LIB_INSTALL)
|
||||
install(PROGRAMS ${CMAKE_SOURCE_DIR}/tests/box64-bash DESTINATION ${TERMUX_PATH}/usr/bin)
|
||||
install(PROGRAMS ${CMAKE_SOURCE_DIR}/system/box64-python DESTINATION ${TERMUX_PATH}/usr/bin)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/system/sitecustomize.py DESTINATION ${TERMUX_PATH}/usr/share/box64)
|
||||
endif()
|
||||
endif()
|
||||
if (GDBJIT)
|
||||
install(TARGETS box64gdbjitreader RUNTIME DESTINATION lib)
|
||||
@@ -1884,6 +1924,11 @@ add_test(lock ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
|
||||
endif()
|
||||
|
||||
if(NOT ANDROID)
|
||||
add_test(NAME xsave_xrstor COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/misc/xsave_xrstor -D TEST_OUTPUT=tmpfile-xsave_xrstor.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/misc/xsave_xrstor.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake)
|
||||
|
||||
file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
|
||||
foreach(file ${extension_tests})
|
||||
get_filename_component(testname "${file}" NAME_WE)
|
||||
|
||||
@@ -16,7 +16,7 @@ Box64 enables running x86_64 Linux programs, including games, on non-x86_64 Linu
|
||||
|
||||
Box64 leverages native system libraries (libc, libm, SDL, OpenGL), offering ease of integration and surprising performance in many applications. For performance benchmarks, check [this analysis](https://box86.org/index.php/2021/06/game-performances/).
|
||||
|
||||
With DynaRec for Arm, RISC-V and LoongArch platforms, Box64 achieves a speed boost 5-10x faster than the interpreter alone. For a deeper look at DynaRec, see [Inner workings](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/).
|
||||
With DynaRec for Arm, RISC-V and LoongArch platforms, Box64 achieves a speed boost 5-10x faster than the interpreter alone. For a deeper look at DynaRec, see [Inner workings](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/). For a more detailed look at Box64 internals and optimization strategies, see our EuroSys 2026 paper, [Practical and Efficient x86-64 Emulation on RISC-V](https://doi.org/10.1145/3767295.3803574), which focuses on RISC-V but covers many techniques that apply more broadly to Box64.
|
||||
|
||||
<img src="docs/img/Box64Icon.png" width="96" height="96" alt="Box64 Icon">
|
||||
|
||||
@@ -58,6 +58,15 @@ Box64 requires 64-bit libraries on the host system, as it directly translates x8
|
||||
1. Box32 is still experimental.
|
||||
2. Some shell scripts (such as the GOG game installer) may rely on `uname -m` to determine the current architecture. Please run them as `box64 script.sh` to allow Box64 to take over.
|
||||
|
||||
Note that DynaCache is now enabled by default (with compression). This will creates files in `~/.cache/box64` to save generated code for executed binaries and libraries, so launch time can be greatly reduced on second run. The files are compressed and will take up to 2Gb by default. You can disable DynaCache writting, by switching it to a Read-only mode by creating (or modifying) `~/.box64rc` and writting there
|
||||
|
||||
```ini
|
||||
[*]
|
||||
BOX64_DYNACACHE=2
|
||||
```
|
||||
|
||||
(or 0 to completly disabled it). Please refer to [Usage Documentation](docs/USAGE.md) for more details on how to configure Box64.
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
+260
-237
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,926 @@
|
||||
<!--- 此文件由 gen.py 自动生成,请勿直接编辑。 -->
|
||||
使用说明
|
||||
----
|
||||
|
||||
Box64 有许多环境变量可用于控制其行为,下面将按类别列出。
|
||||
|
||||
Box64 有两种构建类型:Wine WOW64 构建(WowBox64)和常规 Linux 构建。请注意,只有部分环境变量在 WowBox64 中可用。
|
||||
|
||||
### 配置文件
|
||||
|
||||
除了环境变量之外,如果你使用的是常规 Linux 构建,Box64 默认还会在两个位置查找 rcfile:系统范围的 `/etc/box64.box64rc` 和用户目录下的 `~/.box64rc`。
|
||||
而在 WowBox64 中,配置文件仅在 `%USERPROFILE%/.box64rc` 处检查。
|
||||
设置的优先级如下(从高到低):`~/.box64rc` > `/etc/box64.box64rc` > 环境变量。
|
||||
|
||||
配置示例:
|
||||
|
||||
```
|
||||
[factorio]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
BOX64_DYNAREC_BIGBLOCK=2
|
||||
BOX64_DYNAREC_FORWARD=1024
|
||||
BOX64_DYNAREC_CALLRET=1
|
||||
```
|
||||
|
||||
此配置将使所有名为 `factorio` 的可执行文件应用指定的设置。
|
||||
|
||||
共享选项也可以定义在特殊的 `[*]` 配置段中。这些设置会全局应用,而更具体的配置段只会覆盖它自己显式定义的选项。
|
||||
|
||||
### Linux 构建的高级用法
|
||||
|
||||
1. **通配符匹配**
|
||||
|
||||
可以使用星号(`*`)对应用程序名称进行基本的模式匹配。例如,`[*setup*]` 将匹配名称中包含 "setup" 的任何程序。请注意,这里实现的是简单的通配符匹配,而非完整的正则表达式支持。
|
||||
2. **共享设置**
|
||||
|
||||
特殊的 `[*]` 配置段可为所有应用程序定义共享的 rcfile 选项。它不同于 `[*setup*]` 这类通配符配置段,是一个专用的全局配置段。
|
||||
3. **自定义配置文件**
|
||||
|
||||
`BOX64_RCFILE` 环境变量可以指定一个替代的配置文件,而不是默认的 `/etc/box64.box64rc`。
|
||||
4. **按文件设置**
|
||||
|
||||
以 `/` 开头的配置项适用于特定文件。例如:
|
||||
```
|
||||
[/d3d9.dll]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
```
|
||||
这些设置将仅影响 `d3d9.dll` 文件。此语法同样适用于**模拟的** Linux 库,例如 `[/libstdc++.so.6]`。
|
||||
|
||||
----
|
||||
|
||||
## 性能
|
||||
|
||||
### BOX64_DYNAREC
|
||||
|
||||
启用或禁用动态重编译器(DynaRec)。如果在支持的架构上构建时开启了 DynaRec 支持,则默认为 1。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 禁用 DynaRec。
|
||||
* 1: 启用 DynaRec。
|
||||
|
||||
### BOX64_DYNAREC_ALIGNED_ATOMICS
|
||||
|
||||
仅生成对齐的原子操作(目前仅在 Arm64 上可用)。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 生成非对齐原子操作处理代码。 [默认值]
|
||||
* 1: 仅生成对齐的原子操作,代码更快更小,但在非对齐数据地址上执行 LOCK 前缀指令时会导致 SIGBUS。
|
||||
|
||||
### BOX64_DYNAREC_BIGBLOCK
|
||||
|
||||
尝试构建更大的代码块以提高性能。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不尝试构建尽可能大的代码块,适用于使用大量线程和 JIT 的程序(如 Unity)。
|
||||
* 1: 尽可能构建大的代码块。
|
||||
* 2: 构建更大的代码块,代码块重叠时不停止,但仅针对 elf 内存中的代码块。 [默认值]
|
||||
* 3: 构建更大的代码块,代码块重叠时不停止,适用于所有类型的内存,因此也对 wine 程序有用。
|
||||
|
||||
### BOX64_DYNAREC_CALLRET
|
||||
|
||||
优化 CALL/RET 指令。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不优化 CALL/RET,使用跳转表。 [默认值]
|
||||
* 1: 尝试优化 CALL/RET,在可能的情况下跳过跳转表。
|
||||
* 2: 尝试优化 CALL/RET,在可能的情况下跳过跳转表,同时增加对返回到脏/已修改代码块的代码的处理。在 WowBox64 上不可用。
|
||||
|
||||
### BOX64_DYNAREC_SEP
|
||||
|
||||
使用二级入口点(SEP)进一步优化 CALL/RET。如果 CALLRET 未启用则无效。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不在 CALLRET 返回时添加 SEP。
|
||||
* 1: 在 CALLRET 返回时添加 SEP,仅针对来自已知二进制文件的内存。 [默认值]
|
||||
* 2: 在 CALLRET 返回时添加 SEP,适用于所有类型的内存。
|
||||
|
||||
### BOX64_DYNAREC_DF
|
||||
|
||||
启用或禁用延迟 FLAGS 的使用。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 禁用延迟 FLAGS 的使用。
|
||||
* 1: 启用延迟 FLAGS 的使用。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_DIRTY
|
||||
|
||||
是否允许继续运行未受保护且可能已脏的代码块。
|
||||
|
||||
* 0: 不允许继续运行未受保护且可能已脏的代码块。 [默认值]
|
||||
* 1: 允许继续运行在与代码相同页面中写入数据的代码块,可以加快某些游戏的加载时间,但也可能导致意外崩溃。
|
||||
* 2: 除了 1 之外,当检测到热页时,将该页面标记为永不写保护,但基于该页面构建的代码块将始终被测试。这样可以更快(但某些 SMC 情况可能无法捕获)。
|
||||
|
||||
### BOX64_DYNAREC_NOHOTPAGE
|
||||
|
||||
是否禁用热页检测(即代码执行和数据写入同时发生的页面)。
|
||||
|
||||
* 0: 检测热页。 [默认值]
|
||||
* 1: 不检测热页。
|
||||
|
||||
### BOX64_DYNAREC_FASTNAN
|
||||
|
||||
启用或禁用快速 NaN 处理。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 精确模拟 x86 上的 -NaN 生成。
|
||||
* 1: 不对 -NaN 生成做任何特殊处理,速度更快。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_FASTROUND
|
||||
|
||||
启用或禁用快速舍入。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 生成 float/double -> int 舍入,并使用当前舍入模式进行 float/double 计算,类似 x86。
|
||||
* 1: 不对边缘情况的舍入做任何特殊处理,速度更快。 [默认值]
|
||||
* 2: 使用当前舍入模式生成 float/double -> int 舍入(类似 x86),但使用快速的 int -> float/double 转换。
|
||||
|
||||
### BOX64_DYNAREC_FORWARD
|
||||
|
||||
定义构建代码块时允许的最大前向跳转值。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 无前向跳转值。当前代码块结束时,即使存在之前的前向跳转也不尝试继续前进。
|
||||
* 128: 允许代码块结束与下一个前向跳转之间最多 128 字节的间隙。 [默认值]
|
||||
* XXXX: 允许代码块结束与下一个前向跳转之间最多 XXXX 字节的间隙。
|
||||
|
||||
### BOX64_DYNAREC_NATIVEFLAGS
|
||||
|
||||
启用或禁用原生FLAGS的使用。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不使用原生FLAGS。
|
||||
* 1: 在可能的情况下使用原生FLAGS。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_PAUSE
|
||||
|
||||
启用 x86 PAUSE 模拟,可能有助于自旋锁的性能。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 忽略 x86 PAUSE 指令。 [默认值]
|
||||
* 1: 使用 YIELD 模拟 x86 PAUSE 指令。
|
||||
* 2: 使用 WFI 模拟 x86 PAUSE 指令。
|
||||
* 3: 使用 SEVL+WFE 模拟 x86 PAUSE 指令。
|
||||
|
||||
### BOX64_DYNAREC_SAFEFLAGS
|
||||
|
||||
在 CALL/RET 指令和其他边缘情况下 FLAGS 模拟的行为。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 将 CALL/RET 标记为从不需要任何 FLAGS。
|
||||
* 1: 将大多数 RET 标记为需要 FLAGS,将大多数 CALL 标记为不需要。 [默认值]
|
||||
* 2: 将所有 CALL/RET 都标记为需要 FLAGS。同时也处理所有边缘情况。
|
||||
|
||||
### BOX64_DYNAREC_STRONGMEM
|
||||
|
||||
开启或关闭 x86 强内存模型的模拟。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不做任何特殊处理。 [默认值]
|
||||
* 1: 在写入内存时启用以有限方式模拟 x86 强内存模型的内存屏障。
|
||||
* 2: 包含 1 的全部内容,外加 SIMD 指令的内存屏障。
|
||||
* 3: 包含 2 的全部内容,外加定期添加更多内存屏障。
|
||||
* 4: 模仿 x86 TSO,类似 QEMU 的方法,可用于评估目的。
|
||||
|
||||
### BOX64_DYNAREC_VOLATILE_METADATA
|
||||
|
||||
使用从 PE 文件解析的 volatile 元数据,仅对 64 位 Windows 游戏有效。
|
||||
|
||||
* 0: 不使用 volatile 元数据。
|
||||
* 1: 使用 volatile 元数据,将指导 Box64 进行更好的强内存模拟。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_WAIT
|
||||
|
||||
是否等待代码块构建完成。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不等待,改用解释器,可能在大量多线程或 JIT 程序上略微加速。
|
||||
* 1: 等待代码块构建完成。 [默认值]
|
||||
|
||||
### BOX64_MMAP32
|
||||
|
||||
在运行 32 位代码的 64 位程序(如 Wine WOW64)上强制使用 32 位兼容的内存映射,可提高性能。
|
||||
|
||||
* 0: 不强制使用 32 位内存映射。
|
||||
* 1: 强制使用 32 位内存映射。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_NOARCH
|
||||
|
||||
从代码块中移除架构元数据(在信号处理时使用)。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 为每个代码块生成所有架构元数据,包括 x87/mmx/SSE/AVX 寄存器追踪。会使用更多内存。 [默认值]
|
||||
* 1: 仅生成每个代码块的必要元数据(FLAGS、对齐),节省一些内存,但某些加密软件可能会失败。
|
||||
* 2: 不为代码块生成元数据,进一步节省内存,但在信号处理时可能会失败。
|
||||
|
||||
### BOX64_RDTSC_1GHZ
|
||||
|
||||
如果可用,使用硬件计数器实现 rdtsc。
|
||||
|
||||
* 0: 如果可用,使用硬件计数器实现 rdtsc 指令。 [默认值]
|
||||
* 1: 仅当精度至少为 1GHz 时,使用硬件计数器实现 rdtsc。
|
||||
|
||||
## 不稳定或遗留选项
|
||||
|
||||
### BOX64_DYNAREC_PURGE
|
||||
|
||||
根据年龄阈值(BOX64_DYNAREC_PURGE_AGE)清除最近未执行的代码块。
|
||||
|
||||
* 0: DynaRec 不会清除旧的未使用代码块。 [默认值]
|
||||
* 1: DynaRec 将根据年龄阈值清除旧的未使用代码块。
|
||||
|
||||
### BOX64_DYNAREC_PURGE_AGE
|
||||
|
||||
代码块清除的年龄阈值(需要 BOX64_DYNAREC_PURGE=1)。
|
||||
|
||||
* 4096: 默认年龄阈值。 [默认值]
|
||||
* XXXX: 自定义年龄阈值(范围:10-65536)。
|
||||
|
||||
### BOX64_DYNAREC_WEAKBARRIER
|
||||
|
||||
调整内存屏障以减少强内存模拟的性能影响。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 使用常规安全屏障。
|
||||
* 1: 使用弱屏障以获得更多性能提升。 [默认值]
|
||||
* 2: 包含 1 的全部内容,外加禁用最后的写屏障。
|
||||
|
||||
### BOX64_DYNACACHE
|
||||
|
||||
启用或禁用动态重编译器缓存(DynaCache)。此选项默认为 2(读取已有缓存但不生成新的)。DynaCache 默认将文件写入 home 文件夹,生成新缓存文件时会根据 BOX64_DYNACACHE_LIMIT 控制文件夹大小。
|
||||
|
||||
* 0: 禁用 DynaCache。
|
||||
* 1: 启用 DynaCache。 [默认值]
|
||||
* 2: 使用已有的 DynaCache 文件,但不生成新的。
|
||||
|
||||
### BOX64_DYNACACHE_FOLDER
|
||||
|
||||
设置 DynaCache 文件的文件夹。默认为 $XDG_CACHE_HOME/box64,如果 $XDG_CACHE_HOME 未设置则为 $HOME/.cache/box64。
|
||||
|
||||
* XXXX: 使用文件夹 XXXX 存储 DynaCache 文件。
|
||||
|
||||
### BOX64_DYNACACHE_LIMIT
|
||||
|
||||
DynaCache 文件夹的最大大小(MiB)。超过限制时,会先删除无效的 DynaCache 文件,如仍超限再删除最旧的有效文件。默认大小为 2048MiB。
|
||||
|
||||
* 0: 不限制 DynaCache 文件夹大小。
|
||||
* XXXX: 先删除无效缓存文件,如仍超限再删除最旧的有效缓存文件,将 DynaCache 文件夹保持在 XXXX MiB 以下。
|
||||
* 2048: 默认值为 2048 MiB。 [默认值]
|
||||
|
||||
### BOX64_DYNACACHE_COMPRESS
|
||||
|
||||
设置是否压缩磁盘上的 DynaCache 文件。
|
||||
|
||||
* 0: 不压缩 DynaCache 文件。
|
||||
* 1: 使用 Zlib 最快压缩级别压缩 DynaCache 文件。 [默认值]
|
||||
* 2: 使用 Zlib 默认压缩级别压缩 DynaCache 文件。
|
||||
|
||||
### BOX64_DYNACACHE_MIN
|
||||
|
||||
DynaCache 写入磁盘的最小大小(KB)。默认大小为 350KB。
|
||||
|
||||
* XXXX: 设置将缓存写入磁盘的最小 DynaRec 代码大小(XXXX KB),小于此值将不会保存到磁盘。
|
||||
* 350: 默认值为 350 KB。 [默认值]
|
||||
|
||||
## 兼容性
|
||||
|
||||
### BOX64_AES
|
||||
|
||||
是否暴露 AES 能力。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不暴露 AES 能力。
|
||||
* 1: 暴露 AES 能力。 [默认值]
|
||||
|
||||
### BOX64_ARCH
|
||||
|
||||
在 rcfile 中指定当前条目适用的架构。此选项仅在 rcfile 中使用时生效。
|
||||
|
||||
* `arm64`: 仅对 AArch64 应用当前条目。
|
||||
* `la64`: 仅对 LoongArch64 应用当前条目。
|
||||
* `rv64`: 仅对 RISC-V 应用当前条目。
|
||||
* `<empty>`: 对所有架构应用当前条目,但如果存在更具体的条目,当前条目将被替换。 [默认值]
|
||||
|
||||
### BOX64_AVX
|
||||
|
||||
向 CPUID 和 cpuinfo 文件暴露 AVX 扩展。在 Arm64 和龙架构上默认值为 2,因为 DynaRec 已完全实现,其他架构默认为 0。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不暴露 AVX 能力。
|
||||
* 1: 向 CPUID 和 cpuinfo 文件暴露 AVX、BMI1、F16C 和 VAES 扩展。
|
||||
* 2: 包含 1 的全部内容,外加 AVX2、BMI2、FMA、ADX、VPCLMULQDQ 和 RDRAND 扩展。
|
||||
|
||||
### BOX64_BASH
|
||||
|
||||
用于指定 bash 可执行文件的路径。
|
||||
|
||||
* XXXX: 使用路径为 XXXX 的 bash 可执行文件。
|
||||
|
||||
### BOX64_CPUTYPE
|
||||
|
||||
指定要模拟的 CPU 类型。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 模拟某个 Intel CPU 型号。 [默认值]
|
||||
* 1: 模拟某个 AMD CPU 型号。
|
||||
|
||||
### BOX64_CRASHHANDLER
|
||||
|
||||
是否使用模拟的 crashhandler.so 库。
|
||||
|
||||
* 0: 在需要时使用模拟的 crashhandler.so 库。
|
||||
* 1: 使用内部定义的空 crashhandler.so 库。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_BLEEDING_EDGE
|
||||
|
||||
检测 MonoBleedingEdge 并应用保守设置(仅 Linux)。
|
||||
|
||||
* 0: 不检测 MonoBleedingEdge。
|
||||
* 1: 检测 MonoBleedingEdge,并在检测到时应用 BOX64_DYNAREC_BIGBLOCK=0 和 BOX64_DYNAREC_强内存模型=1。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_DIV0
|
||||
|
||||
启用或禁用除零异常的生成。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不生成除零异常。 [默认值]
|
||||
* 1: 生成除零异常。
|
||||
|
||||
### BOX64_DYNAREC_TBB
|
||||
|
||||
启用或禁用 libtbb 检测。
|
||||
|
||||
* 0: 不检测 libtbb。
|
||||
* 1: 检测 libtbb 并应用保守设置。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_X87DOUBLE
|
||||
|
||||
强制使用 float/double 进行 x87 模拟。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 尝试在可能的情况下对 x87 模拟使用 float。 [默认值]
|
||||
* 1: 仅对 x87 模拟使用 Double。
|
||||
* 2: 在 x87 模拟中检查精度控制的低精度。
|
||||
|
||||
### BOX64_DYNAREC_INTERP_SIGNAL
|
||||
|
||||
允许在信号处理器中使用 DynaRec。
|
||||
|
||||
* 0: 允许在信号处理器中使用 DynaRec。 [默认值]
|
||||
* 1: 仅在信号处理器中使用解释器(与 v0.3.8 及更早版本相同)。
|
||||
|
||||
### BOX64_EXIT
|
||||
|
||||
直接退出,不运行程序。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 直接退出。
|
||||
|
||||
### BOX64_FIX_64BIT_INODES
|
||||
|
||||
修复 64 位 inode。
|
||||
|
||||
* 0: 不修复 64 位 inode。 [默认值]
|
||||
* 1: 修复 64 位 inode。
|
||||
|
||||
### BOX64_FORCE_LD_PRELOAD
|
||||
|
||||
是否强制 BOX64_LD_PRELOAD 库中的符号通过 RTLD_NEXT 解析。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 强制 BOX64_LD_PRELOAD 库中的符号通过 RTLD_NEXT 解析。
|
||||
|
||||
### BOX64_IGNOREINT3
|
||||
|
||||
忽略 INT3 指令。
|
||||
|
||||
* 0: 如果存在处理器则触发 TRAP 信号。 [默认值]
|
||||
* 1: 静默跳过该指令。
|
||||
|
||||
### BOX64_JVM
|
||||
|
||||
检测 libjvm 并应用保守设置。
|
||||
|
||||
* 0: 不执行任何操作。
|
||||
* 1: 检测 libjvm,并在检测到时应用 BOX64_DYNAREC_BIGBLOCK=0 BOX64_DYNAREC_强内存模型=1 BOX64_SSE42=0。 [默认值]
|
||||
|
||||
### BOX64_LIBCEF
|
||||
|
||||
检测 libcef 并应用 BOX64_MALLOC_HACK 设置。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 检测 libcef,并在检测到时应用 BOX64_MALLOC_HACK=2。
|
||||
|
||||
### BOX64_MALLOC_HACK
|
||||
|
||||
挂钩 malloc 操作符时的行为。
|
||||
|
||||
* 0: 不允许重定向 malloc 操作符,重写代码使用常规函数。 [默认值]
|
||||
* 1: 允许重定向 malloc 操作符。
|
||||
* 2: 与 0 类似,但追踪特殊的 mmap/free(某些内联的重定向函数无法被重定向)。
|
||||
|
||||
### BOX64_MAXCPU
|
||||
|
||||
暴露的最大 CPU 核心数。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 使用实际的 CPU 核心数。 [默认值]
|
||||
* XXXX: 使用 XXXX 个 CPU 核心。
|
||||
|
||||
### BOX64_NORCFILES
|
||||
|
||||
不加载任何 rc 文件。
|
||||
|
||||
* 0: 加载 rc 文件。 [默认值]
|
||||
* 1: 不加载任何 rc 文件。
|
||||
|
||||
### BOX64_PATH
|
||||
|
||||
查找 x86_64 二进制文件的路径。
|
||||
|
||||
* XXXX: 将路径 XXXX 添加到二进制搜索路径。
|
||||
|
||||
### BOX64_PCLMULQDQ
|
||||
|
||||
暴露 PCLMULQDQ 能力。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不暴露 PCLMULQDQ 能力。
|
||||
* 1: 暴露 PCLMULQDQ 能力。 [默认值]
|
||||
|
||||
### BOX64_PROFILE
|
||||
|
||||
预定义的环境变量集合,以兼容性或性能为导向。 在 WowBox64 中可用。
|
||||
|
||||
* safest: 禁用所有不安全的 DynaRec 优化的配置文件。
|
||||
* safe: 比 safest 略不安全。
|
||||
* default: 大多数程序都能正常运行且性能适中的默认设置。 [默认值]
|
||||
* fast: 启用许多不安全的优化,但同时启用 强内存模型 模拟。
|
||||
* fastest: 启用许多不安全的优化以获得更好的性能。
|
||||
|
||||
### BOX64_PYTHON3
|
||||
|
||||
python3 可执行文件的路径。
|
||||
|
||||
* XXXX: 使用路径为 XXXX 的 python3 可执行文件。
|
||||
|
||||
### BOX64_RCFILE
|
||||
|
||||
要加载的 rc 文件路径。
|
||||
|
||||
* XXXX: 加载 rc 文件 XXXX,不会加载默认的 rc 文件。
|
||||
|
||||
### BOX64_RDTSC_INV
|
||||
|
||||
在 Intel CPU 类型的 CPUID 中报告 Invariant TSC 位。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不为 Intel CPU 类型报告 Invariant TSC(默认)。 [默认值]
|
||||
* 1: 在 Intel CPU 类型的 CPUID leaf 0x80000007 中报告 Invariant TSC 位。
|
||||
|
||||
### BOX64_RESERVE_HIGH
|
||||
|
||||
为程序保留高内存区域,在 Box32 上始终启用。
|
||||
|
||||
* 0: 不为程序保留高内存区域。 [默认值]
|
||||
* 1: 为程序保留高内存区域。
|
||||
|
||||
### BOX64_SDL2_JGUID
|
||||
|
||||
对包装的 SDL2 使用 SDL_GetJoystickGUIDInfo 函数的变通方案。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 对包装的 SDL2 使用 SDL_GetJoystickGUIDInfo 函数的变通方案。
|
||||
|
||||
### BOX64_SHAEXT
|
||||
|
||||
暴露 SHAEXT(即 SHA_NI)能力。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不暴露 SHAEXT 能力。
|
||||
* 1: 暴露 SHAEXT 能力。 [默认值]
|
||||
|
||||
### BOX64_SSE_FLUSHTO0
|
||||
|
||||
SSE Flush to 0 FLAGS的行为,同时追踪 SSE 异常FLAGS。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 仅追踪FLAGS。 [默认值]
|
||||
* 1: 直接应用 SSE Flush to 0 FLAGS。同时在 DynaRec 中反映 SSE 异常FLAGS(如果可用)。
|
||||
|
||||
### BOX64_SSE42
|
||||
|
||||
暴露 SSE4.2 能力。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不暴露 SSE4.2 能力。
|
||||
* 1: 暴露 SSE4.2 能力。 [默认值]
|
||||
|
||||
### BOX64_STEAM_VULKAN
|
||||
|
||||
为 Linux Steam UI 强制使用 Vulkan。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 为 Linux Steam UI 强制使用 Vulkan。
|
||||
|
||||
### BOX64_SYNC_ROUNDING
|
||||
|
||||
在 x86 和原生之间同步舍入模式。
|
||||
|
||||
* 0: 不同步舍入模式。 [默认值]
|
||||
* 1: 在 x86 和原生之间同步舍入模式。
|
||||
|
||||
### BOX64_UNITYPLAYER
|
||||
|
||||
检测 UnityPlayer 并应用保守设置。
|
||||
|
||||
* 0: 不执行任何操作。
|
||||
* 1: 检测 UnityPlayer(Windows 或 Linux),并在检测到时应用 BOX64_UNITY=1。 [默认值]
|
||||
|
||||
### BOX64_UNITY
|
||||
|
||||
告诉 Box64 这是一个 Unity 游戏。
|
||||
|
||||
* 0: 不执行任何操作。
|
||||
* 1: 这是 Unity 游戏,对 Windows 使用特殊的检测代码,对 Linux 应用 BOX64_DYNAREC_强内存模型=1。 [默认值]
|
||||
|
||||
### BOX64_X11GLX
|
||||
|
||||
是否强制 Xorg GLX 扩展存在。
|
||||
|
||||
* 0: 不强制 Xorg GLX 扩展存在。 [默认值]
|
||||
* 1: 在使用 XQueryExtension 时要求 Xorg GLX 扩展存在。
|
||||
|
||||
### BOX64_X11SYNC
|
||||
|
||||
是否强制 X11 显示同步操作。
|
||||
|
||||
* 0: 不强制 X11 显示同步操作。 [默认值]
|
||||
* 1: 强制 X11 显示同步操作。
|
||||
|
||||
### BOX64_X11THREADS
|
||||
|
||||
加载 X11 时调用 XInitThreads。这主要用于使用 Loki_Compat 库的旧 Loki 游戏。
|
||||
|
||||
* 0: 不调用 XInitThreads。 [默认值]
|
||||
* 1: 一旦加载 libX11 就调用 XInitThreads。
|
||||
|
||||
### BOX64_X87_NO80BITS
|
||||
|
||||
x87 80 位 long double 的行为。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 尝试尽可能精确地处理 80 位 long double。 [默认值]
|
||||
* 1: 对 x87 使用 64 位 double。
|
||||
|
||||
### BOX64_NOPERSONA32BITS
|
||||
|
||||
禁用 32 位二进制文件的自动 personality 切换(在 Box32 上始终启用)。
|
||||
|
||||
* 0: 为 32 位二进制文件切换 personality(如果尚未尝试)。 [默认值]
|
||||
* 1: 不为 32 位二进制文件切换 personality。
|
||||
|
||||
## 参数
|
||||
|
||||
### BOX64_ARGS
|
||||
|
||||
传递给目标程序的参数,仅在没有任何已有参数时有效。
|
||||
|
||||
* XXXX: 将 XXXX 参数传递给目标程序。
|
||||
* XXXX YYYY ZZZZ: 将 XXXX、YYYY 和 ZZZZ 参数传递给目标程序。
|
||||
|
||||
### BOX64_INSERT_ARGS
|
||||
|
||||
在命令行前添加参数。
|
||||
|
||||
* XXXX: 在程序前添加参数 XXXX。
|
||||
* XXXX YYYY ZZZZ: 在目标程序前添加参数 XXXX、YYYY 和 ZZZZ。
|
||||
|
||||
### BOX64_INPROCESSGPU
|
||||
|
||||
向目标程序添加 --in-process-gpu 参数。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 向目标程序添加 --in-process-gpu 参数。
|
||||
|
||||
### BOX64_NOSANDBOX
|
||||
|
||||
向目标程序添加 --no-sandbox 参数。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 向目标程序添加 --no-sandbox 参数。
|
||||
|
||||
## 库
|
||||
|
||||
### BOX64_ADDLIBS
|
||||
|
||||
添加额外需要的共享库(这个选项不太常用)。
|
||||
|
||||
* XXXX: 将 XXXX 共享库添加到所需库列表。
|
||||
* XXXX:YYYY:ZZZZ: 将 XXXX、YYYY 和 ZZZZ 共享库添加到所需库列表。
|
||||
|
||||
### BOX64_ALLOWMISSINGLIBS
|
||||
|
||||
是否允许忽略缺失的共享库。
|
||||
|
||||
* 0: 不允许忽略缺失的共享库。 [默认值]
|
||||
* 1: 允许忽略缺失的共享库。
|
||||
|
||||
### BOX64_EMULATED_LIBS
|
||||
|
||||
强制使用模拟库。
|
||||
|
||||
* XXXX: 强制使用模拟库 XXXX。
|
||||
* XXXX:YYYY:ZZZZ: 强制使用模拟库 XXXX、YYYY 和 ZZZZ。
|
||||
|
||||
### BOX64_LD_LIBRARY_PATH
|
||||
|
||||
查找 x86_64 库的路径。
|
||||
|
||||
* XXXX: 将路径 XXXX 添加到库搜索路径。
|
||||
|
||||
### BOX64_LD_PRELOAD
|
||||
|
||||
强制随二进制文件加载库。
|
||||
|
||||
* XXXX: 强制加载库 XXXX。
|
||||
* XXXX:YYYY: 强制加载库 XXXX 和 YYYY。
|
||||
|
||||
### BOX64_LIBGL
|
||||
|
||||
设置 libGL 的名称。
|
||||
|
||||
* libXXXX: 将 libGL 的名称设置为 libXXXX。
|
||||
* /path/to/libXXXX: 将 libGL 的名称和路径设置为 /path/to/libXXXX,你也可以使用 SDL_VIDEO_GL_DRIVER。
|
||||
|
||||
### BOX64_NOGTK
|
||||
|
||||
不加载包装的 GTK 库。
|
||||
|
||||
* 0: 加载包装的 GTK 库。 [默认值]
|
||||
* 1: 不加载包装的 GTK 库。
|
||||
|
||||
### BOX64_NOPULSE
|
||||
|
||||
不加载 PulseAudio 库(原生库和模拟库均不加载)。
|
||||
|
||||
* 0: 加载 PulseAudio 库。 [默认值]
|
||||
* 1: 不加载 PulseAudio 库。
|
||||
|
||||
### BOX64_NOVULKAN
|
||||
|
||||
不加载 Vulkan 库。
|
||||
|
||||
* 0: 加载 Vulkan 库。 [默认值]
|
||||
* 1: 不加载 Vulkan 库,原生库和模拟库均不加载。
|
||||
|
||||
### BOX64_NOVULKANOVERLAY
|
||||
|
||||
不加载 x64 Vulkan 覆盖层。
|
||||
|
||||
* 0: 尝试加载 x64 Vulkan 覆盖层。 [默认值]
|
||||
* 1: 不加载 x64 Vulkan 覆盖层。
|
||||
|
||||
### BOX64_PREFER_EMULATED
|
||||
|
||||
优先使用模拟库而非原生库。
|
||||
|
||||
* 0: 优先使用原生库而非模拟库。 [默认值]
|
||||
* 1: 优先使用模拟库而非原生库。
|
||||
|
||||
### BOX64_PREFER_WRAPPED
|
||||
|
||||
即使库使用绝对路径指定,也优先使用包装库。
|
||||
|
||||
* 0: 优先使用绝对路径指定的库而非包装库。 [默认值]
|
||||
* 1: 即使库使用绝对路径指定,也优先使用包装库。
|
||||
|
||||
### BOX64_WRAP_EGL
|
||||
|
||||
优先使用包装库处理 EGL 和 GLESv2。
|
||||
|
||||
* 0: 优先使用模拟库处理 EGL 和 GLESv2。 [默认值]
|
||||
* 1: 优先使用包装库处理 EGL 和 GLESv2。
|
||||
|
||||
## 环境变量
|
||||
|
||||
### BOX64_ENV
|
||||
|
||||
添加环境变量。
|
||||
|
||||
* XXXX=yyyy: 添加值为 yyyy 的环境变量 XXXX。
|
||||
|
||||
### BOX64_ENV[1-5]
|
||||
|
||||
添加环境变量。
|
||||
|
||||
* XXXX=yyyy: 添加值为 yyyy 的环境变量 XXXX。
|
||||
|
||||
## 调试
|
||||
|
||||
### BOX64_DLSYM_ERROR
|
||||
|
||||
启用或禁用 dlsym 错误的日志记录。
|
||||
|
||||
* 0: 禁用 dlsym 错误的日志记录。 [默认值]
|
||||
* 1: 启用 dlsym 错误的日志记录。
|
||||
|
||||
### BOX64_DUMP
|
||||
|
||||
是否输出 elfloader 调试信息。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不输出 elfloader 调试信息。 [默认值]
|
||||
* 1: 输出 elfloader 调试信息。
|
||||
|
||||
### BOX64_DYNAREC_DUMP
|
||||
|
||||
启用 DynaRec 转储。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不转储代码块。 [默认值]
|
||||
* 1: 转储代码块。
|
||||
* 2: 转储代码块并带有颜色。
|
||||
|
||||
### BOX64_DYNAREC_DUMP_RANGE
|
||||
|
||||
转储指定范围内的代码块。 在 WowBox64 中可用。
|
||||
|
||||
* 0xXXXXXXXX-0xYYYYYYYY: 定义代码块 被转储的范围(左闭右开)。
|
||||
|
||||
### BOX64_DYNAREC_GDBJIT
|
||||
|
||||
GDBJIT 调试支持,仅在使用 `-DGDBJIT=ON` 构建时可用,通过 gdb 命令启用:jit-reader-load /usr/local/lib/libbox64gdbjitreader.so。
|
||||
|
||||
* 0: DynaRec 不会生成 GDBJIT 调试信息。 [默认值]
|
||||
* 1: DynaRec 将生成 GDBJIT 调试信息。
|
||||
* 2: DynaRec 将生成包含内部状态的详细 GDBJIT 调试信息。
|
||||
* 3: DynaRec 将仅对目标程序陷入的代码块 注册详细的 GDBJIT 调试信息,大幅提升性能。
|
||||
* 0xXXXXXXX-0xYYYYYYY: 定义 DynaRec 将生成包含内部状态的详细 GDBJIT 调试信息的范围。
|
||||
|
||||
### BOX64_DYNAREC_LOG
|
||||
|
||||
禁用或启用 DynaRec 日志。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 禁用 DynaRec 日志。 [默认值]
|
||||
* 1: 启用最小级别的 DynaRec 日志。
|
||||
* 2: 启用调试级别的 DynaRec 日志。
|
||||
* 3: 启用详细级别的 DynaRec 日志。
|
||||
|
||||
### BOX64_DYNAREC_MISSING
|
||||
|
||||
打印缺失的指令。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不打印缺失的指令。 [默认值]
|
||||
* 1: 打印缺失的指令。
|
||||
* 2: 打印回退到标量指令的信息,仅对 RISC-V 有效。
|
||||
|
||||
### BOX64_DYNAREC_NOHOSTEXT
|
||||
|
||||
禁用可选的主机扩展。
|
||||
|
||||
* 0: 不禁用任何扩展。 [默认值]
|
||||
* 1: 禁用所有可选扩展。
|
||||
* xxx,yyy,zzz: 禁用指定的可选扩展,可选项包括 Arm:`crc32,pmull,aes,atomics,sha1,sha2,uscat,flagm,flagm2,frintts,afp,rndr`,LoongArch:`lasx,lbt,frecipe,lam_bh,lamcas,scq`,以及 RISC-V:`zba,zbb,zbc,zbs,vector,xtheadba,xtheadbb,xtheadbs,xtheadmemidx,xtheadmempair,xtheadcondmov`。
|
||||
|
||||
### BOX64_DYNAREC_PERFMAP
|
||||
|
||||
为 Linux perf 工具生成映射文件。
|
||||
|
||||
* 0: DynaRec 不会生成 perf 映射。 [默认值]
|
||||
* 1: DynaRec 将生成 perf 映射。
|
||||
|
||||
### BOX64_DYNAREC_TEST
|
||||
|
||||
启用 DynaRec 与解释器的执行对比,非常慢,仅用于测试。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不进行对比。 [默认值]
|
||||
* 1: 每个指令都在解释器和 DynaRec 上运行,当寄存器或内存不同时进行对比并打印。
|
||||
* 0xXXXXXXXX-0xYYYYYYYY: 定义 DynaRec 测试的范围(左闭右开)。
|
||||
|
||||
### BOX64_DYNAREC_TEST_NODUP
|
||||
|
||||
启用 COSIM 发现差异的 IP 地址去重。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 显示所有出错的地址。 [默认值]
|
||||
* 1: 每个出错地址仅显示一次,即使转储可能不同。
|
||||
|
||||
### BOX64_DYNAREC_TEST_NODUMP
|
||||
|
||||
当 BOX64_DYNAREC_DUMP 启用时不转储测试代码。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 转储测试代码。
|
||||
* 1: 不转储测试代码。 [默认值]
|
||||
|
||||
### BOX64_DYNAREC_TRACE
|
||||
|
||||
启用或禁用 DynaRec 追踪。
|
||||
|
||||
* 0: 不追踪代码块。 [默认值]
|
||||
* 1: 追踪代码块,会大幅降低程序速度并生成大量日志。
|
||||
|
||||
### BOX64_JITGDB
|
||||
|
||||
发生 SIGSEGV、SIGILL 和 SIGBUS 时是否启动 gdb。
|
||||
|
||||
* 0: 捕获信号时仅打印消息。 [默认值]
|
||||
* 1: 当捕获到 SIGSEGV、SIGILL 或 SIGBUS 信号时启动 gdb,附加到有问题的进程并进入无限循环等待。在 gdb 中,你需要自己找到正确的线程(在其堆栈中有 `my_box64signalhandler` 的线程),然后可能需要 `finish` 1 或 2 个函数(在 `usleep(..)` 内部),之后你将进入 `my_box64signalhandler`,就在 Segfault 消息的 printf 之前。然后 `set waiting=0` 退出无限循环。
|
||||
* 2: 当捕获到 SIGSEGV、SIGILL 或 SIGBUS 信号时启动 gdbserver,附加到有问题的进程,并进入无限循环等待。使用 `gdb /PATH/TO/box64` 然后 `target remote 127.0.0.1:1234` 连接到 gdbserver(如果不在本机,则使用实际 IP)。之后的操作步骤与 `BOX64_JITGDB=1` 相同。
|
||||
* 3: 当捕获到 SIGSEGV、SIGILL 或 SIGBUS 信号时启动 lldb,附加到有问题的进程并进入无限循环等待。
|
||||
|
||||
### BOX64_LOAD_ADDR
|
||||
|
||||
设置程序加载的地址,仅对 PIE 目标程序有效。
|
||||
|
||||
* 0xXXXXXXXX: 设置程序加载的地址。
|
||||
|
||||
### BOX64_LOG
|
||||
|
||||
启用或禁用 Box64 日志,如果 stdout 不是终端则默认为 0,否则为 1。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 禁用 Box64 日志。
|
||||
* 1: 启用最小级别的 Box64 日志。
|
||||
* 2: 启用调试级别的 Box64 日志。
|
||||
* 3: 启用详细级别的 Box64 日志。
|
||||
|
||||
### BOX64_NOBANNER
|
||||
|
||||
禁用 Box64 横幅。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 显示 Box64 横幅。
|
||||
* 1: 不显示 Box64 横幅。
|
||||
|
||||
### BOX64_NODYNAREC
|
||||
|
||||
在指定的地址范围内禁止创建代码块,有助于调试 DynaRec 和解释器之间的行为差异。 在 WowBox64 中可用。
|
||||
|
||||
* 0xXXXXXXXX-0xYYYYYYYY: 定义禁止创建代码块 的范围(左闭右开)。
|
||||
|
||||
### BOX64_NODYNAREC_DELAY
|
||||
|
||||
延迟后移除 NoDynaRec 范围。 在 WowBox64 中可用。
|
||||
|
||||
* 0: 不移除 NoDynaRec 范围。 [默认值]
|
||||
* 1: 创建 2 个线程后移除 NoDynaRec 范围。
|
||||
|
||||
### BOX64_NOSIGSEGV
|
||||
|
||||
禁用 SIGSEGV 的处理。
|
||||
|
||||
* 0: 允许 x86 程序为 SIGSEGV 设置信号处理器。 [默认值]
|
||||
* 1: 禁用 SIGSEGV 的处理。
|
||||
|
||||
### BOX64_NOSIGILL
|
||||
|
||||
禁用 SIGILL 的处理。
|
||||
|
||||
* 0: 允许 x86 程序为 SIGILL 设置信号处理器。 [默认值]
|
||||
* 1: 禁用 SIGILL 的处理。
|
||||
|
||||
### BOX64_ROLLING_LOG
|
||||
|
||||
当捕获信号时显示最近几个包装函数调用。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 捕获信号时显示最近 16 个包装函数调用。
|
||||
* XXXX: 捕获信号时显示最近 XXXX 个包装函数调用。
|
||||
|
||||
### BOX64_SHOWBT
|
||||
|
||||
捕获信号时显示原生和模拟的回溯。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 捕获信号时显示原生和模拟的回溯。
|
||||
|
||||
### BOX64_SHOWSEGV
|
||||
|
||||
始终显示 SIGSEGV 信号详情。
|
||||
|
||||
* 0: 不执行任何操作。 [默认值]
|
||||
* 1: 始终显示 SIGSEGV 信号详情。
|
||||
|
||||
### BOX64_TRACE_COLOR
|
||||
|
||||
启用或禁用彩色追踪输出。
|
||||
|
||||
* 0: 禁用彩色追踪输出。 [默认值]
|
||||
* 1: 启用彩色追踪输出。
|
||||
|
||||
### BOX64_TRACE_EMM
|
||||
|
||||
启用或禁用 EMM(即 MMX)追踪输出。
|
||||
|
||||
* 0: 禁用 EMM 追踪输出。 [默认值]
|
||||
* 1: 启用 EMM 追踪输出。
|
||||
|
||||
### BOX64_TRACE_FILE
|
||||
|
||||
将所有日志和追踪发送到文件而非 `stdout`。
|
||||
|
||||
* XXXX: 将所有日志和追踪发送到文件 XXXX。
|
||||
* XXXX%pid: 将所有日志和追踪发送到文件 XXXX,文件名中附加 pid。
|
||||
* stderr: 将所有日志和追踪发送到 `stderr`。 [默认值]
|
||||
* stdout: 将所有日志和追踪发送到 `stdout`。
|
||||
|
||||
### BOX64_TRACE_INIT
|
||||
|
||||
与 BOX64_TRACE 相同,但立即开始追踪。
|
||||
|
||||
* 0: 禁用追踪输出。 [默认值]
|
||||
* 1: 启用追踪输出。追踪在依赖项初始化之前开始。
|
||||
* symbolname: 仅对 `symbolname` 启用追踪输出。追踪在依赖项初始化之前开始。
|
||||
* 0xXXXXXXX-0xYYYYYYY: 对指定地址范围(左闭右开)启用追踪输出。追踪在依赖项初始化之前开始。
|
||||
|
||||
### BOX64_TRACE_START
|
||||
|
||||
在 N 个指令执行后开始追踪。
|
||||
|
||||
* 0: 立即开始追踪。 [默认值]
|
||||
* 1: 执行 1 个指令后开始追踪。
|
||||
* XXXX: 执行 XXXX 个指令后开始追踪。
|
||||
|
||||
### BOX64_TRACE_XMM
|
||||
|
||||
启用或禁用 XMM(即 SSE)追踪输出。
|
||||
|
||||
* 0: 禁用 XMM 追踪输出。 [默认值]
|
||||
* 1: 启用 XMM 追踪输出。
|
||||
|
||||
### BOX64_TRACE
|
||||
|
||||
仅在带追踪功能的 box64 构建中可用。添加所有执行指令的追踪以及寄存器转储。
|
||||
|
||||
* 0: 禁用追踪输出。 [默认值]
|
||||
* 1: 启用追踪输出。
|
||||
* symbolname: 仅对 `symbolname` 启用追踪输出。
|
||||
* 0xXXXXXXX-0xYYYYYYY: 对指定地址范围(左闭右开)启用追踪输出。
|
||||
|
||||
+75
-54
@@ -44,6 +44,9 @@ Example:
|
||||
BOX64_DYNAREC_FORWARD=1024
|
||||
BOX64_DYNAREC_CALLRET=1
|
||||
|
||||
The special C<[*]> section defines shared rcfile options for all applications.
|
||||
More specific sections override only the options they define themselves.
|
||||
|
||||
=head1 ENVIRONMENT VARIABLES
|
||||
|
||||
=over 8
|
||||
@@ -93,7 +96,7 @@ Arguments to pass to the guest program, only valid if there is no existing argum
|
||||
|
||||
=item B<BOX64_AVX> =I<0|1|2>
|
||||
|
||||
Expose AVX extension to CPUID and cpuinfo file. Default value is 2 on Arm64 because it's fully implemented in DynaRec, 0 otherwise. Available in WowBox64.
|
||||
Expose AVX extension to CPUID and cpuinfo file. Default value is 2 on Arm64 and LoongArch64 because it's fully implemented in DynaRec, 0 otherwise. Available in WowBox64.
|
||||
|
||||
* 0 : Do not expose AVX capabilities.
|
||||
* 1 : Expose AVX, BMI1, F16C and VAES extensions to CPUID and cpuinfo file.
|
||||
@@ -160,9 +163,9 @@ Generate aligned atomics only (only available on Arm64 for now). Available in Wo
|
||||
Enable building bigger DynaRec code blocks for better performance. Available in WowBox64.
|
||||
|
||||
* 0 : Do not try to build block as big as possible, suitable for programs using lots of threads and JIT, like Unity.
|
||||
* 1 : Build Dynarec block as big as possible.
|
||||
* 2 : Build Dynarec block bigger, do not stop when block overlaps, but only for blocks in elf memory. [Default]
|
||||
* 3 : Build Dynarec block bigger, do not stop when block overlaps, for all type of memory, useful for wine programs.
|
||||
* 1 : Build DynaRec block as big as possible.
|
||||
* 2 : Build DynaRec block bigger, do not stop when block overlaps, but only for blocks in elf memory. [Default]
|
||||
* 3 : Build DynaRec block bigger, do not stop when block overlaps, for all type of memory, useful for wine programs.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_BLEEDING_EDGE> =I<0|1>
|
||||
@@ -184,10 +187,10 @@ Optimize CALL/RET opcodes. Available in WowBox64.
|
||||
|
||||
=item B<BOX64_DYNAREC_SEP> =I<0|1|2>
|
||||
|
||||
Optimize CALL/RET further with Secondary Entry Points (SEP). Have no effect is CALLRET is not enabled Available in WowBox64.
|
||||
Optimize CALL/RET further with Secondary Entry Points (SEP). Has no effect if CALLRET is not enabled Available in WowBox64.
|
||||
|
||||
* 0 : Do not add SEP at CALLRET return
|
||||
* 1 : Add SEP at CALLRET return, on meory that are from known binary files [Default]
|
||||
* 1 : Add SEP at CALLRET return, on memory that are from known binary files [Default]
|
||||
* 2 : Add SEP at CALLRET return for all type of memory.
|
||||
|
||||
|
||||
@@ -204,8 +207,8 @@ Enable or disable the use of deferred flags. Available in WowBox64.
|
||||
Allow continue running a block that is unprotected and potentially dirty.
|
||||
|
||||
* 0 : Do not allow continue running a block that is unprotected and potentially dirty. [Default]
|
||||
* 1 : Allow continue to run a dynablock that write data in the same page as code. It can gets faster in loading time of some game but can also get unexpected crashes.
|
||||
* 2 : Will also, when it detect an HotPage, flag that page as NEVERCLEAN, and so it will not be write protected but Block build from that page will always be tested. It can be faster that way (but soem SMC case might not be trapped).
|
||||
* 1 : Allow continue to run a DynaBlock that write data in the same page as code. It can gets faster in loading time of some game but can also get unexpected crashes.
|
||||
* 2 : Will also, when it detects a HotPage, flag that page as NEVERCLEAN, and so it will not be write protected but blocks built from that page will always be tested. It can be faster that way (but some SMC case might not be trapped).
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_NOHOTPAGE> =I<0|1>
|
||||
@@ -216,14 +219,6 @@ Disable detection of hot page (where code is executed and data written at the sa
|
||||
* 1 : Do not detect hot page
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_HOTPAGE_ALT> =I<0|1>
|
||||
|
||||
Use alternative way to detect HotPages (legacy way).
|
||||
|
||||
* 0 : Detect hot page, using new method from v0.3.9+ [Default]
|
||||
* 1 : Use alternate method to detect HotPage (from v0.3.8 and earlier)
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_DIV0> =I<0|1>
|
||||
|
||||
Enable or disable the generation of division-by-zero exception. Available in WowBox64.
|
||||
@@ -245,7 +240,7 @@ Enable DynaRec dump. Available in WowBox64.
|
||||
|
||||
Dump DynaRec blocks in the specified range. Available in WowBox64.
|
||||
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : Define the range where dynablock gets dumped (inclusive-exclusive).
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : Define the range where DynaBlock gets dumped (inclusive-exclusive).
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_FASTNAN> =I<0|1>
|
||||
@@ -278,11 +273,11 @@ Define max allowed forward value when building block. Available in WowBox64.
|
||||
|
||||
The GDBJIT debugging support, only available on build with `-DGDBJIT=ON`, enable it with gdb command: jit-reader-load /usr/local/lib/libbox64gdbjitreader.so.
|
||||
|
||||
* 0 : Dynarec will not generate GDBJIT debuginfo. [Default]
|
||||
* 1 : Dynarec will generate GDBJIT debuginfo.
|
||||
* 2 : Dynarec will generate detailed GDBJIT debuginfo with internal state.
|
||||
* 3 : Dynarec will register detailed GDBJIT debuginfo only for dynablocks that the guest program trap into, greatly improving performance.
|
||||
* 0xXXXXXXX-0xYYYYYYY : Define the range where Dynarec will generate detailed GDBJIT debuginfo with internal state.
|
||||
* 0 : DynaRec will not generate GDBJIT debuginfo. [Default]
|
||||
* 1 : DynaRec will generate GDBJIT debuginfo.
|
||||
* 2 : DynaRec will generate detailed GDBJIT debuginfo with internal state.
|
||||
* 3 : DynaRec will register detailed GDBJIT debuginfo only for DynaBlocks that the guest program trap into, greatly improving performance.
|
||||
* 0xXXXXXXX-0xYYYYYYY : Define the range where DynaRec will generate detailed GDBJIT debuginfo with internal state.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_LOG> =I<0|1|2|3>
|
||||
@@ -335,21 +330,21 @@ Enable x86 PAUSE emulation, may help the performance of spinlocks. Available in
|
||||
|
||||
Generate map file for Linux perf tool.
|
||||
|
||||
* 0 : Dynarec will not generate perf map. [Default]
|
||||
* 1 : Dynarec will generate perf map.
|
||||
* 0 : DynaRec will not generate perf map. [Default]
|
||||
* 1 : DynaRec will generate perf map.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_PURGE> =I<0|1>
|
||||
|
||||
Purge dynablocks that haven't been executed recently, based on tick age threshold (BOX64_DYNAREC_PURGE_AGE).
|
||||
Purge DynaBlocks that haven't been executed recently, based on tick age threshold (BOX64_DYNAREC_PURGE_AGE).
|
||||
|
||||
* 0 : Dynarec will not purge old unused dynablocks. [Default]
|
||||
* 1 : Dynarec will purge old unused dynablocks based on tick age.
|
||||
* 0 : DynaRec will not purge old unused DynaBlocks. [Default]
|
||||
* 1 : DynaRec will purge old unused DynaBlocks based on tick age.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_PURGE_AGE> =I<4096|XXXX>
|
||||
|
||||
Tick age threshold for dynablock purging (requires BOX64_DYNAREC_PURGE=1).
|
||||
Tick age threshold for DynaBlock purging (requires BOX64_DYNAREC_PURGE=1).
|
||||
|
||||
* 4096 : Default age threshold. [Default]
|
||||
* XXXX : Custom age threshold (range: 10-65536).
|
||||
@@ -388,8 +383,8 @@ Enable or disable libtbb detection.
|
||||
Enable DynaRec execution comparison with the interpreter, very slow, only for testing. Available in WowBox64.
|
||||
|
||||
* 0 : No comparison. [Default]
|
||||
* 1 : Each opcode runs on interpreter and on Dynarec, regs and memory are compared and printed when they differ.
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : Define the range where dynarec is tested (inclusive-exclusive).
|
||||
* 1 : Each opcode runs on interpreter and on DynaRec, regs and memory are compared and printed when they differ.
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : Define the range where DynaRec is tested (inclusive-exclusive).
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_TEST_NODUP> =I<0|1>
|
||||
@@ -434,11 +429,11 @@ Wait or not for the building of a DynaRec code block to be ready. Available in W
|
||||
|
||||
=item B<BOX64_DYNAREC_WEAKBARRIER> =I<0|1|2>
|
||||
|
||||
Tweak the memory barriers to reduce the performance impact by strong memory emualtion. Available in WowBox64.
|
||||
Tweak the memory barriers to reduce the performance impact by strong memory emulation. Available in WowBox64.
|
||||
|
||||
* 0 : Use regular safe barrier.
|
||||
* 1 : Use weak barriers to have more performance boost. [Default]
|
||||
* 2 : All in 1, plus disabled the last write barriers.
|
||||
* 2 : All in 1, plus disable the last write barriers.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_X87DOUBLE> =I<0|1|2>
|
||||
@@ -452,19 +447,19 @@ Force the use of float/double for x87 emulation. Available in WowBox64.
|
||||
|
||||
=item B<BOX64_DYNAREC_INTERP_SIGNAL> =I<0|1>
|
||||
|
||||
Allow the use of Dynarec in Signal Handlers.
|
||||
Allow the use of DynaRec in Signal Handlers.
|
||||
|
||||
* 0 : Allow the use of Dynarec in signal handlers. [Default]
|
||||
* 0 : Allow the use of DynaRec in signal handlers. [Default]
|
||||
* 1 : Only use the Interpreter for signal handlers (as it was in v0.3.8 and earlier).
|
||||
|
||||
|
||||
=item B<BOX64_DYNACACHE> =I<0|1|2>
|
||||
|
||||
Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache write file to home folder by default, and can grow without limit.
|
||||
Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache writes files to the home folder by default, and keeps its folder below BOX64_DYNACACHE_LIMIT when generating new cache files.
|
||||
|
||||
* 0 : Disable DynaCache.
|
||||
* 1 : Enable DynaCache.
|
||||
* 2 : Use DynaCache files if present, but do not generate new one. [Default]
|
||||
* 1 : Enable DynaCache. [Default]
|
||||
* 2 : Use DynaCache files if present, but do not generate new one.
|
||||
|
||||
|
||||
=item B<BOX64_DYNACACHE_FOLDER> =I<XXXX>
|
||||
@@ -474,11 +469,29 @@ Set the folder for DynaCache files. Default is $XDG_CACHE_HOME/box64 or $HOME/.c
|
||||
* XXXX : Use folder XXXX for DynaCache files.
|
||||
|
||||
|
||||
=item B<BOX64_DYNACACHE_LIMIT> =I<0|XXXX|2048>
|
||||
|
||||
Maximum size, in MiB, for the DynaCache folder. When the limit is exceeded, invalid DynaCache files are removed first, then the oldest valid files are removed if needed. Default size is 2048MiB.
|
||||
|
||||
* 0 : Do not limit the DynaCache folder size.
|
||||
* XXXX : Keep the DynaCache folder below XXXX MiB by removing invalid cache files first, then the oldest valid cache files.
|
||||
* 2048 : A size of 2048 MiB is the default value. [Default]
|
||||
|
||||
|
||||
=item B<BOX64_DYNACACHE_COMPRESS> =I<0|1|2>
|
||||
|
||||
Compress or not DynaCache files on disk
|
||||
|
||||
* 0 : Do not compress dynacache files
|
||||
* 1 : Compress dynacache files using Zlib with fastest compression. [Default]
|
||||
* 2 : Compress dynacache files using ZLib with default compression.
|
||||
|
||||
|
||||
=item B<BOX64_DYNACACHE_MIN> =I<XXXX|350>
|
||||
|
||||
Minimum size, in KB, for a DynaCache to be written to disk. Default size is 350KB
|
||||
|
||||
* XXXX : Set a minimum size of XXXX KB of Dynarec code to write the dynacache to disk. Will not be saved to disk else.
|
||||
* XXXX : Set a minimum size of XXXX KB of DynaRec code to write the dynacache to disk. Will not be saved to disk else.
|
||||
* 350 : A size of 350 KB is the default value. [Default]
|
||||
|
||||
|
||||
@@ -557,7 +570,7 @@ Add --in-process-gpu argument to the guest program.
|
||||
Launch gdb or not for SIGSEGV, SIGILL, and SIGBUS.
|
||||
|
||||
* 0 : Just print the message when the signal is caught. [Default]
|
||||
* 1 : Launch gdb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting. Inside gdb, you need to find the correct thread yourself (the one with `my_box64signalhandler` in is stack), then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box64signalhandler`, just before the printf of the Segfault message. Then `set waiting=0` to exit the infinite loop.
|
||||
* 1 : Launch gdb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting. Inside gdb, you need to find the correct thread yourself (the one with `my_box64signalhandler` in its stack), then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box64signalhandler`, just before the printf of the Segfault message. Then `set waiting=0` to exit the infinite loop.
|
||||
* 2 : Launch gdbserver when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process, and go in an endless loop, waiting. Use `gdb /PATH/TO/box64` 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 `BOX64_JITGDB=1`.
|
||||
* 3 : Launch lldb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting.
|
||||
|
||||
@@ -653,26 +666,26 @@ Disable the Box64 banner. Available in WowBox64.
|
||||
|
||||
=item B<BOX64_NODYNAREC> =I<0xXXXXXXXX-0xYYYYYYYY>
|
||||
|
||||
Forbid dynablock creation in the address range specified, helpful for debugging behaviour difference between Dynarec and Interpreter. Available in WowBox64.
|
||||
Forbid DynaBlock creation in the address range specified, helpful for debugging behaviour difference between DynaRec and Interpreter. Available in WowBox64.
|
||||
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : Define the range where dynablock creation is forbidden (inclusive-exclusive).
|
||||
* 0xXXXXXXXX-0xYYYYYYYY : Define the range where DynaBlock creation is forbidden (inclusive-exclusive).
|
||||
|
||||
|
||||
=item B<BOX64_NODYNAREC_DELAY> =I<0|1>
|
||||
|
||||
Remove NoDynarec range after a delay. Available in WowBox64.
|
||||
Remove NoDynaRec range after a delay. Available in WowBox64.
|
||||
|
||||
* 0 : Do not remove NoDynarec range. [Default]
|
||||
* 1 : Remove the NoDynarec range once 2 threads have been created.
|
||||
* 0 : Do not remove NoDynaRec range. [Default]
|
||||
* 1 : Remove the NoDynaRec range once 2 threads have been created.
|
||||
|
||||
|
||||
=item B<BOX64_DYNAREC_NOARCH> =I<0|1|2>
|
||||
|
||||
Remove Architecture metatdata from Dynarec blocks (used on signal). Available in WowBox64.
|
||||
Remove Architecture metadata from DynaRec blocks (used on signal). Available in WowBox64.
|
||||
|
||||
* 0 : Generate all architecture metadata for each blocks, including x87/mmx/SSE/AVX regs tracking. Wil use some more memory. [Default]
|
||||
* 1 : Generate only essential metadata for each blocks (flags, alignments), saving some memory, but some encrypted software might fails.
|
||||
* 2 : Do not generate metadata for blocks. Saving a bit more memory but might fails on signal handling.
|
||||
* 0 : Generate all architecture metadata for each blocks, including x87/mmx/SSE/AVX regs tracking. Will use some more memory. [Default]
|
||||
* 1 : Generate only essential metadata for each blocks (flags, alignments), saving some memory, but some encrypted software might fail.
|
||||
* 2 : Do not generate metadata for blocks. Saving a bit more memory but might fail on signal handling.
|
||||
|
||||
|
||||
=item B<BOX64_NOGTK> =I<0|1>
|
||||
@@ -735,7 +748,7 @@ Do not load Vulkan libraries.
|
||||
|
||||
Do not load x64 Vulkan overlay.
|
||||
|
||||
* 0 : Do try to Load x64 Vulkan overlay. [Default]
|
||||
* 0 : Try to load x64 Vulkan overlay. [Default]
|
||||
* 1 : Do not load x64 Vulkan overlay.
|
||||
|
||||
|
||||
@@ -805,7 +818,7 @@ Use hardware counter for rdtsc if available.
|
||||
|
||||
=item B<BOX64_RDTSC_INV> =I<0|1>
|
||||
|
||||
Report Invariant TSC bit in CPUID for Intel CPU type.
|
||||
Report Invariant TSC bit in CPUID for Intel CPU type. Available in WowBox64.
|
||||
|
||||
* 0 : Do not report Invariant TSC for Intel CPU type (default). [Default]
|
||||
* 1 : Report Invariant TSC bit in CPUID leaf 0x80000007 for Intel CPU type.
|
||||
@@ -854,10 +867,10 @@ Show native and emulated backtrace when a signal is caught.
|
||||
|
||||
=item B<BOX64_SHOWSEGV> =I<0|1>
|
||||
|
||||
Always show SIGSEGV signal detailes.
|
||||
Always show SIGSEGV signal details.
|
||||
|
||||
* 0 : Does nothing. [Default]
|
||||
* 1 : Always show SIGSEGV signal detailes.
|
||||
* 1 : Always show SIGSEGV signal details.
|
||||
|
||||
|
||||
=item B<BOX64_SSE_FLUSHTO0> =I<0|1>
|
||||
@@ -865,7 +878,7 @@ Always show SIGSEGV signal detailes.
|
||||
Behaviour of SSE Flush to 0 flags. Also tracking SSE exception flags. Available in WowBox64.
|
||||
|
||||
* 0 : Just track the flag. [Default]
|
||||
* 1 : Apply SSE Flush to 0 flag directly. Also reflect SSE exception flags in Dynarec (if available)
|
||||
* 1 : Apply SSE Flush to 0 flag directly. Also reflect SSE exception flags in DynaRec (if available)
|
||||
|
||||
|
||||
=item B<BOX64_SSE42> =I<0|1>
|
||||
@@ -1005,12 +1018,20 @@ Call XInitThreads when loading X11. This is mostly for old Loki games with the L
|
||||
|
||||
=item B<BOX64_X87_NO80BITS> =I<0|1>
|
||||
|
||||
Behavoiur of x87 80bits long double. Available in WowBox64.
|
||||
Behaviour of x87 80bits long double. Available in WowBox64.
|
||||
|
||||
* 0 : Try to handle 80bits long double as precise as possible. [Default]
|
||||
* 1 : Use 64bits double for x87.
|
||||
|
||||
|
||||
=item B<BOX64_NOPERSONA32BITS> =I<0|1>
|
||||
|
||||
Disable the automatic switch of personality for 32-bit binaries (always enabled on Box32).
|
||||
|
||||
* 0 : Switch personality for 32-bit binaries (if not already tried). [Default]
|
||||
* 1 : Do not switch personality for 32-bit binaries.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
+144
-29
@@ -8,17 +8,18 @@ from collections import defaultdict
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
usage_file = os.path.join(script_dir, 'usage.json')
|
||||
|
||||
with open(usage_file, 'r') as file:
|
||||
data = json.load(file)
|
||||
|
||||
with open(os.path.join(script_dir, '../USAGE.md'), 'w') as md_file:
|
||||
md_file.write("""<!--- This file is generated by gen.py, do not edit it directly. -->
|
||||
# Language definitions — add a key here and a corresponding usage_<lang>.json
|
||||
# (if translations are needed) to add a new language.
|
||||
LANG = {
|
||||
"en": {
|
||||
"suffix": "",
|
||||
"preamble": """<!--- This file is generated by gen.py, do not edit it directly. -->
|
||||
Usage
|
||||
----
|
||||
|
||||
There are many environment variables to control Box64's behaviour, which will be listed below by category.
|
||||
|
||||
There are 2 types of Box64 builds: the Wine WOW64 build (WowBox64) and the regular Linux build. Beware only some of the environment variables are available in WowBox64.
|
||||
There are 2 types of Box64 builds: the Wine WOW64 build (WowBox64) and the regular Linux build. Note that only some of the environment variables are available in WowBox64.
|
||||
|
||||
### Configuration files
|
||||
|
||||
@@ -38,15 +39,20 @@ BOX64_DYNAREC_CALLRET=1
|
||||
|
||||
This configuration will apply the specified settings application-wide to any executable named `factorio`.
|
||||
|
||||
Shared options can also be defined in a special `[*]` section. Those settings apply globally, and any more specific section only overrides the options it defines itself.
|
||||
|
||||
### Advanced usage for Linux build
|
||||
|
||||
1. **Wildcard Matching**
|
||||
|
||||
Asterisks (`*`) can be used for basic pattern matching in application names. For instance, `[*setup*]` will match any program containing "setup" in its name. Note this implements simple wildcard matching rather than full regex support.
|
||||
2. **Custom Configuration File**
|
||||
Asterisks (`*`) can be used for basic pattern matching in application names. For instance, `[*setup*]` will match any program containing "setup" in its name. Note that this implements simple wildcard matching rather than full regex support.
|
||||
2. **Shared Settings**
|
||||
|
||||
The special `[*]` section defines shared rcfile options for all applications. Unlike wildcard sections such as `[*setup*]`, this is a dedicated global section.
|
||||
3. **Custom Configuration File**
|
||||
|
||||
The `BOX64_RCFILE` environment variable can specify an alternative configuration file instead of the default `/etc/box64.box64rc`.
|
||||
3. **Per-File Settings**
|
||||
4. **Per-File Settings**
|
||||
|
||||
Sections starting with `/` apply to specific files. For example:
|
||||
```
|
||||
@@ -57,25 +63,130 @@ This configuration will apply the specified settings application-wide to any exe
|
||||
|
||||
----
|
||||
|
||||
""")
|
||||
""",
|
||||
"wine": "Available in WowBox64.",
|
||||
"default": "[Default]",
|
||||
"top_cat": "Performance",
|
||||
"categories": {},
|
||||
},
|
||||
"cn": {
|
||||
"suffix": "_CN",
|
||||
"preamble": """<!--- 此文件由 gen.py 自动生成,请勿直接编辑。 -->
|
||||
使用说明
|
||||
----
|
||||
|
||||
categories = defaultdict(list)
|
||||
for entry in data:
|
||||
categories[entry["category"]].append(entry)
|
||||
Box64 有许多环境变量可用于控制其行为,下面将按类别列出。
|
||||
|
||||
# Put "Performance" at the top, then sort the rest alphabetically
|
||||
sorted_categories = sorted(categories.items(), key=lambda x: (x[0] != "Performance", x[0]))
|
||||
for category, entries in sorted_categories:
|
||||
md_file.write(f"## {category}\n\n")
|
||||
for entry in entries:
|
||||
md_file.write(f"### {entry['name']}\n\n{entry['description']}{' Available in WowBox64.' if entry['wine'] else ''}\n\n")
|
||||
for option in entry['options']:
|
||||
md_file.write(f" * {option['key']}: {option['description']} {'[Default]' if option['default'] else ''}\n")
|
||||
md_file.write("\n")
|
||||
Box64 有两种构建类型:Wine WOW64 构建(WowBox64)和常规 Linux 构建。请注意,只有部分环境变量在 WowBox64 中可用。
|
||||
|
||||
### 配置文件
|
||||
|
||||
除了环境变量之外,如果你使用的是常规 Linux 构建,Box64 默认还会在两个位置查找 rcfile:系统范围的 `/etc/box64.box64rc` 和用户目录下的 `~/.box64rc`。
|
||||
而在 WowBox64 中,配置文件仅在 `%USERPROFILE%/.box64rc` 处检查。
|
||||
设置的优先级如下(从高到低):`~/.box64rc` > `/etc/box64.box64rc` > 环境变量。
|
||||
|
||||
配置示例:
|
||||
|
||||
```
|
||||
[factorio]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
BOX64_DYNAREC_BIGBLOCK=2
|
||||
BOX64_DYNAREC_FORWARD=1024
|
||||
BOX64_DYNAREC_CALLRET=1
|
||||
```
|
||||
|
||||
此配置将使所有名为 `factorio` 的可执行文件应用指定的设置。
|
||||
|
||||
共享选项也可以定义在特殊的 `[*]` 配置段中。这些设置会全局应用,而更具体的配置段只会覆盖它自己显式定义的选项。
|
||||
|
||||
### Linux 构建的高级用法
|
||||
|
||||
1. **通配符匹配**
|
||||
|
||||
可以使用星号(`*`)对应用程序名称进行基本的模式匹配。例如,`[*setup*]` 将匹配名称中包含 "setup" 的任何程序。请注意,这里实现的是简单的通配符匹配,而非完整的正则表达式支持。
|
||||
2. **共享设置**
|
||||
|
||||
特殊的 `[*]` 配置段可为所有应用程序定义共享的 rcfile 选项。它不同于 `[*setup*]` 这类通配符配置段,是一个专用的全局配置段。
|
||||
3. **自定义配置文件**
|
||||
|
||||
`BOX64_RCFILE` 环境变量可以指定一个替代的配置文件,而不是默认的 `/etc/box64.box64rc`。
|
||||
4. **按文件设置**
|
||||
|
||||
以 `/` 开头的配置项适用于特定文件。例如:
|
||||
```
|
||||
[/d3d9.dll]
|
||||
BOX64_DYNAREC_SAFEFLAGS=0
|
||||
```
|
||||
这些设置将仅影响 `d3d9.dll` 文件。此语法同样适用于**模拟的** Linux 库,例如 `[/libstdc++.so.6]`。
|
||||
|
||||
----
|
||||
|
||||
""",
|
||||
"wine": "在 WowBox64 中可用。",
|
||||
"default": "[默认值]",
|
||||
"top_cat": "性能",
|
||||
"categories": {
|
||||
"Performance": "性能",
|
||||
"Arguments": "参数",
|
||||
"Compatibility": "兼容性",
|
||||
"Debugging": "调试",
|
||||
"Environment": "环境变量",
|
||||
"Libraries": "库",
|
||||
"Fragile or Legacy": "不稳定或遗留选项",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
with open(os.path.join(script_dir, '../box64.pod'), 'w') as pod_file:
|
||||
pod_file.write("""=head1 NAME
|
||||
def write_md(data, lang, t_data=None):
|
||||
L = LANG[lang]
|
||||
out_path = os.path.join(script_dir, f'../USAGE{L["suffix"]}.md')
|
||||
|
||||
with open(out_path, 'w') as md_file:
|
||||
md_file.write(L['preamble'])
|
||||
|
||||
categories = defaultdict(list)
|
||||
for entry in data:
|
||||
entry = dict(entry)
|
||||
entry['category'] = L['categories'].get(entry['category'], entry['category'])
|
||||
categories[entry["category"]].append(entry)
|
||||
|
||||
sorted_categories = sorted(categories.items(), key=lambda x: (x[0] != L['top_cat'], x[0]))
|
||||
for category, entries in sorted_categories:
|
||||
md_file.write(f"## {category}\n\n")
|
||||
for entry in entries:
|
||||
if t_data:
|
||||
t_entry = t_data.get(entry['name'], {})
|
||||
desc = t_entry.get('description', entry['description'])
|
||||
else:
|
||||
desc = entry['description']
|
||||
wine_note = f" {L['wine']}" if entry['wine'] else ""
|
||||
md_file.write(f"### {entry['name']}\n\n{desc}{wine_note}\n\n")
|
||||
for option in entry['options']:
|
||||
if t_data:
|
||||
t_opts = t_data.get(entry['name'], {}).get('options', {})
|
||||
opt_desc = t_opts.get(option['key'], option['description'])
|
||||
else:
|
||||
opt_desc = option['description']
|
||||
default_mark = f" {L['default']}" if option['default'] else ""
|
||||
md_file.write(f" * {option['key']}: {opt_desc}{default_mark}\n")
|
||||
md_file.write("\n")
|
||||
|
||||
|
||||
with open(usage_file, 'r') as file:
|
||||
data = json.load(file)
|
||||
|
||||
for lang in LANG:
|
||||
t_file = os.path.join(script_dir, f'usage_{lang}.json')
|
||||
t_data = None
|
||||
if os.path.exists(t_file):
|
||||
with open(t_file, 'r') as file:
|
||||
t_data = json.load(file)
|
||||
write_md(data, lang, t_data)
|
||||
|
||||
with open(os.path.join(script_dir, '../box64.pod'), 'w') as pod_file:
|
||||
pod_file.write(
|
||||
"""=head1 NAME
|
||||
|
||||
box64 - Linux Userspace x86_64 Emulator with a twist
|
||||
|
||||
@@ -121,17 +232,21 @@ Example:
|
||||
BOX64_DYNAREC_FORWARD=1024
|
||||
BOX64_DYNAREC_CALLRET=1
|
||||
|
||||
The special C<[*]> section defines shared rcfile options for all applications.
|
||||
More specific sections override only the options they define themselves.
|
||||
|
||||
=head1 ENVIRONMENT VARIABLES
|
||||
|
||||
=over 8
|
||||
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
for entry in data:
|
||||
pod_file.write(f"\n=item B<{entry['name']}> =I<{ '|'.join(option['key'] for option in entry['options']) }>\n\n{entry['description']}{' Available in WowBox64.' if entry['wine'] else ''}\n\n")
|
||||
for option in entry['options']:
|
||||
pod_file.write(f" * {option['key']} : {option['description']} {'[Default]' if option['default'] else ''}\n")
|
||||
pod_file.write("\n")
|
||||
pod_file.write(f"\n=item B<{entry['name']}> =I<{ '|'.join(option['key'] for option in entry['options']) }>\n\n{entry['description']}{' Available in WowBox64.' if entry['wine'] else ''}\n\n")
|
||||
for option in entry['options']:
|
||||
pod_file.write(f" * {option['key']} : {option['description']} {'[Default]' if option['default'] else ''}\n")
|
||||
pod_file.write("\n")
|
||||
|
||||
pod_file.write("""
|
||||
=back
|
||||
|
||||
+117
-71
@@ -101,7 +101,7 @@
|
||||
},
|
||||
{
|
||||
"name": "BOX64_AVX",
|
||||
"description": "Expose AVX extension to CPUID and cpuinfo file. Default value is 2 on Arm64 because it's fully implemented in DynaRec, 0 otherwise.",
|
||||
"description": "Expose AVX extension to CPUID and cpuinfo file. Default value is 2 on Arm64 and LoongArch64 because it's fully implemented in DynaRec, 0 otherwise.",
|
||||
"category": "Compatibility",
|
||||
"wine": true,
|
||||
"options": [
|
||||
@@ -256,17 +256,17 @@
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Build Dynarec block as big as possible.",
|
||||
"description": "Build DynaRec block as big as possible.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "2",
|
||||
"description": "Build Dynarec block bigger, do not stop when block overlaps, but only for blocks in elf memory.",
|
||||
"description": "Build DynaRec block bigger, do not stop when block overlaps, but only for blocks in elf memory.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "3",
|
||||
"description": "Build Dynarec block bigger, do not stop when block overlaps, for all type of memory, useful for wine programs.",
|
||||
"description": "Build DynaRec block bigger, do not stop when block overlaps, for all type of memory, useful for wine programs.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -314,7 +314,7 @@
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNAREC_SEP",
|
||||
"description": "Optimize CALL/RET further with Secondary Entry Points (SEP). Have no effect is CALLRET is not enabled",
|
||||
"description": "Optimize CALL/RET further with Secondary Entry Points (SEP). Has no effect if CALLRET is not enabled",
|
||||
"category": "Performance",
|
||||
"wine": true,
|
||||
"options": [
|
||||
@@ -325,7 +325,7 @@
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Add SEP at CALLRET return, on meory that are from known binary files",
|
||||
"description": "Add SEP at CALLRET return, on memory that are from known binary files",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
@@ -366,12 +366,12 @@
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Allow continue to run a dynablock that write data in the same page as code. It can gets faster in loading time of some game but can also get unexpected crashes.",
|
||||
"description": "Allow continue to run a DynaBlock that write data in the same page as code. It can gets faster in loading time of some game but can also get unexpected crashes.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "2",
|
||||
"description": "Will also, when it detect an HotPage, flag that page as NEVERCLEAN, and so it will not be write protected but Block build from that page will always be tested. It can be faster that way (but soem SMC case might not be trapped).",
|
||||
"description": "Will also, when it detects a HotPage, flag that page as NEVERCLEAN, and so it will not be write protected but blocks built from that page will always be tested. It can be faster that way (but some SMC case might not be trapped).",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -394,24 +394,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNAREC_HOTPAGE_ALT",
|
||||
"description": "Use alternative way to detect HotPages (legacy way).",
|
||||
"category": "Performance",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Detect hot page, using new method from v0.3.9+",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Use alternate method to detect HotPage (from v0.3.8 and earlier)",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNAREC_DIV0",
|
||||
"description": "Enable or disable the generation of division-by-zero exception.",
|
||||
@@ -461,7 +443,7 @@
|
||||
"options": [
|
||||
{
|
||||
"key": "0xXXXXXXXX-0xYYYYYYYY",
|
||||
"description": "Define the range where dynablock gets dumped (inclusive-exclusive).",
|
||||
"description": "Define the range where DynaBlock gets dumped (inclusive-exclusive).",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -538,27 +520,27 @@
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Dynarec will not generate GDBJIT debuginfo.",
|
||||
"description": "DynaRec will not generate GDBJIT debuginfo.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Dynarec will generate GDBJIT debuginfo.",
|
||||
"description": "DynaRec will generate GDBJIT debuginfo.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "2",
|
||||
"description": "Dynarec will generate detailed GDBJIT debuginfo with internal state.",
|
||||
"description": "DynaRec will generate detailed GDBJIT debuginfo with internal state.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "3",
|
||||
"description": "Dynarec will register detailed GDBJIT debuginfo only for dynablocks that the guest program trap into, greatly improving performance.",
|
||||
"description": "DynaRec will register detailed GDBJIT debuginfo only for DynaBlocks that the guest program trap into, greatly improving performance.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "0xXXXXXXX-0xYYYYYYY",
|
||||
"description": "Define the range where Dynarec will generate detailed GDBJIT debuginfo with internal state.",
|
||||
"description": "Define the range where DynaRec will generate detailed GDBJIT debuginfo with internal state.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -691,38 +673,38 @@
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Dynarec will not generate perf map.",
|
||||
"description": "DynaRec will not generate perf map.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Dynarec will generate perf map.",
|
||||
"description": "DynaRec will generate perf map.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNAREC_PURGE",
|
||||
"description": "Purge dynablocks that haven't been executed recently, based on tick age threshold (BOX64_DYNAREC_PURGE_AGE).",
|
||||
"category": "Performance",
|
||||
"description": "Purge DynaBlocks that haven't been executed recently, based on tick age threshold (BOX64_DYNAREC_PURGE_AGE).",
|
||||
"category": "Fragile or Legacy",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Dynarec will not purge old unused dynablocks.",
|
||||
"description": "DynaRec will not purge old unused DynaBlocks.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Dynarec will purge old unused dynablocks based on tick age.",
|
||||
"description": "DynaRec will purge old unused DynaBlocks based on tick age.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNAREC_PURGE_AGE",
|
||||
"description": "Tick age threshold for dynablock purging (requires BOX64_DYNAREC_PURGE=1).",
|
||||
"category": "Performance",
|
||||
"description": "Tick age threshold for DynaBlock purging (requires BOX64_DYNAREC_PURGE=1).",
|
||||
"category": "Fragile or Legacy",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
@@ -824,12 +806,12 @@
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Each opcode runs on interpreter and on Dynarec, regs and memory are compared and printed when they differ.",
|
||||
"description": "Each opcode runs on interpreter and on DynaRec, regs and memory are compared and printed when they differ.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "0xXXXXXXXX-0xYYYYYYYY",
|
||||
"description": "Define the range where dynarec is tested (inclusive-exclusive).",
|
||||
"description": "Define the range where DynaRec is tested (inclusive-exclusive).",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -926,8 +908,8 @@
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNAREC_WEAKBARRIER",
|
||||
"description": "Tweak the memory barriers to reduce the performance impact by strong memory emualtion.",
|
||||
"category": "Performance",
|
||||
"description": "Tweak the memory barriers to reduce the performance impact by strong memory emulation.",
|
||||
"category": "Fragile or Legacy",
|
||||
"wine": true,
|
||||
"options": [
|
||||
{
|
||||
@@ -942,7 +924,7 @@
|
||||
},
|
||||
{
|
||||
"key": "2",
|
||||
"description": "All in 1, plus disabled the last write barriers.",
|
||||
"description": "All in 1, plus disable the last write barriers.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -972,13 +954,13 @@
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNAREC_INTERP_SIGNAL",
|
||||
"description": "Allow the use of Dynarec in Signal Handlers.",
|
||||
"description": "Allow the use of DynaRec in Signal Handlers.",
|
||||
"category": "Compatibility",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Allow the use of Dynarec in signal handlers.",
|
||||
"description": "Allow the use of DynaRec in signal handlers.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
@@ -990,8 +972,8 @@
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNACACHE",
|
||||
"description": "Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache write file to home folder by default, and can grow without limit.",
|
||||
"category": "Performance",
|
||||
"description": "Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache writes files to the home folder by default, and keeps its folder below BOX64_DYNACACHE_LIMIT when generating new cache files.",
|
||||
"category": "Fragile or Legacy",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
@@ -1002,19 +984,19 @@
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Enable DynaCache.",
|
||||
"default": false
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "2",
|
||||
"description": "Use DynaCache files if present, but do not generate new one.",
|
||||
"default": true
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNACACHE_FOLDER",
|
||||
"description": "Set the folder for DynaCache files. Default is $XDG_CACHE_HOME/box64 or $HOME/.cache/box64 if $XDG_CACHE_HOME is not set.",
|
||||
"category": "Performance",
|
||||
"category": "Fragile or Legacy",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
@@ -1024,15 +1006,61 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNACACHE_LIMIT",
|
||||
"description": "Maximum size, in MiB, for the DynaCache folder. When the limit is exceeded, invalid DynaCache files are removed first, then the oldest valid files are removed if needed. Default size is 2048MiB.",
|
||||
"category": "Fragile or Legacy",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Do not limit the DynaCache folder size.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "XXXX",
|
||||
"description": "Keep the DynaCache folder below XXXX MiB by removing invalid cache files first, then the oldest valid cache files.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "2048",
|
||||
"description": "A size of 2048 MiB is the default value.",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNACACHE_COMPRESS",
|
||||
"description": "Compress or not DynaCache files on disk",
|
||||
"category": "Fragile or Legacy",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Do not compress dynacache files",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Compress dynacache files using Zlib with fastest compression.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "2",
|
||||
"description": "Compress dynacache files using ZLib with default compression.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNACACHE_MIN",
|
||||
"description": "Minimum size, in KB, for a DynaCache to be written to disk. Default size is 350KB",
|
||||
"category": "Performance",
|
||||
"category": "Fragile or Legacy",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
"key": "XXXX",
|
||||
"description": "Set a minimum size of XXXX KB of Dynarec code to write the dynacache to disk. Will not be saved to disk else.",
|
||||
"description": "Set a minimum size of XXXX KB of DynaRec code to write the dynacache to disk. Will not be saved to disk else.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
@@ -1207,7 +1235,7 @@
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Launch gdb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting. Inside gdb, you need to find the correct thread yourself (the one with `my_box64signalhandler` in is stack), then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box64signalhandler`, just before the printf of the Segfault message. Then `set waiting=0` to exit the infinite loop.",
|
||||
"description": "Launch gdb when a SIGSEGV, SIGILL or SIGBUS signal is trapped, attached to the offending process and go in an endless loop, waiting. Inside gdb, you need to find the correct thread yourself (the one with `my_box64signalhandler` in its stack), then probably need to `finish` 1 or 2 functions (inside `usleep(..)`) and then you'll be in `my_box64signalhandler`, just before the printf of the Segfault message. Then `set waiting=0` to exit the infinite loop.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
@@ -1427,54 +1455,54 @@
|
||||
},
|
||||
{
|
||||
"name": "BOX64_NODYNAREC",
|
||||
"description": "Forbid dynablock creation in the address range specified, helpful for debugging behaviour difference between Dynarec and Interpreter.",
|
||||
"category": "Performance",
|
||||
"description": "Forbid DynaBlock creation in the address range specified, helpful for debugging behaviour difference between DynaRec and Interpreter.",
|
||||
"category": "Debugging",
|
||||
"wine": true,
|
||||
"options": [
|
||||
{
|
||||
"key": "0xXXXXXXXX-0xYYYYYYYY",
|
||||
"description": "Define the range where dynablock creation is forbidden (inclusive-exclusive).",
|
||||
"description": "Define the range where DynaBlock creation is forbidden (inclusive-exclusive).",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_NODYNAREC_DELAY",
|
||||
"description": "Remove NoDynarec range after a delay.",
|
||||
"description": "Remove NoDynaRec range after a delay.",
|
||||
"category": "Debugging",
|
||||
"wine": true,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Do not remove NoDynarec range.",
|
||||
"description": "Do not remove NoDynaRec range.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Remove the NoDynarec range once 2 threads have been created.",
|
||||
"description": "Remove the NoDynaRec range once 2 threads have been created.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_DYNAREC_NOARCH",
|
||||
"description": "Remove Architecture metatdata from Dynarec blocks (used on signal).",
|
||||
"description": "Remove Architecture metadata from DynaRec blocks (used on signal).",
|
||||
"category": "Performance",
|
||||
"wine": true,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Generate all architecture metadata for each blocks, including x87/mmx/SSE/AVX regs tracking. Wil use some more memory.",
|
||||
"description": "Generate all architecture metadata for each blocks, including x87/mmx/SSE/AVX regs tracking. Will use some more memory.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Generate only essential metadata for each blocks (flags, alignments), saving some memory, but some encrypted software might fails.",
|
||||
"description": "Generate only essential metadata for each blocks (flags, alignments), saving some memory, but some encrypted software might fail.",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"key": "2",
|
||||
"description": "Do not generate metadata for blocks. Saving a bit more memory but might fails on signal handling.",
|
||||
"description": "Do not generate metadata for blocks. Saving a bit more memory but might fail on signal handling.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -1613,7 +1641,7 @@
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Do try to Load x64 Vulkan overlay.",
|
||||
"description": "Try to load x64 Vulkan overlay.",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
@@ -1771,7 +1799,7 @@
|
||||
"name": "BOX64_RDTSC_INV",
|
||||
"description": "Report Invariant TSC bit in CPUID for Intel CPU type.",
|
||||
"category": "Compatibility",
|
||||
"wine": false,
|
||||
"wine": true,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
@@ -1882,7 +1910,7 @@
|
||||
},
|
||||
{
|
||||
"name": "BOX64_SHOWSEGV",
|
||||
"description": "Always show SIGSEGV signal detailes.",
|
||||
"description": "Always show SIGSEGV signal details.",
|
||||
"category": "Debugging",
|
||||
"wine": false,
|
||||
"options": [
|
||||
@@ -1893,7 +1921,7 @@
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Always show SIGSEGV signal detailes.",
|
||||
"description": "Always show SIGSEGV signal details.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -1911,7 +1939,7 @@
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Apply SSE Flush to 0 flag directly. Also reflect SSE exception flags in Dynarec (if available)",
|
||||
"description": "Apply SSE Flush to 0 flag directly. Also reflect SSE exception flags in DynaRec (if available)",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
@@ -2241,7 +2269,7 @@
|
||||
},
|
||||
{
|
||||
"name": "BOX64_X87_NO80BITS",
|
||||
"description": "Behavoiur of x87 80bits long double.",
|
||||
"description": "Behaviour of x87 80bits long double.",
|
||||
"category": "Compatibility",
|
||||
"wine": true,
|
||||
"options": [
|
||||
@@ -2256,5 +2284,23 @@
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BOX64_NOPERSONA32BITS",
|
||||
"description": "Disable the automatic switch of personality for 32-bit binaries (always enabled on Box32).",
|
||||
"category": "Compatibility",
|
||||
"wine": false,
|
||||
"options": [
|
||||
{
|
||||
"key": "0",
|
||||
"description": "Switch personality for 32-bit binaries (if not already tried).",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"description": "Do not switch personality for 32-bit binaries.",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,864 @@
|
||||
{
|
||||
"BOX64_ADDLIBS": {
|
||||
"description": "添加额外需要的共享库(这个选项不太常用)。",
|
||||
"options": {
|
||||
"XXXX": "将 XXXX 共享库添加到所需库列表。",
|
||||
"XXXX:YYYY:ZZZZ": "将 XXXX、YYYY 和 ZZZZ 共享库添加到所需库列表。"
|
||||
}
|
||||
},
|
||||
"BOX64_AES": {
|
||||
"description": "是否暴露 AES 能力。",
|
||||
"options": {
|
||||
"0": "不暴露 AES 能力。",
|
||||
"1": "暴露 AES 能力。"
|
||||
}
|
||||
},
|
||||
"BOX64_ALLOWMISSINGLIBS": {
|
||||
"description": "是否允许忽略缺失的共享库。",
|
||||
"options": {
|
||||
"0": "不允许忽略缺失的共享库。",
|
||||
"1": "允许忽略缺失的共享库。"
|
||||
}
|
||||
},
|
||||
"BOX64_ARCH": {
|
||||
"description": "在 rcfile 中指定当前条目适用的架构。此选项仅在 rcfile 中使用时生效。",
|
||||
"options": {
|
||||
"`arm64`": "仅对 AArch64 应用当前条目。",
|
||||
"`la64`": "仅对 LoongArch64 应用当前条目。",
|
||||
"`rv64`": "仅对 RISC-V 应用当前条目。",
|
||||
"`<empty>`": "对所有架构应用当前条目,但如果存在更具体的条目,当前条目将被替换。"
|
||||
}
|
||||
},
|
||||
"BOX64_ARGS": {
|
||||
"description": "传递给目标程序的参数,仅在没有任何已有参数时有效。",
|
||||
"options": {
|
||||
"XXXX": "将 XXXX 参数传递给目标程序。",
|
||||
"XXXX YYYY ZZZZ": "将 XXXX、YYYY 和 ZZZZ 参数传递给目标程序。"
|
||||
}
|
||||
},
|
||||
"BOX64_AVX": {
|
||||
"description": "向 CPUID 和 cpuinfo 文件暴露 AVX 扩展。在 Arm64 和龙架构上默认值为 2,因为 DynaRec 已完全实现,其他架构默认为 0。",
|
||||
"options": {
|
||||
"0": "不暴露 AVX 能力。",
|
||||
"1": "向 CPUID 和 cpuinfo 文件暴露 AVX、BMI1、F16C 和 VAES 扩展。",
|
||||
"2": "包含 1 的全部内容,外加 AVX2、BMI2、FMA、ADX、VPCLMULQDQ 和 RDRAND 扩展。"
|
||||
}
|
||||
},
|
||||
"BOX64_BASH": {
|
||||
"description": "用于指定 bash 可执行文件的路径。",
|
||||
"options": {
|
||||
"XXXX": "使用路径为 XXXX 的 bash 可执行文件。"
|
||||
}
|
||||
},
|
||||
"BOX64_CPUTYPE": {
|
||||
"description": "指定要模拟的 CPU 类型。",
|
||||
"options": {
|
||||
"0": "模拟某个 Intel CPU 型号。",
|
||||
"1": "模拟某个 AMD CPU 型号。"
|
||||
}
|
||||
},
|
||||
"BOX64_CRASHHANDLER": {
|
||||
"description": "是否使用模拟的 crashhandler.so 库。",
|
||||
"options": {
|
||||
"0": "在需要时使用模拟的 crashhandler.so 库。",
|
||||
"1": "使用内部定义的空 crashhandler.so 库。"
|
||||
}
|
||||
},
|
||||
"BOX64_DLSYM_ERROR": {
|
||||
"description": "启用或禁用 dlsym 错误的日志记录。",
|
||||
"options": {
|
||||
"0": "禁用 dlsym 错误的日志记录。",
|
||||
"1": "启用 dlsym 错误的日志记录。"
|
||||
}
|
||||
},
|
||||
"BOX64_DUMP": {
|
||||
"description": "是否输出 elfloader 调试信息。",
|
||||
"options": {
|
||||
"0": "不输出 elfloader 调试信息。",
|
||||
"1": "输出 elfloader 调试信息。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC": {
|
||||
"description": "启用或禁用动态重编译器(DynaRec)。如果在支持的架构上构建时开启了 DynaRec 支持,则默认为 1。",
|
||||
"options": {
|
||||
"0": "禁用 DynaRec。",
|
||||
"1": "启用 DynaRec。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_ALIGNED_ATOMICS": {
|
||||
"description": "仅生成对齐的原子操作(目前仅在 Arm64 上可用)。",
|
||||
"options": {
|
||||
"0": "生成非对齐原子操作处理代码。",
|
||||
"1": "仅生成对齐的原子操作,代码更快更小,但在非对齐数据地址上执行 LOCK 前缀指令时会导致 SIGBUS。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_BIGBLOCK": {
|
||||
"description": "尝试构建更大的代码块以提高性能。",
|
||||
"options": {
|
||||
"0": "不尝试构建尽可能大的代码块,适用于使用大量线程和 JIT 的程序(如 Unity)。",
|
||||
"1": "尽可能构建大的代码块。",
|
||||
"2": "构建更大的代码块,代码块重叠时不停止,但仅针对 elf 内存中的代码块。",
|
||||
"3": "构建更大的代码块,代码块重叠时不停止,适用于所有类型的内存,因此也对 wine 程序有用。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_BLEEDING_EDGE": {
|
||||
"description": "检测 MonoBleedingEdge 并应用保守设置(仅 Linux)。",
|
||||
"options": {
|
||||
"0": "不检测 MonoBleedingEdge。",
|
||||
"1": "检测 MonoBleedingEdge,并在检测到时应用 BOX64_DYNAREC_BIGBLOCK=0 和 BOX64_DYNAREC_强内存模型=1。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_CALLRET": {
|
||||
"description": "优化 CALL/RET 指令。",
|
||||
"options": {
|
||||
"0": "不优化 CALL/RET,使用跳转表。",
|
||||
"1": "尝试优化 CALL/RET,在可能的情况下跳过跳转表。",
|
||||
"2": "尝试优化 CALL/RET,在可能的情况下跳过跳转表,同时增加对返回到脏/已修改代码块的代码的处理。在 WowBox64 上不可用。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_SEP": {
|
||||
"description": "使用二级入口点(SEP)进一步优化 CALL/RET。如果 CALLRET 未启用则无效。",
|
||||
"options": {
|
||||
"0": "不在 CALLRET 返回时添加 SEP。",
|
||||
"1": "在 CALLRET 返回时添加 SEP,仅针对来自已知二进制文件的内存。",
|
||||
"2": "在 CALLRET 返回时添加 SEP,适用于所有类型的内存。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_DF": {
|
||||
"description": "启用或禁用延迟 FLAGS 的使用。",
|
||||
"options": {
|
||||
"0": "禁用延迟 FLAGS 的使用。",
|
||||
"1": "启用延迟 FLAGS 的使用。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_DIRTY": {
|
||||
"description": "是否允许继续运行未受保护且可能已脏的代码块。",
|
||||
"options": {
|
||||
"0": "不允许继续运行未受保护且可能已脏的代码块。",
|
||||
"1": "允许继续运行在与代码相同页面中写入数据的代码块,可以加快某些游戏的加载时间,但也可能导致意外崩溃。",
|
||||
"2": "除了 1 之外,当检测到热页时,将该页面标记为永不写保护,但基于该页面构建的代码块将始终被测试。这样可以更快(但某些 SMC 情况可能无法捕获)。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_NOHOTPAGE": {
|
||||
"description": "是否禁用热页检测(即代码执行和数据写入同时发生的页面)。",
|
||||
"options": {
|
||||
"0": "检测热页。",
|
||||
"1": "不检测热页。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_DIV0": {
|
||||
"description": "启用或禁用除零异常的生成。",
|
||||
"options": {
|
||||
"0": "不生成除零异常。",
|
||||
"1": "生成除零异常。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_DUMP": {
|
||||
"description": "启用 DynaRec 转储。",
|
||||
"options": {
|
||||
"0": "不转储代码块。",
|
||||
"1": "转储代码块。",
|
||||
"2": "转储代码块并带有颜色。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_DUMP_RANGE": {
|
||||
"description": "转储指定范围内的代码块。",
|
||||
"options": {
|
||||
"0xXXXXXXXX-0xYYYYYYYY": "定义代码块 被转储的范围(左闭右开)。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_FASTNAN": {
|
||||
"description": "启用或禁用快速 NaN 处理。",
|
||||
"options": {
|
||||
"0": "精确模拟 x86 上的 -NaN 生成。",
|
||||
"1": "不对 -NaN 生成做任何特殊处理,速度更快。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_FASTROUND": {
|
||||
"description": "启用或禁用快速舍入。",
|
||||
"options": {
|
||||
"0": "生成 float/double -> int 舍入,并使用当前舍入模式进行 float/double 计算,类似 x86。",
|
||||
"1": "不对边缘情况的舍入做任何特殊处理,速度更快。",
|
||||
"2": "使用当前舍入模式生成 float/double -> int 舍入(类似 x86),但使用快速的 int -> float/double 转换。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_FORWARD": {
|
||||
"description": "定义构建代码块时允许的最大前向跳转值。",
|
||||
"options": {
|
||||
"0": "无前向跳转值。当前代码块结束时,即使存在之前的前向跳转也不尝试继续前进。",
|
||||
"128": "允许代码块结束与下一个前向跳转之间最多 128 字节的间隙。",
|
||||
"XXXX": "允许代码块结束与下一个前向跳转之间最多 XXXX 字节的间隙。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_GDBJIT": {
|
||||
"description": "GDBJIT 调试支持,仅在使用 `-DGDBJIT=ON` 构建时可用,通过 gdb 命令启用:jit-reader-load /usr/local/lib/libbox64gdbjitreader.so。",
|
||||
"options": {
|
||||
"0": "DynaRec 不会生成 GDBJIT 调试信息。",
|
||||
"1": "DynaRec 将生成 GDBJIT 调试信息。",
|
||||
"2": "DynaRec 将生成包含内部状态的详细 GDBJIT 调试信息。",
|
||||
"3": "DynaRec 将仅对目标程序陷入的代码块 注册详细的 GDBJIT 调试信息,大幅提升性能。",
|
||||
"0xXXXXXXX-0xYYYYYYY": "定义 DynaRec 将生成包含内部状态的详细 GDBJIT 调试信息的范围。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_LOG": {
|
||||
"description": "禁用或启用 DynaRec 日志。",
|
||||
"options": {
|
||||
"0": "禁用 DynaRec 日志。",
|
||||
"1": "启用最小级别的 DynaRec 日志。",
|
||||
"2": "启用调试级别的 DynaRec 日志。",
|
||||
"3": "启用详细级别的 DynaRec 日志。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_MISSING": {
|
||||
"description": "打印缺失的指令。",
|
||||
"options": {
|
||||
"0": "不打印缺失的指令。",
|
||||
"1": "打印缺失的指令。",
|
||||
"2": "打印回退到标量指令的信息,仅对 RISC-V 有效。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_NATIVEFLAGS": {
|
||||
"description": "启用或禁用原生FLAGS的使用。",
|
||||
"options": {
|
||||
"0": "不使用原生FLAGS。",
|
||||
"1": "在可能的情况下使用原生FLAGS。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_NOHOSTEXT": {
|
||||
"description": "禁用可选的主机扩展。",
|
||||
"options": {
|
||||
"0": "不禁用任何扩展。",
|
||||
"1": "禁用所有可选扩展。",
|
||||
"xxx,yyy,zzz": "禁用指定的可选扩展,可选项包括 Arm:`crc32,pmull,aes,atomics,sha1,sha2,uscat,flagm,flagm2,frintts,afp,rndr`,LoongArch:`lasx,lbt,frecipe,lam_bh,lamcas,scq`,以及 RISC-V:`zba,zbb,zbc,zbs,vector,xtheadba,xtheadbb,xtheadbs,xtheadmemidx,xtheadmempair,xtheadcondmov`。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_PAUSE": {
|
||||
"description": "启用 x86 PAUSE 模拟,可能有助于自旋锁的性能。",
|
||||
"options": {
|
||||
"0": "忽略 x86 PAUSE 指令。",
|
||||
"1": "使用 YIELD 模拟 x86 PAUSE 指令。",
|
||||
"2": "使用 WFI 模拟 x86 PAUSE 指令。",
|
||||
"3": "使用 SEVL+WFE 模拟 x86 PAUSE 指令。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_PERFMAP": {
|
||||
"description": "为 Linux perf 工具生成映射文件。",
|
||||
"options": {
|
||||
"0": "DynaRec 不会生成 perf 映射。",
|
||||
"1": "DynaRec 将生成 perf 映射。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_PURGE": {
|
||||
"description": "根据年龄阈值(BOX64_DYNAREC_PURGE_AGE)清除最近未执行的代码块。",
|
||||
"options": {
|
||||
"0": "DynaRec 不会清除旧的未使用代码块。",
|
||||
"1": "DynaRec 将根据年龄阈值清除旧的未使用代码块。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_PURGE_AGE": {
|
||||
"description": "代码块清除的年龄阈值(需要 BOX64_DYNAREC_PURGE=1)。",
|
||||
"options": {
|
||||
"4096": "默认年龄阈值。",
|
||||
"XXXX": "自定义年龄阈值(范围:10-65536)。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_SAFEFLAGS": {
|
||||
"description": "在 CALL/RET 指令和其他边缘情况下 FLAGS 模拟的行为。",
|
||||
"options": {
|
||||
"0": "将 CALL/RET 标记为从不需要任何 FLAGS。",
|
||||
"1": "将大多数 RET 标记为需要 FLAGS,将大多数 CALL 标记为不需要。",
|
||||
"2": "将所有 CALL/RET 都标记为需要 FLAGS。同时也处理所有边缘情况。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_STRONGMEM": {
|
||||
"description": "开启或关闭 x86 强内存模型的模拟。",
|
||||
"options": {
|
||||
"0": "不做任何特殊处理。",
|
||||
"1": "在写入内存时启用以有限方式模拟 x86 强内存模型的内存屏障。",
|
||||
"2": "包含 1 的全部内容,外加 SIMD 指令的内存屏障。",
|
||||
"3": "包含 2 的全部内容,外加定期添加更多内存屏障。",
|
||||
"4": "模仿 x86 TSO,类似 QEMU 的方法,可用于评估目的。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_TBB": {
|
||||
"description": "启用或禁用 libtbb 检测。",
|
||||
"options": {
|
||||
"0": "不检测 libtbb。",
|
||||
"1": "检测 libtbb 并应用保守设置。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_TEST": {
|
||||
"description": "启用 DynaRec 与解释器的执行对比,非常慢,仅用于测试。",
|
||||
"options": {
|
||||
"0": "不进行对比。",
|
||||
"1": "每个指令都在解释器和 DynaRec 上运行,当寄存器或内存不同时进行对比并打印。",
|
||||
"0xXXXXXXXX-0xYYYYYYYY": "定义 DynaRec 测试的范围(左闭右开)。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_TEST_NODUP": {
|
||||
"description": "启用 COSIM 发现差异的 IP 地址去重。",
|
||||
"options": {
|
||||
"0": "显示所有出错的地址。",
|
||||
"1": "每个出错地址仅显示一次,即使转储可能不同。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_TEST_NODUMP": {
|
||||
"description": "当 BOX64_DYNAREC_DUMP 启用时不转储测试代码。",
|
||||
"options": {
|
||||
"0": "转储测试代码。",
|
||||
"1": "不转储测试代码。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_TRACE": {
|
||||
"description": "启用或禁用 DynaRec 追踪。",
|
||||
"options": {
|
||||
"0": "不追踪代码块。",
|
||||
"1": "追踪代码块,会大幅降低程序速度并生成大量日志。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_VOLATILE_METADATA": {
|
||||
"description": "使用从 PE 文件解析的 volatile 元数据,仅对 64 位 Windows 游戏有效。",
|
||||
"options": {
|
||||
"0": "不使用 volatile 元数据。",
|
||||
"1": "使用 volatile 元数据,将指导 Box64 进行更好的强内存模拟。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_WAIT": {
|
||||
"description": "是否等待代码块构建完成。",
|
||||
"options": {
|
||||
"0": "不等待,改用解释器,可能在大量多线程或 JIT 程序上略微加速。",
|
||||
"1": "等待代码块构建完成。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_WEAKBARRIER": {
|
||||
"description": "调整内存屏障以减少强内存模拟的性能影响。",
|
||||
"options": {
|
||||
"0": "使用常规安全屏障。",
|
||||
"1": "使用弱屏障以获得更多性能提升。",
|
||||
"2": "包含 1 的全部内容,外加禁用最后的写屏障。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_X87DOUBLE": {
|
||||
"description": "强制使用 float/double 进行 x87 模拟。",
|
||||
"options": {
|
||||
"0": "尝试在可能的情况下对 x87 模拟使用 float。",
|
||||
"1": "仅对 x87 模拟使用 Double。",
|
||||
"2": "在 x87 模拟中检查精度控制的低精度。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_INTERP_SIGNAL": {
|
||||
"description": "允许在信号处理器中使用 DynaRec。",
|
||||
"options": {
|
||||
"0": "允许在信号处理器中使用 DynaRec。",
|
||||
"1": "仅在信号处理器中使用解释器(与 v0.3.8 及更早版本相同)。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNACACHE": {
|
||||
"description": "启用或禁用动态重编译器缓存(DynaCache)。此选项默认为 2(读取已有缓存但不生成新的)。DynaCache 默认将文件写入 home 文件夹,生成新缓存文件时会根据 BOX64_DYNACACHE_LIMIT 控制文件夹大小。",
|
||||
"options": {
|
||||
"0": "禁用 DynaCache。",
|
||||
"1": "启用 DynaCache。",
|
||||
"2": "使用已有的 DynaCache 文件,但不生成新的。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNACACHE_FOLDER": {
|
||||
"description": "设置 DynaCache 文件的文件夹。默认为 $XDG_CACHE_HOME/box64,如果 $XDG_CACHE_HOME 未设置则为 $HOME/.cache/box64。",
|
||||
"options": {
|
||||
"XXXX": "使用文件夹 XXXX 存储 DynaCache 文件。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNACACHE_LIMIT": {
|
||||
"description": "DynaCache 文件夹的最大大小(MiB)。超过限制时,会先删除无效的 DynaCache 文件,如仍超限再删除最旧的有效文件。默认大小为 2048MiB。",
|
||||
"options": {
|
||||
"0": "不限制 DynaCache 文件夹大小。",
|
||||
"XXXX": "先删除无效缓存文件,如仍超限再删除最旧的有效缓存文件,将 DynaCache 文件夹保持在 XXXX MiB 以下。",
|
||||
"2048": "默认值为 2048 MiB。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNACACHE_COMPRESS": {
|
||||
"description": "设置是否压缩磁盘上的 DynaCache 文件。",
|
||||
"options": {
|
||||
"0": "不压缩 DynaCache 文件。",
|
||||
"1": "使用 Zlib 最快压缩级别压缩 DynaCache 文件。",
|
||||
"2": "使用 Zlib 默认压缩级别压缩 DynaCache 文件。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNACACHE_MIN": {
|
||||
"description": "DynaCache 写入磁盘的最小大小(KB)。默认大小为 350KB。",
|
||||
"options": {
|
||||
"XXXX": "设置将缓存写入磁盘的最小 DynaRec 代码大小(XXXX KB),小于此值将不会保存到磁盘。",
|
||||
"350": "默认值为 350 KB。"
|
||||
}
|
||||
},
|
||||
"BOX64_EMULATED_LIBS": {
|
||||
"description": "强制使用模拟库。",
|
||||
"options": {
|
||||
"XXXX": "强制使用模拟库 XXXX。",
|
||||
"XXXX:YYYY:ZZZZ": "强制使用模拟库 XXXX、YYYY 和 ZZZZ。"
|
||||
}
|
||||
},
|
||||
"BOX64_ENV": {
|
||||
"description": "添加环境变量。",
|
||||
"options": {
|
||||
"XXXX=yyyy": "添加值为 yyyy 的环境变量 XXXX。"
|
||||
}
|
||||
},
|
||||
"BOX64_ENV[1-5]": {
|
||||
"description": "添加环境变量。",
|
||||
"options": {
|
||||
"XXXX=yyyy": "添加值为 yyyy 的环境变量 XXXX。"
|
||||
}
|
||||
},
|
||||
"BOX64_EXIT": {
|
||||
"description": "直接退出,不运行程序。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "直接退出。"
|
||||
}
|
||||
},
|
||||
"BOX64_FIX_64BIT_INODES": {
|
||||
"description": "修复 64 位 inode。",
|
||||
"options": {
|
||||
"0": "不修复 64 位 inode。",
|
||||
"1": "修复 64 位 inode。"
|
||||
}
|
||||
},
|
||||
"BOX64_FORCE_LD_PRELOAD": {
|
||||
"description": "是否强制 BOX64_LD_PRELOAD 库中的符号通过 RTLD_NEXT 解析。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "强制 BOX64_LD_PRELOAD 库中的符号通过 RTLD_NEXT 解析。"
|
||||
}
|
||||
},
|
||||
"BOX64_IGNOREINT3": {
|
||||
"description": "忽略 INT3 指令。",
|
||||
"options": {
|
||||
"0": "如果存在处理器则触发 TRAP 信号。",
|
||||
"1": "静默跳过该指令。"
|
||||
}
|
||||
},
|
||||
"BOX64_INSERT_ARGS": {
|
||||
"description": "在命令行前添加参数。",
|
||||
"options": {
|
||||
"XXXX": "在程序前添加参数 XXXX。",
|
||||
"XXXX YYYY ZZZZ": "在目标程序前添加参数 XXXX、YYYY 和 ZZZZ。"
|
||||
}
|
||||
},
|
||||
"BOX64_INPROCESSGPU": {
|
||||
"description": "向目标程序添加 --in-process-gpu 参数。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "向目标程序添加 --in-process-gpu 参数。"
|
||||
}
|
||||
},
|
||||
"BOX64_JITGDB": {
|
||||
"description": "发生 SIGSEGV、SIGILL 和 SIGBUS 时是否启动 gdb。",
|
||||
"options": {
|
||||
"0": "捕获信号时仅打印消息。",
|
||||
"1": "当捕获到 SIGSEGV、SIGILL 或 SIGBUS 信号时启动 gdb,附加到有问题的进程并进入无限循环等待。在 gdb 中,你需要自己找到正确的线程(在其堆栈中有 `my_box64signalhandler` 的线程),然后可能需要 `finish` 1 或 2 个函数(在 `usleep(..)` 内部),之后你将进入 `my_box64signalhandler`,就在 Segfault 消息的 printf 之前。然后 `set waiting=0` 退出无限循环。",
|
||||
"2": "当捕获到 SIGSEGV、SIGILL 或 SIGBUS 信号时启动 gdbserver,附加到有问题的进程,并进入无限循环等待。使用 `gdb /PATH/TO/box64` 然后 `target remote 127.0.0.1:1234` 连接到 gdbserver(如果不在本机,则使用实际 IP)。之后的操作步骤与 `BOX64_JITGDB=1` 相同。",
|
||||
"3": "当捕获到 SIGSEGV、SIGILL 或 SIGBUS 信号时启动 lldb,附加到有问题的进程并进入无限循环等待。"
|
||||
}
|
||||
},
|
||||
"BOX64_JVM": {
|
||||
"description": "检测 libjvm 并应用保守设置。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "检测 libjvm,并在检测到时应用 BOX64_DYNAREC_BIGBLOCK=0 BOX64_DYNAREC_强内存模型=1 BOX64_SSE42=0。"
|
||||
}
|
||||
},
|
||||
"BOX64_LD_LIBRARY_PATH": {
|
||||
"description": "查找 x86_64 库的路径。",
|
||||
"options": {
|
||||
"XXXX": "将路径 XXXX 添加到库搜索路径。"
|
||||
}
|
||||
},
|
||||
"BOX64_LD_PRELOAD": {
|
||||
"description": "强制随二进制文件加载库。",
|
||||
"options": {
|
||||
"XXXX": "强制加载库 XXXX。",
|
||||
"XXXX:YYYY": "强制加载库 XXXX 和 YYYY。"
|
||||
}
|
||||
},
|
||||
"BOX64_LIBCEF": {
|
||||
"description": "检测 libcef 并应用 BOX64_MALLOC_HACK 设置。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "检测 libcef,并在检测到时应用 BOX64_MALLOC_HACK=2。"
|
||||
}
|
||||
},
|
||||
"BOX64_LIBGL": {
|
||||
"description": "设置 libGL 的名称。",
|
||||
"options": {
|
||||
"libXXXX": "将 libGL 的名称设置为 libXXXX。",
|
||||
"/path/to/libXXXX": "将 libGL 的名称和路径设置为 /path/to/libXXXX,你也可以使用 SDL_VIDEO_GL_DRIVER。"
|
||||
}
|
||||
},
|
||||
"BOX64_LOAD_ADDR": {
|
||||
"description": "设置程序加载的地址,仅对 PIE 目标程序有效。",
|
||||
"options": {
|
||||
"0xXXXXXXXX": "设置程序加载的地址。"
|
||||
}
|
||||
},
|
||||
"BOX64_LOG": {
|
||||
"description": "启用或禁用 Box64 日志,如果 stdout 不是终端则默认为 0,否则为 1。",
|
||||
"options": {
|
||||
"0": "禁用 Box64 日志。",
|
||||
"1": "启用最小级别的 Box64 日志。",
|
||||
"2": "启用调试级别的 Box64 日志。",
|
||||
"3": "启用详细级别的 Box64 日志。"
|
||||
}
|
||||
},
|
||||
"BOX64_MALLOC_HACK": {
|
||||
"description": "挂钩 malloc 操作符时的行为。",
|
||||
"options": {
|
||||
"0": "不允许重定向 malloc 操作符,重写代码使用常规函数。",
|
||||
"1": "允许重定向 malloc 操作符。",
|
||||
"2": "与 0 类似,但追踪特殊的 mmap/free(某些内联的重定向函数无法被重定向)。"
|
||||
}
|
||||
},
|
||||
"BOX64_MAXCPU": {
|
||||
"description": "暴露的最大 CPU 核心数。",
|
||||
"options": {
|
||||
"0": "使用实际的 CPU 核心数。",
|
||||
"XXXX": "使用 XXXX 个 CPU 核心。"
|
||||
}
|
||||
},
|
||||
"BOX64_MMAP32": {
|
||||
"description": "在运行 32 位代码的 64 位程序(如 Wine WOW64)上强制使用 32 位兼容的内存映射,可提高性能。",
|
||||
"options": {
|
||||
"0": "不强制使用 32 位内存映射。",
|
||||
"1": "强制使用 32 位内存映射。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOBANNER": {
|
||||
"description": "禁用 Box64 横幅。",
|
||||
"options": {
|
||||
"0": "显示 Box64 横幅。",
|
||||
"1": "不显示 Box64 横幅。"
|
||||
}
|
||||
},
|
||||
"BOX64_NODYNAREC": {
|
||||
"description": "在指定的地址范围内禁止创建代码块,有助于调试 DynaRec 和解释器之间的行为差异。",
|
||||
"options": {
|
||||
"0xXXXXXXXX-0xYYYYYYYY": "定义禁止创建代码块 的范围(左闭右开)。"
|
||||
}
|
||||
},
|
||||
"BOX64_NODYNAREC_DELAY": {
|
||||
"description": "延迟后移除 NoDynaRec 范围。",
|
||||
"options": {
|
||||
"0": "不移除 NoDynaRec 范围。",
|
||||
"1": "创建 2 个线程后移除 NoDynaRec 范围。"
|
||||
}
|
||||
},
|
||||
"BOX64_DYNAREC_NOARCH": {
|
||||
"description": "从代码块中移除架构元数据(在信号处理时使用)。",
|
||||
"options": {
|
||||
"0": "为每个代码块生成所有架构元数据,包括 x87/mmx/SSE/AVX 寄存器追踪。会使用更多内存。",
|
||||
"1": "仅生成每个代码块的必要元数据(FLAGS、对齐),节省一些内存,但某些加密软件可能会失败。",
|
||||
"2": "不为代码块生成元数据,进一步节省内存,但在信号处理时可能会失败。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOGTK": {
|
||||
"description": "不加载包装的 GTK 库。",
|
||||
"options": {
|
||||
"0": "加载包装的 GTK 库。",
|
||||
"1": "不加载包装的 GTK 库。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOPULSE": {
|
||||
"description": "不加载 PulseAudio 库(原生库和模拟库均不加载)。",
|
||||
"options": {
|
||||
"0": "加载 PulseAudio 库。",
|
||||
"1": "不加载 PulseAudio 库。"
|
||||
}
|
||||
},
|
||||
"BOX64_NORCFILES": {
|
||||
"description": "不加载任何 rc 文件。",
|
||||
"options": {
|
||||
"0": "加载 rc 文件。",
|
||||
"1": "不加载任何 rc 文件。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOSANDBOX": {
|
||||
"description": "向目标程序添加 --no-sandbox 参数。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "向目标程序添加 --no-sandbox 参数。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOSIGSEGV": {
|
||||
"description": "禁用 SIGSEGV 的处理。",
|
||||
"options": {
|
||||
"0": "允许 x86 程序为 SIGSEGV 设置信号处理器。",
|
||||
"1": "禁用 SIGSEGV 的处理。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOSIGILL": {
|
||||
"description": "禁用 SIGILL 的处理。",
|
||||
"options": {
|
||||
"0": "允许 x86 程序为 SIGILL 设置信号处理器。",
|
||||
"1": "禁用 SIGILL 的处理。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOVULKAN": {
|
||||
"description": "不加载 Vulkan 库。",
|
||||
"options": {
|
||||
"0": "加载 Vulkan 库。",
|
||||
"1": "不加载 Vulkan 库,原生库和模拟库均不加载。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOVULKANOVERLAY": {
|
||||
"description": "不加载 x64 Vulkan 覆盖层。",
|
||||
"options": {
|
||||
"0": "尝试加载 x64 Vulkan 覆盖层。",
|
||||
"1": "不加载 x64 Vulkan 覆盖层。"
|
||||
}
|
||||
},
|
||||
"BOX64_PATH": {
|
||||
"description": "查找 x86_64 二进制文件的路径。",
|
||||
"options": {
|
||||
"XXXX": "将路径 XXXX 添加到二进制搜索路径。"
|
||||
}
|
||||
},
|
||||
"BOX64_PCLMULQDQ": {
|
||||
"description": "暴露 PCLMULQDQ 能力。",
|
||||
"options": {
|
||||
"0": "不暴露 PCLMULQDQ 能力。",
|
||||
"1": "暴露 PCLMULQDQ 能力。"
|
||||
}
|
||||
},
|
||||
"BOX64_PREFER_EMULATED": {
|
||||
"description": "优先使用模拟库而非原生库。",
|
||||
"options": {
|
||||
"0": "优先使用原生库而非模拟库。",
|
||||
"1": "优先使用模拟库而非原生库。"
|
||||
}
|
||||
},
|
||||
"BOX64_PREFER_WRAPPED": {
|
||||
"description": "即使库使用绝对路径指定,也优先使用包装库。",
|
||||
"options": {
|
||||
"0": "优先使用绝对路径指定的库而非包装库。",
|
||||
"1": "即使库使用绝对路径指定,也优先使用包装库。"
|
||||
}
|
||||
},
|
||||
"BOX64_PROFILE": {
|
||||
"description": "预定义的环境变量集合,以兼容性或性能为导向。",
|
||||
"options": {
|
||||
"safest": "禁用所有不安全的 DynaRec 优化的配置文件。",
|
||||
"safe": "比 safest 略不安全。",
|
||||
"default": "大多数程序都能正常运行且性能适中的默认设置。",
|
||||
"fast": "启用许多不安全的优化,但同时启用 强内存模型 模拟。",
|
||||
"fastest": "启用许多不安全的优化以获得更好的性能。"
|
||||
}
|
||||
},
|
||||
"BOX64_PYTHON3": {
|
||||
"description": "python3 可执行文件的路径。",
|
||||
"options": {
|
||||
"XXXX": "使用路径为 XXXX 的 python3 可执行文件。"
|
||||
}
|
||||
},
|
||||
"BOX64_RCFILE": {
|
||||
"description": "要加载的 rc 文件路径。",
|
||||
"options": {
|
||||
"XXXX": "加载 rc 文件 XXXX,不会加载默认的 rc 文件。"
|
||||
}
|
||||
},
|
||||
"BOX64_RDTSC_1GHZ": {
|
||||
"description": "如果可用,使用硬件计数器实现 rdtsc。",
|
||||
"options": {
|
||||
"0": "如果可用,使用硬件计数器实现 rdtsc 指令。",
|
||||
"1": "仅当精度至少为 1GHz 时,使用硬件计数器实现 rdtsc。"
|
||||
}
|
||||
},
|
||||
"BOX64_RDTSC_INV": {
|
||||
"description": "在 Intel CPU 类型的 CPUID 中报告 Invariant TSC 位。",
|
||||
"options": {
|
||||
"0": "不为 Intel CPU 类型报告 Invariant TSC(默认)。",
|
||||
"1": "在 Intel CPU 类型的 CPUID leaf 0x80000007 中报告 Invariant TSC 位。"
|
||||
}
|
||||
},
|
||||
"BOX64_RESERVE_HIGH": {
|
||||
"description": "为程序保留高内存区域,在 Box32 上始终启用。",
|
||||
"options": {
|
||||
"0": "不为程序保留高内存区域。",
|
||||
"1": "为程序保留高内存区域。"
|
||||
}
|
||||
},
|
||||
"BOX64_ROLLING_LOG": {
|
||||
"description": "当捕获信号时显示最近几个包装函数调用。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "捕获信号时显示最近 16 个包装函数调用。",
|
||||
"XXXX": "捕获信号时显示最近 XXXX 个包装函数调用。"
|
||||
}
|
||||
},
|
||||
"BOX64_SDL2_JGUID": {
|
||||
"description": "对包装的 SDL2 使用 SDL_GetJoystickGUIDInfo 函数的变通方案。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "对包装的 SDL2 使用 SDL_GetJoystickGUIDInfo 函数的变通方案。"
|
||||
}
|
||||
},
|
||||
"BOX64_SHAEXT": {
|
||||
"description": "暴露 SHAEXT(即 SHA_NI)能力。",
|
||||
"options": {
|
||||
"0": "不暴露 SHAEXT 能力。",
|
||||
"1": "暴露 SHAEXT 能力。"
|
||||
}
|
||||
},
|
||||
"BOX64_SHOWBT": {
|
||||
"description": "捕获信号时显示原生和模拟的回溯。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "捕获信号时显示原生和模拟的回溯。"
|
||||
}
|
||||
},
|
||||
"BOX64_SHOWSEGV": {
|
||||
"description": "始终显示 SIGSEGV 信号详情。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "始终显示 SIGSEGV 信号详情。"
|
||||
}
|
||||
},
|
||||
"BOX64_SSE_FLUSHTO0": {
|
||||
"description": "SSE Flush to 0 FLAGS的行为,同时追踪 SSE 异常FLAGS。",
|
||||
"options": {
|
||||
"0": "仅追踪FLAGS。",
|
||||
"1": "直接应用 SSE Flush to 0 FLAGS。同时在 DynaRec 中反映 SSE 异常FLAGS(如果可用)。"
|
||||
}
|
||||
},
|
||||
"BOX64_SSE42": {
|
||||
"description": "暴露 SSE4.2 能力。",
|
||||
"options": {
|
||||
"0": "不暴露 SSE4.2 能力。",
|
||||
"1": "暴露 SSE4.2 能力。"
|
||||
}
|
||||
},
|
||||
"BOX64_STEAM_VULKAN": {
|
||||
"description": "为 Linux Steam UI 强制使用 Vulkan。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "为 Linux Steam UI 强制使用 Vulkan。"
|
||||
}
|
||||
},
|
||||
"BOX64_SYNC_ROUNDING": {
|
||||
"description": "在 x86 和原生之间同步舍入模式。",
|
||||
"options": {
|
||||
"0": "不同步舍入模式。",
|
||||
"1": "在 x86 和原生之间同步舍入模式。"
|
||||
}
|
||||
},
|
||||
"BOX64_TRACE_COLOR": {
|
||||
"description": "启用或禁用彩色追踪输出。",
|
||||
"options": {
|
||||
"0": "禁用彩色追踪输出。",
|
||||
"1": "启用彩色追踪输出。"
|
||||
}
|
||||
},
|
||||
"BOX64_TRACE_EMM": {
|
||||
"description": "启用或禁用 EMM(即 MMX)追踪输出。",
|
||||
"options": {
|
||||
"0": "禁用 EMM 追踪输出。",
|
||||
"1": "启用 EMM 追踪输出。"
|
||||
}
|
||||
},
|
||||
"BOX64_TRACE_FILE": {
|
||||
"description": "将所有日志和追踪发送到文件而非 `stdout`。",
|
||||
"options": {
|
||||
"XXXX": "将所有日志和追踪发送到文件 XXXX。",
|
||||
"XXXX%pid": "将所有日志和追踪发送到文件 XXXX,文件名中附加 pid。",
|
||||
"stderr": "将所有日志和追踪发送到 `stderr`。",
|
||||
"stdout": "将所有日志和追踪发送到 `stdout`。"
|
||||
}
|
||||
},
|
||||
"BOX64_TRACE_INIT": {
|
||||
"description": "与 BOX64_TRACE 相同,但立即开始追踪。",
|
||||
"options": {
|
||||
"0": "禁用追踪输出。",
|
||||
"1": "启用追踪输出。追踪在依赖项初始化之前开始。",
|
||||
"symbolname": "仅对 `symbolname` 启用追踪输出。追踪在依赖项初始化之前开始。",
|
||||
"0xXXXXXXX-0xYYYYYYY": "对指定地址范围(左闭右开)启用追踪输出。追踪在依赖项初始化之前开始。"
|
||||
}
|
||||
},
|
||||
"BOX64_TRACE_START": {
|
||||
"description": "在 N 个指令执行后开始追踪。",
|
||||
"options": {
|
||||
"0": "立即开始追踪。",
|
||||
"1": "执行 1 个指令后开始追踪。",
|
||||
"XXXX": "执行 XXXX 个指令后开始追踪。"
|
||||
}
|
||||
},
|
||||
"BOX64_TRACE_XMM": {
|
||||
"description": "启用或禁用 XMM(即 SSE)追踪输出。",
|
||||
"options": {
|
||||
"0": "禁用 XMM 追踪输出。",
|
||||
"1": "启用 XMM 追踪输出。"
|
||||
}
|
||||
},
|
||||
"BOX64_TRACE": {
|
||||
"description": "仅在带追踪功能的 box64 构建中可用。添加所有执行指令的追踪以及寄存器转储。",
|
||||
"options": {
|
||||
"0": "禁用追踪输出。",
|
||||
"1": "启用追踪输出。",
|
||||
"symbolname": "仅对 `symbolname` 启用追踪输出。",
|
||||
"0xXXXXXXX-0xYYYYYYY": "对指定地址范围(左闭右开)启用追踪输出。"
|
||||
}
|
||||
},
|
||||
"BOX64_UNITYPLAYER": {
|
||||
"description": "检测 UnityPlayer 并应用保守设置。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "检测 UnityPlayer(Windows 或 Linux),并在检测到时应用 BOX64_UNITY=1。"
|
||||
}
|
||||
},
|
||||
"BOX64_UNITY": {
|
||||
"description": "告诉 Box64 这是一个 Unity 游戏。",
|
||||
"options": {
|
||||
"0": "不执行任何操作。",
|
||||
"1": "这是 Unity 游戏,对 Windows 使用特殊的检测代码,对 Linux 应用 BOX64_DYNAREC_强内存模型=1。"
|
||||
}
|
||||
},
|
||||
"BOX64_WRAP_EGL": {
|
||||
"description": "优先使用包装库处理 EGL 和 GLESv2。",
|
||||
"options": {
|
||||
"0": "优先使用模拟库处理 EGL 和 GLESv2。",
|
||||
"1": "优先使用包装库处理 EGL 和 GLESv2。"
|
||||
}
|
||||
},
|
||||
"BOX64_X11GLX": {
|
||||
"description": "是否强制 Xorg GLX 扩展存在。",
|
||||
"options": {
|
||||
"0": "不强制 Xorg GLX 扩展存在。",
|
||||
"1": "在使用 XQueryExtension 时要求 Xorg GLX 扩展存在。"
|
||||
}
|
||||
},
|
||||
"BOX64_X11SYNC": {
|
||||
"description": "是否强制 X11 显示同步操作。",
|
||||
"options": {
|
||||
"0": "不强制 X11 显示同步操作。",
|
||||
"1": "强制 X11 显示同步操作。"
|
||||
}
|
||||
},
|
||||
"BOX64_X11THREADS": {
|
||||
"description": "加载 X11 时调用 XInitThreads。这主要用于使用 Loki_Compat 库的旧 Loki 游戏。",
|
||||
"options": {
|
||||
"0": "不调用 XInitThreads。",
|
||||
"1": "一旦加载 libX11 就调用 XInitThreads。"
|
||||
}
|
||||
},
|
||||
"BOX64_X87_NO80BITS": {
|
||||
"description": "x87 80 位 long double 的行为。",
|
||||
"options": {
|
||||
"0": "尝试尽可能精确地处理 80 位 long double。",
|
||||
"1": "对 x87 使用 64 位 double。"
|
||||
}
|
||||
},
|
||||
"BOX64_NOPERSONA32BITS": {
|
||||
"description": "禁用 32 位二进制文件的自动 personality 切换(在 Box32 上始终启用)。",
|
||||
"options": {
|
||||
"0": "为 32 位二进制文件切换 personality(如果尚未尝试)。",
|
||||
"1": "不为 32 位二进制文件切换 personality。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,9 @@
|
||||
#include "os.h"
|
||||
#include "box64context.h"
|
||||
#include "debug.h"
|
||||
#ifdef DYNAREC
|
||||
#include "dynablock.h"
|
||||
#endif
|
||||
#include "elfloader.h"
|
||||
#include "custommem.h"
|
||||
#include "threads.h"
|
||||
@@ -351,6 +354,10 @@ void FreeBox64Context(box64context_t** context)
|
||||
signal(i, SIG_DFL);
|
||||
}
|
||||
|
||||
#ifdef DYNAREC
|
||||
FlushZombieDynablocks(); // free all deferred-free dynablocks before my_context goes away
|
||||
#endif
|
||||
|
||||
*context = NULL; // bye bye my_context
|
||||
|
||||
CleanStackSize(ctx);
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@
|
||||
|
||||
#define BOX64_MAJOR 0
|
||||
#define BOX64_MINOR 4
|
||||
#define BOX64_REVISION 2
|
||||
#define BOX64_REVISION 3
|
||||
|
||||
#endif //__BOX64_VERSION_H_
|
||||
+44
-28
@@ -46,6 +46,7 @@
|
||||
#include "library.h"
|
||||
#include "core.h"
|
||||
#include "env.h"
|
||||
#include "dynacache.h"
|
||||
#include "cleanup.h"
|
||||
#include "freq.h"
|
||||
#include "hostext.h"
|
||||
@@ -225,7 +226,6 @@ static void displayMiscInfo(void)
|
||||
#if defined(LA64)
|
||||
if (box64env.avx && !cpuext.lasx) {
|
||||
box64env.avx = 0;
|
||||
box64env.avx2 = 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -424,8 +424,6 @@ static void addLibPaths(box64context_t* context)
|
||||
GO("libpng12.so.0");
|
||||
GO("libpng16.so.16");
|
||||
GO("libcurl.so.4");
|
||||
if(getenv("BOX64_PRESSURE_VESSEL_FILES")) // use emulated gnutls in this case, it's safer
|
||||
GO("libgnutls.so.30");
|
||||
GO("libtbbmalloc.so.2");
|
||||
GO("libtbbmalloc_proxy.so.2");
|
||||
GO("libicuuc.so.64");
|
||||
@@ -702,16 +700,14 @@ void endBox64()
|
||||
const int max_wait_ms = 2000; // 2s
|
||||
int waited_ms = 0;
|
||||
|
||||
printf_log(LOG_INFO, "endBox64: waiting emu workers to exit (n=%d)\n", workers);
|
||||
printf_log(LOG_DEBUG, "endBox64: waiting emu workers to exit (n=%d)\n", workers);
|
||||
while ((workers = get_active_emu_workers()) > 0 && waited_ms < max_wait_ms) {
|
||||
usleep(sleep_us);
|
||||
waited_ms += sleep_us / 1000;
|
||||
}
|
||||
|
||||
if (workers > 0) {
|
||||
printf_log(LOG_INFO,
|
||||
"endBox64: %d emu workers still alive after %dms, skip unload/free to avoid UAF crash\n",
|
||||
workers, waited_ms);
|
||||
printf_log(LOG_DEBUG, "endBox64: %d emu workers still alive after %dms, skip unload/free to avoid UAF crash\n", workers, waited_ms);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -834,13 +830,23 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf
|
||||
}
|
||||
if (!strcmp(prog, "-k") || !strcmp(prog, "--kill-all")) {
|
||||
KillAllInstances();
|
||||
#ifdef DYNAREC
|
||||
DetectHostCpuFeatures();
|
||||
#endif
|
||||
DynaCacheClean();
|
||||
exit(0);
|
||||
}
|
||||
if(!strcmp(prog, "--dynacache-list")) {
|
||||
#ifdef DYNAREC
|
||||
DetectHostCpuFeatures();
|
||||
#endif
|
||||
DynaCacheList(argv[nextarg+1]);
|
||||
exit(0);
|
||||
}
|
||||
if(!strcmp(prog, "--dynacache-clean")) {
|
||||
#ifdef DYNAREC
|
||||
DetectHostCpuFeatures();
|
||||
#endif
|
||||
DynaCacheClean();
|
||||
exit(0);
|
||||
}
|
||||
@@ -880,11 +886,11 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf
|
||||
{
|
||||
char* p = BOX64ENV(python3);
|
||||
if(p) {
|
||||
if(FileIsX64ELF(p)) {
|
||||
if(FileExist(p, IS_FILE)) {
|
||||
pythonpath = p;
|
||||
printf_log(LOG_INFO, "Using python3 \"%s\"\n", pythonpath);
|
||||
printf_log(LOG_INFO, "Using python helper \"%s\"\n", pythonpath);
|
||||
} else {
|
||||
printf_log(LOG_INFO, "The x86_64 python3 \"%s\" is not an x86_64 binary.\n", p);
|
||||
printf_log(LOG_INFO, "The python helper \"%s\" was not found.\n", p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -930,24 +936,6 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf
|
||||
}
|
||||
}
|
||||
box64_wine = 1;
|
||||
// check if it's proton, with it's custom gstreamer build, to disable gtk3 loading
|
||||
char tmp[strlen(prog)+100];
|
||||
strcpy(tmp, prog);
|
||||
char* pp = strrchr(tmp, '/');
|
||||
if(pp) {
|
||||
*pp = '\0'; // remove the wine binary call
|
||||
strcat(tmp, "/../lib64/gstreamer-1.0");
|
||||
// check if it exist
|
||||
if(FileExist(tmp, 0)) {
|
||||
box64_custom_gstreamer = box_strdup(tmp);
|
||||
} else {
|
||||
*pp = '\0';
|
||||
strcat(tmp, "/../lib/x86_64-linux-gnu/gstreamer-1.0");
|
||||
if(FileExist(tmp, 0)) {
|
||||
box64_custom_gstreamer = box_strdup(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try to get the name of the exe being run, to ApplyEnvFileEntry laters
|
||||
if(argv[nextarg+1] && argv[nextarg+1][0]!='-' && strlen(argv[nextarg+1])>4 /*&& !strcasecmp(argv[nextarg+1]+strlen(argv[nextarg+1])-4, ".exe")*/) {
|
||||
const char* pp = strrchr(argv[nextarg+1], '/');
|
||||
@@ -991,6 +979,30 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf
|
||||
my_context = NewBox64Context(argc - nextarg);
|
||||
|
||||
addLibPaths(my_context);
|
||||
if(box64_wine) {
|
||||
// check if it's proton, with it's custom gstreamer build, to disable gtk3 loading
|
||||
char* tmp_ = ResolveFile(prog_, &my_context->box64_path);
|
||||
if(tmp_) {
|
||||
char tmp[strlen(tmp_)+100];
|
||||
strcpy(tmp, tmp_);
|
||||
box_free(tmp_);
|
||||
char* pp = strrchr(tmp, '/');
|
||||
if(pp) {
|
||||
*pp = '\0'; // remove the wine binary call
|
||||
strcat(tmp, "/../lib64/gstreamer-1.0");
|
||||
// check if it exist
|
||||
if(FileExist(tmp, 0)) {
|
||||
box64_custom_gstreamer = box_strdup(tmp);
|
||||
} else {
|
||||
*pp = '\0';
|
||||
strcat(tmp, "/../lib/x86_64-linux-gnu/gstreamer-1.0");
|
||||
if(FileExist(tmp, 0)) {
|
||||
box64_custom_gstreamer = box_strdup(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Append ld_list if it exist
|
||||
if(ld_libs_args!=-1)
|
||||
@@ -1012,6 +1024,8 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf
|
||||
unsetenv("BOX64_ARG0");
|
||||
if(!my_context->bashpath)
|
||||
my_context->bashpath = ResolveFile("box64-bash", &my_context->box64_path);
|
||||
if(!my_context->pythonpath)
|
||||
my_context->pythonpath = ResolveFile("box64-python", &my_context->box64_path);
|
||||
pressure_vessel(argc, argv, nextarg+1, prog);
|
||||
}
|
||||
#endif
|
||||
@@ -1113,6 +1127,8 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf
|
||||
bashpath = ResolveFile("box64-bash", &my_context->box64_path);
|
||||
if(bashpath)
|
||||
my_context->bashpath = box_strdup(bashpath);
|
||||
if(!pythonpath)
|
||||
pythonpath = ResolveFile("box64-python", &my_context->box64_path);
|
||||
if(pythonpath)
|
||||
my_context->pythonpath = box_strdup(pythonpath);
|
||||
|
||||
|
||||
+126
-42
@@ -16,6 +16,9 @@
|
||||
#include "callback.h"
|
||||
#include "x64trace.h"
|
||||
#include "custommem.h"
|
||||
#ifndef _WIN32
|
||||
#include "signals.h"
|
||||
#endif
|
||||
#include "khash.h"
|
||||
#include "threads.h"
|
||||
#include "rbtree.h"
|
||||
@@ -26,6 +29,7 @@
|
||||
#include "dynarec/dynablock_private.h"
|
||||
#include "dynarec/native_lock.h"
|
||||
#include "dynarec/dynarec_next.h"
|
||||
#include "dynacache_compress.h"
|
||||
#include "freq.h"
|
||||
|
||||
// init inside dynablocks.c
|
||||
@@ -561,24 +565,57 @@ static uintptr_t defered_prot_p = 0;
|
||||
static size_t defered_prot_sz = 0;
|
||||
static uint32_t defered_prot_prot = 0;
|
||||
static mem_flag_t defered_prot_flags = MEM_ALLOCATED;
|
||||
static sigset_t critical_prot = {0};
|
||||
static void setProtection_generic(uintptr_t addr, size_t sz, uint32_t prot, mem_flag_t flags);
|
||||
#define LOCK_PROT() sigset_t old_sig = {0}; pthread_sigmask(SIG_BLOCK, &critical_prot, &old_sig); mutex_lock(&mutex_prot)
|
||||
#define LOCK_PROT_READ() sigset_t old_sig = {0}; pthread_sigmask(SIG_BLOCK, &critical_prot, &old_sig); mutex_lock(&mutex_prot)
|
||||
#define LOCK_PROT_FAST() mutex_lock(&mutex_prot)
|
||||
#define UNLOCK_PROT() if(defered_prot_p) { \
|
||||
uintptr_t p = defered_prot_p; size_t sz = defered_prot_sz; uint32_t prot = defered_prot_prot; mem_flag_t f = defered_prot_flags;\
|
||||
defered_prot_p = 0; \
|
||||
pthread_sigmask(SIG_SETMASK, &old_sig, NULL); \
|
||||
mutex_unlock(&mutex_prot); \
|
||||
setProtection_generic(p, sz, prot, f); \
|
||||
} else { \
|
||||
pthread_sigmask(SIG_SETMASK, &old_sig, NULL); \
|
||||
mutex_unlock(&mutex_prot); \
|
||||
}
|
||||
#define UNLOCK_PROT_READ() mutex_unlock(&mutex_prot); pthread_sigmask(SIG_SETMASK, &old_sig, NULL)
|
||||
#define UNLOCK_PROT_FAST() mutex_unlock(&mutex_prot)
|
||||
|
||||
#ifdef _WIN32
|
||||
void enter_critical_section(void) {}
|
||||
void leave_critical_section(void) {}
|
||||
#endif
|
||||
|
||||
static void setProtection_generic(uintptr_t addr, size_t sz, uint32_t prot, mem_flag_t flags);
|
||||
#define LOCK_PROT() \
|
||||
do { \
|
||||
enter_critical_section(); \
|
||||
mutex_lock(&mutex_prot); \
|
||||
} while (0)
|
||||
|
||||
#define LOCK_PROT_READ() \
|
||||
do { \
|
||||
enter_critical_section(); \
|
||||
mutex_lock(&mutex_prot); \
|
||||
} while (0)
|
||||
|
||||
#define LOCK_PROT_FAST() \
|
||||
do { \
|
||||
mutex_lock(&mutex_prot); \
|
||||
} while (0)
|
||||
|
||||
#define UNLOCK_PROT() \
|
||||
do { \
|
||||
if (defered_prot_p) { \
|
||||
uintptr_t p = defered_prot_p; \
|
||||
size_t sz = defered_prot_sz; \
|
||||
uint32_t prot = defered_prot_prot; \
|
||||
mem_flag_t f = defered_prot_flags; \
|
||||
defered_prot_p = 0; \
|
||||
mutex_unlock(&mutex_prot); \
|
||||
leave_critical_section(); \
|
||||
setProtection_generic(p, sz, prot, f); \
|
||||
} else { \
|
||||
mutex_unlock(&mutex_prot); \
|
||||
leave_critical_section(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define UNLOCK_PROT_READ() \
|
||||
do { \
|
||||
mutex_unlock(&mutex_prot); \
|
||||
leave_critical_section(); \
|
||||
} while (0)
|
||||
|
||||
#define UNLOCK_PROT_FAST() \
|
||||
do { \
|
||||
mutex_unlock(&mutex_prot); \
|
||||
} while (0)
|
||||
|
||||
#ifdef TRACE_MEMSTAT
|
||||
static uint64_t customMalloc_allocated = 0;
|
||||
@@ -1433,25 +1470,13 @@ size_t MmaplistTotalAlloc(mmaplist_t* list)
|
||||
|
||||
int ApplyRelocs(dynablock_t* block, intptr_t delta_block, intptr_t delat_map, uintptr_t mapping_start);
|
||||
uintptr_t RelocGetNext();
|
||||
int MmaplistAddBlock(mmaplist_t* list, int fd, off_t offset, void* orig, size_t size, intptr_t delta_map, uintptr_t mapping_start)
|
||||
int MmaplistAddBlock_internal(mmaplist_t* list, void* map, void* orig, size_t size, intptr_t delta_map, uintptr_t mapping_start)
|
||||
{
|
||||
if(!list) return -1;
|
||||
if(list->cap==list->size) {
|
||||
list->cap += 4;
|
||||
list->chunks = box_realloc(list->chunks, list->cap*sizeof(blocklist_t**));
|
||||
}
|
||||
int i = list->size++;
|
||||
void* map = MAP_FAILED;
|
||||
#ifdef BOX32
|
||||
if(box64_is32bits)
|
||||
map = box32_dynarec_mmap(size, fd, offset);
|
||||
#endif
|
||||
if(map==MAP_FAILED)
|
||||
map = InternalMmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, offset);
|
||||
if(map==MAP_FAILED) {
|
||||
printf_log(LOG_INFO, "Failed to load block %d of a maplist\n", i);
|
||||
return -3;
|
||||
}
|
||||
#ifdef MADV_HUGEPAGE
|
||||
madvise(map, size, MADV_HUGEPAGE);
|
||||
#endif
|
||||
@@ -1476,7 +1501,6 @@ int MmaplistAddBlock(mmaplist_t* list, int fd, off_t offset, void* orig, size_t
|
||||
#define GO(A) if(bl->A) bl->A = ((void*)bl->A)+delta
|
||||
GO(block);
|
||||
GO(actual_block);
|
||||
GO(previous);
|
||||
GO(instsize);
|
||||
GO(arch);
|
||||
GO(callrets);
|
||||
@@ -1495,8 +1519,18 @@ int MmaplistAddBlock(mmaplist_t* list, int fd, off_t offset, void* orig, size_t
|
||||
db_ref = (bl->jmpnext-sizeof(void*)+3*sizeof(void*));
|
||||
*db_ref = native_next;
|
||||
}
|
||||
// adjust x64_addr with delta_map
|
||||
if(bl->gone || !bl->done) {
|
||||
dynarec_log(LOG_DEBUG, "Skipping stale DynCache block %p for %p (done=%d, gone=%d)\n", bl, bl->x64_addr, bl->done, bl->gone);
|
||||
p = NEXT_BLOCK((blockmark_t*)p);
|
||||
continue;
|
||||
}
|
||||
// adjust guest source addresses with delta_map
|
||||
bl->x64_addr += delta_map;
|
||||
bl->x64_readaddr += delta_map;
|
||||
for (int j = 0; j < bl->sep_size; ++j) {
|
||||
// SEP native entries also carry a hidden dynablock reference.
|
||||
*(dynablock_t**)(bl->block + bl->sep[j].nat_offs - sizeof(void*)) = bl;
|
||||
}
|
||||
*(uintptr_t*)(bl->jmpnext+2*sizeof(void*)) = RelocGetNext();
|
||||
if(bl->relocs && bl->relocsize)
|
||||
ApplyRelocs(bl, delta, delta_map, mapping_start);
|
||||
@@ -1509,8 +1543,7 @@ int MmaplistAddBlock(mmaplist_t* list, int fd, off_t offset, void* orig, size_t
|
||||
} else {
|
||||
for(int i=0; i<bl->sep_size; ++i) {
|
||||
uint32_t x64_offs = bl->sep[i].x64_offs;
|
||||
uint32_t nat_offs = bl->sep[i].nat_offs;
|
||||
if(addJumpTableIfDefault64(bl->x64_addr+x64_offs, (bl->dirty || bl->always_test)?bl->jmpnext:(bl->block+nat_offs)))
|
||||
if (addJumpTableIfDefault64(bl->x64_addr + x64_offs, bl->jmpnext))
|
||||
bl->sep[i].active = 1;
|
||||
else
|
||||
bl->sep[i].active = 0;
|
||||
@@ -1534,13 +1567,53 @@ int MmaplistAddBlock(mmaplist_t* list, int fd, off_t offset, void* orig, size_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MmaplistFillBlocks(mmaplist_t* list, DynaCacheBlock_t* blocks)
|
||||
int MmaplistAddBlock(mmaplist_t* list, int fd, off_t offset, void* orig, size_t size, intptr_t delta_map, uintptr_t mapping_start)
|
||||
{
|
||||
if(!list) return -1;
|
||||
void* map = MAP_FAILED;
|
||||
#ifdef BOX32
|
||||
if(box64_is32bits)
|
||||
map = box32_dynarec_mmap(size, fd, offset);
|
||||
#endif
|
||||
if(map==MAP_FAILED)
|
||||
map = InternalMmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, offset);
|
||||
if(map==MAP_FAILED) {
|
||||
printf_log(LOG_INFO, "Failed to Mmap a block of a maplist\n");
|
||||
return -3;
|
||||
}
|
||||
return MmaplistAddBlock_internal(list, map, orig, size, delta_map, mapping_start);
|
||||
}
|
||||
#ifndef WIN32
|
||||
int MmaplistAddCompressedBlock(mmaplist_t* list, int type, void* src, size_t src_size, void* orig, size_t size, intptr_t delta_map, uintptr_t mapping_start)
|
||||
{
|
||||
if(!list) return -1;
|
||||
void* map = MAP_FAILED;
|
||||
#ifdef BOX32
|
||||
if(box64_is32bits)
|
||||
map = box32_dynarec_mmap(size, -1, 0);
|
||||
#endif
|
||||
if(map==MAP_FAILED)
|
||||
map = InternalMmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
if(map==MAP_FAILED) {
|
||||
printf_log(LOG_INFO, "Failed to Alloc a block of a maplist\n");
|
||||
return -3;
|
||||
}
|
||||
if(dc_uncompress(src, src_size, type, map, size)) {
|
||||
printf_log(LOG_INFO, "Failed to Uncompress a block of a maplist\n");
|
||||
return -3;
|
||||
}
|
||||
return MmaplistAddBlock_internal(list, map, orig, size, delta_map, mapping_start);
|
||||
}
|
||||
#endif
|
||||
void MmaplistFillBlocks(mmaplist_t* list, CompressedDynaCacheBlock_t* blocks)
|
||||
{
|
||||
if(!list) return;
|
||||
for(int i=0; i<list->size; ++i) {
|
||||
blocks[i].block = list->chunks[i];
|
||||
blocks[i].size = list->chunks[i]->size+sizeof(blocklist_t);
|
||||
blocks[i].free_size = list->chunks[i]->maxfree;
|
||||
blocks[i].block.block = list->chunks[i];
|
||||
blocks[i].block.size = list->chunks[i]->size+sizeof(blocklist_t);
|
||||
blocks[i].block.free_size = list->chunks[i]->maxfree;
|
||||
blocks[i].compsize = 0;
|
||||
blocks[i].type = COMP_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1550,6 +1623,7 @@ void DelMmaplist(mmaplist_t* list)
|
||||
for(int i=0; i<list->size; ++i)
|
||||
if(list->chunks[i]->size) {
|
||||
cleanDBFromAddressRange((uintptr_t)list->chunks[i]->block, list->chunks[i]->size, 1);
|
||||
DeferFreeDynablockClearRange(list->chunks[i]->block, list->chunks[i]->size);
|
||||
rb_unset(rbt_dynmem, (uintptr_t)list->chunks[i]->block, (uintptr_t)list->chunks[i]->block+list->chunks[i]->size);
|
||||
// the blocklist_t "chunk" structure is port of the memory map, so grab info before freing the memory
|
||||
// also need to include back the blocklist_t that is excluded from the blocklist tracking
|
||||
@@ -2073,10 +2147,11 @@ int setJumpTableIfRef64(void* addr, void* jmp, void* ref)
|
||||
idx1 = (((uintptr_t)addr)>>JMPTABL_START1)&JMPTABLE_MASK1;
|
||||
idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0;
|
||||
#ifdef JMPTABL_SHIFT4
|
||||
return (native_lock_storeifref2(create_jmptbl(0, idx0, idx1, idx2, idx3, idx4), jmp, ref)==ref)?1:0;
|
||||
void* ret = native_lock_storeifref2(create_jmptbl(0, idx0, idx1, idx2, idx3, idx4), jmp, ref);
|
||||
#else
|
||||
return (native_lock_storeifref2(create_jmptbl(0, idx0, idx1, idx2, idx3), jmp, ref)==ref)?1:0;
|
||||
void* ret = native_lock_storeifref2(create_jmptbl(0, idx0, idx1, idx2, idx3), jmp, ref);
|
||||
#endif
|
||||
return ((ret==ref) || (ret==jmp))?1:0;
|
||||
}
|
||||
int isJumpTableDefault64(void* addr)
|
||||
{
|
||||
@@ -2584,7 +2659,11 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
|
||||
rb_get_end(memprot, cur, &oprot, &bend);
|
||||
if(bend>end) bend = end;
|
||||
uint32_t dyn=(oprot&PROT_DYN);
|
||||
uint32_t never = dyn&PROT_NEVERPROT;
|
||||
if (dyn & PROT_NOPROT) {
|
||||
cur = bend;
|
||||
continue;
|
||||
}
|
||||
uint32_t never = dyn & PROT_NEVERCLEAN;
|
||||
if(!(never)) {
|
||||
if(dyn && (prot&PROT_WRITE)) { // need to remove the write protection from this block
|
||||
dyn = PROT_DYNAREC;
|
||||
@@ -3058,7 +3137,6 @@ void init_custommem_helper(box64context_t* ctx)
|
||||
for(int i=0; i<n_blocks; ++i)
|
||||
rb_set(blockstree, (uintptr_t)p_blocks[i].block, (uintptr_t)p_blocks[i].block+p_blocks[i].size, i);
|
||||
memprot = rbtree_init("memprot");
|
||||
sigfillset(&critical_prot);
|
||||
#ifdef DYNAREC
|
||||
if(BOX64ENV(dynarec)) {
|
||||
#ifdef JMPTABL_SHIFT4
|
||||
@@ -3256,6 +3334,12 @@ EXPORT void* box_mmap(void *addr, size_t length, int prot, int flags, int fd, ss
|
||||
}
|
||||
#endif
|
||||
void* ret = InternalMmap(addr, length, prot, new_flags, fd, offset);
|
||||
// io_uring doesn't support non-NULL address.
|
||||
// The optimal approach is to detect whether an fd is an io_uring instance,
|
||||
// but this is overly complex. So we simply retry the mmap call with the
|
||||
// original address here.
|
||||
if (ret == MAP_FAILED && old_addr == NULL && fd >= 0)
|
||||
ret = InternalMmap(old_addr, length, prot, new_flags, fd, offset);
|
||||
#if !defined(NOALIGN)
|
||||
if((ret!=MAP_FAILED) && (flags&MAP_32BIT) &&
|
||||
(((uintptr_t)ret>0xffffffffLL) || ((box64_wine) && ((uintptr_t)ret&0xffff) && (ret!=addr)))) {
|
||||
|
||||
@@ -950,7 +950,26 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
break;
|
||||
case 0x62:
|
||||
nextop = F8;
|
||||
if(rex.is32bits && !MODREG) {
|
||||
if(!rex.is32bits) {
|
||||
vex_t vex = {0};
|
||||
u8 = F8;
|
||||
u16 = F8;
|
||||
if(FillVEXFromEVEX(&vex, rex, nextop, u8, u16)) {
|
||||
INST_NAME("EVEX");
|
||||
addr = dynarec64_AVX(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
} else {
|
||||
INST_NAME("Illegal 62");
|
||||
if(BOX64DRENV(dynarec_safeflags)>1) {
|
||||
READFLAGS(X_PEND);
|
||||
} else {
|
||||
SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state
|
||||
}
|
||||
GETIP(ip);
|
||||
UDF(0);
|
||||
*need_epilog = 1;
|
||||
*ok = 0;
|
||||
}
|
||||
} else if(!MODREG) {
|
||||
INST_NAME("BOUND Gd, Ed");
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
LDRxw_U12(x2, wback, 0);
|
||||
|
||||
@@ -2075,7 +2075,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
BARRIER(BARRIER_FLOAT);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
if(ed!=x1) {MOVx_REG(x1, ed);}
|
||||
MOV32w(x2, rex.w?0:1);
|
||||
MOV32w(x2, rex.is32bits);
|
||||
CALL(const_fpu_xsave, -1);
|
||||
break;
|
||||
case 5:
|
||||
@@ -2084,7 +2084,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
BARRIER(BARRIER_FLOAT);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
|
||||
if(ed!=x1) {MOVx_REG(x1, ed);}
|
||||
MOV32w(x2, rex.w?0:1);
|
||||
MOV32w(x2, rex.is32bits);
|
||||
CALL(const_fpu_xrstor, -1);
|
||||
break;
|
||||
case 7:
|
||||
|
||||
@@ -103,59 +103,61 @@ static int arch_build(dynarec_arm_t* dyn, int ninst, arch_build_t* arch, int noa
|
||||
arch->unaligned = dyn->insts[ninst].unaligned;
|
||||
if(!noarch) {
|
||||
// got through all naoncache to gather regs assignments
|
||||
int idx;
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->insts[ninst].n.neoncache[i].v)
|
||||
switch(dyn->insts[ninst].n.neoncache[i].t) {
|
||||
case NEON_CACHE_XMMW:
|
||||
arch->sse = 1;
|
||||
arch->sse_.sse |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
break;
|
||||
case NEON_CACHE_MM:
|
||||
arch->mmx = 1;
|
||||
arch->mmx_.mmx |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
break;
|
||||
case NEON_CACHE_YMMW:
|
||||
arch->ymm = 1;
|
||||
arch->ymm_.ymm |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
idx = i;
|
||||
if(idx>=EMM0 && idx<=EMM0+8)
|
||||
idx-=EMM0;
|
||||
else
|
||||
idx-=SCRATCH0-8;
|
||||
arch->ymm_.ymm_pos |= idx<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
break;
|
||||
case NEON_CACHE_ST_D:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_D)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_ST_F:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_F)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_ST_I64:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_I64)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_XMMR:
|
||||
case NEON_CACHE_YMMR:
|
||||
default:
|
||||
// doing nothing, it's just a value read in memory
|
||||
break;
|
||||
}
|
||||
if(dyn->use_x87 || dyn->use_mmx || dyn->use_xmm || dyn->use_ymm) {
|
||||
int idx;
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->insts[ninst].n.neoncache[i].v)
|
||||
switch(dyn->insts[ninst].n.neoncache[i].t) {
|
||||
case NEON_CACHE_XMMW:
|
||||
arch->sse = 1;
|
||||
arch->sse_.sse |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
break;
|
||||
case NEON_CACHE_MM:
|
||||
arch->mmx = 1;
|
||||
arch->mmx_.mmx |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
break;
|
||||
case NEON_CACHE_YMMW:
|
||||
arch->ymm = 1;
|
||||
arch->ymm_.ymm |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
idx = i;
|
||||
if(idx>=EMM0 && idx<=EMM0+8)
|
||||
idx-=EMM0;
|
||||
else
|
||||
idx-=SCRATCH0-8;
|
||||
arch->ymm_.ymm_pos |= idx<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
break;
|
||||
case NEON_CACHE_ST_D:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_D)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_ST_F:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_F)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_ST_I64:
|
||||
arch->x87 = 1;
|
||||
arch->x87_.x87 |= 1<<dyn->insts[ninst].n.neoncache[i].n;
|
||||
arch->x87_.x87_pos = (i-EMM0)<<(dyn->insts[ninst].n.neoncache[i].n*4);
|
||||
arch->x87_.x87_type = (X87_ST_I64)<<(dyn->insts[ninst].n.neoncache[i].n*2);
|
||||
break;
|
||||
case NEON_CACHE_XMMR:
|
||||
case NEON_CACHE_YMMR:
|
||||
default:
|
||||
// doing nothing, it's just a value read in memory
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ymm0
|
||||
if(dyn->insts[ninst].ymm0_out) {
|
||||
if(dyn->use_ymm && dyn->insts[ninst].ymm0_out) {
|
||||
arch->ymm = 1;
|
||||
arch->ymm_.ymm0 = dyn->insts[ninst].ymm0_out;
|
||||
}
|
||||
// x87 top
|
||||
if(dyn->insts[ninst].n.x87stack) {
|
||||
if((dyn->use_x87 || dyn->insts[ninst].x87_used) && dyn->insts[ninst].n.x87stack) {
|
||||
arch->x87 = 1;
|
||||
arch->x87_.delta = dyn->insts[ninst].n.x87stack;
|
||||
}
|
||||
|
||||
@@ -40,38 +40,43 @@ static const char* avx_map_string(uint16_t m)
|
||||
}
|
||||
}
|
||||
|
||||
typedef uintptr_t (*dynarec64_avx_f)(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog);
|
||||
|
||||
uintptr_t dynarec64_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
(void)ip; (void)need_epilog;
|
||||
|
||||
uint8_t opcode = PK(0);
|
||||
rex_t rex = vex.rex;
|
||||
static const dynarec64_avx_f avx_dispatch[4][4] = {
|
||||
[VEX_M_0F] = {
|
||||
[VEX_P_NONE] = dynarec64_AVX_0F,
|
||||
[VEX_P_66] = dynarec64_AVX_66_0F,
|
||||
[VEX_P_F3] = dynarec64_AVX_F3_0F,
|
||||
[VEX_P_F2] = dynarec64_AVX_F2_0F,
|
||||
},
|
||||
[VEX_M_0F38] = {
|
||||
[VEX_P_NONE] = dynarec64_AVX_0F38,
|
||||
[VEX_P_66] = dynarec64_AVX_66_0F38,
|
||||
[VEX_P_F3] = dynarec64_AVX_F3_0F38,
|
||||
[VEX_P_F2] = dynarec64_AVX_F2_0F38,
|
||||
},
|
||||
[VEX_M_0F3A] = {
|
||||
[VEX_P_66] = dynarec64_AVX_66_0F3A,
|
||||
[VEX_P_F2] = dynarec64_AVX_F2_0F3A,
|
||||
},
|
||||
};
|
||||
|
||||
if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_NONE))
|
||||
addr = dynarec64_AVX_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_NONE))
|
||||
addr = dynarec64_AVX_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_66))
|
||||
addr = dynarec64_AVX_66_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F2))
|
||||
addr = dynarec64_AVX_F2_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F3))
|
||||
addr = dynarec64_AVX_F3_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_66))
|
||||
addr = dynarec64_AVX_66_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_66))
|
||||
addr = dynarec64_AVX_66_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2))
|
||||
addr = dynarec64_AVX_F2_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_F2))
|
||||
addr = dynarec64_AVX_F2_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F3))
|
||||
addr = dynarec64_AVX_F3_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else {DEFAULT;}
|
||||
if(vex.m < 4 && vex.p < 4 && avx_dispatch[vex.m][vex.p])
|
||||
addr = avx_dispatch[vex.m][vex.p](dyn, addr, ip, ninst, vex, ok, need_epilog);
|
||||
else {
|
||||
DEFAULT;
|
||||
}
|
||||
|
||||
if((*ok==-1) && (BOX64ENV(dynarec_log)>=LOG_INFO || dyn->need_dump || BOX64ENV(dynarec_missing)))
|
||||
if(!dyn->size || BOX64ENV(dynarec_log)>LOG_INFO || dyn->need_dump) {
|
||||
dynarec_log(LOG_NONE, " Dynarec unimplemented VEX opcode size %d prefix %s map %s opcode %02X\n", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
|
||||
dynarec_log(LOG_NONE, " Dynarec unimplemented %s opcode size %d prefix %s map %s opcode %02X\n",
|
||||
vex.evex ? "EVEX" : "VEX", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -214,7 +214,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
q0 = fpu_get_scratch(dyn, ninst);
|
||||
q1 = fpu_get_scratch(dyn, ninst);
|
||||
// check if any input value was NAN
|
||||
FCMEQS(q0, v1, v1); // 0 if NAN, 1 if not NAN
|
||||
FCMEQS(q0, d0, d0); // 0 if NAN, 1 if not NAN
|
||||
}
|
||||
FSQRTS(d1, d0);
|
||||
if(!BOX64ENV(dynarec_fastnan)) {
|
||||
|
||||
@@ -176,6 +176,19 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// check if stack is empty (freed register will not count, but might work if using tags instead)
|
||||
i2 = -dyn->n.x87stack;
|
||||
LDRw_U12(x3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
if(i2) {
|
||||
if(i2<0) {
|
||||
ADDw_U12(x3, x3, -i2);
|
||||
} else {
|
||||
SUBw_U12(x3, x3, i2);
|
||||
}
|
||||
}
|
||||
CMPSw_U12(x3, 0);
|
||||
MOV32w(x4, 0b100000100000000); // empty: C3,C2,C0 = 101
|
||||
B_MARK3(cLE);
|
||||
// simply move from cache reg to x2
|
||||
v1 = dyn->n.x87reg[i1];
|
||||
VMOVQDto(x2, v1, 0);
|
||||
@@ -443,7 +456,9 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_D(const_direct_fscale, v1, v1, v2, -1, -1);
|
||||
else
|
||||
u8 = 0;
|
||||
CALL_D(const_direct_fscale, v1, v1, v2, u8, -1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
@@ -453,7 +468,9 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_D(const_direct_fsin, v1, v1, -1, -1, -1);
|
||||
else
|
||||
u8 = 0;
|
||||
CALL_D(const_direct_fsin, v1, v1, -1, u8, -1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
@@ -463,7 +480,9 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
u8 = x87_setround(dyn, ninst, x1, x2, x4);
|
||||
CALL_D(const_direct_fcos, v1, v1, -1, -1, -1);
|
||||
else
|
||||
u8 = 0;
|
||||
CALL_D(const_direct_fcos, v1, v1, -1, u8, -1);
|
||||
if(!BOX64ENV(dynarec_fastround))
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
|
||||
@@ -545,6 +545,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
|
||||
case 0xBB:
|
||||
case 0xBC: // this one is still BSR, not TZCNT
|
||||
case 0xBD: // and this one is still BSF, not LZCNT
|
||||
case 0xBF:
|
||||
case 0xC1:
|
||||
case 0xCD:
|
||||
return dynarec64_0F(dyn, addr-1, ip, ninst, rex, ok, need_epilog);
|
||||
|
||||
@@ -98,22 +98,23 @@ int fpu_get_reg_x87(dynarec_arm_t* dyn, int ninst, int t, int n)
|
||||
void fpu_free_reg(dynarec_arm_t* dyn, int reg)
|
||||
{
|
||||
// TODO: check upper limit?
|
||||
int t = dyn->n.neoncache[reg].t;
|
||||
int n = dyn->n.neoncache[reg].n;
|
||||
dyn->n.fpuused[reg] = 0;
|
||||
if(dyn->n.neoncache[reg].t==NEON_CACHE_YMMR || dyn->n.neoncache[reg].t==NEON_CACHE_YMMW) {
|
||||
dyn->n.ymm_removed |= 1<<dyn->n.neoncache[reg].n;
|
||||
if(dyn->n.neoncache[reg].t==NEON_CACHE_YMMW)
|
||||
dyn->n.ymm_write |= 1<<dyn->n.neoncache[reg].n;
|
||||
if(t==NEON_CACHE_XMMR || t==NEON_CACHE_XMMW) {
|
||||
dyn->n.xmm_removed |= 1<<n;
|
||||
if(t==NEON_CACHE_XMMW)
|
||||
dyn->n.xmm_write |= 1<<n;
|
||||
} else if(t==NEON_CACHE_YMMR || t==NEON_CACHE_YMMW) {
|
||||
dyn->n.ymm_removed |= 1<<n;
|
||||
if(t==NEON_CACHE_YMMW)
|
||||
dyn->n.ymm_write |= 1<<n;
|
||||
if(reg>SCRATCH0)
|
||||
dyn->n.ymm_regs |= (8LL+reg-SCRATCH0)<<(dyn->n.neoncache[reg].n*4);
|
||||
dyn->n.ymm_regs |= (8LL+reg-SCRATCH0)<<(n*4);
|
||||
else
|
||||
dyn->n.ymm_regs |= ((uint64_t)(reg-EMM0))<<(dyn->n.neoncache[reg].n*4);
|
||||
dyn->n.ymm_regs |= ((uint64_t)(reg-EMM0))<<(n*4);
|
||||
}
|
||||
if(dyn->n.neoncache[reg].t==NEON_CACHE_XMMR || dyn->n.neoncache[reg].t==NEON_CACHE_XMMW) {
|
||||
dyn->n.xmm_removed |= 1<<dyn->n.neoncache[reg].n;
|
||||
if(dyn->n.neoncache[reg].t==NEON_CACHE_XMMW)
|
||||
dyn->n.xmm_write |= 1<<dyn->n.neoncache[reg].n;
|
||||
}
|
||||
if(dyn->n.neoncache[reg].t!=NEON_CACHE_ST_F && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_D && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_I64)
|
||||
if(t!=NEON_CACHE_ST_F && t!=NEON_CACHE_ST_D && t!=NEON_CACHE_ST_I64)
|
||||
dyn->n.neoncache[reg].v = 0;
|
||||
if(dyn->n.fpu_scratch && reg==SCRATCH0+dyn->n.fpu_scratch-1)
|
||||
--dyn->n.fpu_scratch;
|
||||
@@ -448,13 +449,12 @@ int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst) {
|
||||
if((dyn->insts[i2].x64.barrier&BARRIER_FLOAT))
|
||||
// if the barrier as already been apply, no transform needed
|
||||
return ((dyn->insts[ninst].x64.barrier&BARRIER_FLOAT))?0:(isCacheEmpty(dyn, ninst)?0:1);
|
||||
int ret = 0;
|
||||
if(!i2) { // just purge
|
||||
if(dyn->insts[ninst].n.stack_next)
|
||||
return 1;
|
||||
if(dyn->insts[ninst].ymm0_out)
|
||||
return 1;
|
||||
for(int i=0; i<32 && !ret; ++i)
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->insts[ninst].n.neoncache[i].v) { // there is something at ninst for i
|
||||
int t = dyn->insts[ninst].n.neoncache[i].t;
|
||||
int n = dyn->insts[ninst].n.neoncache[i].n;
|
||||
@@ -463,15 +463,15 @@ int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst) {
|
||||
|| t==NEON_CACHE_ST_D
|
||||
|| t==NEON_CACHE_ST_I64)
|
||||
&& n<dyn->insts[ninst].n.stack_pop))
|
||||
ret = 1;
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
// Check if ninst can be compatible to i2
|
||||
if(dyn->insts[ninst].n.stack_next != dyn->insts[i2].n.stack-dyn->insts[i2].n.stack_push) {
|
||||
return 1;
|
||||
}
|
||||
if(dyn->insts[ninst].ymm0_out && (dyn->insts[ninst].ymm0_out&~dyn->insts[i2].ymm0_in))
|
||||
if(dyn->insts[ninst].ymm0_out && (dyn->insts[ninst].ymm0_out&~dyn->insts[i2].ymm0_in&~dyn->insts[i2].n.ymm_unneeded))
|
||||
return 1;
|
||||
neoncache_t cache_i2 = dyn->insts[i2].n;
|
||||
neoncacheUnwind(&cache_i2);
|
||||
@@ -484,22 +484,22 @@ int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst) {
|
||||
if(((t==NEON_CACHE_XMMR) || (t==NEON_CACHE_XMMW)) && (cache_i2.xmm_unneeded&(1<<n))) { /* nothing*/}
|
||||
else if(((t==NEON_CACHE_YMMR) || (t==NEON_CACHE_YMMW)) && (cache_i2.ymm_unneeded&(1<<n))) { /* nothing*/}
|
||||
else
|
||||
ret = 1;
|
||||
return 1;
|
||||
} else if(dyn->insts[ninst].n.neoncache[i].v!=cache_i2.neoncache[i].v) { // there is something different
|
||||
if(n!=cache_i2.neoncache[i].n) { // not the same x64 reg
|
||||
ret = 1;
|
||||
return 1;
|
||||
}
|
||||
else if((t == NEON_CACHE_XMMR) && cache_i2.neoncache[i].t == NEON_CACHE_XMMW)
|
||||
{/* nothing */ }
|
||||
else if((t == NEON_CACHE_YMMR) && cache_i2.neoncache[i].t == NEON_CACHE_YMMW)
|
||||
{/* nothing */ }
|
||||
else
|
||||
ret = 1;
|
||||
return 1;
|
||||
}
|
||||
} else if(cache_i2.neoncache[i].v)
|
||||
ret = 1;
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void neoncacheUnwind(neoncache_t* cache)
|
||||
@@ -880,6 +880,8 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
|
||||
if (dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2) {
|
||||
length += sprintf(buf + length, " %s:%d/%d", dyn->insts[ninst].n.swapped ? "SWP" : "CMB", dyn->insts[ninst].n.combined1, dyn->insts[ninst].n.combined2);
|
||||
}
|
||||
if(dyn->insts[ninst].x64.self_loop)
|
||||
length += sprintf(buf + length, " self-loop");
|
||||
if (dyn->need_dump) {
|
||||
printf_x64_instruction(dyn, rex.is32bits ? my_context->dec32 : my_context->dec, &dyn->insts[ninst].x64, name);
|
||||
dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, %s%s\n",
|
||||
@@ -942,20 +944,21 @@ static void mmx_reset(neoncache_t* n)
|
||||
n->mmxcache[i] = -1;
|
||||
}
|
||||
|
||||
static void sse_reset(neoncache_t* n)
|
||||
static void sse_reset(neoncache_t* n, int use_ymm)
|
||||
{
|
||||
for (int i=0; i<16; ++i)
|
||||
n->ssecache[i].v = -1;
|
||||
for (int i=0; i<32; ++i)
|
||||
if(n->neoncache[i].t==NEON_CACHE_YMMR || n->neoncache[i].t==NEON_CACHE_YMMW)
|
||||
n->neoncache[i].v = 0;
|
||||
if(use_ymm)
|
||||
for (int i=0; i<32; ++i)
|
||||
if(n->neoncache[i].t==NEON_CACHE_YMMR || n->neoncache[i].t==NEON_CACHE_YMMW)
|
||||
n->neoncache[i].v = 0;
|
||||
}
|
||||
|
||||
void fpu_reset(dynarec_native_t* dyn)
|
||||
{
|
||||
x87_reset(&dyn->n);
|
||||
mmx_reset(&dyn->n);
|
||||
sse_reset(&dyn->n);
|
||||
sse_reset(&dyn->n, dyn->use_ymm);
|
||||
fpu_reset_reg(dyn);
|
||||
dyn->ymm_zero = 0;
|
||||
}
|
||||
@@ -964,7 +967,7 @@ void fpu_reset_ninst(dynarec_native_t* dyn, int ninst)
|
||||
{
|
||||
x87_reset(&dyn->insts[ninst].n);
|
||||
mmx_reset(&dyn->insts[ninst].n);
|
||||
sse_reset(&dyn->insts[ninst].n);
|
||||
sse_reset(&dyn->insts[ninst].n, dyn->use_ymm);
|
||||
fpu_reset_reg_neoncache(&dyn->insts[ninst].n);
|
||||
|
||||
}
|
||||
@@ -1588,4 +1591,4 @@ void addSSEPreload(dynarec_arm_t* dyn, int ninst, int i2, uint32_t preload)
|
||||
dyn->insts[i2].preload_from = ninst;
|
||||
dyn->insts[i2].n.xmm_unneeded |= preload&0xffff;
|
||||
dyn->insts[i2].n.ymm_unneeded |= ymm_mask;
|
||||
}
|
||||
}
|
||||
@@ -665,13 +665,10 @@ void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w)
|
||||
MOVx_REG(x4, xR8);
|
||||
MOVx_REG(x5, xR9);
|
||||
// native call
|
||||
if(dyn->need_reloc) {
|
||||
// fnc is indirect, to help with relocation (but PltResolver might be an issue here)
|
||||
TABLE64(16, (uintptr_t)fnc);
|
||||
LDRx_U12(16, 16, 0);
|
||||
} else {
|
||||
TABLE64_(16, *(uintptr_t*)fnc); // using x16 as scratch regs for call address
|
||||
}
|
||||
TABLE64_(16, *(uintptr_t*)fnc); // using x16 as scratch regs for call address
|
||||
// Note that if need_reloc is active, the TABLE64 will trigger cancel block,
|
||||
// because native function might be very different on a next run: different function address, different brick, different everything basicaly
|
||||
// and we don't have a relocation mecanism here, it's too complex
|
||||
BLR(16);
|
||||
// put return value in x64 regs
|
||||
if(w>0) {
|
||||
@@ -1781,9 +1778,10 @@ void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
|
||||
if((dyn->n.ssecache[i].v!=-1) && (dyn->n.ssecache[i].write))
|
||||
++n;
|
||||
}
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMW)
|
||||
++n;
|
||||
if(dyn->use_ymm)
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMW)
|
||||
++n;
|
||||
if(!n)
|
||||
return;
|
||||
MESSAGE(LOG_DUMP, "\tPush XMM Cache (%d)------\n", n);
|
||||
@@ -1793,10 +1791,11 @@ void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
|
||||
}
|
||||
}
|
||||
// push the YMM values
|
||||
for(int i=0; i<32; ++i) {
|
||||
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMW)
|
||||
VSTR128_U12(i, xEmu, offsetof(x64emu_t, ymm[dyn->n.neoncache[i].n]));
|
||||
}
|
||||
if(dyn->use_ymm)
|
||||
for(int i=0; i<32; ++i) {
|
||||
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMW)
|
||||
VSTR128_U12(i, xEmu, offsetof(x64emu_t, ymm[dyn->n.neoncache[i].n]));
|
||||
}
|
||||
MESSAGE(LOG_DUMP, "\t------- Push XMM Cache (%d)\n", n);
|
||||
}
|
||||
|
||||
@@ -1808,9 +1807,10 @@ void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
|
||||
for (int i=start; i<16; i++)
|
||||
if(dyn->n.ssecache[i].v!=-1)
|
||||
++n;
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMW || dyn->n.neoncache[i].t==NEON_CACHE_YMMR)
|
||||
++n;
|
||||
if(dyn->use_ymm)
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMW || dyn->n.neoncache[i].t==NEON_CACHE_YMMR)
|
||||
++n;
|
||||
if(!n)
|
||||
return;
|
||||
MESSAGE(LOG_DUMP, "\tPop XMM Cache (%d)------\n", n);
|
||||
@@ -1820,9 +1820,10 @@ void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
|
||||
/*dyn->n.ssecache[i].write = 0; // OPTIM: it's sync, so not write anymore
|
||||
dyn->n.neoncache[dyn->n.ssecache[i].reg].t = NEON_CACHE_XMMR;*/
|
||||
}
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMW || dyn->n.neoncache[i].t==NEON_CACHE_YMMR)
|
||||
VLDR128_U12(i, xEmu, offsetof(x64emu_t, ymm[dyn->n.neoncache[i].n]));
|
||||
if(dyn->use_ymm)
|
||||
for(int i=0; i<32; ++i)
|
||||
if(dyn->n.neoncache[i].t==NEON_CACHE_YMMW || dyn->n.neoncache[i].t==NEON_CACHE_YMMR)
|
||||
VLDR128_U12(i, xEmu, offsetof(x64emu_t, ymm[dyn->n.neoncache[i].n]));
|
||||
MESSAGE(LOG_DUMP, "\t------- Pop XMM Cache (%d)\n", n);
|
||||
}
|
||||
|
||||
@@ -1886,6 +1887,55 @@ static int findCacheSlot(dynarec_arm_t* dyn, int ninst, int t, int n, neoncache_
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void buildCacheMasks(neoncache_t* cache, uint8_t* st, uint8_t* mm, uint16_t* xmm, uint16_t* ymm)
|
||||
{
|
||||
*st = *mm = 0;
|
||||
*xmm = *ymm = 0;
|
||||
for(int i=0; i<32; ++i) {
|
||||
if(!cache->neoncache[i].v)
|
||||
continue;
|
||||
int n = cache->neoncache[i].n;
|
||||
switch(cache->neoncache[i].t) {
|
||||
case NEON_CACHE_ST_F:
|
||||
case NEON_CACHE_ST_D:
|
||||
case NEON_CACHE_ST_I64:
|
||||
*st |= 1<<n;
|
||||
break;
|
||||
case NEON_CACHE_MM:
|
||||
*mm |= 1<<n;
|
||||
break;
|
||||
case NEON_CACHE_XMMR:
|
||||
case NEON_CACHE_XMMW:
|
||||
*xmm |= 1<<n;
|
||||
break;
|
||||
case NEON_CACHE_YMMR:
|
||||
case NEON_CACHE_YMMW:
|
||||
*ymm |= 1<<n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int cacheMaskHas(int t, int n, uint8_t st, uint8_t mm, uint16_t xmm, uint16_t ymm)
|
||||
{
|
||||
switch(t) {
|
||||
case NEON_CACHE_ST_F:
|
||||
case NEON_CACHE_ST_D:
|
||||
case NEON_CACHE_ST_I64:
|
||||
return st&(1<<n);
|
||||
case NEON_CACHE_MM:
|
||||
return mm&(1<<n);
|
||||
case NEON_CACHE_XMMR:
|
||||
case NEON_CACHE_XMMW:
|
||||
return xmm&(1<<n);
|
||||
case NEON_CACHE_YMMR:
|
||||
case NEON_CACHE_YMMW:
|
||||
return ymm&(1<<n);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void swapCache(dynarec_arm_t* dyn, int ninst, int i, int j, neoncache_t *cache)
|
||||
{
|
||||
if (i==j)
|
||||
@@ -2095,6 +2145,9 @@ static void fpuCacheTransform(dynarec_arm_t* dyn, int ninst, int s1, int s2, int
|
||||
}
|
||||
neoncache_t cache_i2 = dyn->insts[i2].n;
|
||||
neoncacheUnwind(&cache_i2);
|
||||
uint8_t cache_i2_st, cache_i2_mm;
|
||||
uint16_t cache_i2_xmm, cache_i2_ymm;
|
||||
buildCacheMasks(&cache_i2, &cache_i2_st, &cache_i2_mm, &cache_i2_xmm, &cache_i2_ymm);
|
||||
|
||||
if(!cache_i2.stack) {
|
||||
int purge = 0; // default to purge if there is any regs that are not needed at jump
|
||||
@@ -2143,22 +2196,22 @@ static void fpuCacheTransform(dynarec_arm_t* dyn, int ninst, int s1, int s2, int
|
||||
// check SSE first, than MMX, in order, to optimize successive memory write
|
||||
for(int i=0; i<16; ++i) {
|
||||
int j=findCacheSlot(dyn, ninst, NEON_CACHE_XMMW, i, &cache);
|
||||
if(j>=0 && findCacheSlot(dyn, ninst, NEON_CACHE_XMMW, i, &cache_i2)==-1)
|
||||
if(j>=0 && !(cache_i2_xmm&(1<<i)))
|
||||
unloadCache(dyn, ninst, stack_cnt, s1, s2, s3, &s1_val, &s2_val, &s3_top, &cache, j, cache.neoncache[j].t, cache.neoncache[j].n, i2);
|
||||
}
|
||||
for(int i=0; i<16; ++i) {
|
||||
int j=findCacheSlot(dyn, ninst, NEON_CACHE_YMMW, i, &cache);
|
||||
if(j>=0 && findCacheSlot(dyn, ninst, NEON_CACHE_YMMW, i, &cache_i2)==-1)
|
||||
if(j>=0 && !(cache_i2_ymm&(1<<i)))
|
||||
unloadCache(dyn, ninst, stack_cnt, s1, s2, s3, &s1_val, &s2_val, &s3_top, &cache, j, cache.neoncache[j].t, cache.neoncache[j].n, i2);
|
||||
}
|
||||
for(int i=0; i<8; ++i) {
|
||||
int j=findCacheSlot(dyn, ninst, NEON_CACHE_MM, i, &cache);
|
||||
if(j>=0 && findCacheSlot(dyn, ninst, NEON_CACHE_MM, i, &cache_i2)==-1)
|
||||
if(j>=0 && !(cache_i2_mm&(1<<i)))
|
||||
unloadCache(dyn, ninst, stack_cnt, s1, s2, s3, &s1_val, &s2_val, &s3_top, &cache, j, cache.neoncache[j].t, cache.neoncache[j].n, i2);
|
||||
}
|
||||
for(int i=0; i<32; ++i) {
|
||||
if(cache.neoncache[i].v)
|
||||
if(findCacheSlot(dyn, ninst, cache.neoncache[i].t, cache.neoncache[i].n, &cache_i2)==-1)
|
||||
if(!cacheMaskHas(cache.neoncache[i].t, cache.neoncache[i].n, cache_i2_st, cache_i2_mm, cache_i2_xmm, cache_i2_ymm))
|
||||
unloadCache(dyn, ninst, stack_cnt, s1, s2, s3, &s1_val, &s2_val, &s3_top, &cache, i, cache.neoncache[i].t, cache.neoncache[i].n, i2);
|
||||
}
|
||||
// and now load/swap the missing one
|
||||
@@ -2930,4 +2983,4 @@ void checkCRC(dynarec_arm_t* dyn, int ninst)
|
||||
CBZw(x1, 4+2*4);
|
||||
TABLE64C(x3, const_native_next_invalidate);
|
||||
BLR(x3);
|
||||
}
|
||||
}
|
||||
@@ -1872,7 +1872,7 @@ uintptr_t dynarec64_AVX_F3_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
|
||||
|
||||
#define PURGE_YMM() \
|
||||
do { \
|
||||
if ((ok > 0) && reset_n == -1 && dyn->insts[ninst + 1].purge_ymm) \
|
||||
if (dyn->use_ymm && (ok > 0) && reset_n == -1 && dyn->insts[ninst + 1].purge_ymm) \
|
||||
avx_purge_ymm(dyn, ninst, dyn->insts[ninst + 1].purge_ymm, x1); \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -95,8 +95,7 @@ void* create_updateflags()
|
||||
helper.callret_size = 0;
|
||||
// pass 3, emit (log emit native opcode)
|
||||
if(helper.need_dump) {
|
||||
dynarec_log(LOG_NONE, "%s%04d|Emitting %zu bytes for UpdateFlags", (helper.need_dump>1)?"\e[01;36m":"", GetTID(), helper.native_size);
|
||||
PrintFunctionAddr(helper.start, " => ");
|
||||
dynarec_log(LOG_NONE, "%s%04d|Emitting %zu bytes for UpdateFlags (%p)", (helper.need_dump>1)?"\e[01;36m":"", GetTID(), helper.native_size, helper.native_start);
|
||||
dynarec_log_prefix(0, LOG_NONE, "%s\n", (helper.need_dump>1)?"\e[m":"");
|
||||
}
|
||||
helper.native_size = 0;
|
||||
|
||||
@@ -164,7 +164,7 @@ SETMARK(d_inc64);
|
||||
RET(xLR);
|
||||
SETMARK(d_imul8);
|
||||
LDRSH_U12(x1, xEmu, offsetof(x64emu_t, res));
|
||||
ASRxw(x2, x1, 8);
|
||||
ASRxw(x2, x1, 7);
|
||||
CMPSw_REG_ASR(x2, x1, 16);
|
||||
CSETw(x3, cNE);
|
||||
BFIw(xFlags, x3, F_CF, 1);
|
||||
@@ -179,7 +179,7 @@ SETMARK(d_imul8);
|
||||
RET(xLR);
|
||||
SETMARK(d_imul16);
|
||||
LDRw_U12(x1, xEmu, offsetof(x64emu_t, res));
|
||||
ASRw(x2, x1, 16);
|
||||
ASRw(x2, x1, 15);
|
||||
CMPSw_REG_ASR(x2, x1, 31);
|
||||
CSETw(x3, cNE);
|
||||
BFIw(xFlags, x3, F_CF, 1);
|
||||
@@ -783,7 +783,7 @@ SETMARK(d_rol8);
|
||||
BFIw(xFlags, x2, F_OF, 1);
|
||||
} else {
|
||||
LDRB_U12(x2, xEmu, offsetof(x64emu_t, op1));
|
||||
LSLw_IMM(x3, x2, 6);
|
||||
LSRw_IMM(x3, x2, 6);
|
||||
EORw_REG_LSR(x3, x3, x3, 1);
|
||||
BFIw(xFlags, x3, F_OF, 1);
|
||||
}
|
||||
@@ -796,7 +796,7 @@ SETMARK(d_rol16);
|
||||
BFIw(xFlags, x2, F_OF, 1);
|
||||
} else {
|
||||
LDRH_U12(x2, xEmu, offsetof(x64emu_t, op1));
|
||||
LSLw_IMM(x3, x2, 14);
|
||||
LSRw_IMM(x3, x2, 14);
|
||||
EORw_REG_LSR(x3, x3, x3, 1);
|
||||
BFIw(xFlags, x3, F_OF, 1);
|
||||
}
|
||||
@@ -809,7 +809,7 @@ SETMARK(d_rol32);
|
||||
BFIw(xFlags, x2, F_OF, 1);
|
||||
} else {
|
||||
LDRw_U12(x2, xEmu, offsetof(x64emu_t, op1));
|
||||
LSLw_IMM(x3, x2, 30);
|
||||
LSRw_IMM(x3, x2, 30);
|
||||
EORw_REG_LSR(x3, x3, x3, 1);
|
||||
BFIw(xFlags, x3, F_OF, 1);
|
||||
}
|
||||
@@ -822,7 +822,7 @@ SETMARK(d_rol64);
|
||||
BFIw(xFlags, x2, F_OF, 1);
|
||||
} else {
|
||||
LDRx_U12(x2, xEmu, offsetof(x64emu_t, op1));
|
||||
LSLx_IMM(x3, x2, 62);
|
||||
LSRw_IMM(x3, x2, 62);
|
||||
EORw_REG_LSR(x3, x3, x3, 1);
|
||||
BFIw(xFlags, x3, F_OF, 1);
|
||||
}
|
||||
|
||||
+40
-93
@@ -75,34 +75,24 @@ dynablock_t* InvalidDynablock(dynablock_t* db, int need_lock)
|
||||
return db;
|
||||
}
|
||||
|
||||
dynablock_t* SwitchDynablock(dynablock_t* db, int need_lock)
|
||||
static void DeferFreeDynablockMap(dynablock_t* db)
|
||||
{
|
||||
if(db) {
|
||||
if(!db->done || !db->previous || !db->previous->gone)
|
||||
return NULL; // not a correct block!
|
||||
dynarec_log(LOG_DEBUG, "SwitchDynablock(%p/%p), db->block=%p->%p x64=%p:%p->%p hash->%x->%x\n", db, db->previous, db->block, db->previous->block, db->x64_addr, db->x64_addr+db->x64_size-1, db->previous->x64_addr+db->previous->x64_size-1, db->hash, db->previous->hash);
|
||||
// remove jumptable without waiting
|
||||
dynablock_t* db_new = db->previous;
|
||||
db->previous = NULL;
|
||||
if(need_lock)
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
InvalidDynablock(db, 0);
|
||||
db_new->done = 1;
|
||||
db_new->gone = 0;
|
||||
db_new->previous = db;
|
||||
#ifdef ARCH_NOP
|
||||
if(db_new->callret_size) {
|
||||
// mark all callrets to UDF
|
||||
for(int i=0; i<db_new->callret_size; ++i)
|
||||
*(uint32_t*)(db_new->block+db_new->callrets[i].offs) = ARCH_NOP;
|
||||
ClearCache(db_new->block, db_new->size);
|
||||
}
|
||||
#endif
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
return db_new;
|
||||
// enq for a deferred free so any threads still running in this block has a better chance to finish.
|
||||
if (my_context->db_zombie_count == DB_ZOMBIE_SIZE) {
|
||||
if(my_context->db_zombie[my_context->db_zombie_head])
|
||||
FreeDynarecMap((uintptr_t)my_context->db_zombie[my_context->db_zombie_head]->actual_block);
|
||||
} else {
|
||||
my_context->db_zombie_count++;
|
||||
}
|
||||
return db;
|
||||
my_context->db_zombie[my_context->db_zombie_head] = db;
|
||||
my_context->db_zombie_head = (my_context->db_zombie_head + 1) % DB_ZOMBIE_SIZE;
|
||||
}
|
||||
|
||||
void DeferFreeDynablockClearRange(void* addr, size_t sz)
|
||||
{
|
||||
for(int i=0; i<my_context->db_zombie_count; ++i)
|
||||
if(my_context->db_zombie[i] && ((void*)my_context->db_zombie[i]>=addr) && ((void*)my_context->db_zombie[i]<(addr+sz)))
|
||||
my_context->db_zombie[i] = NULL;
|
||||
}
|
||||
|
||||
void FreeInvalidDynablock(dynablock_t* db, int need_lock)
|
||||
@@ -110,18 +100,19 @@ void FreeInvalidDynablock(dynablock_t* db, int need_lock)
|
||||
if(db) {
|
||||
if(!db->gone)
|
||||
return; // already in the process of deletion!
|
||||
dynarec_log(LOG_DEBUG, "FreeInvalidDynablock(%p), db->block=%p x64=%p:%p already gone=%d\n", db, db->block, db->x64_addr, db->x64_addr+db->x64_size-1, db->gone);
|
||||
dynarec_log(LOG_DEBUG, "FreeInvalidDynablock(%p), db->block=%p x64=%p:%p\n", db, db->block, db->x64_addr, db->x64_addr + db->x64_size - 1);
|
||||
uintptr_t db_size = db->x64_size;
|
||||
if(need_lock)
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
if(db_size && my_context && BOX64ENV(dynarec_dirty)) {
|
||||
// need_lock is also used to check if db_size needs to be decremented...
|
||||
if(need_lock && db_size && my_context && BOX64ENV(dynarec_dirty)) {
|
||||
uint32_t n = rb_dec(my_context->db_sizes, db_size, db_size+1);
|
||||
if(!n && (db_size >= my_context->max_db_size)) {
|
||||
my_context->max_db_size = rb_get_rightmost(my_context->db_sizes);
|
||||
dynarec_log(LOG_INFO, "BOX64 Dynarec: lower max_db=%d\n", my_context->max_db_size);
|
||||
}
|
||||
}
|
||||
FreeDynarecMap((uintptr_t)db->actual_block); // will also free db
|
||||
DeferFreeDynablockMap(db);
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
}
|
||||
@@ -153,16 +144,12 @@ void FreeDynablock(dynablock_t* db, int need_lock, int need_remove)
|
||||
dynarec_log(LOG_INFO, "BOX64 Dynarec: lower max_db=%d\n", my_context->max_db_size);
|
||||
}
|
||||
}
|
||||
if(db->previous)
|
||||
FreeInvalidDynablock(db->previous, 0);
|
||||
FreeDynarecMap((uintptr_t)db->actual_block); // will also free db
|
||||
DeferFreeDynablockMap(db);
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MarkDynablock(dynablock_t* db)
|
||||
{
|
||||
if(db) {
|
||||
@@ -175,13 +162,10 @@ void MarkDynablock(dynablock_t* db)
|
||||
db = getDB((uintptr_t)old->x64_addr);
|
||||
if(!old->gone && db!=old) {
|
||||
printf_log(LOG_INFO, "Warning, couldn't mark block as dirty for %p, block=%p, current_block=%p\n", old->x64_addr, old, db);
|
||||
// the block is lost, need to invalidate it...
|
||||
// the block is lost, need to invalidate and defer its free
|
||||
old->gone = 1;
|
||||
old->done = 0;
|
||||
if(!db || db->previous)
|
||||
FreeInvalidDynablock(old, 1);
|
||||
else
|
||||
db->previous = old;
|
||||
FreeInvalidDynablock(old, 1);
|
||||
}
|
||||
#ifdef ARCH_NOP
|
||||
} else {
|
||||
@@ -288,7 +272,7 @@ dynablock_t* CreateDBnoAlt(x64emu_t* emu, uintptr_t addr, int is32bits)
|
||||
return NULL if block is not found / cannot be created.
|
||||
Don't create if create==0
|
||||
*/
|
||||
static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int need_lock, int is32bits, int is_new)
|
||||
dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int need_lock, int is32bits, int is_new)
|
||||
{
|
||||
const uint32_t req_prot = (box64_pagesize==4096)?(PROT_EXEC|PROT_READ):PROT_READ;
|
||||
if(BOX64ENV(nodynarec_delay) && (addr>=BOX64ENV(nodynarec_start)) && (addr<BOX64ENV(nodynarec_end)))
|
||||
@@ -386,51 +370,16 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, int create
|
||||
return block;
|
||||
}
|
||||
|
||||
dynablock_t* DBSwapInvalid(x64emu_t* emu, dynablock_t* db, uintptr_t addr, int is32bits, int need_lock)
|
||||
void FlushZombieDynablocks(void)
|
||||
{
|
||||
if(need_lock)
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
db->done = 0; // invalidating the block
|
||||
dynarec_log(LOG_DEBUG, "Invalidating alt block %p from %p:%p (hash:%X, gone:%d, autocrc:%d, to_delete:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size, db->hash, db->gone, db->autocrc, db->to_delete, (void*)addr);
|
||||
// Free db, it's now invalid!
|
||||
dynablock_t* old = InvalidDynablock(db, 0);
|
||||
if(old->previous) {
|
||||
dynarec_log(LOG_DEBUG, "Free alt alt block %p\n", db->previous);
|
||||
FreeInvalidDynablock(db->previous, 0);
|
||||
old->previous = NULL;
|
||||
if (!my_context) return;
|
||||
if (!my_context->db_zombie_count) return;
|
||||
int head = my_context->db_zombie_head;
|
||||
for (int i = 0; i < my_context->db_zombie_count; ++i) {
|
||||
int idx = (head - my_context->db_zombie_count + i + DB_ZOMBIE_SIZE) % DB_ZOMBIE_SIZE;
|
||||
FreeDynarecMap((uintptr_t)my_context->db_zombie[idx]->actual_block);
|
||||
}
|
||||
// start again... (will create a new block)
|
||||
db = internalDBGetBlock(emu, addr, 1, 0, is32bits, 0);
|
||||
if(db) {
|
||||
if(db->previous)
|
||||
FreeInvalidDynablock(db->previous, 0);
|
||||
db->previous = old;
|
||||
} else
|
||||
FreeInvalidDynablock(old, 0);
|
||||
if(need_lock)
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
return db;
|
||||
}
|
||||
|
||||
dynablock_t* DBSwitchPrevious(x64emu_t* emu, dynablock_t* db, uintptr_t addr, int need_lock)
|
||||
{
|
||||
dynarec_log(LOG_DEBUG, "Switching to alt block %p from %p:%p (hash:%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size, db->hash, (void*)addr);
|
||||
db = SwitchDynablock(db, need_lock);
|
||||
if(!addJumpTableIfDefault64(db->x64_addr, (db->always_test)?db->jmpnext:db->block)) {
|
||||
FreeDynablock(db, need_lock, 0);
|
||||
db = getDB(addr);
|
||||
MarkDynablock(db); // just in case...
|
||||
} else {
|
||||
for(int i=0; i<db->sep_size; ++i) {
|
||||
uint32_t x64_offs = db->sep[i].x64_offs;
|
||||
uint32_t nat_offs = db->sep[i].nat_offs;
|
||||
if(addJumpTableIfDefault64(db->x64_addr+x64_offs, (db->always_test)?db->jmpnext:(db->block+nat_offs)))
|
||||
db->sep[i].active = 1;
|
||||
else
|
||||
db->sep[i].active = 0;
|
||||
}
|
||||
}
|
||||
return db;
|
||||
my_context->db_zombie_count = 0;
|
||||
}
|
||||
|
||||
dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
|
||||
@@ -444,18 +393,16 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
|
||||
uint32_t hash = X31_hash_code((void*)db->x64_readaddr, db->x64_size);
|
||||
mutex_lock(&my_context->mutex_dyndump)?1:0;
|
||||
if(hash!=db->hash) {
|
||||
if(is_inhotpage && db->previous) {
|
||||
// check alternate
|
||||
if(db->previous && !db->dirty && X31_hash_code((void*)db->previous->x64_readaddr, db->previous->x64_size)==db->previous->hash) {
|
||||
db = DBSwitchPrevious(emu, db, addr, 0);
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
return db;
|
||||
}
|
||||
if (is_inhotpage) {
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
dynarec_log(LOG_DEBUG, "Cannot run block (or previous) %p from %p:%p (hash:%X/%X, always_test:%d, previous=%p/hash=%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, db->always_test,db->previous, db->previous?db->previous->hash:0,(void*)addr);
|
||||
return NULL; // will be handle when hotpage is over
|
||||
dynarec_log(LOG_DEBUG, "Cannot run block %p from %p:%p (hash:%X/%X, always_test:%d) for %p, hotpage\n", db, db->x64_addr, db->x64_addr + db->x64_size - 1, hash, db->hash, db->always_test, (void*)addr);
|
||||
return NULL; // will be handled when hotpage is over
|
||||
}
|
||||
db = DBSwapInvalid(emu, db, addr, is32bits, 0);
|
||||
db->done = 0;
|
||||
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X, gone:%d, autocrc:%d, to_delete:%d) for %p\n", db, db->x64_addr, db->x64_addr + db->x64_size, db->hash, db->gone, db->autocrc, db->to_delete, (void*)addr);
|
||||
dynablock_t* old = InvalidDynablock(db, 0);
|
||||
FreeInvalidDynablock(old, 0);
|
||||
db = internalDBGetBlock(emu, addr, 1, 0, is32bits, 0);
|
||||
} else {
|
||||
if(is_inhotpage) {
|
||||
db->always_test = 2;
|
||||
|
||||
@@ -20,7 +20,6 @@ typedef struct sep_s {
|
||||
typedef struct dynablock_s {
|
||||
void* block; // block-sizeof(void*) == self
|
||||
void* actual_block; // the actual start of the block (so block-sizeof(void*))
|
||||
struct dynablock_s* previous; // a previous block that might need to be freed
|
||||
uint32_t in_used;// will be 0 if not in_used, >0 if used be some code
|
||||
uint32_t tick; // last "tick" when dynablock was run
|
||||
void* x64_addr;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "dynacache_compress.h"
|
||||
#include "debug.h"
|
||||
#include "custommem.h"
|
||||
|
||||
static void* libz = NULL;
|
||||
static int libz_init = 0;
|
||||
|
||||
typedef size_t(*LFL_t)(size_t);
|
||||
typedef int(*iFpppL_t)(void*, void*, void*, size_t);
|
||||
typedef int(*iFpppLi_t)(void*, void*, void*, size_t, int);
|
||||
|
||||
static iFpppL_t libz_uncompress = NULL;
|
||||
static iFpppLi_t libz_compress2 = NULL;
|
||||
static LFL_t libz_compressBound = NULL;
|
||||
|
||||
static void init_libz()
|
||||
{
|
||||
libz_init = 1;
|
||||
libz = dlopen("libz.so.1", RTLD_LAZY);
|
||||
if(!libz) libz = dlopen("libz.so", RTLD_LAZY);
|
||||
if(!libz) return;
|
||||
libz_compress2 = dlsym(libz, "compress2");
|
||||
libz_uncompress = dlsym(libz, "uncompress");
|
||||
libz_compressBound = dlsym(libz, "compressBound");
|
||||
}
|
||||
|
||||
void* z_compress(void* src, size_t src_size, int type, size_t* dest_size)
|
||||
{
|
||||
if(!libz_init)
|
||||
init_libz();
|
||||
if(!libz_compress2 || !libz_compressBound)
|
||||
return NULL;
|
||||
size_t sz = libz_compressBound(src_size);
|
||||
void* dest = box_malloc(sz);
|
||||
int ret = libz_compress2(dest, &sz, src, src_size, (type==COMP_Z_MAX)?-1:1);
|
||||
if(ret) {
|
||||
printf_log(LOG_DEBUG, "Failed to compress a DynaCache block (%d)\n", ret);
|
||||
box_free(dest);
|
||||
return NULL;
|
||||
} else
|
||||
*dest_size = sz;
|
||||
return dest;
|
||||
}
|
||||
|
||||
void* dc_compress(void* src, size_t src_size, int type, size_t* dest_size)
|
||||
{
|
||||
switch(type) {
|
||||
case COMP_Z:
|
||||
case COMP_Z_MAX:
|
||||
return z_compress(src, src_size, type, dest_size);
|
||||
case COMP_NONE:
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int z_uncompress(void* src, size_t src_size, void* dest, size_t dest_size)
|
||||
{
|
||||
if(!libz_init)
|
||||
init_libz();
|
||||
if(!libz_uncompress)
|
||||
return -1;
|
||||
size_t sz = dest_size;
|
||||
int ret = libz_uncompress(dest, &sz, src, src_size);
|
||||
if(ret) {
|
||||
printf_log(LOG_DEBUG, "Failed to uncompress a DynaCache block (%d)\n", ret);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dc_uncompress(void* src, size_t src_size, int type, void* dest, size_t dest_size)
|
||||
{
|
||||
switch(type) {
|
||||
case COMP_Z:
|
||||
case COMP_Z_MAX:
|
||||
return z_uncompress(src, src_size, dest, dest_size);
|
||||
case COMP_NONE:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -106,14 +106,17 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
|
||||
}
|
||||
void* LinkNextInvalid(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
|
||||
{
|
||||
// like LinkNext, but invalid the db found first
|
||||
// like LinkNext, but invalidate the db found first
|
||||
int is32bits = (R_CS == 0x23);
|
||||
dynablock_t* db = getDB(addr);
|
||||
if(db) {
|
||||
if(db->previous && !db->dirty && X31_hash_code(db->previous->x64_addr, db->previous->x64_size)==db->previous->hash)
|
||||
db = DBSwitchPrevious(emu, db, addr, 1);
|
||||
else
|
||||
db = DBSwapInvalid(emu, db, addr, is32bits, 1);
|
||||
mutex_lock(&my_context->mutex_dyndump);
|
||||
db->done = 0;
|
||||
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X, gone:%d, autocrc:%d, to_delete:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size, db->hash, db->gone, db->autocrc, db->to_delete, (void*)addr);
|
||||
dynablock_t* old = InvalidDynablock(db, 0);
|
||||
FreeInvalidDynablock(old, 0);
|
||||
db = internalDBGetBlock(emu, addr, 1, 0, is32bits, 0);
|
||||
mutex_unlock(&my_context->mutex_dyndump);
|
||||
if(db && db->done && db->block) {
|
||||
void* jblock = db->block;
|
||||
if(db->sep_size && (uintptr_t)db->x64_addr!=addr) {
|
||||
|
||||
@@ -77,7 +77,7 @@ extern void la64_crc_autocrc(); // same as la64_crc, but not using regular ABI
|
||||
#define ARCH_CRC(A, B) return la64_crc(A, B)
|
||||
|
||||
#define ARCH_NOP (0b0000001101<<22)
|
||||
#define ARCH_UDF 0b1010100
|
||||
#define ARCH_UDF 0x38600400
|
||||
|
||||
#define JMPNEXT_SIZE (4*sizeof(void*))
|
||||
#define ADDITIONNAL_CHECKS()
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include "khash.h"
|
||||
|
||||
KHASH_MAP_INIT_INT64(table64, uint32_t)
|
||||
KHASH_SET_INIT_INT64(nextset)
|
||||
|
||||
static kh_nextset_t* khnextset = NULL;
|
||||
|
||||
void printf_x64_instruction(dynarec_native_t* dyn, zydis_dec_t* dec, instruction_x64_t* inst, const char* name) {
|
||||
uint8_t *ip = (uint8_t*)inst->addr;
|
||||
@@ -65,16 +68,10 @@ void printf_x64_instruction(dynarec_native_t* dyn, zydis_dec_t* dec, instruction
|
||||
void add_next(dynarec_native_t *dyn, uintptr_t addr) {
|
||||
if (!BOX64DRENV(dynarec_bigblock))
|
||||
return;
|
||||
// exist?
|
||||
for(int i=0; i<dyn->next_sz; ++i)
|
||||
if(dyn->next[i]==addr)
|
||||
return;
|
||||
// put in a free slot
|
||||
for(int i=0; i<dyn->next_sz; ++i)
|
||||
if(!dyn->next[i]) {
|
||||
dyn->next[i] = addr;
|
||||
return;
|
||||
}
|
||||
int ret;
|
||||
kh_put(nextset, khnextset, addr, &ret);
|
||||
if(!ret)
|
||||
return;
|
||||
// add slots
|
||||
if(dyn->next_sz == dyn->next_cap) {
|
||||
printf_log(LOG_NONE, "Warning, overallocating next\n");
|
||||
@@ -85,15 +82,19 @@ uintptr_t get_closest_next(dynarec_native_t *dyn, uintptr_t addr) {
|
||||
// get closest, but no addresses before
|
||||
uintptr_t best = 0;
|
||||
int i = 0;
|
||||
while((i<dyn->next_sz) && (best!=addr)) {
|
||||
if(dyn->next[i]) {
|
||||
if(dyn->next[i]<addr) { // remove the address, it's before current address
|
||||
dyn->next[i] = 0;
|
||||
} else {
|
||||
if((dyn->next[i]<best) || !best)
|
||||
best = dyn->next[i];
|
||||
while(i<dyn->next_sz) {
|
||||
uintptr_t next = dyn->next[i];
|
||||
if(!next || next<addr) {
|
||||
if(next) {
|
||||
khint_t k = kh_get(nextset, khnextset, next);
|
||||
if(k != kh_end(khnextset))
|
||||
kh_del(nextset, khnextset, k);
|
||||
}
|
||||
dyn->next[i] = dyn->next[--dyn->next_sz];
|
||||
continue;
|
||||
}
|
||||
if((next<best) || !best)
|
||||
best = next;
|
||||
++i;
|
||||
}
|
||||
return best;
|
||||
@@ -472,6 +473,9 @@ dynablock_t* FillBlock64(uintptr_t addr, int is32bits, int inst_max, int is_new,
|
||||
// init the helper
|
||||
dynarec_native_t helper = {0};
|
||||
dynarec_native_t* dyn = &helper;
|
||||
if(!khnextset)
|
||||
khnextset = kh_init(nextset);
|
||||
kh_clear(nextset, khnextset);
|
||||
#ifdef GDBJIT
|
||||
helper.gdbjit_block = box_calloc(1, sizeof(gdbjit_block_t));
|
||||
#endif
|
||||
|
||||
@@ -291,7 +291,7 @@ void native_fsave(x64emu_t* emu, uint8_t* ed)
|
||||
uint8_t* p = ed;
|
||||
p += 28;
|
||||
for (int i=0; i<8; ++i) {
|
||||
LD2D(p, &emu->x87[7-i].d);
|
||||
LD2D(p, &ST(i).d);
|
||||
p+=10;
|
||||
}
|
||||
reset_fpu(emu);
|
||||
@@ -303,7 +303,7 @@ void native_fsave16(x64emu_t* emu, uint8_t* ed)
|
||||
uint8_t* p = ed;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
LD2D(p, &emu->x87[7-i].d);
|
||||
LD2D(p, &ST(i).d);
|
||||
p+=10;
|
||||
}
|
||||
reset_fpu(emu);
|
||||
@@ -315,7 +315,7 @@ void native_frstor(x64emu_t* emu, uint8_t* ed)
|
||||
uint8_t* p = ed;
|
||||
p += 28;
|
||||
for (int i=0; i<8; ++i) {
|
||||
D2LD(&emu->x87[7-i].d, p);
|
||||
D2LD(&ST(i).d, p);
|
||||
p+=10;
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ void native_frstor16(x64emu_t* emu, uint8_t* ed)
|
||||
uint8_t* p = ed;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
D2LD(&emu->x87[7-i].d, p);
|
||||
D2LD(&ST(i).d, p);
|
||||
p+=10;
|
||||
}
|
||||
|
||||
@@ -704,51 +704,67 @@ void native_aeskeygenassist(x64emu_t* emu, int gx, int ex, void* p, uint32_t u8)
|
||||
GX->ud[3] ^= u8;
|
||||
}
|
||||
|
||||
static inline __int128 pclmul_4bit(uint64_t a, uint64_t b)
|
||||
{
|
||||
__uint128_t result = 0;
|
||||
__uint128_t op2 = b;
|
||||
__uint128_t table[16];
|
||||
table[0] = 0;
|
||||
table[1] = op2;
|
||||
table[2] = op2 << 1;
|
||||
table[3] = table[2] ^ table[1];
|
||||
table[4] = op2 << 2;
|
||||
table[5] = table[4] ^ table[1];
|
||||
table[6] = table[4] ^ table[2];
|
||||
table[7] = table[6] ^ table[1];
|
||||
table[8] = op2 << 3;
|
||||
table[9] = table[8] ^ table[1];
|
||||
table[10] = table[8] ^ table[2];
|
||||
table[11] = table[10] ^ table[1];
|
||||
table[12] = table[8] ^ table[4];
|
||||
table[13] = table[12] ^ table[1];
|
||||
table[14] = table[12] ^ table[2];
|
||||
table[15] = table[14] ^ table[1];
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
result ^= table[(a >> (i * 4)) & 0xf] << (i * 4);
|
||||
}
|
||||
return (__int128)result;
|
||||
}
|
||||
|
||||
void native_pclmul(x64emu_t* emu, int gx, int ex, void* p, uint32_t u8)
|
||||
{
|
||||
sse_regs_t *EX = p?((sse_regs_t*)p):&emu->xmm[ex];
|
||||
sse_regs_t *GX = &emu->xmm[gx];
|
||||
int g = (u8&1)?1:0;
|
||||
int e = (u8&0b10000)?1:0;
|
||||
__int128 result = 0;
|
||||
__int128 op2 = EX->q[e];
|
||||
for (int i=0; i<64; ++i)
|
||||
if(GX->q[g]&(1LL<<i))
|
||||
result ^= (op2<<i);
|
||||
GX->u128 = result;
|
||||
sse_regs_t* EX = p ? ((sse_regs_t*)p) : &emu->xmm[ex];
|
||||
sse_regs_t* GX = &emu->xmm[gx];
|
||||
int g = (u8 & 1) ? 1 : 0;
|
||||
int e = (u8 & 0b10000) ? 1 : 0;
|
||||
|
||||
GX->u128 = pclmul_4bit(GX->q[g], EX->q[e]);
|
||||
}
|
||||
|
||||
void native_pclmul_x(x64emu_t* emu, int gx, int vx, void* p, uint32_t u8)
|
||||
{
|
||||
sse_regs_t* EX = ((uintptr_t)p > 15) ? (sse_regs_t*)p : &emu->xmm[(uintptr_t)p];
|
||||
sse_regs_t* GX = &emu->xmm[gx];
|
||||
sse_regs_t* VX = &emu->xmm[vx];
|
||||
int g = (u8 & 1) ? 1 : 0;
|
||||
int e = (u8 & 0b10000) ? 1 : 0;
|
||||
|
||||
sse_regs_t *EX = ((uintptr_t)p>15)?((sse_regs_t*)p):&emu->xmm[(uintptr_t)p];
|
||||
sse_regs_t *GX = &emu->xmm[gx];
|
||||
sse_regs_t *VX = &emu->xmm[vx];
|
||||
int g = (u8&1)?1:0;
|
||||
int e = (u8&0b10000)?1:0;
|
||||
__int128 result = 0;
|
||||
__int128 op2 = EX->q[e];
|
||||
for (int i=0; i<64; ++i)
|
||||
if(VX->q[g]&(1LL<<i))
|
||||
result ^= (op2<<i);
|
||||
|
||||
GX->u128 = result;
|
||||
GX->u128 = pclmul_4bit(VX->q[g], EX->q[e]);
|
||||
}
|
||||
|
||||
void native_pclmul_y(x64emu_t* emu, int gy, int vy, void* p, uint32_t u8)
|
||||
{
|
||||
//compute both low and high values
|
||||
native_pclmul_x(emu, gy, vy, p, u8);
|
||||
sse_regs_t *EY = ((uintptr_t)p>15)?((sse_regs_t*)(p+16)):&emu->ymm[(uintptr_t)p];
|
||||
sse_regs_t *GY = &emu->ymm[gy];
|
||||
sse_regs_t *VY = &emu->ymm[vy];
|
||||
int g = (u8&1)?1:0;
|
||||
int e = (u8&0b10000)?1:0;
|
||||
__int128 result = 0;
|
||||
__int128 op2 = EY->q[e];
|
||||
for (int i=0; i<64; ++i)
|
||||
if(VY->q[g]&(1LL<<i))
|
||||
result ^= (op2<<i);
|
||||
|
||||
GY->u128 = result;
|
||||
sse_regs_t* EY = ((uintptr_t)p > 15) ? (sse_regs_t*)((char*)p + 16)
|
||||
: &emu->ymm[(uintptr_t)p];
|
||||
sse_regs_t* GY = &emu->ymm[gy];
|
||||
sse_regs_t* VY = &emu->ymm[vy];
|
||||
int g = (u8 & 1) ? 1 : 0;
|
||||
int e = (u8 & 0b10000) ? 1 : 0;
|
||||
|
||||
GY->u128 = pclmul_4bit(VY->q[g], EY->q[e]);
|
||||
}
|
||||
|
||||
static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) {
|
||||
|
||||
@@ -54,6 +54,46 @@ static int dynarec_can_read_window(uintptr_t addr, uintptr_t size)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define X64_PREFIX_LOCK 1
|
||||
#define X64_PREFIX_REP_F2 2
|
||||
#define X64_PREFIX_REP_F3 3
|
||||
#define X64_PREFIX_SEG0 4
|
||||
#define X64_PREFIX_FS 5
|
||||
#define X64_PREFIX_GS 6
|
||||
#define X64_PREFIX_66 7
|
||||
#define X64_PREFIX_67 8
|
||||
#define X64_PREFIX_REX 9
|
||||
|
||||
static const uint8_t x64_prefix_kind[256] = {
|
||||
[0x26] = X64_PREFIX_SEG0,
|
||||
[0x2e] = X64_PREFIX_SEG0,
|
||||
[0x36] = X64_PREFIX_SEG0,
|
||||
[0x3e] = X64_PREFIX_SEG0,
|
||||
[0x40] = X64_PREFIX_REX,
|
||||
[0x41] = X64_PREFIX_REX,
|
||||
[0x42] = X64_PREFIX_REX,
|
||||
[0x43] = X64_PREFIX_REX,
|
||||
[0x44] = X64_PREFIX_REX,
|
||||
[0x45] = X64_PREFIX_REX,
|
||||
[0x46] = X64_PREFIX_REX,
|
||||
[0x47] = X64_PREFIX_REX,
|
||||
[0x48] = X64_PREFIX_REX,
|
||||
[0x49] = X64_PREFIX_REX,
|
||||
[0x4a] = X64_PREFIX_REX,
|
||||
[0x4b] = X64_PREFIX_REX,
|
||||
[0x4c] = X64_PREFIX_REX,
|
||||
[0x4d] = X64_PREFIX_REX,
|
||||
[0x4e] = X64_PREFIX_REX,
|
||||
[0x4f] = X64_PREFIX_REX,
|
||||
[0x64] = X64_PREFIX_FS,
|
||||
[0x65] = X64_PREFIX_GS,
|
||||
[0x66] = X64_PREFIX_66,
|
||||
[0x67] = X64_PREFIX_67,
|
||||
[0xf0] = X64_PREFIX_LOCK,
|
||||
[0xf2] = X64_PREFIX_REP_F2,
|
||||
[0xf3] = X64_PREFIX_REP_F3,
|
||||
};
|
||||
|
||||
uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits, int inst_max)
|
||||
{
|
||||
int ok = 1;
|
||||
@@ -217,9 +257,15 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
|
||||
if((trace_end == 0)
|
||||
|| ((ip >= trace_start) && (ip < trace_end))) {
|
||||
MESSAGE(LOG_DUMP, "TRACE ----\n");
|
||||
#if defined (SPILL_NF_REGISTERS)
|
||||
if (BOX64ENV(dynarec_nativeflags)) SPILL_NF_REGISTERS;
|
||||
#endif
|
||||
fpu_reflectcache(dyn, ninst, x1, x2, x3);
|
||||
GO_TRACE(PrintTrace, 1, x5);
|
||||
fpu_unreflectcache(dyn, ninst, x1, x2, x3);
|
||||
#if defined (RESTORE_NF_REGISTERS)
|
||||
if (BOX64ENV(dynarec_nativeflags)) RESTORE_NF_REGISTERS;
|
||||
#endif
|
||||
MESSAGE(LOG_DUMP, "----------\n");
|
||||
}
|
||||
}
|
||||
@@ -235,27 +281,22 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
|
||||
rex.is67 = 0;
|
||||
rex.isf0 = 0;
|
||||
rex.rep = 0;
|
||||
while((pk==0xF2) || (pk==0xF3) || (pk==0xf0)
|
||||
|| (pk==0x3E) || (pk==0x26) || (pk==0x2e) || (pk==0x36)
|
||||
|| (pk==0x64) || (pk==0x65) || (pk==0x66) || (pk==0x67)
|
||||
|| (!is32bits && (pk>=0x40 && pk<=0x4f))) {
|
||||
switch (pk) {
|
||||
case 0xF0: rex.isf0 = 1; rex.rex = 0; break;
|
||||
case 0xF2: rex.rep = 1; rex.rex = 0; break;
|
||||
case 0xF3: rex.rep = 2; rex.rex = 0; break;
|
||||
case 0x26: /* ES: */
|
||||
case 0x2E: /* CS: */
|
||||
case 0x36: /* SS; */
|
||||
case 0x3E: /* DS; */
|
||||
rex.seg = 0; rex.rex = 0; break;
|
||||
case 0x64: rex.seg = _FS; rex.rex = 0; break;
|
||||
case 0x65: rex.seg = _GS; rex.rex = 0; break;
|
||||
case 0x66: rex.is66 = 1; rex.rex = 0; break;
|
||||
case 0x67: rex.is67 = 1; rex.rex = 0; break;
|
||||
case 0x40 ... 0x4F: rex.rex = pk; break;
|
||||
uint8_t prefix = x64_prefix_kind[pk];
|
||||
while(prefix && (prefix!=X64_PREFIX_REX || !is32bits)) {
|
||||
switch (prefix) {
|
||||
case X64_PREFIX_LOCK: rex.isf0 = 1; rex.rex = 0; break;
|
||||
case X64_PREFIX_REP_F2: rex.rep = 1; rex.rex = 0; break;
|
||||
case X64_PREFIX_REP_F3: rex.rep = 2; rex.rex = 0; break;
|
||||
case X64_PREFIX_SEG0: rex.seg = 0; rex.rex = 0; break;
|
||||
case X64_PREFIX_FS: rex.seg = _FS; rex.rex = 0; break;
|
||||
case X64_PREFIX_GS: rex.seg = _GS; rex.rex = 0; break;
|
||||
case X64_PREFIX_66: rex.is66 = 1; rex.rex = 0; break;
|
||||
case X64_PREFIX_67: rex.is67 = 1; rex.rex = 0; break;
|
||||
case X64_PREFIX_REX: rex.rex = pk; break;
|
||||
}
|
||||
++addr;
|
||||
pk = PK(0);
|
||||
prefix = x64_prefix_kind[pk];
|
||||
}
|
||||
if(rex.isf0) {
|
||||
if(rex.is66 && !rex.w)
|
||||
|
||||
@@ -3123,7 +3123,11 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
case 0xD7:
|
||||
INST_NAME("XLAT");
|
||||
BSTRPICK_D(x1, xRAX, 7, 0);
|
||||
LDXxw(x1, xRBX, x1);
|
||||
if (rex.seg) {
|
||||
grab_segdata(dyn, addr, ninst, x2, rex.seg);
|
||||
ADD_D(x1, x1, x2);
|
||||
}
|
||||
LDX_BU(x1, xRBX, x1);
|
||||
BSTRINS_D(xRAX, x1, 7, 0);
|
||||
break;
|
||||
case 0xD8:
|
||||
@@ -3281,7 +3285,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
break;
|
||||
case 0xE8:
|
||||
INST_NAME("CALL Id");
|
||||
i32 = F32S;
|
||||
i32 = (rex.is32bits && rex.is66) ? F16S : F32S;
|
||||
if (addr + i32 == 0) {
|
||||
#if STEP == 3
|
||||
printf_log(LOG_INFO, "Warning, CALL to 0x0 at %p (%p)\n", (void*)addr, (void*)(addr - 1));
|
||||
@@ -3429,35 +3433,42 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
case 0xE9:
|
||||
case 0xEB:
|
||||
BARRIER(BARRIER_MAYBE);
|
||||
if (opcode == 0xE9) {
|
||||
INST_NAME("JMP Id");
|
||||
i32 = F32S;
|
||||
if(opcode==0xEB && PK(0)==0xFF) {
|
||||
INST_NAME("JMP ib");
|
||||
MESSAGE(LOG_DEBUG, "Hack for EB FF opcode");
|
||||
NOP();
|
||||
} else {
|
||||
INST_NAME("JMP Ib");
|
||||
i32 = F8S;
|
||||
}
|
||||
if (rex.is32bits)
|
||||
j64 = (uint32_t)(addr + i32);
|
||||
else
|
||||
j64 = addr + i32;
|
||||
JUMP((uintptr_t)getAlternate((void*)j64), 0);
|
||||
if (dyn->insts[ninst].x64.jmp_insts == -1) {
|
||||
// out of the block
|
||||
BARRIER(BARRIER_FLOAT);
|
||||
jump_to_next(dyn, (uintptr_t)getAlternate((void*)j64), 0, ninst, rex.is32bits);
|
||||
} else {
|
||||
// inside the block
|
||||
CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3);
|
||||
tmp = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size);
|
||||
MESSAGE(1, "Jump to %d / 0x%x\n", tmp, tmp);
|
||||
if (tmp == 4) {
|
||||
NOP();
|
||||
if (opcode == 0xE9) {
|
||||
INST_NAME("JMP Id");
|
||||
i32 = F32S;
|
||||
} else {
|
||||
B(tmp);
|
||||
INST_NAME("JMP Ib");
|
||||
i32 = F8S;
|
||||
}
|
||||
if (rex.is32bits)
|
||||
j64 = (uint32_t)(addr + i32);
|
||||
else
|
||||
j64 = addr + i32;
|
||||
j64 = (uintptr_t)getAlternate((void*)j64);
|
||||
JUMP(j64, 0);
|
||||
if (dyn->insts[ninst].x64.jmp_insts == -1) {
|
||||
// out of the block
|
||||
BARRIER(BARRIER_FLOAT);
|
||||
jump_to_next(dyn, (uintptr_t)getAlternate((void*)j64), 0, ninst, rex.is32bits);
|
||||
} else {
|
||||
// inside the block
|
||||
CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3);
|
||||
tmp = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size);
|
||||
MESSAGE(1, "Jump to %d / 0x%x\n", tmp, tmp);
|
||||
if (tmp == 4) {
|
||||
NOP();
|
||||
} else {
|
||||
B(tmp);
|
||||
}
|
||||
}
|
||||
*need_epilog = 0;
|
||||
*ok = 0;
|
||||
}
|
||||
*need_epilog = 0;
|
||||
*ok = 0;
|
||||
break;
|
||||
case 0xEA:
|
||||
if (rex.is32bits) {
|
||||
|
||||
@@ -81,7 +81,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
switch ((nextop >> 3) & 7) {
|
||||
case 0:
|
||||
INST_NAME("SGDT Ed");
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 0, 0);
|
||||
MOV32w(x1, 0x7f);
|
||||
ST_H(x1, wback, 0);
|
||||
if (rex.is32bits) {
|
||||
@@ -94,7 +94,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("SIDT Ed");
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 0, 0);
|
||||
MOV32w(x1, 0xfff);
|
||||
ST_H(x1, wback, 0);
|
||||
if (rex.is32bits) {
|
||||
@@ -357,12 +357,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
INST_NAME("MOVNTPS Ex, Gx");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if (MODREG) {
|
||||
ed = (nextop & 7) + (rex.b << 3);
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
|
||||
VOR_V(v1, v0, v0);
|
||||
DEFAULT;
|
||||
} else {
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
|
||||
VST(v0, ed, fixedaddress);
|
||||
}
|
||||
@@ -483,10 +481,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
RDTIME_D(x3, xZR);
|
||||
}
|
||||
if (box64_rdtsc_shift) {
|
||||
SRLI_D(x3, x3, box64_rdtsc_shift);
|
||||
SLLI_D(x3, x3, box64_rdtsc_shift);
|
||||
}
|
||||
SRLI_D(xRDX, x3, 32);
|
||||
ZEROUP2(xRDX, x3);
|
||||
ZEROUP2(xRAX, x3);
|
||||
break;
|
||||
case 0x38:
|
||||
// SSE3
|
||||
@@ -503,8 +501,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
VLDI(v0, 0b0000010000111); // broadcast 0b10000111 as byte
|
||||
VAND_V(v0, v0, q1);
|
||||
VMINI_BU(v0, v0, 0x1f);
|
||||
VXOR_V(v1, v1, v1);
|
||||
VSHUF_B(q0, v1, q0, v0);
|
||||
VSHUF_B(q0, VZERO, q0, v0);
|
||||
break;
|
||||
case 0x01:
|
||||
INST_NAME("PHADDW Gm, Em");
|
||||
@@ -641,27 +638,21 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
nextop = F8;
|
||||
GETGM(q0);
|
||||
GETEM(q1, 0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_B(q0, q1, v0);
|
||||
VABSD_B(q0, q1, VZERO);
|
||||
break;
|
||||
case 0x1D:
|
||||
INST_NAME("PABSW Gm, Em");
|
||||
nextop = F8;
|
||||
GETGM(q0);
|
||||
GETEM(q1, 0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_H(q0, q1, v0);
|
||||
VABSD_H(q0, q1, VZERO);
|
||||
break;
|
||||
case 0x1E:
|
||||
INST_NAME("PABSD Gm, Em");
|
||||
nextop = F8;
|
||||
GETGM(q0);
|
||||
GETEM(q1, 0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_W(q0, q1, v0);
|
||||
VABSD_W(q0, q1, VZERO);
|
||||
break;
|
||||
case 0xC8 ... 0xCD:
|
||||
u8 = nextop;
|
||||
@@ -1711,7 +1702,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
BARRIER(BARRIER_FLOAT);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 0);
|
||||
MOV32w(x2, rex.w ? 0 : 1);
|
||||
MOV32w(x2, rex.is32bits);
|
||||
CALL(const_fpu_xsave, -1, ed, x2);
|
||||
break;
|
||||
case 5:
|
||||
@@ -1719,7 +1710,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
BARRIER(BARRIER_FLOAT);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 0);
|
||||
MOV32w(x2, rex.w ? 0 : 1);
|
||||
MOV32w(x2, rex.is32bits);
|
||||
CALL(const_fpu_xrstor, -1, ed, x2);
|
||||
break;
|
||||
case 7:
|
||||
@@ -1999,6 +1990,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) ORI(xFlags, xFlags, 1 << F_PF);
|
||||
}
|
||||
if (!rex.w) ZEROUP(gd);
|
||||
B_MARK2_nocond;
|
||||
MARK;
|
||||
CTZxw(gd, ed);
|
||||
@@ -2029,6 +2021,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) ORI(xFlags, xFlags, 1 << F_PF);
|
||||
}
|
||||
if (!rex.w) ZEROUP(gd);
|
||||
B_MARK2_nocond;
|
||||
MARK;
|
||||
CLZxw(gd, ed);
|
||||
|
||||
@@ -132,6 +132,8 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
emit_adc16(dyn, ninst, gd, ed, x4, x6, x5);
|
||||
GWBACK;
|
||||
break;
|
||||
case 0x14:
|
||||
return dynarec64_00(dyn, addr - 1, ip, ninst, rex, ok, need_epilog);
|
||||
case 0x15:
|
||||
INST_NAME("ADC AX, Iw");
|
||||
READFLAGS(X_CF);
|
||||
@@ -1349,6 +1351,8 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
case 0xE6: /* OUT Ib, AL */
|
||||
case 0xE7: /* OUT Ib, AX */
|
||||
return dynarec64_00(dyn, addr - 1, ip, ninst, rex, ok, need_epilog);
|
||||
case 0xE8: /* CALL Imm */
|
||||
return dynarec64_00(dyn, addr - 1, ip, ninst, rex, ok, need_epilog);
|
||||
case 0xEC: /* IN AL, DX */
|
||||
case 0xED: /* IN AX, DX */
|
||||
case 0xEE: /* OUT DX, AL */
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "dynarec_la64_private.h"
|
||||
#include "dynarec_la64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_la64_aes.h"
|
||||
#include "emu/x64compstrings.h"
|
||||
|
||||
uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
|
||||
@@ -226,13 +227,11 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
case 0x2B:
|
||||
INST_NAME("MOVNTPD Ex,Gx");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
if (MODREG) {
|
||||
ed = (nextop & 7) + (rex.b << 3);
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
|
||||
VOR_V(v1, v0, v0);
|
||||
DEFAULT;
|
||||
} else {
|
||||
GETG;
|
||||
v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
|
||||
VST(v0, ed, fixedaddress);
|
||||
}
|
||||
@@ -370,8 +369,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VLDI(v0, 0b0000010001111); // broadcast 0b10001111 as byte
|
||||
VAND_V(v0, v0, q1);
|
||||
VMINI_BU(v0, v0, 0x1f);
|
||||
VXOR_V(v1, v1, v1);
|
||||
VSHUF_B(q0, v1, q0, v0);
|
||||
VSHUF_B(q0, VZERO, q0, v0);
|
||||
break;
|
||||
case 0x01:
|
||||
INST_NAME("PHADDW Gx, Ex");
|
||||
@@ -577,18 +575,14 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
nextop = F8;
|
||||
GETEX(q1, 0, 0);
|
||||
GETGX_empty(q0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_B(q0, q1, v0);
|
||||
VABSD_B(q0, q1, VZERO);
|
||||
break;
|
||||
case 0x1D:
|
||||
INST_NAME("PABSW Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(q1, 0, 0);
|
||||
GETGX_empty(q0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_H(q0, q1, v0);
|
||||
VABSD_H(q0, q1, VZERO);
|
||||
break;
|
||||
case 0x1E:
|
||||
INST_NAME("PABSD Gx, Ex");
|
||||
@@ -661,9 +655,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
INST_NAME("MOVNTDQA Gx, Ex");
|
||||
nextop = F8;
|
||||
if (MODREG) {
|
||||
v1 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0);
|
||||
GETGX_empty(v0);
|
||||
VOR_V(v0, v1, v1);
|
||||
DEFAULT;
|
||||
} else {
|
||||
GETGX_empty(v0);
|
||||
SMREAD();
|
||||
@@ -826,7 +818,12 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VMIN_HU(q2, q0, q1); // all lane is min(abcdefgh)
|
||||
VSEQ_H(q0, q2, v1); // get mask(0xffff)
|
||||
VFRSTPI_H(q2, q0, 1); // find first neg(0xffff),insert index to q2
|
||||
XVPICKVE_W(v0, q2, 0);
|
||||
if (cpuext.lasx) {
|
||||
XVPICKVE_W(v0, q2, 0);
|
||||
} else {
|
||||
VXOR_V(v0, v0, v0);
|
||||
VEXTRINS_W(v0, q2, 0);
|
||||
}
|
||||
break;
|
||||
case 0xDB:
|
||||
INST_NAME("AESIMC Gx, Ex"); // AES-NI
|
||||
@@ -836,9 +833,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
if (q0 != q1) {
|
||||
VOR_V(q0, q1, q1);
|
||||
}
|
||||
sse_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aesimc, -1, x1, 0);
|
||||
la64_aesimc_lsx(dyn, ninst, q0);
|
||||
break;
|
||||
case 0xDC:
|
||||
INST_NAME("AESENC Gx, Ex"); // AES-NI
|
||||
@@ -850,10 +845,8 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VOR_V(d0, q1, q1);
|
||||
} else
|
||||
d0 = -1;
|
||||
sse_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aese, -1, x1, 0);
|
||||
GETGX(q0, 1);
|
||||
la64_aese_lsx(dyn, ninst, q0);
|
||||
VXOR_V(q0, q0, (d0 != -1) ? d0 : q1);
|
||||
break;
|
||||
case 0xDD:
|
||||
@@ -866,10 +859,8 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VOR_V(d0, q1, q1);
|
||||
} else
|
||||
d0 = -1;
|
||||
sse_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aeselast, -1, x1, 0);
|
||||
GETGX(q0, 1);
|
||||
la64_aeselast_lsx(dyn, ninst, q0);
|
||||
VXOR_V(q0, q0, (d0 != -1) ? d0 : q1);
|
||||
break;
|
||||
case 0xDE:
|
||||
@@ -882,10 +873,8 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VOR_V(d0, q1, q1);
|
||||
} else
|
||||
d0 = -1;
|
||||
sse_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aesd, -1, x1, 0);
|
||||
GETGX(q0, 1);
|
||||
la64_aesd_lsx(dyn, ninst, q0);
|
||||
VXOR_V(q0, q0, (d0 != -1) ? d0 : q1);
|
||||
break;
|
||||
case 0xDF:
|
||||
@@ -898,10 +887,8 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VOR_V(d0, q1, q1);
|
||||
} else
|
||||
d0 = -1;
|
||||
sse_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aesdlast, -1, x1, 0);
|
||||
GETGX(q0, 1);
|
||||
la64_aesdlast_lsx(dyn, ninst, q0);
|
||||
VXOR_V(q0, q0, (d0 != -1) ? d0 : q1);
|
||||
break;
|
||||
case 0xF0:
|
||||
@@ -1255,11 +1242,10 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VEXTRINS_W(q0, q2, VEXTRINS_IMM_4_0(((u8 >> 4) & 3), 0)); // src index is zero when Ex is mem operand
|
||||
}
|
||||
uint8_t zmask = u8 & 0xf;
|
||||
VXOR_V(q2, q2, q2);
|
||||
if (zmask) {
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (zmask & (1 << i)) {
|
||||
VEXTRINS_W(q0, q2, VEXTRINS_IMM_4_0(i, 0));
|
||||
VEXTRINS_W(q0, VZERO, VEXTRINS_IMM_4_0(i, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1285,12 +1271,10 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
u8 = F8;
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
v1 = fpu_get_scratch(dyn);
|
||||
v2 = fpu_get_scratch(dyn);
|
||||
VFMUL_S(v0, q0, q1);
|
||||
VXOR_V(v2, v2, v2);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!(u8 & (1 << (4 + i)))) {
|
||||
VEXTRINS_W(v0, v2, (i << 4));
|
||||
VEXTRINS_W(v0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
VSHUF4I_W(v1, v0, 0b10110001); // v0[a,b,c,d] v1[b,a,d,c]
|
||||
@@ -1300,7 +1284,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VREPLVEI_W(q0, v0, 0);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!(u8 & (1 << i))) {
|
||||
VEXTRINS_W(q0, v2, (i << 4));
|
||||
VEXTRINS_W(q0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1312,12 +1296,10 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
u8 = F8;
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
v1 = fpu_get_scratch(dyn);
|
||||
v2 = fpu_get_scratch(dyn);
|
||||
VFMUL_D(v0, q0, q1);
|
||||
VXOR_V(v2, v2, v2);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!(u8 & (1 << (4 + i)))) {
|
||||
VEXTRINS_D(v0, v2, (i << 4));
|
||||
VEXTRINS_D(v0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
VSHUF4I_W(v1, v0, 0b01001110); // v0[a,b] v1[b,a]
|
||||
@@ -1325,7 +1307,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VREPLVEI_D(q0, v0, 0);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!(u8 & (1 << i))) {
|
||||
VEXTRINS_D(q0, v2, (i << 4));
|
||||
VEXTRINS_D(q0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1419,23 +1401,12 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
INST_NAME("AESKEYGENASSIST Gx, Ex, Ib"); // AES-NI
|
||||
nextop = F8;
|
||||
GETG;
|
||||
sse_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd); // gx
|
||||
if (MODREG) {
|
||||
ed = (nextop & 7) + (rex.b << 3);
|
||||
sse_forget_reg(dyn, ninst, ed);
|
||||
MOV32w(x2, ed);
|
||||
MOV32w(x3, 0); // p = NULL
|
||||
} else {
|
||||
MOV32w(x2, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 1);
|
||||
if (ed != x3) {
|
||||
MV(x3, ed);
|
||||
}
|
||||
}
|
||||
GETEX(q1, 0, 1);
|
||||
GETGX_empty(q0);
|
||||
if (q0 != q1)
|
||||
VOR_V(q0, q1, q1);
|
||||
u8 = F8;
|
||||
MOV32w(x4, u8);
|
||||
CALL4(const_native_aeskeygenassist, -1, x1, x2, x3, x4);
|
||||
la64_aeskeygenassist_lsx(dyn, ninst, q0, u8);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
@@ -1590,11 +1561,16 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
nextop = F8;
|
||||
GETEX(v1, 0, 0);
|
||||
GETGX_empty(v0);
|
||||
// TODO: !BOX64ENV(dynarec_fastround)
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x6, x4);
|
||||
}
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
VFCVT_S_D(q0, v1, v1);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VEXTRINS_D(v0, q0, 0);
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
break;
|
||||
case 0x5B:
|
||||
INST_NAME("CVTPS2DQ Gx, Ex");
|
||||
@@ -2942,11 +2918,10 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
case 0xE7:
|
||||
INST_NAME("MOVNTDQ Ex, Gx");
|
||||
nextop = F8;
|
||||
GETGX(v0, 0);
|
||||
if (MODREG) {
|
||||
v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop & 7) + (rex.b << 3));
|
||||
VOR_V(v1, v0, v0);
|
||||
DEFAULT;
|
||||
} else {
|
||||
GETGX(v0, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
|
||||
VST(v0, ed, fixedaddress);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,437 @@
|
||||
#ifndef __DYNAREC_LA64_AES_H_
|
||||
#define __DYNAREC_LA64_AES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "dynarec_la64_consts.h"
|
||||
|
||||
static inline void la64_subbytes_lsx(dynarec_la64_t* dyn, int ninst, int dst, int zero, int t0, int t1, int t2, int t3, int tab)
|
||||
{
|
||||
(void)dyn;
|
||||
(void)ninst;
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
VLD(tab, x5, 1 * 16);
|
||||
VSHUF_B(t2, zero, tab, t1);
|
||||
VLD(tab, x5, 0 * 16);
|
||||
VSHUF_B(dst, zero, tab, t0);
|
||||
VXOR_V(dst, dst, t2);
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VLD(tab, x5, 3 * 16);
|
||||
VSHUF_B(t2, zero, tab, t0);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
VLD(tab, x5, 2 * 16);
|
||||
VSHUF_B(dst, zero, tab, t1);
|
||||
VXOR_V(t3, t1, t0);
|
||||
VXOR_V(dst, dst, t2);
|
||||
VSHUF_B(t0, zero, tab, t3);
|
||||
VSHUF_B(dst, zero, tab, dst);
|
||||
VXOR_V(t2, t0, t2);
|
||||
VXOR_V(t0, dst, t3);
|
||||
VSHUF_B(t2, zero, tab, t2);
|
||||
VLD(tab, x5, 4 * 16);
|
||||
VSHUF_B(t0, zero, tab, t0);
|
||||
VXOR_V(t2, t2, t1);
|
||||
VLD(tab, x5, 5 * 16);
|
||||
VSHUF_B(t2, zero, tab, t2);
|
||||
VXOR_V(dst, t0, t2);
|
||||
VXORI_B(dst, dst, 99);
|
||||
}
|
||||
|
||||
static inline void la64_subbytes_lasx(dynarec_la64_t* dyn, int ninst, int dst, int zero, int t0, int t1, int t2, int t3, int tab)
|
||||
{
|
||||
(void)dyn;
|
||||
(void)ninst;
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
XVLD(tab, x5, 1 * 32);
|
||||
XVSHUF_B(t2, zero, tab, t1);
|
||||
XVLD(tab, x5, 0 * 32);
|
||||
XVSHUF_B(dst, zero, tab, t0);
|
||||
XVXOR_V(dst, dst, t2);
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVLD(tab, x5, 3 * 32);
|
||||
XVSHUF_B(t2, zero, tab, t0);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
XVLD(tab, x5, 2 * 32);
|
||||
XVSHUF_B(dst, zero, tab, t1);
|
||||
XVXOR_V(t3, t1, t0);
|
||||
XVXOR_V(dst, dst, t2);
|
||||
XVSHUF_B(t0, zero, tab, t3);
|
||||
XVSHUF_B(dst, zero, tab, dst);
|
||||
XVXOR_V(t2, t0, t2);
|
||||
XVXOR_V(t0, dst, t3);
|
||||
XVSHUF_B(t2, zero, tab, t2);
|
||||
XVLD(tab, x5, 4 * 32);
|
||||
XVSHUF_B(t0, zero, tab, t0);
|
||||
XVXOR_V(t2, t2, t1);
|
||||
XVLD(tab, x5, 5 * 32);
|
||||
XVSHUF_B(t2, zero, tab, t2);
|
||||
XVXOR_V(dst, t0, t2);
|
||||
XVXORI_B(dst, dst, 99);
|
||||
}
|
||||
|
||||
static inline void la64_xtime_table_lsx(dynarec_la64_t* dyn, int ninst, int dst, int src, int tmp, int tab_lo, int tab_hi)
|
||||
{
|
||||
(void)dyn;
|
||||
(void)ninst;
|
||||
VANDI_B(tmp, src, 0x0f);
|
||||
VSRLI_B(dst, src, 4);
|
||||
VSHUF_B(tmp, tab_lo, tab_lo, tmp);
|
||||
VSHUF_B(dst, tab_hi, tab_hi, dst);
|
||||
VXOR_V(dst, dst, tmp);
|
||||
}
|
||||
|
||||
static inline void la64_mixcolumns_xtime_lsx(dynarec_la64_t* dyn, int ninst, int dst, int tab_lo, int tab_hi, int t0, int t1, int t2, int t3)
|
||||
{
|
||||
la64_xtime_table_lsx(dyn, ninst, t0, dst, t3, tab_lo, tab_hi);
|
||||
VSHUF4I_B(t1, dst, 0x39);
|
||||
VSHUF4I_B(t2, dst, 0x4e);
|
||||
la64_xtime_table_lsx(dyn, ninst, dst, t1, t3, tab_lo, tab_hi);
|
||||
VSHUF4I_B(t3, t2, 0x39);
|
||||
VXOR_V(t2, t2, t3);
|
||||
VXOR_V(dst, dst, t1);
|
||||
VXOR_V(dst, dst, t0);
|
||||
VXOR_V(dst, dst, t2);
|
||||
}
|
||||
|
||||
static inline void la64_invmixcolumns_xtime_lsx(dynarec_la64_t* dyn, int ninst, int dst, int tab_lo, int tab_hi, int t0, int t1, int t2, int t3)
|
||||
{
|
||||
VSHUF4I_B(t0, dst, 0x4e);
|
||||
VXOR_V(t0, t0, dst);
|
||||
la64_xtime_table_lsx(dyn, ninst, t0, t0, t1, tab_lo, tab_hi);
|
||||
la64_xtime_table_lsx(dyn, ninst, t0, t0, t1, tab_lo, tab_hi);
|
||||
VXOR_V(dst, dst, t0);
|
||||
la64_mixcolumns_xtime_lsx(dyn, ninst, dst, tab_lo, tab_hi, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_xtime_table_lasx(dynarec_la64_t* dyn, int ninst, int dst, int src, int tmp, int tab_lo, int tab_hi)
|
||||
{
|
||||
(void)dyn;
|
||||
(void)ninst;
|
||||
XVANDI_B(tmp, src, 0x0f);
|
||||
XVSRLI_B(dst, src, 4);
|
||||
XVSHUF_B(tmp, tab_lo, tab_lo, tmp);
|
||||
XVSHUF_B(dst, tab_hi, tab_hi, dst);
|
||||
XVXOR_V(dst, dst, tmp);
|
||||
}
|
||||
|
||||
static inline void la64_mixcolumns_xtime_lasx(dynarec_la64_t* dyn, int ninst, int dst, int tab_lo, int tab_hi, int t0, int t1, int t2, int t3)
|
||||
{
|
||||
la64_xtime_table_lasx(dyn, ninst, t0, dst, t3, tab_lo, tab_hi);
|
||||
XVSHUF4I_B(t1, dst, 0x39);
|
||||
XVSHUF4I_B(t2, dst, 0x4e);
|
||||
la64_xtime_table_lasx(dyn, ninst, dst, t1, t3, tab_lo, tab_hi);
|
||||
XVSHUF4I_B(t3, t2, 0x39);
|
||||
XVXOR_V(t2, t2, t3);
|
||||
XVXOR_V(dst, dst, t1);
|
||||
XVXOR_V(dst, dst, t0);
|
||||
XVXOR_V(dst, dst, t2);
|
||||
}
|
||||
|
||||
static inline void la64_invmixcolumns_xtime_lasx(dynarec_la64_t* dyn, int ninst, int dst, int tab_lo, int tab_hi, int t0, int t1, int t2, int t3)
|
||||
{
|
||||
XVSHUF4I_B(t0, dst, 0x4e);
|
||||
XVXOR_V(t0, t0, dst);
|
||||
la64_xtime_table_lasx(dyn, ninst, t0, t0, t1, tab_lo, tab_hi);
|
||||
la64_xtime_table_lasx(dyn, ninst, t0, t0, t1, tab_lo, tab_hi);
|
||||
XVXOR_V(dst, dst, t0);
|
||||
la64_mixcolumns_xtime_lasx(dyn, ninst, dst, tab_lo, tab_hi, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aesimc_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int tab_lo = fpu_get_scratch(dyn);
|
||||
int tab_hi = fpu_get_scratch(dyn);
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables);
|
||||
VLD(tab_lo, x5, 7 * 16);
|
||||
VLD(tab_hi, x5, 8 * 16);
|
||||
la64_invmixcolumns_xtime_lsx(dyn, ninst, dst, tab_lo, tab_hi, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aesimc_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int tab_lo = fpu_get_scratch(dyn);
|
||||
int tab_hi = fpu_get_scratch(dyn);
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables_xv);
|
||||
XVLD(tab_lo, x5, 7 * 32);
|
||||
XVLD(tab_hi, x5, 8 * 32);
|
||||
la64_invmixcolumns_xtime_lasx(dyn, ninst, dst, tab_lo, tab_hi, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aeselast_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_enc_tables);
|
||||
la64_subbytes_lsx(dyn, ninst, dst, zero, t0, t1, t2, t3, tab);
|
||||
VLD(tab, x5, 6 * 16);
|
||||
VSHUF_B(dst, dst, dst, tab);
|
||||
}
|
||||
|
||||
static inline void la64_aeselast_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_enc_tables_xv);
|
||||
la64_subbytes_lasx(dyn, ninst, dst, zero, t0, t1, t2, t3, tab);
|
||||
XVLD(tab, x5, 6 * 32);
|
||||
XVSHUF_B(dst, dst, dst, tab);
|
||||
}
|
||||
|
||||
static inline void la64_aese_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
int tab_hi = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_enc_tables);
|
||||
la64_subbytes_lsx(dyn, ninst, dst, zero, t0, t1, t2, t3, tab);
|
||||
VLD(tab, x5, 6 * 16);
|
||||
VSHUF_B(dst, dst, dst, tab);
|
||||
VLD(tab, x5, 7 * 16);
|
||||
VLD(tab_hi, x5, 8 * 16);
|
||||
la64_mixcolumns_xtime_lsx(dyn, ninst, dst, tab, tab_hi, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aese_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
int tab_hi = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_enc_tables_xv);
|
||||
la64_subbytes_lasx(dyn, ninst, dst, zero, t0, t1, t2, t3, tab);
|
||||
XVLD(tab, x5, 6 * 32);
|
||||
XVSHUF_B(dst, dst, dst, tab);
|
||||
XVLD(tab, x5, 7 * 32);
|
||||
XVLD(tab_hi, x5, 8 * 32);
|
||||
la64_mixcolumns_xtime_lasx(dyn, ninst, dst, tab, tab_hi, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aesdlast_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int t4 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables);
|
||||
VLD(tab, x5, 6 * 16);
|
||||
VSHUF_B(dst, dst, dst, tab);
|
||||
VXORI_B(dst, dst, 99);
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
VLD(tab, x5, 1 * 16);
|
||||
VSHUF_B(t1, zero, tab, t1);
|
||||
VLD(tab, x5, 0 * 16);
|
||||
VSHUF_B(dst, zero, tab, t0);
|
||||
VXOR_V(dst, dst, t1);
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
VLD(tab, x5, 2 * 16);
|
||||
VSHUF_B(t2, zero, tab, t1);
|
||||
VLD(tab, x5, 3 * 16);
|
||||
VSHUF_B(t3, zero, tab, t0);
|
||||
VXOR_V(t0, t1, t0);
|
||||
VXOR_V(t2, t2, t3);
|
||||
VLD(tab, x5, 2 * 16);
|
||||
VSHUF_B(t4, zero, tab, t0);
|
||||
VSHUF_B(t2, zero, tab, t2);
|
||||
VXOR_V(t3, t4, t3);
|
||||
VXOR_V(t0, t2, t0);
|
||||
VSHUF_B(t3, zero, tab, t3);
|
||||
VXOR_V(t3, t3, t1);
|
||||
VLD(tab, x5, 4 * 16);
|
||||
VSHUF_B(t0, zero, tab, t0);
|
||||
VLD(tab, x5, 5 * 16);
|
||||
VSHUF_B(t1, zero, tab, t3);
|
||||
VXOR_V(dst, t0, t1);
|
||||
}
|
||||
|
||||
static inline void la64_aesdlast_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int t4 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables_xv);
|
||||
XVLD(tab, x5, 6 * 32);
|
||||
XVSHUF_B(dst, dst, dst, tab);
|
||||
XVXORI_B(dst, dst, 99);
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
XVLD(tab, x5, 1 * 32);
|
||||
XVSHUF_B(t1, zero, tab, t1);
|
||||
XVLD(tab, x5, 0 * 32);
|
||||
XVSHUF_B(dst, zero, tab, t0);
|
||||
XVXOR_V(dst, dst, t1);
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
XVLD(tab, x5, 2 * 32);
|
||||
XVSHUF_B(t2, zero, tab, t1);
|
||||
XVLD(tab, x5, 3 * 32);
|
||||
XVSHUF_B(t3, zero, tab, t0);
|
||||
XVXOR_V(t0, t1, t0);
|
||||
XVXOR_V(t2, t2, t3);
|
||||
XVLD(tab, x5, 2 * 32);
|
||||
XVSHUF_B(t4, zero, tab, t0);
|
||||
XVSHUF_B(t2, zero, tab, t2);
|
||||
XVXOR_V(t3, t4, t3);
|
||||
XVXOR_V(t0, t2, t0);
|
||||
XVSHUF_B(t3, zero, tab, t3);
|
||||
XVXOR_V(t3, t3, t1);
|
||||
XVLD(tab, x5, 4 * 32);
|
||||
XVSHUF_B(t0, zero, tab, t0);
|
||||
XVLD(tab, x5, 5 * 32);
|
||||
XVSHUF_B(t1, zero, tab, t3);
|
||||
XVXOR_V(dst, t0, t1);
|
||||
}
|
||||
|
||||
static inline void la64_aesd_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int t4 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables);
|
||||
VLD(tab, x5, 6 * 16);
|
||||
VSHUF_B(dst, dst, dst, tab);
|
||||
VXORI_B(dst, dst, 99);
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
VLD(tab, x5, 1 * 16);
|
||||
VSHUF_B(t1, zero, tab, t1);
|
||||
VLD(tab, x5, 0 * 16);
|
||||
VSHUF_B(dst, zero, tab, t0);
|
||||
VXOR_V(dst, dst, t1);
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
VLD(tab, x5, 2 * 16);
|
||||
VSHUF_B(t2, zero, tab, t1);
|
||||
VLD(tab, x5, 3 * 16);
|
||||
VSHUF_B(t3, zero, tab, t0);
|
||||
VXOR_V(t0, t1, t0);
|
||||
VXOR_V(t2, t2, t3);
|
||||
VLD(tab, x5, 2 * 16);
|
||||
VSHUF_B(t4, zero, tab, t0);
|
||||
VSHUF_B(t2, zero, tab, t2);
|
||||
VXOR_V(t3, t4, t3);
|
||||
VXOR_V(t0, t2, t0);
|
||||
VSHUF_B(t3, zero, tab, t3);
|
||||
VXOR_V(t3, t3, t1);
|
||||
VLD(tab, x5, 4 * 16);
|
||||
VSHUF_B(t0, zero, tab, t0);
|
||||
VLD(tab, x5, 5 * 16);
|
||||
VSHUF_B(t1, zero, tab, t3);
|
||||
VXOR_V(dst, t0, t1);
|
||||
VLD(tab, x5, 7 * 16);
|
||||
VLD(t4, x5, 8 * 16);
|
||||
la64_invmixcolumns_xtime_lsx(dyn, ninst, dst, tab, t4, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aesd_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int t4 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables_xv);
|
||||
XVLD(tab, x5, 6 * 32);
|
||||
XVSHUF_B(dst, dst, dst, tab);
|
||||
XVXORI_B(dst, dst, 99);
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
XVLD(tab, x5, 1 * 32);
|
||||
XVSHUF_B(t1, zero, tab, t1);
|
||||
XVLD(tab, x5, 0 * 32);
|
||||
XVSHUF_B(dst, zero, tab, t0);
|
||||
XVXOR_V(dst, dst, t1);
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
XVLD(tab, x5, 2 * 32);
|
||||
XVSHUF_B(t2, zero, tab, t1);
|
||||
XVLD(tab, x5, 3 * 32);
|
||||
XVSHUF_B(t3, zero, tab, t0);
|
||||
XVXOR_V(t0, t1, t0);
|
||||
XVXOR_V(t2, t2, t3);
|
||||
XVLD(tab, x5, 2 * 32);
|
||||
XVSHUF_B(t4, zero, tab, t0);
|
||||
XVSHUF_B(t2, zero, tab, t2);
|
||||
XVXOR_V(t3, t4, t3);
|
||||
XVXOR_V(t0, t2, t0);
|
||||
XVSHUF_B(t3, zero, tab, t3);
|
||||
XVXOR_V(t3, t3, t1);
|
||||
XVLD(tab, x5, 4 * 32);
|
||||
XVSHUF_B(t0, zero, tab, t0);
|
||||
XVLD(tab, x5, 5 * 32);
|
||||
XVSHUF_B(t1, zero, tab, t3);
|
||||
XVXOR_V(dst, t0, t1);
|
||||
XVLD(tab, x5, 7 * 32);
|
||||
XVLD(t4, x5, 8 * 32);
|
||||
la64_invmixcolumns_xtime_lasx(dyn, ninst, dst, tab, t4, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aeskeygenassist_lsx(dynarec_la64_t* dyn, int ninst, int dst, uint8_t imm)
|
||||
{
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
int rcon = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_keygen_tables);
|
||||
la64_subbytes_lsx(dyn, ninst, dst, zero, t0, t1, t2, t3, tab);
|
||||
VLD(tab, x5, 6 * 16);
|
||||
VSHUF_B(dst, zero, dst, tab);
|
||||
VLDI(rcon, imm);
|
||||
VLD(tab, x5, 7 * 16);
|
||||
VAND_V(rcon, rcon, tab);
|
||||
VXOR_V(dst, dst, rcon);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -506,14 +506,12 @@ uintptr_t dynarec64_AVX_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, in
|
||||
if (vex.v != 0) {
|
||||
UDF();
|
||||
} else {
|
||||
q2 = fpu_get_scratch(dyn);
|
||||
XVXOR_V(q2, q2, q2);
|
||||
for (int i = 0; i < (rex.is32bits ? 8 : 16); ++i) {
|
||||
if (dyn->lsx.avxcache[i].v != -1) {
|
||||
q1 = avx_get_reg(dyn, ninst, x1, i, 1, LSX_AVX_WIDTH_256);
|
||||
XVPERMI_Q(q1, q2, XVPERMI_IMM_4_0(0, 2));
|
||||
XVPERMI_Q(q1, VZERO, XVPERMI_IMM_4_0(0, 2));
|
||||
} else {
|
||||
VST(q2, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
}
|
||||
}
|
||||
SMWRITE2();
|
||||
|
||||
@@ -210,10 +210,10 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
case 0x2B:
|
||||
INST_NAME("VMOVNTPD Ex, Gx");
|
||||
nextop = F8;
|
||||
GETGYxy(q0, 0);
|
||||
if (MODREG) {
|
||||
DEFAULT;
|
||||
} else {
|
||||
GETGYxy(q0, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x4, x5, &fixedaddress, rex, NULL, 1, 0);
|
||||
if (vex.l) {
|
||||
XVST(q0, ed, fixedaddress);
|
||||
@@ -375,19 +375,18 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
nextop = F8;
|
||||
GETEYxy(v1, 0, 0);
|
||||
GETGYx_empty(v0);
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x6, x4);
|
||||
}
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVFCVT_S_D(v0, d0, v1);
|
||||
XVFCVT_S_D(v0, VZERO, v1);
|
||||
XVPERMI_D(v0, v0, 0b11011000);
|
||||
} else {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VFCVT_S_D(d0, v1, v1);
|
||||
XVPICKVE_D(v0, d0, 0);
|
||||
}
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
break;
|
||||
@@ -1048,13 +1047,13 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
VADDxy(D, v0, v1, v2);
|
||||
break;
|
||||
case 0xD5:
|
||||
INST_NAME("VPMULLW Gx, Ex");
|
||||
INST_NAME("VPMULLW Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
VMULxy(H, v0, v1, v2);
|
||||
break;
|
||||
case 0xD6:
|
||||
INST_NAME("VMOVD Ex, Gx");
|
||||
INST_NAME("VMOVQ Ex, Gx");
|
||||
nextop = F8;
|
||||
GETGYx(q0, 0);
|
||||
if (MODREG) {
|
||||
@@ -1177,12 +1176,11 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
nextop = F8;
|
||||
GETEYxy(v1, 0, 0);
|
||||
GETGYx_empty(v0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVFTINTRZ_W_D(d1, d0, v1); // v0 [lo0, lo1, --, --, hi0, hi1, --, -- ]
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
XVFTINTRZ_W_D(d1, VZERO, v1); // v0 [lo0, lo1, --, --, hi0, hi1, --, -- ]
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
q1 = fpu_get_scratch(dyn);
|
||||
XVLDI(q0, 0b1001110000000); // broadcast 0x80000000 to all
|
||||
@@ -1198,6 +1196,7 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
XVPERMI_D(v0, v0, 0b11011000);
|
||||
} else {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VFTINTRZ_W_D(d0, v1, v1);
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "dynarec_la64_private.h"
|
||||
#include "dynarec_la64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_la64_aes.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
@@ -62,12 +63,10 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
q1 = fpu_get_scratch(dyn);
|
||||
VLDIxy(q0, 0b0000010001111); // broadcast 0b10001111 as byte
|
||||
VAND_Vxy(q0, q0, v2);
|
||||
VMINIxy(BU, q0, q0, 0x1f);
|
||||
VXOR_Vxy(q1, q1, q1);
|
||||
VSHUF_Bxy(v0, q1, v1, q0);
|
||||
VSHUF_Bxy(v0, VZERO, v1, q0);
|
||||
break;
|
||||
case 0x01:
|
||||
INST_NAME("VPHADDW Gx, Vx, Ex");
|
||||
@@ -345,25 +344,19 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
INST_NAME("VPABSB Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_EY_xy(v0, v1, 0);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
XVXOR_V(q0, q0, q0);
|
||||
VABSDxy(B, v0, v1, q0);
|
||||
VABSDxy(B, v0, v1, VZERO);
|
||||
break;
|
||||
case 0x1D:
|
||||
INST_NAME("VPABSW Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_EY_xy(v0, v1, 0);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
XVXOR_V(q0, q0, q0);
|
||||
VABSDxy(H, v0, v1, q0);
|
||||
VABSDxy(H, v0, v1, VZERO);
|
||||
break;
|
||||
case 0x1E:
|
||||
INST_NAME("VPABSD Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_EY_xy(v0, v1, 0);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
XVXOR_V(q0, q0, q0);
|
||||
VABSDxy(W, v0, v1, q0);
|
||||
VABSDxy(W, v0, v1, VZERO);
|
||||
break;
|
||||
case 0x20:
|
||||
INST_NAME("VPMOVSXBW Gx, Ex");
|
||||
@@ -497,32 +490,26 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
INST_NAME("VMASKMOVPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVSLTI_W(d1, v1, 0); // create all-one mask for negetive element.
|
||||
XVBITSEL_V(v0, d0, v2, d1);
|
||||
XVBITSEL_V(v0, VZERO, v2, d1);
|
||||
} else {
|
||||
VXOR_V(d0, d0, d0);
|
||||
VSLTI_W(d1, v1, 0); // create all-one mask for negetive element.
|
||||
VBITSEL_V(v0, d0, v2, d1);
|
||||
VBITSEL_V(v0, VZERO, v2, d1);
|
||||
}
|
||||
break;
|
||||
case 0x2D:
|
||||
INST_NAME("VMASKMOVPD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVSLTI_D(d1, v1, 0); // create all-one mask for negetive element.
|
||||
XVBITSEL_V(v0, d0, v2, d1);
|
||||
XVBITSEL_V(v0, VZERO, v2, d1);
|
||||
} else {
|
||||
VXOR_V(d0, d0, d0);
|
||||
VSLTI_D(d1, v1, 0); // create all-one mask for negetive element.
|
||||
VBITSEL_V(v0, d0, v2, d1);
|
||||
VBITSEL_V(v0, VZERO, v2, d1);
|
||||
}
|
||||
break;
|
||||
case 0x2E:
|
||||
@@ -697,7 +684,7 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
VMAXxy(WU, v0, v1, v2);
|
||||
break;
|
||||
case 0x40:
|
||||
INST_NAME("VPMULLD Gx, Ex");
|
||||
INST_NAME("VPMULLD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
VMULxy(W, v0, v1, v2);
|
||||
@@ -835,24 +822,21 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
INST_NAME("VPMASKMOVD/Q Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
if (rex.w) {
|
||||
XVSLTI_D(d1, v1, 0);
|
||||
} else {
|
||||
XVSLTI_W(d1, v1, 0);
|
||||
}
|
||||
XVBITSEL_V(v0, d0, v2, d1);
|
||||
XVBITSEL_V(v0, VZERO, v2, d1);
|
||||
} else {
|
||||
VXOR_V(d0, d0, d0);
|
||||
if (rex.w) {
|
||||
VSLTI_D(d1, v1, 0);
|
||||
} else {
|
||||
VSLTI_W(d1, v1, 0);
|
||||
}
|
||||
VBITSEL_V(v0, d0, v2, d1);
|
||||
VBITSEL_V(v0, VZERO, v2, d1);
|
||||
}
|
||||
break;
|
||||
case 0x8E:
|
||||
@@ -1304,10 +1288,7 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
if (q0 != q1) {
|
||||
VOR_V(q0, q1, q1);
|
||||
}
|
||||
avx_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aesimc, -1, x1, 0);
|
||||
GETGYx(q0, 1); // reget writable for mark zeroup hi-128bits.
|
||||
la64_aesimc_lsx(dyn, ninst, q0);
|
||||
break;
|
||||
case 0xDC:
|
||||
INST_NAME("VAESENC Gx, Vx, Ex");
|
||||
@@ -1321,14 +1302,11 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
if (gd != vex.v) {
|
||||
VOR_Vxy(q0, q1, q1);
|
||||
}
|
||||
avx_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aese, -1, x1, 0);
|
||||
if (vex.l) {
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aese_y, -1, x1, 0);
|
||||
la64_aese_lasx(dyn, ninst, q0);
|
||||
} else {
|
||||
la64_aese_lsx(dyn, ninst, q0);
|
||||
}
|
||||
GETGYxy(q0, 1);
|
||||
VXOR_Vxy(q0, q0, (d0 != -1) ? d0 : q2);
|
||||
break;
|
||||
case 0xDD:
|
||||
@@ -1343,14 +1321,11 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
if (gd != vex.v) {
|
||||
VOR_Vxy(q0, q1, q1);
|
||||
}
|
||||
avx_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aeselast, -1, x1, 0);
|
||||
if (vex.l) {
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aeselast_y, -1, x1, 0);
|
||||
la64_aeselast_lasx(dyn, ninst, q0);
|
||||
} else {
|
||||
la64_aeselast_lsx(dyn, ninst, q0);
|
||||
}
|
||||
GETGYxy(q0, 1);
|
||||
VXOR_Vxy(q0, q0, (d0 != -1) ? d0 : q2);
|
||||
break;
|
||||
case 0xDE:
|
||||
@@ -1365,14 +1340,11 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
if (gd != vex.v) {
|
||||
VOR_Vxy(q0, q1, q1);
|
||||
}
|
||||
avx_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aesd, -1, x1, 0);
|
||||
if (vex.l) {
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aesd_y, -1, x1, 0);
|
||||
la64_aesd_lasx(dyn, ninst, q0);
|
||||
} else {
|
||||
la64_aesd_lsx(dyn, ninst, q0);
|
||||
}
|
||||
GETGYxy(q0, 1);
|
||||
VXOR_Vxy(q0, q0, (d0 != -1) ? d0 : q2);
|
||||
break;
|
||||
case 0xDF:
|
||||
@@ -1387,14 +1359,11 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
if (gd != vex.v) {
|
||||
VOR_Vxy(q0, q1, q1);
|
||||
}
|
||||
avx_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aesdlast, -1, x1, 0);
|
||||
if (vex.l) {
|
||||
MOV32w(x1, gd);
|
||||
CALL(const_native_aesdlast_y, -1, x1, 0);
|
||||
la64_aesdlast_lasx(dyn, ninst, q0);
|
||||
} else {
|
||||
la64_aesdlast_lsx(dyn, ninst, q0);
|
||||
}
|
||||
GETGYxy(q0, 1);
|
||||
VXOR_Vxy(q0, q0, (d0 != -1) ? d0 : q2);
|
||||
break;
|
||||
case 0xF7:
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "dynarec_la64_private.h"
|
||||
#include "dynarec_la64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
#include "dynarec_la64_aes.h"
|
||||
|
||||
uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
|
||||
{
|
||||
@@ -34,7 +35,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int d0, d1;
|
||||
int s0;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
@@ -146,7 +147,6 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
XVXOR_V(v0, v0, v0);
|
||||
break;
|
||||
}
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
uint8_t zero_low = (u8 & 0x8) >> 3;
|
||||
uint8_t zero_up = (u8 & 0x80) >> 7;
|
||||
uint8_t vec_lo = (u8 & 0x2) >> 1;
|
||||
@@ -164,13 +164,12 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
}
|
||||
break;
|
||||
}
|
||||
XVXOR_V(d0, d0, d0);
|
||||
if (zero_low) {
|
||||
XVORI_B(v0, vec_hi ? v2 : v1, 0);
|
||||
XVPERMI_Q(v0, d0, XVPERMI_IMM_4_0(2 + index_hi, 0));
|
||||
XVPERMI_Q(v0, VZERO, XVPERMI_IMM_4_0(2 + index_hi, 0));
|
||||
} else {
|
||||
XVORI_B(v0, vec_lo ? v2 : v1, 0);
|
||||
XVPERMI_Q(v0, d0, XVPERMI_IMM_4_0(0, 2 + index_lo));
|
||||
XVPERMI_Q(v0, VZERO, XVPERMI_IMM_4_0(0, 2 + index_lo));
|
||||
}
|
||||
break;
|
||||
case 0x08:
|
||||
@@ -506,7 +505,6 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
GETEYSD(v1, 1, 1);
|
||||
}
|
||||
u8 = F8;
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
if (u8 & 4) {
|
||||
u8 = sse_setround(dyn, ninst, x4, x5);
|
||||
} else {
|
||||
@@ -516,13 +514,11 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
u8 = x4;
|
||||
}
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVFCVT_H_S(v1, d0, v0);
|
||||
XVFCVT_H_S(v1, VZERO, v0);
|
||||
XVPERMI_D(v1, v1, 0b11011000);
|
||||
PUTEYx(v1);
|
||||
} else {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
VFCVT_H_S(v1, d0, v0);
|
||||
VFCVT_H_S(v1, VZERO, v0);
|
||||
PUTEYSD(v1);
|
||||
}
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
@@ -572,10 +568,9 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
}
|
||||
uint8_t zmask = u8 & 0xf;
|
||||
if (zmask) {
|
||||
VXOR_V(q1, q1, q1);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (zmask & (1 << i)) {
|
||||
VEXTRINS_W(v0, q1, VEXTRINS_IMM_4_0(i, 0));
|
||||
VEXTRINS_W(v0, VZERO, VEXTRINS_IMM_4_0(i, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,12 +600,10 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
u8 = F8;
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
d2 = fpu_get_scratch(dyn);
|
||||
VFMULxy(S, d0, v1, v2);
|
||||
VXOR_Vxy(d2, d2, d2);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!(u8 & (1 << (4 + i)))) {
|
||||
VEXTRINSxy(W, d0, d2, (i << 4));
|
||||
VEXTRINSxy(W, d0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
VSHUF4Ixy(W, d1, d0, 0b10110001); // v0[a,b,c,d] v1[b,a,d,c]
|
||||
@@ -620,7 +613,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
VREPLVEIxy(W, v0, d0, 0);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!(u8 & (1 << i))) {
|
||||
VEXTRINSxy(W, v0, d2, (i << 4));
|
||||
VEXTRINSxy(W, v0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -631,12 +624,10 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
u8 = F8;
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
d2 = fpu_get_scratch(dyn);
|
||||
VFMULxy(D, d0, v1, v2);
|
||||
VXOR_Vxy(d2, d2, d2);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!(u8 & (1 << (4 + i)))) {
|
||||
VEXTRINSxy(D, d0, d2, (i << 4));
|
||||
VEXTRINSxy(D, d0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
VSHUF4Ixy(W, d1, d0, 0b01001110); // v0[a,b] v1[b,a]
|
||||
@@ -644,7 +635,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
VREPLVEIxy(D, v0, d0, 0);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!(u8 & (1 << i))) {
|
||||
VEXTRINSxy(D, v0, d2, (i << 4));
|
||||
VEXTRINSxy(D, v0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -789,27 +780,16 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
INST_NAME("VAESKEYGENASSIST Gx, Ex, Ib");
|
||||
nextop = F8;
|
||||
GETG;
|
||||
avx_forget_reg(dyn, ninst, gd);
|
||||
MOV32w(x1, gd); // gx
|
||||
if (MODREG) {
|
||||
ed = (nextop & 7) + (rex.b << 3);
|
||||
avx_forget_reg(dyn, ninst, ed);
|
||||
MOV32w(x2, ed);
|
||||
MOV32w(x3, 0); // p = NULL
|
||||
GETEYx(q1, 0, 1);
|
||||
if (vex.l) {
|
||||
GETGYy(q0, 1);
|
||||
} else {
|
||||
MOV32w(x2, 0);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 1);
|
||||
if (ed != x3) {
|
||||
MV(x3, ed);
|
||||
}
|
||||
GETGYx_empty(q0);
|
||||
}
|
||||
if (q0 != q1)
|
||||
VOR_V(q0, q1, q1);
|
||||
u8 = F8;
|
||||
MOV32w(x4, u8);
|
||||
CALL4(const_native_aeskeygenassist, -1, x1, x2, x3, x4);
|
||||
if (!vex.l) {
|
||||
ST_D(xZR, xEmu, offsetof(x64emu_t, ymm[gd]));
|
||||
ST_D(xZR, xEmu, offsetof(x64emu_t, ymm[gd]) + 8);
|
||||
}
|
||||
la64_aeskeygenassist_lsx(dyn, ninst, q0, u8);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -117,7 +117,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETVYx(v1, 0);
|
||||
GETGYx_empty(v0);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x2, x3);
|
||||
}
|
||||
if (rex.w) {
|
||||
@@ -127,7 +127,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
MOVGR2FR_W(d1, ed);
|
||||
FFINT_D_W(d1, d1);
|
||||
}
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
if (v0 != v1) VOR_V(v0, v1, v1);
|
||||
@@ -202,9 +202,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
FSQRT_D(d1, v2);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(d0, d0, d0);
|
||||
FCMP_D(fcc0, v2, d0, cLT);
|
||||
FCMP_D(fcc0, v2, VZERO, cLT);
|
||||
BCEQZ(fcc0, 4 + 4);
|
||||
FNEG_D(d1, d1);
|
||||
}
|
||||
@@ -270,7 +268,13 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETVYx(v1, 0);
|
||||
GETGYx_empty(v0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x2, x3);
|
||||
}
|
||||
FCVT_S_D(d0, v2);
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
if (v0 != v1) VOR_V(v0, v1, v1);
|
||||
XVINSVE0_W(v0, d0, 0);
|
||||
break;
|
||||
@@ -432,8 +436,8 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETVYx(v1, 0);
|
||||
GETEYSD(v2, 0, 1);
|
||||
GETGYx(v0, 1);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
u8 = F8;
|
||||
q0 = ((u8 & 0xf) == 0x0b) ? VZERO : fpu_get_scratch(dyn);
|
||||
switch (u8 & 0xf) {
|
||||
case 0x00: VFCMP_D(q0, v1, v2, cEQ); break; // Equal, not unordered
|
||||
case 0x01: VFCMP_D(q0, v1, v2, cLT); break; // Less than
|
||||
@@ -446,7 +450,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
case 0x08: VFCMP_D(q0, v1, v2, cUEQ); break; // Equal, or unordered
|
||||
case 0x09: VFCMP_D(q0, v1, v2, cULT); break; // Less than or unordered
|
||||
case 0x0a: VFCMP_D(q0, v1, v2, cULE); break; // Less or equal or unordered
|
||||
case 0x0b: VXOR_V(q0, q0, q0); break; // false
|
||||
case 0x0b: break; // false
|
||||
case 0x0c: VFCMP_D(q0, v1, v2, cNE); break; // Not Eual, ordered
|
||||
case 0x0d: VFCMP_D(q0, v2, v1, cLE); break; // Greater or Equal ordered
|
||||
case 0x0e: VFCMP_D(q0, v2, v1, cLT); break; // Greater ordered
|
||||
@@ -489,18 +493,17 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETEYxy(v1, 0, 0);
|
||||
GETGYx_empty(v0);
|
||||
u8 = sse_setround(dyn, ninst, x1, x2);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
q1 = fpu_get_scratch(dyn);
|
||||
q2 = fpu_get_scratch(dyn);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
XVFTINT_L_D(q2, v1);
|
||||
XVFCMP_D(d1, v1, v1, cUN); // get NaN mask
|
||||
}
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVFTINT_W_D(v0, d0, v1); // v0 [lo0, lo1, --, --, hi0, hi1, --, -- ]
|
||||
XVFTINT_W_D(v0, VZERO, v1); // v0 [lo0, lo1, --, --, hi0, hi1, --, -- ]
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
XVLDI(q0, 0b1001110000000); // broadcast 0x80000000 to all
|
||||
MOV32w(x5, 0x7FFFFFFF);
|
||||
@@ -513,6 +516,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
XVPERMI_D(v0, v0, 0b11011000);
|
||||
} else {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VFTINT_W_D(d0, v1, v1);
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
|
||||
@@ -107,7 +107,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETVYx(v1, 0);
|
||||
GETGYx_empty(v0);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x2, x3);
|
||||
}
|
||||
if (rex.w) {
|
||||
@@ -117,7 +117,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
MOVGR2FR_W(d1, ed);
|
||||
FFINT_S_W(d1, d1);
|
||||
}
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
if (v0 != v1) VOR_V(v0, v1, v1);
|
||||
@@ -194,9 +194,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
FSQRT_S(d1, v2);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(d0, d0, d0);
|
||||
FCMP_S(fcc0, v2, d0, cLT);
|
||||
FCMP_S(fcc0, v2, VZERO, cLT);
|
||||
BCEQZ(fcc0, 4 + 4);
|
||||
FNEG_S(d1, d1);
|
||||
}
|
||||
@@ -475,8 +473,8 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETVYx(v1, 0);
|
||||
GETEYSS(v2, 0, 1);
|
||||
GETGYx(v0, 1);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
u8 = F8;
|
||||
q0 = ((u8 & 0xf) == 0x0b) ? VZERO : fpu_get_scratch(dyn);
|
||||
switch (u8 & 0xf) {
|
||||
case 0x00: VFCMP_S(q0, v1, v2, cEQ); break; // Equal, not unordered
|
||||
case 0x01: VFCMP_S(q0, v1, v2, cLT); break; // Less than
|
||||
@@ -489,7 +487,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
case 0x08: VFCMP_S(q0, v1, v2, cUEQ); break; // Equal, or unordered
|
||||
case 0x09: VFCMP_S(q0, v1, v2, cULT); break; // Less than or unordered
|
||||
case 0x0a: VFCMP_S(q0, v1, v2, cULE); break; // Less or equal or unordered
|
||||
case 0x0b: VXOR_V(q0, q0, q0); break; // false
|
||||
case 0x0b: break; // false
|
||||
case 0x0c: VFCMP_S(q0, v1, v2, cNE); break; // Not Eual, ordered
|
||||
case 0x0d: VFCMP_S(q0, v2, v1, cLE); break; // Greater or Equal ordered
|
||||
case 0x0e: VFCMP_S(q0, v2, v1, cLT); break; // Greater ordered
|
||||
|
||||
@@ -25,10 +25,76 @@
|
||||
#include "bitutils.h"
|
||||
#include "random.h"
|
||||
|
||||
void* create_updateflags();
|
||||
|
||||
#ifndef HAVE_TRACE
|
||||
void PrintTrace() {}
|
||||
#endif
|
||||
|
||||
static const uint8_t la64_vpaes_enc_tables[9][16] __attribute__((aligned(16))) = {
|
||||
{ 0x00, 0x70, 0x2a, 0x5a, 0x98, 0xe8, 0xb2, 0xc2, 0x08, 0x78, 0x22, 0x52, 0x90, 0xe0, 0xba, 0xca },
|
||||
{ 0x00, 0x4d, 0x7c, 0x31, 0x7d, 0x30, 0x01, 0x4c, 0x81, 0xcc, 0xfd, 0xb0, 0xfc, 0xb1, 0x80, 0xcd },
|
||||
{ 0x10, 0x01, 0x08, 0x0d, 0x0f, 0x06, 0x05, 0x0e, 0x02, 0x0c, 0x0b, 0x0a, 0x09, 0x03, 0x07, 0x04 },
|
||||
{ 0x10, 0x07, 0x0b, 0x0f, 0x06, 0x0a, 0x04, 0x01, 0x09, 0x08, 0x05, 0x02, 0x0c, 0x0e, 0x0d, 0x03 },
|
||||
{ 0x00, 0xc7, 0xbd, 0x6f, 0x17, 0x6d, 0xd2, 0xd0, 0x78, 0xa8, 0x02, 0xc5, 0x7a, 0xbf, 0xaa, 0x15 },
|
||||
{ 0x00, 0x6a, 0xbb, 0x5f, 0xa5, 0x74, 0xe4, 0xcf, 0xfa, 0x35, 0x2b, 0x41, 0xd1, 0x90, 0x1e, 0x8e },
|
||||
{ 0x00, 0x05, 0x0a, 0x0f, 0x04, 0x09, 0x0e, 0x03, 0x08, 0x0d, 0x02, 0x07, 0x0c, 0x01, 0x06, 0x0b },
|
||||
{ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e },
|
||||
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x1b, 0x3b, 0x5b, 0x7b, 0x9b, 0xbb, 0xdb, 0xfb },
|
||||
};
|
||||
|
||||
static const uint8_t la64_vpaes_dec_tables[9][16] __attribute__((aligned(16))) = {
|
||||
{ 0x00, 0x5f, 0x54, 0x0b, 0x04, 0x5b, 0x50, 0x0f, 0x1a, 0x45, 0x4e, 0x11, 0x1e, 0x41, 0x4a, 0x15 },
|
||||
{ 0x00, 0x65, 0x05, 0x60, 0xe6, 0x83, 0xe3, 0x86, 0x94, 0xf1, 0x91, 0xf4, 0x72, 0x17, 0x77, 0x12 },
|
||||
{ 0x10, 0x01, 0x08, 0x0d, 0x0f, 0x06, 0x05, 0x0e, 0x02, 0x0c, 0x0b, 0x0a, 0x09, 0x03, 0x07, 0x04 },
|
||||
{ 0x10, 0x07, 0x0b, 0x0f, 0x06, 0x0a, 0x04, 0x01, 0x09, 0x08, 0x05, 0x02, 0x0c, 0x0e, 0x0d, 0x03 },
|
||||
{ 0x00, 0x40, 0xf9, 0x7e, 0x53, 0xea, 0x87, 0x13, 0x2d, 0x3e, 0x94, 0xd4, 0xb9, 0x6d, 0xaa, 0xc7 },
|
||||
{ 0x00, 0x1d, 0x44, 0x93, 0x0f, 0x56, 0xd7, 0x12, 0x9c, 0x8e, 0xc5, 0xd8, 0x59, 0x81, 0x4b, 0xca },
|
||||
{ 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b, 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03 },
|
||||
{ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e },
|
||||
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x1b, 0x3b, 0x5b, 0x7b, 0x9b, 0xbb, 0xdb, 0xfb },
|
||||
};
|
||||
|
||||
static const uint8_t la64_vpaes_keygen_tables[8][16] __attribute__((aligned(16))) = {
|
||||
{ 0x00, 0x70, 0x2a, 0x5a, 0x98, 0xe8, 0xb2, 0xc2, 0x08, 0x78, 0x22, 0x52, 0x90, 0xe0, 0xba, 0xca },
|
||||
{ 0x00, 0x4d, 0x7c, 0x31, 0x7d, 0x30, 0x01, 0x4c, 0x81, 0xcc, 0xfd, 0xb0, 0xfc, 0xb1, 0x80, 0xcd },
|
||||
{ 0x10, 0x01, 0x08, 0x0d, 0x0f, 0x06, 0x05, 0x0e, 0x02, 0x0c, 0x0b, 0x0a, 0x09, 0x03, 0x07, 0x04 },
|
||||
{ 0x10, 0x07, 0x0b, 0x0f, 0x06, 0x0a, 0x04, 0x01, 0x09, 0x08, 0x05, 0x02, 0x0c, 0x0e, 0x0d, 0x03 },
|
||||
{ 0x00, 0xc7, 0xbd, 0x6f, 0x17, 0x6d, 0xd2, 0xd0, 0x78, 0xa8, 0x02, 0xc5, 0x7a, 0xbf, 0xaa, 0x15 },
|
||||
{ 0x00, 0x6a, 0xbb, 0x5f, 0xa5, 0x74, 0xe4, 0xcf, 0xfa, 0x35, 0x2b, 0x41, 0xd1, 0x90, 0x1e, 0x8e },
|
||||
{ 0x04, 0x05, 0x06, 0x07, 0x05, 0x06, 0x07, 0x04, 0x0c, 0x0d, 0x0e, 0x0f, 0x0d, 0x0e, 0x0f, 0x0c },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00 },
|
||||
};
|
||||
|
||||
#define LA64_DUP16(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
|
||||
a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p
|
||||
|
||||
static const uint8_t la64_vpaes_enc_tables_xv[9][32] __attribute__((aligned(32))) = {
|
||||
{ LA64_DUP16(0x00, 0x70, 0x2a, 0x5a, 0x98, 0xe8, 0xb2, 0xc2, 0x08, 0x78, 0x22, 0x52, 0x90, 0xe0, 0xba, 0xca) },
|
||||
{ LA64_DUP16(0x00, 0x4d, 0x7c, 0x31, 0x7d, 0x30, 0x01, 0x4c, 0x81, 0xcc, 0xfd, 0xb0, 0xfc, 0xb1, 0x80, 0xcd) },
|
||||
{ LA64_DUP16(0x10, 0x01, 0x08, 0x0d, 0x0f, 0x06, 0x05, 0x0e, 0x02, 0x0c, 0x0b, 0x0a, 0x09, 0x03, 0x07, 0x04) },
|
||||
{ LA64_DUP16(0x10, 0x07, 0x0b, 0x0f, 0x06, 0x0a, 0x04, 0x01, 0x09, 0x08, 0x05, 0x02, 0x0c, 0x0e, 0x0d, 0x03) },
|
||||
{ LA64_DUP16(0x00, 0xc7, 0xbd, 0x6f, 0x17, 0x6d, 0xd2, 0xd0, 0x78, 0xa8, 0x02, 0xc5, 0x7a, 0xbf, 0xaa, 0x15) },
|
||||
{ LA64_DUP16(0x00, 0x6a, 0xbb, 0x5f, 0xa5, 0x74, 0xe4, 0xcf, 0xfa, 0x35, 0x2b, 0x41, 0xd1, 0x90, 0x1e, 0x8e) },
|
||||
{ LA64_DUP16(0x00, 0x05, 0x0a, 0x0f, 0x04, 0x09, 0x0e, 0x03, 0x08, 0x0d, 0x02, 0x07, 0x0c, 0x01, 0x06, 0x0b) },
|
||||
{ LA64_DUP16(0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e) },
|
||||
{ LA64_DUP16(0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x1b, 0x3b, 0x5b, 0x7b, 0x9b, 0xbb, 0xdb, 0xfb) },
|
||||
};
|
||||
|
||||
static const uint8_t la64_vpaes_dec_tables_xv[9][32] __attribute__((aligned(32))) = {
|
||||
{ LA64_DUP16(0x00, 0x5f, 0x54, 0x0b, 0x04, 0x5b, 0x50, 0x0f, 0x1a, 0x45, 0x4e, 0x11, 0x1e, 0x41, 0x4a, 0x15) },
|
||||
{ LA64_DUP16(0x00, 0x65, 0x05, 0x60, 0xe6, 0x83, 0xe3, 0x86, 0x94, 0xf1, 0x91, 0xf4, 0x72, 0x17, 0x77, 0x12) },
|
||||
{ LA64_DUP16(0x10, 0x01, 0x08, 0x0d, 0x0f, 0x06, 0x05, 0x0e, 0x02, 0x0c, 0x0b, 0x0a, 0x09, 0x03, 0x07, 0x04) },
|
||||
{ LA64_DUP16(0x10, 0x07, 0x0b, 0x0f, 0x06, 0x0a, 0x04, 0x01, 0x09, 0x08, 0x05, 0x02, 0x0c, 0x0e, 0x0d, 0x03) },
|
||||
{ LA64_DUP16(0x00, 0x40, 0xf9, 0x7e, 0x53, 0xea, 0x87, 0x13, 0x2d, 0x3e, 0x94, 0xd4, 0xb9, 0x6d, 0xaa, 0xc7) },
|
||||
{ LA64_DUP16(0x00, 0x1d, 0x44, 0x93, 0x0f, 0x56, 0xd7, 0x12, 0x9c, 0x8e, 0xc5, 0xd8, 0x59, 0x81, 0x4b, 0xca) },
|
||||
{ LA64_DUP16(0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b, 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03) },
|
||||
{ LA64_DUP16(0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e) },
|
||||
{ LA64_DUP16(0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x1b, 0x3b, 0x5b, 0x7b, 0x9b, 0xbb, 0xdb, 0xfb) },
|
||||
};
|
||||
|
||||
#undef LA64_DUP16
|
||||
|
||||
uintptr_t getConst(la64_consts_t which)
|
||||
{
|
||||
switch(which) {
|
||||
@@ -61,6 +127,11 @@ uintptr_t getConst(la64_consts_t which)
|
||||
case const_native_aeselast: return (uintptr_t)native_aeselast;
|
||||
case const_native_aeselast_y: return (uintptr_t)native_aeselast_y;
|
||||
case const_native_aeskeygenassist: return (uintptr_t)native_aeskeygenassist;
|
||||
case const_la64_vpaes_enc_tables: return (uintptr_t)la64_vpaes_enc_tables;
|
||||
case const_la64_vpaes_dec_tables: return (uintptr_t)la64_vpaes_dec_tables;
|
||||
case const_la64_vpaes_keygen_tables: return (uintptr_t)la64_vpaes_keygen_tables;
|
||||
case const_la64_vpaes_enc_tables_xv: return (uintptr_t)la64_vpaes_enc_tables_xv;
|
||||
case const_la64_vpaes_dec_tables_xv: return (uintptr_t)la64_vpaes_dec_tables_xv;
|
||||
case const_native_pclmul: return (uintptr_t)native_pclmul;
|
||||
case const_native_pclmul_x: return (uintptr_t)native_pclmul_x;
|
||||
case const_native_pclmul_y: return (uintptr_t)native_pclmul_y;
|
||||
@@ -107,6 +178,7 @@ uintptr_t getConst(la64_consts_t which)
|
||||
case const_cpuid: return (uintptr_t)my_cpuid;
|
||||
case const_getsegmentbase: return (uintptr_t)GetSegmentBaseEmu;
|
||||
case const_updateflags: return (uintptr_t)UpdateFlags;
|
||||
case const_updateflags_la64: return (uintptr_t)create_updateflags();
|
||||
case const_reset_fpu: return (uintptr_t)reset_fpu;
|
||||
case const_sha1nexte: return (uintptr_t)sha1nexte;
|
||||
case const_sha1msg1: return (uintptr_t)sha1msg1;
|
||||
@@ -141,4 +213,4 @@ uintptr_t getConst(la64_consts_t which)
|
||||
}
|
||||
dynarec_log(LOG_NONE, "Warning, Unknown const %d used\n", which);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,11 @@ typedef enum la64_consts_s {
|
||||
const_native_aeselast,
|
||||
const_native_aeselast_y,
|
||||
const_native_aeskeygenassist,
|
||||
const_la64_vpaes_enc_tables,
|
||||
const_la64_vpaes_dec_tables,
|
||||
const_la64_vpaes_keygen_tables,
|
||||
const_la64_vpaes_enc_tables_xv,
|
||||
const_la64_vpaes_dec_tables_xv,
|
||||
const_native_pclmul,
|
||||
const_native_pclmul_x,
|
||||
const_native_pclmul_y,
|
||||
@@ -77,6 +82,7 @@ typedef enum la64_consts_s {
|
||||
const_cpuid,
|
||||
const_getsegmentbase,
|
||||
const_updateflags,
|
||||
const_updateflags_la64,
|
||||
const_reset_fpu,
|
||||
const_sha1nexte,
|
||||
const_sha1msg1,
|
||||
@@ -114,4 +120,4 @@ uintptr_t getConst(la64_consts_t which);
|
||||
// temporary define...
|
||||
#define const_PrintTrace const_printtrace
|
||||
|
||||
#endif //__DYNAREC_LA64_CONSTS__
|
||||
#endif //__DYNAREC_LA64_CONSTS__
|
||||
@@ -121,7 +121,7 @@ uintptr_t dynarec64_D9(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
} else {
|
||||
// not in cache, so check Empty status and load it
|
||||
i2 = -dyn->lsx.x87stack;
|
||||
LD_WU(x3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
LD_W(x3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
if (i2) {
|
||||
ADDI_D(x3, x3, -i2);
|
||||
}
|
||||
@@ -149,6 +149,14 @@ uintptr_t dynarec64_D9(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// check if stack is empty (freed register will not count, but might work if using tags instead)
|
||||
i2 = -dyn->lsx.x87stack;
|
||||
LD_W(x3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
if (i2) {
|
||||
ADDI_D(x3, x3, -i2);
|
||||
}
|
||||
MOV32w(x4, 0b100000100000000); // empty: C3,C2,C0 = 101
|
||||
BGE_MARK3(xZR, x3);
|
||||
// simply move from cache reg to x2
|
||||
v1 = dyn->lsx.x87reg[i1];
|
||||
MOVFR2GR_D(x2, v1);
|
||||
|
||||
@@ -98,6 +98,9 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGX(v0, 1);
|
||||
GETED(0);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x2, x3);
|
||||
}
|
||||
if (rex.w) {
|
||||
MOVGR2FR_D(d1, ed);
|
||||
FFINT_D_L(d1, d1);
|
||||
@@ -105,6 +108,9 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
MOVGR2FR_W(d1, ed);
|
||||
FFINT_D_W(d1, d1);
|
||||
}
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
VEXTRINS_D(v0, d1, 0);
|
||||
break;
|
||||
case 0x2C:
|
||||
@@ -266,7 +272,13 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGX(v0, 1);
|
||||
GETEXSD(d0, 0, 0);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x2, x3);
|
||||
}
|
||||
FCVT_S_D(d1, d0);
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
VEXTRINS_W(v0, d1, 0);
|
||||
break;
|
||||
case 0x5C:
|
||||
@@ -414,6 +426,25 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VBITSEL_V(q0, q0, d1, d0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA3: // ignore F2 prefix
|
||||
case 0xA4:
|
||||
case 0xA5:
|
||||
case 0xAB:
|
||||
case 0xAC:
|
||||
case 0xAD:
|
||||
case 0xAF:
|
||||
case 0xB3:
|
||||
case 0xB7:
|
||||
case 0xBA:
|
||||
case 0xBB:
|
||||
case 0xBC: // this one is still BSR, not TZCNT
|
||||
case 0xBD: // and this one is still BSF, not LZCNT
|
||||
case 0xBF:
|
||||
case 0xC1:
|
||||
case 0xCD:
|
||||
return dynarec64_0F(dyn, addr - 1, ip, ninst, rex, ok, need_epilog);
|
||||
|
||||
case 0xAE:
|
||||
nextop = F8;
|
||||
switch ((nextop >> 3) & 7) {
|
||||
|
||||
@@ -105,11 +105,17 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETED(0);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
MOVGR2FR_D(d1, ed);
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x5, x6);
|
||||
}
|
||||
if (rex.w) {
|
||||
FFINT_S_L(d1, d1);
|
||||
} else {
|
||||
FFINT_S_W(d1, d1);
|
||||
}
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
}
|
||||
VEXTRINS_W(v0, d1, 0);
|
||||
break;
|
||||
case 0x2C:
|
||||
@@ -512,6 +518,22 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
SMWRITE2();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA3: // ignore F3 prefix
|
||||
case 0xA4:
|
||||
case 0xA5:
|
||||
case 0xAC:
|
||||
case 0xAD:
|
||||
case 0xAF:
|
||||
case 0xB3:
|
||||
case 0xB7:
|
||||
case 0xBA:
|
||||
case 0xBB:
|
||||
case 0xBF:
|
||||
case 0xC1:
|
||||
case 0xCD:
|
||||
return dynarec64_0F(dyn, addr - 1, ip, ninst, rex, ok, need_epilog);
|
||||
|
||||
case 0xAE:
|
||||
nextop = F8;
|
||||
switch ((nextop >> 3) & 7) {
|
||||
|
||||
@@ -35,7 +35,12 @@
|
||||
// Get a FPU scratch reg
|
||||
int fpu_get_scratch(dynarec_la64_t* dyn)
|
||||
{
|
||||
return SCRATCH0 + dyn->lsx.fpu_scratch++; // return an Sx
|
||||
int ret = SCRATCH0 + dyn->lsx.fpu_scratch++; // return an Sx
|
||||
if (ret >= SCRATCH_LIMIT) {
|
||||
dyn->abort = 1;
|
||||
ret = SCRATCH_LIMIT - 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// Reset scratch regs counter
|
||||
void fpu_reset_scratch(dynarec_la64_t* dyn)
|
||||
@@ -652,6 +657,8 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
|
||||
length += sprintf(buf + length, " X87:%d/%d(+%d/-%d)%d", dyn->lsx.stack, dyn->insts[ninst].lsx.stack_next, dyn->insts[ninst].lsx.stack_push, dyn->insts[ninst].lsx.stack_pop, dyn->insts[ninst].lsx.x87stack);
|
||||
if (dyn->insts[ninst].lsx.combined1 || dyn->insts[ninst].lsx.combined2)
|
||||
length += sprintf(buf + length, " %s:%d/%d", dyn->insts[ninst].lsx.swapped ? "SWP" : "CMB", dyn->insts[ninst].lsx.combined1, dyn->insts[ninst].lsx.combined2);
|
||||
if(dyn->insts[ninst].x64.self_loop)
|
||||
length += sprintf(buf + length, " self-loop");
|
||||
|
||||
if (dyn->need_dump) {
|
||||
printf_x64_instruction(dyn, rex.is32bits ? my_context->dec32 : my_context->dec, &dyn->insts[ninst].x64, name);
|
||||
@@ -922,4 +929,4 @@ void propagateFpuBarrier(dynarec_la64_t* dyn)
|
||||
last_fpu_used = -1; // reset the last_fpu_used...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,10 @@
|
||||
|
||||
#include "../dynarec_native_functions.h"
|
||||
|
||||
#define SCRATCH0 24
|
||||
#define SCRATCH0 24
|
||||
#define VZERO 30
|
||||
#define SCRATCH 31
|
||||
#define SCRATCH_LIMIT VZERO
|
||||
|
||||
typedef struct x64emu_s x64emu_t;
|
||||
typedef struct dynarec_la64_s dynarec_la64_t;
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "dynarec_la64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
#define SCRATCH 31
|
||||
|
||||
/* setup r2 to address pointed by ED, 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 geted(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, rex_t rex, int* l, int i12, int delta)
|
||||
{
|
||||
@@ -461,7 +459,9 @@ void ret_to_next(dynarec_la64_t* dyn, uintptr_t ip, int ninst, rex_t rex)
|
||||
|
||||
void iret_to_next(dynarec_la64_t* dyn, uintptr_t ip, int ninst, int is32bits, int is64bits)
|
||||
{
|
||||
int64_t j64;
|
||||
MAYUSE(ninst);
|
||||
MAYUSE(j64);
|
||||
MESSAGE(LOG_DUMP, "IRet to next\n");
|
||||
if (is64bits) {
|
||||
POP1(xRIP);
|
||||
@@ -481,6 +481,12 @@ void iret_to_next(dynarec_la64_t* dyn, uintptr_t ip, int ninst, int is32bits, in
|
||||
ORI(xFlags, xFlags, 0x2);
|
||||
SPILL_EFLAGS();
|
||||
CHECK_DFNONE(0);
|
||||
if (is32bits) {
|
||||
ANDI(x1, x2, 0xff);
|
||||
// check if return segment is 64bits, then restore rsp too
|
||||
MOV32w(x3, 0x23);
|
||||
BEQ_MARKSEG(x1, x3);
|
||||
}
|
||||
// POP RSP
|
||||
if (is64bits) {
|
||||
POP1(x3); // rsp
|
||||
@@ -493,6 +499,7 @@ void iret_to_next(dynarec_la64_t* dyn, uintptr_t ip, int ninst, int is32bits, in
|
||||
ST_H(x2, xEmu, offsetof(x64emu_t, segs[_SS]));
|
||||
// set new RSP
|
||||
MV(xRSP, x3);
|
||||
MARKSEG;
|
||||
// Ret....
|
||||
rex_t dummy = { 0 };
|
||||
dummy.is32bits = is32bits;
|
||||
@@ -536,6 +543,7 @@ void call_c(dynarec_la64_t* dyn, int ninst, la64_consts_t fnc, int reg, int ret,
|
||||
if (arg6) MV(A6, arg6);
|
||||
MV(A0, xEmu);
|
||||
JIRL(xRA, reg, 0);
|
||||
LA64_RESTORE_VZERO();
|
||||
if (ret >= 0) {
|
||||
MV(ret, A0);
|
||||
}
|
||||
@@ -586,14 +594,12 @@ void call_n(dynarec_la64_t* dyn, int ninst, void* fnc, int w)
|
||||
}
|
||||
}
|
||||
// native call
|
||||
if (dyn->need_reloc) {
|
||||
// fnc is indirect, to help with relocation (but PltResolver might be an issue here)
|
||||
TABLE64(x3, (uintptr_t)fnc);
|
||||
LD_D(x3, x3, 0);
|
||||
} else {
|
||||
TABLE64_(x3, *(uintptr_t*)fnc); // using x16 as scratch regs for call address
|
||||
}
|
||||
TABLE64_(x3, *(uintptr_t*)fnc); // using x16 as scratch regs for call address
|
||||
// Note that if need_reloc is active, the TABLE64 will trigger cancel block,
|
||||
// because native function might be very different on a next run: different function address, different brick, different everything basicaly
|
||||
// and we don't have a relocation mecanism here, it's too complex
|
||||
JIRL(xRA, x3, 0x0);
|
||||
LA64_RESTORE_VZERO();
|
||||
// put return value in x64 regs
|
||||
if (w > 0) {
|
||||
MV(xRAX, A0);
|
||||
@@ -629,11 +635,11 @@ int x87_stackcount(dynarec_la64_t* dyn, int ninst, int scratch)
|
||||
int a = dyn->lsx.x87stack;
|
||||
// Add x87stack to emu fpu_stack
|
||||
LD_W(scratch, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
ADDI_D(scratch, scratch, a);
|
||||
ADDI_W(scratch, scratch, a);
|
||||
ST_W(scratch, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
// Sub x87stack to top, with and 7
|
||||
LD_W(scratch, xEmu, offsetof(x64emu_t, top));
|
||||
ADDI_D(scratch, scratch, -a);
|
||||
ADDI_W(scratch, scratch, -a);
|
||||
ANDI(scratch, scratch, 7);
|
||||
ST_W(scratch, xEmu, offsetof(x64emu_t, top));
|
||||
// reset x87stack, but not the stack count of extcache
|
||||
@@ -1415,11 +1421,11 @@ void sse_purge07cache(dynarec_la64_t* dyn, int ninst, int s1)
|
||||
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[i].reg].t == LSX_CACHE_YMMW) {
|
||||
VST(dyn->lsx.avxcache[i].reg, xEmu, offsetof(x64emu_t, xmm[i]));
|
||||
if (dyn->lsx.avxcache[i].dirty) {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
} else {
|
||||
XVPERMI_Q(SCRATCH, dyn->lsx.avxcache[i].reg, XVPERMI_IMM_4_0(0, 1));
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
}
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
fpu_free_reg(dyn, dyn->lsx.avxcache[i].reg);
|
||||
dyn->lsx.avxcache[i].v = -1;
|
||||
} else if (dyn->lsx.lsxcache[dyn->lsx.ssecache[i].reg].t == LSX_CACHE_XMMW) {
|
||||
@@ -1508,8 +1514,10 @@ int avx_get_reg_empty(dynarec_la64_t* dyn, int ninst, int s1, int a, int width)
|
||||
dyn->lsx.avxcache[a].dirty = width == LSX_AVX_WIDTH_128;
|
||||
return dyn->lsx.avxcache[a].reg;
|
||||
}
|
||||
fpu_free_reg(dyn, dyn->lsx.ssecache[a].reg);
|
||||
dyn->lsx.ssecache[a].v = -1;
|
||||
if (dyn->lsx.ssecache[a].v != -1) {
|
||||
fpu_free_reg(dyn, dyn->lsx.ssecache[a].reg);
|
||||
dyn->lsx.ssecache[a].v = -1;
|
||||
}
|
||||
dyn->lsx.avxcache[a].v = 0;
|
||||
dyn->lsx.avxcache[a].reg = fpu_get_reg_ymm(dyn, LSX_CACHE_YMMW, a);
|
||||
dyn->lsx.avxcache[a].write = 1;
|
||||
@@ -1538,11 +1546,11 @@ void avx_forget_reg(dynarec_la64_t* dyn, int ninst, int a)
|
||||
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[a].reg].t == LSX_CACHE_YMMW) {
|
||||
VST(dyn->lsx.avxcache[a].reg, xEmu, offsetof(x64emu_t, xmm[a]));
|
||||
if (dyn->lsx.avxcache[a].dirty) {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
} else {
|
||||
XVPERMI_Q(SCRATCH, dyn->lsx.avxcache[a].reg, XVPERMI_IMM_4_0(0, 1));
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
}
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
}
|
||||
fpu_free_reg(dyn, dyn->lsx.avxcache[a].reg);
|
||||
dyn->lsx.avxcache[a].v = -1;
|
||||
@@ -1557,12 +1565,12 @@ void avx_reflect_reg(dynarec_la64_t* dyn, int ninst, int a)
|
||||
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[a].reg].t == LSX_CACHE_YMMW) {
|
||||
VST(dyn->lsx.avxcache[a].reg, xEmu, offsetof(x64emu_t, xmm[a]));
|
||||
if (dyn->lsx.avxcache[a].dirty) {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[a].reg, SCRATCH, 0b00000010);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[a].reg, VZERO, 0b00000010);
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
} else {
|
||||
XVPERMI_Q(SCRATCH, dyn->lsx.avxcache[a].reg, XVPERMI_IMM_4_0(0, 1));
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
}
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
dyn->lsx.avxcache[a].dirty = 0;
|
||||
}
|
||||
}
|
||||
@@ -1578,8 +1586,7 @@ void avx_cleancache(dynarec_la64_t* dyn, int ninst)
|
||||
MESSAGE(LOG_DUMP, "\tClean AVX Cache ------\n");
|
||||
++old;
|
||||
}
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, SCRATCH, 0b00000010);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, VZERO, 0b00000010);
|
||||
dyn->lsx.avxcache[i].dirty = 0;
|
||||
}
|
||||
}
|
||||
@@ -1602,11 +1609,11 @@ static void avx_purgecache(dynarec_la64_t* dyn, int ninst, int next, int s1)
|
||||
}
|
||||
VST(dyn->lsx.avxcache[i].reg, xEmu, offsetof(x64emu_t, xmm[i]));
|
||||
if (dyn->lsx.avxcache[i].dirty) {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
} else {
|
||||
XVPERMI_Q(SCRATCH, dyn->lsx.avxcache[i].reg, XVPERMI_IMM_4_0(0, 1));
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
}
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
} else {
|
||||
MESSAGE(LOG_DUMP, "\tAVX Cache for YMM%d is not write, no need to store back %d\n", i, dyn->lsx.lsxcache[dyn->lsx.avxcache[i].reg].t);
|
||||
}
|
||||
@@ -1685,6 +1692,8 @@ void fpu_popcache(dynarec_la64_t* dyn, int ninst, int s1, int not07)
|
||||
if (!dyn->lsx.avxcache[i].dirty) {
|
||||
VLD(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, SCRATCH, XVPERMI_IMM_4_0(0, 2));
|
||||
} else {
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, VZERO, XVPERMI_IMM_4_0(0, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2175,11 +2184,11 @@ static void fpuCacheTransform(dynarec_la64_t* dyn, int ninst, int s1, int s2, in
|
||||
MESSAGE(LOG_DUMP, "\t - adjust stack count %d -> %d -\n", stack_cnt, cache_i2.stack);
|
||||
int a = stack_cnt - cache_i2.stack;
|
||||
// Add x87stack to emu fpu_stack
|
||||
LD_WU(s3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
LD_W(s3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
ADDI_D(s3, s3, a);
|
||||
ST_W(s3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
// Sub x87stack to top, with and 7
|
||||
LD_WU(s3, xEmu, offsetof(x64emu_t, top));
|
||||
LD_W(s3, xEmu, offsetof(x64emu_t, top));
|
||||
ADDI_D(s3, s3, -a);
|
||||
ANDI(s3, s3, 7);
|
||||
ST_W(s3, xEmu, offsetof(x64emu_t, top));
|
||||
@@ -2239,7 +2248,9 @@ static void flagsCacheTransform(dynarec_la64_t* dyn, int ninst, int s1)
|
||||
j64 = (GETMARKF2) - (dyn->native_size);
|
||||
BEQZ(s1, j64);
|
||||
}
|
||||
CALL_(const_updateflags, -1, 0, 0, 0);
|
||||
TABLE64C(s1, const_updateflags_la64);
|
||||
JIRL(xRA, s1, 0);
|
||||
LA64_RESTORE_VZERO();
|
||||
MARKF2;
|
||||
}
|
||||
MESSAGE(LOG_DUMP, "\t---- Flags fetch\n");
|
||||
@@ -2294,10 +2305,11 @@ void checkCRC(dynarec_la64_t* dyn, int ninst)
|
||||
LD_D(x1, x6, offsetof(dynablock_t, x64_addr));
|
||||
LD_WU(x2, x6, offsetof(dynablock_t, x64_size));
|
||||
JIRL(xRA, x3, 0x0);
|
||||
LA64_RESTORE_VZERO();
|
||||
// done, result in x1, load the stored hash (sign extended, as the crc will also be sign extended)
|
||||
LD_W(x2, x6, offsetof(dynablock_t, hash));
|
||||
// compare computed crc with stored one, jump to continue is equal
|
||||
BEQ(x1, x2, 4+3*4); // TABLE64C generates 2 opcodes...
|
||||
TABLE64C(x3, const_native_next_invalid);
|
||||
JIRL(xRA, x3, 0x0);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
// undef to get Close to SSE Float->int conversions
|
||||
// #define PRECISE_CVT
|
||||
|
||||
#ifndef STEP_PASS
|
||||
#if STEP == 0
|
||||
#include "dynarec_la64_pass0.h"
|
||||
#elif STEP == 1
|
||||
@@ -13,11 +14,22 @@
|
||||
#elif STEP == 3
|
||||
#include "dynarec_la64_pass3.h"
|
||||
#endif
|
||||
#define STEP_PASS
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
#include "la64_emitter.h"
|
||||
#include "../emu/x64primop.h"
|
||||
#include "dynarec_la64_consts.h"
|
||||
#include "dynarec_la64_functions.h"
|
||||
|
||||
#define LA64_RESTORE_VZERO() \
|
||||
do { \
|
||||
if (cpuext.lasx) \
|
||||
XVXOR_V(VZERO, VZERO, VZERO); \
|
||||
else \
|
||||
VXOR_V(VZERO, VZERO, VZERO); \
|
||||
} while (0)
|
||||
|
||||
#define F8 *(uint8_t*)(addr++)
|
||||
#define F8S *(int8_t*)(addr++)
|
||||
@@ -799,6 +811,10 @@
|
||||
#define CBNZ_MARKSEG(reg) \
|
||||
j64 = GETMARKSEG - (dyn->native_size); \
|
||||
BNEZ(reg, j64);
|
||||
// Branch to MARKSEG if reg1==reg2 (use j64)
|
||||
#define BEQ_MARKSEG(reg1, reg2) \
|
||||
j64 = GETMARKSEG - (dyn->native_size); \
|
||||
BEQ(reg1, reg2, j64);
|
||||
|
||||
#define IFX(A) if ((dyn->insts[ninst].x64.gen_flags & (A)))
|
||||
#define IFXA(A, B) if ((dyn->insts[ninst].x64.gen_flags & (A)) && (B))
|
||||
@@ -952,11 +968,13 @@
|
||||
#endif
|
||||
|
||||
#ifndef READFLAGS
|
||||
#define READFLAGS(A) \
|
||||
if ((A) != X_PEND \
|
||||
&& (dyn->f == status_unk)) { \
|
||||
CALL_(const_updateflags, -1, 0, 0, 0); \
|
||||
dyn->f = status_none; \
|
||||
#define READFLAGS(A) \
|
||||
if ((A) != X_PEND \
|
||||
&& (dyn->f == status_unk)) { \
|
||||
TABLE64C(x6, const_updateflags_la64); \
|
||||
JIRL(xRA, x6, 0); \
|
||||
LA64_RESTORE_VZERO(); \
|
||||
dyn->f = status_none; \
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -993,7 +1011,9 @@
|
||||
#define GRABFLAGS(A) \
|
||||
if ((A) != X_PEND \
|
||||
&& ((dyn->f == status_unk) || (dyn->f == status_set))) { \
|
||||
CALL_(const_updateflags, -1, 0, 0, 0); \
|
||||
TABLE64C(x6, const_updateflags_la64); \
|
||||
JIRL(xRA, x6, 0); \
|
||||
LA64_RESTORE_VZERO(); \
|
||||
dyn->f = status_none; \
|
||||
}
|
||||
|
||||
@@ -1137,6 +1157,7 @@
|
||||
#endif
|
||||
|
||||
#define native_pass STEPNAME(native_pass)
|
||||
#define updateflags_pass STEPNAME(updateflags_pass)
|
||||
|
||||
#define dynarec64_00 STEPNAME(dynarec64_00)
|
||||
#define dynarec64_0F STEPNAME(dynarec64_0F)
|
||||
|
||||
@@ -200,7 +200,37 @@ int Table64(dynarec_la64_t *dyn, uint64_t val, int pass); // add a value to tab
|
||||
|
||||
void CreateJmpNext(void* addr, void* next);
|
||||
|
||||
// While we could theoretically traverse forward to find the flags-consuming x86
|
||||
// instruction and get the exact scratch registers to save, this is too complicated.
|
||||
// So we went with the simpler approach of saving all scratch registers, this won't
|
||||
// add noticeable performance overhead in trace mode.
|
||||
#define SPILL_NF_REGISTERS \
|
||||
do { \
|
||||
ADDI_D(xSP, xSP, -64); \
|
||||
ST_D(x1, xSP, 0 * 8); \
|
||||
ST_D(x2, xSP, 1 * 8); \
|
||||
ST_D(x3, xSP, 2 * 8); \
|
||||
ST_D(x4, xSP, 3 * 8); \
|
||||
ST_D(x5, xSP, 4 * 8); \
|
||||
ST_D(x6, xSP, 5 * 8); \
|
||||
ST_D(x7, xSP, 6 * 8); \
|
||||
} while(0);
|
||||
|
||||
#define RESTORE_NF_REGISTERS \
|
||||
do { \
|
||||
LD_D(x1, xSP, 0 * 8); \
|
||||
LD_D(x2, xSP, 1 * 8); \
|
||||
LD_D(x3, xSP, 2 * 8); \
|
||||
LD_D(x4, xSP, 3 * 8); \
|
||||
LD_D(x5, xSP, 4 * 8); \
|
||||
LD_D(x6, xSP, 5 * 8); \
|
||||
LD_D(x7, xSP, 6 * 8); \
|
||||
ADDI_D(xSP, xSP, 64); \
|
||||
} while(0);
|
||||
|
||||
#define GO_TRACE(A, B, s0) \
|
||||
if(cpuext.lbt) \
|
||||
RESTORE_EFLAGS(s0); \
|
||||
GETIP(addr, s0); \
|
||||
MV(x1, xRIP); \
|
||||
STORE_XEMU_CALL(); \
|
||||
|
||||
@@ -152,6 +152,8 @@
|
||||
|
||||
// DBAR hint
|
||||
#define DBAR(hint) EMIT(type_hint(0b00111000011100100, hint))
|
||||
// IBAR hint
|
||||
#define IBAR(hint) EMIT(type_hint(0b00111000011100101, hint))
|
||||
|
||||
#define DBAR_RW_RW() DBAR(0b10000)
|
||||
#define DBAR_R_RW() DBAR(0b10100)
|
||||
@@ -187,8 +189,8 @@
|
||||
|
||||
#define BREAK() EMIT(0b1010100)
|
||||
|
||||
// there is no UDF instruction, use BREAK instead is an acceptable offer
|
||||
#define UDF() BREAK()
|
||||
// there is no UDF instruction, use AMSWAP_W($r0, $r1, $r0) like gcc
|
||||
#define UDF() AMSWAP_W(0, 1, 0)
|
||||
|
||||
// tmp = SLL(GR[rj][31:0], GR[rk][4:0])
|
||||
// GR[rd] = SignExtend(tmp[31:0], GRLEN)
|
||||
|
||||
@@ -10,9 +10,20 @@
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.extern cpuext
|
||||
.extern LinkNext
|
||||
.extern LinkNextInvalid
|
||||
|
||||
.macro restore_vzero
|
||||
.word 0x71277bde // vxor.v $vr30, $vr30, $vr30
|
||||
la.global $r19, cpuext
|
||||
ldptr.d $r19, $r19, 0
|
||||
andi $r19, $r19, 0x20
|
||||
beqz $r19, 1f
|
||||
.word 0x75277bde // xvxor.v $xr30, $xr30, $xr30
|
||||
1:
|
||||
.endm
|
||||
|
||||
.global la64_next
|
||||
.global la64_next_invalid
|
||||
|
||||
@@ -20,7 +31,7 @@
|
||||
la64_next:
|
||||
// move emu to a0
|
||||
// move IP address to a1
|
||||
addi.d $sp, $sp, -(8 * 11)
|
||||
addi.d $sp, $sp, -(8 * 12)
|
||||
st.d RDI, $sp, 0
|
||||
st.d RSI, $sp, 8
|
||||
st.d RDX, $sp, 16
|
||||
@@ -32,7 +43,14 @@ la64_next:
|
||||
st.d RSP, $sp, 64
|
||||
st.d RBP, $sp, 72
|
||||
st.d RIP, $sp, 80 // also save r29(rip) to allow change in LinkNext
|
||||
|
||||
// Save LBT.eflags too if lbt is enabled
|
||||
la.global $r19, cpuext
|
||||
ldptr.d $r19, $r19, 0
|
||||
andi $r19, $r19, 1
|
||||
beqz $r19, 1f
|
||||
x86mfflag $r19, 0b111111
|
||||
st.d $r19, $sp, 88
|
||||
1:
|
||||
move $a0, Emu
|
||||
move $a1, RIP
|
||||
move $a2, $ra // "from" is in ra, so put in a2
|
||||
@@ -41,6 +59,7 @@ la64_next:
|
||||
bl LinkNext
|
||||
// preserve return value
|
||||
move $r16, $a0
|
||||
restore_vzero
|
||||
// pop regs
|
||||
ld.d RDI, $sp, 0
|
||||
ld.d RSI, $sp, 8
|
||||
@@ -53,14 +72,22 @@ la64_next:
|
||||
ld.d RSP, $sp, 64
|
||||
ld.d RBP, $sp, 72
|
||||
ld.d RIP, $sp, 80
|
||||
addi.d $sp, $sp, (8 * 11)
|
||||
// restore LBT.eflags
|
||||
la.global $r19, cpuext
|
||||
ldptr.d $r19, $r19, 0
|
||||
andi $r19, $r19, 1
|
||||
beqz $r19, 2f
|
||||
ld.d $r19, $sp, 88
|
||||
x86mtflag $r19, 0b111111
|
||||
2:
|
||||
addi.d $sp, $sp, (8 * 12)
|
||||
// return offset is jump address
|
||||
jr $r16
|
||||
|
||||
la64_next_invalid:
|
||||
// move emu to a0
|
||||
// move IP address to a1
|
||||
addi.d $sp, $sp, -(8 * 11)
|
||||
addi.d $sp, $sp, -(8 * 12)
|
||||
st.d RDI, $sp, 0
|
||||
st.d RSI, $sp, 8
|
||||
st.d RDX, $sp, 16
|
||||
@@ -72,7 +99,14 @@ la64_next_invalid:
|
||||
st.d RSP, $sp, 64
|
||||
st.d RBP, $sp, 72
|
||||
st.d RIP, $sp, 80 // also save r29(rip) to allow change in LinkNext
|
||||
|
||||
// Save LBT.eflags too if lbt is enabled
|
||||
la.global $r19, cpuext
|
||||
ldptr.d $r19, $r19, 0
|
||||
andi $r19, $r19, 1
|
||||
beqz $r19, 1f
|
||||
x86mfflag $r19, 0b111111
|
||||
st.d $r19, $sp, 88
|
||||
1:
|
||||
move $a0, Emu
|
||||
move $a1, RIP
|
||||
move $a2, $ra // "from" is in ra, so put in a2
|
||||
@@ -81,6 +115,7 @@ la64_next_invalid:
|
||||
bl LinkNextInvalid
|
||||
// preserve return value
|
||||
move $r16, $a0
|
||||
restore_vzero
|
||||
// pop regs
|
||||
ld.d RDI, $sp, 0
|
||||
ld.d RSI, $sp, 8
|
||||
@@ -93,6 +128,14 @@ la64_next_invalid:
|
||||
ld.d RSP, $sp, 64
|
||||
ld.d RBP, $sp, 72
|
||||
ld.d RIP, $sp, 80
|
||||
addi.d $sp, $sp, (8 * 11)
|
||||
// restore LBT.eflags
|
||||
la.global $r19, cpuext
|
||||
ldptr.d $r19, $r19, 0
|
||||
andi $r19, $r19, 1
|
||||
beqz $r19, 2f
|
||||
ld.d $r19, $sp, 88
|
||||
x86mtflag $r19, 0b111111
|
||||
2:
|
||||
addi.d $sp, $sp, (8 * 12)
|
||||
// return offset is jump address
|
||||
jr $r16
|
||||
@@ -12,6 +12,16 @@
|
||||
|
||||
.extern cpuext
|
||||
|
||||
.macro restore_vzero
|
||||
.word 0x71277bde // vxor.v $vr30, $vr30, $vr30
|
||||
la.global $r19, cpuext
|
||||
ldptr.d $r19, $r19, 0
|
||||
andi $r19, $r19, 0x20
|
||||
beqz $r19, 1f
|
||||
.word 0x75277bde // xvxor.v $xr30, $xr30, $xr30
|
||||
1:
|
||||
.endm
|
||||
|
||||
.global la64_prolog
|
||||
la64_prolog:
|
||||
//save all 18 used register
|
||||
@@ -72,5 +82,6 @@ la64_prolog:
|
||||
addi.d $sp, $sp, -16
|
||||
// save old sp into xSavedSP
|
||||
addi.d SavedSP, $sp, 16
|
||||
restore_vzero
|
||||
//jump to function
|
||||
jirl $r0, $r16, 0
|
||||
@@ -0,0 +1,129 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "debug.h"
|
||||
#include "box64context.h"
|
||||
#include "custommem.h"
|
||||
#include "box64cpu.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "x64emu.h"
|
||||
#include "box64stack.h"
|
||||
#include "callback.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "x64trace.h"
|
||||
#include "dynablock.h"
|
||||
#include "../dynablock_private.h"
|
||||
|
||||
#include "dynarec_native.h"
|
||||
#include "../dynarec_arch.h"
|
||||
|
||||
void updateflags_pass0(dynarec_la64_t* dyn, uint64_t jmp_df[]);
|
||||
void updateflags_pass1(dynarec_la64_t* dyn, uint64_t jmp_df[]);
|
||||
void updateflags_pass2(dynarec_la64_t* dyn, uint64_t jmp_df[]);
|
||||
void updateflags_pass3(dynarec_la64_t* dyn, uint64_t jmp_df[]);
|
||||
|
||||
static dynablock_t* updateflags_la64 = NULL;
|
||||
|
||||
static uint8_t dummy_code[] = {0x90, 0xc3};
|
||||
|
||||
void* create_updateflags()
|
||||
{
|
||||
if (updateflags_la64)
|
||||
return updateflags_la64->block;
|
||||
|
||||
uint64_t jmp_df[d_unknown + 1] = {0};
|
||||
dynarec_la64_t helper = {0};
|
||||
instruction_la64_t insts[1] = {0};
|
||||
helper.insts = insts;
|
||||
helper.need_dump = BOX64ENV(dynarec_dump);
|
||||
helper.cap = 1;
|
||||
helper.f = status_none;
|
||||
helper.insts[0].x64.gen_flags = X_ALL;
|
||||
|
||||
updateflags_pass0(&helper, jmp_df);
|
||||
int ok = 1;
|
||||
for (int i = d_none; i < d_unknown; ++i)
|
||||
if (!jmp_df[i]) {
|
||||
printf_log(LOG_NONE, "Error, UpdateFlags case %d is not handled, will crash later\n", i);
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
updateflags_pass1(&helper, jmp_df);
|
||||
helper.native_size = 0;
|
||||
updateflags_pass2(&helper, jmp_df);
|
||||
|
||||
size_t native_size = (helper.native_size + 7) & ~7;
|
||||
size_t sz = sizeof(void*) + native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + 0 + 0 + 0 + sizeof(dynablock_t) + 0;
|
||||
// dynablock_t* block (arm insts) table64 jmpnext code instsize arch callrets dynablock relocs
|
||||
void* actual_p = (void*)AllocDynarecMap((uintptr_t)&dummy_code, sz, 1);
|
||||
void* p = (void*)(((uintptr_t)actual_p) + sizeof(void*));
|
||||
void* tablestart = p + native_size;
|
||||
void* next = tablestart + helper.table64size * sizeof(uint64_t);
|
||||
void* instsize = next + 4 * sizeof(void*);
|
||||
void* callrets = instsize;
|
||||
if (actual_p == NULL) {
|
||||
dynarec_log(LOG_INFO, "AllocDynarecMap(%zu) failed, canceling UpdateBlock\n", sz);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
helper.block = p;
|
||||
dynablock_t* block = (dynablock_t*)(callrets + 0);
|
||||
memset(block, 0, sizeof(dynablock_t));
|
||||
void* relocs = helper.need_reloc ? (block + 1) : NULL;
|
||||
// fill the block
|
||||
block->x64_addr = &dummy_code;
|
||||
block->actual_block = actual_p;
|
||||
helper.relocs = relocs;
|
||||
block->relocs = relocs;
|
||||
block->table64size = helper.table64size;
|
||||
helper.native_start = (uintptr_t)p;
|
||||
helper.tablestart = (uintptr_t)tablestart;
|
||||
helper.jmp_next = (uintptr_t)next + sizeof(void*);
|
||||
helper.instsize = (instsize_t*)instsize;
|
||||
*(dynablock_t**)actual_p = block;
|
||||
helper.table64cap = helper.table64size;
|
||||
helper.table64 = (uint64_t*)helper.tablestart;
|
||||
helper.callrets = (callret_t*)callrets;
|
||||
block->table64 = helper.table64;
|
||||
|
||||
if (helper.need_dump) {
|
||||
dynarec_log(LOG_NONE, "%s%04d|Emitting %zu bytes for UpdateFlags (%p)", (helper.need_dump > 1) ? "\e[01;36m" : "", GetTID(), helper.native_size, helper.native_start);
|
||||
dynarec_log_prefix(0, LOG_NONE, "%s\n", (helper.need_dump > 1) ? "\e[m" : "");
|
||||
}
|
||||
|
||||
helper.native_size = 0;
|
||||
updateflags_pass3(&helper, jmp_df);
|
||||
helper.jmp_sz = helper.jmp_cap = 0;
|
||||
helper.jmps = NULL;
|
||||
|
||||
block->instsize = instsize;
|
||||
helper.table64 = NULL;
|
||||
helper.instsize = NULL;
|
||||
helper.predecessor = NULL;
|
||||
block->size = sz;
|
||||
block->isize = helper.size;
|
||||
block->block = p;
|
||||
block->jmpnext = next + sizeof(void*);
|
||||
block->always_test = helper.always_test;
|
||||
block->dirty = block->always_test;
|
||||
block->is32bits = 0;
|
||||
block->relocsize = helper.reloc_size * sizeof(uint32_t);
|
||||
block->arch = NULL;
|
||||
block->arch_size = 0;
|
||||
block->callret_size = helper.callret_size;
|
||||
block->callrets = helper.callrets;
|
||||
block->native_size = native_size;
|
||||
*(dynablock_t**)next = block;
|
||||
*(void**)(next + 3 * sizeof(void*)) = NULL;
|
||||
CreateJmpNext(block->jmpnext, next + 3 * sizeof(void*));
|
||||
ClearCache(block->jmpnext, 4 * sizeof(void*));
|
||||
block->x64_size = 0;
|
||||
ClearCache(actual_p + sizeof(void*), native_size);
|
||||
|
||||
updateflags_la64 = block;
|
||||
return block->block;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -722,13 +722,10 @@ void call_n(dynarec_ppc64le_t* dyn, int ninst, void* fnc, int w)
|
||||
}
|
||||
}
|
||||
// native call — load function pointer into x7 (r10) to avoid clobbering argument regs
|
||||
if (dyn->need_reloc) {
|
||||
// fnc is indirect, to help with relocation (but PltResolver might be an issue here)
|
||||
TABLE64(x7, (uintptr_t)fnc);
|
||||
LD(x7, 0, x7);
|
||||
} else {
|
||||
TABLE64_(x7, *(uintptr_t*)fnc);
|
||||
}
|
||||
TABLE64_(x7, *(uintptr_t*)fnc);
|
||||
// Note that if need_reloc is active, the TABLE64 will trigger cancel block,
|
||||
// because native function might be very different on a next run: different function address, different brick, different everything basicaly
|
||||
// and we don't have a relocation mecanism here, it's too complex
|
||||
// ELFv2 ABI: r12 must be set to the function entry address
|
||||
MR(12, x7);
|
||||
MTCTR(x7);
|
||||
|
||||
@@ -218,6 +218,34 @@ int Table64(dynarec_ppc64le_t *dyn, uint64_t val, int pass); // add a value to
|
||||
|
||||
void CreateJmpNext(void* addr, void* next);
|
||||
|
||||
// While we could theoretically traverse forward to find the flags-consuming x86
|
||||
// instruction and get the exact scratch registers to save, this is too complicated.
|
||||
// So we went with the simpler approach of saving all scratch registers, this won't
|
||||
// add noticeable performance overhead in trace mode.
|
||||
#define SPILL_NF_REGISTERS \
|
||||
do { \
|
||||
ADDI(xSP, xSP, -64); \
|
||||
STD(x1, 0 * 8, xSP); \
|
||||
STD(x2, 1 * 8, xSP); \
|
||||
STD(x3, 2 * 8, xSP); \
|
||||
STD(x4, 3 * 8, xSP); \
|
||||
STD(x5, 4 * 8, xSP); \
|
||||
STD(x6, 5 * 8, xSP); \
|
||||
STD(x7, 6 * 8, xSP); \
|
||||
} while(0);
|
||||
|
||||
#define RESTORE_NF_REGISTERS \
|
||||
do { \
|
||||
LD(x1, 0 * 8, xSP); \
|
||||
LD(x2, 1 * 8, xSP); \
|
||||
LD(x3, 2 * 8, xSP); \
|
||||
LD(x4, 3 * 8, xSP); \
|
||||
LD(x5, 4 * 8, xSP); \
|
||||
LD(x6, 5 * 8, xSP); \
|
||||
LD(x7, 6 * 8, xSP); \
|
||||
ADDI(xSP, xSP, 64); \
|
||||
} while(0);
|
||||
|
||||
#define GO_TRACE(A, B, s0) \
|
||||
GETIP(addr, s0); \
|
||||
MV(x1, xRIP); \
|
||||
|
||||
@@ -920,6 +920,10 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
case 0xD7:
|
||||
INST_NAME("XLAT");
|
||||
ANDI(x1, xRAX, 0xff);
|
||||
if (rex.seg) {
|
||||
grab_segdata(dyn, addr, ninst, x2, rex.seg);
|
||||
ADD(x1, x1, x2);
|
||||
}
|
||||
ADD(x1, xRBX, x1);
|
||||
LBU(x1, x1, 0);
|
||||
ANDI(xRAX, xRAX, ~0xff);
|
||||
|
||||
@@ -875,8 +875,8 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
GETGD;
|
||||
SMREAD();
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
|
||||
REV8xw(x1, gd, x1, x2, x3, x4);
|
||||
SDxw(x1, wback, fixedaddress);
|
||||
REV8xw(x3, gd, x3, x4, x5, x6);
|
||||
SDxw(x3, wback, fixedaddress);
|
||||
break;
|
||||
default:
|
||||
DEFAULT;
|
||||
@@ -1109,11 +1109,23 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
s0 = fpu_get_scratch(dyn);
|
||||
s1 = fpu_get_scratch(dyn);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
// GX->f[i] += EX->f[i];
|
||||
FLW(s0, wback, fixedaddress + i * 4);
|
||||
FLW(s1, gback, gdoffset + i * 4);
|
||||
FADDS(s1, s1, s0);
|
||||
FSW(s1, gback, gdoffset + i * 4);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x3, s0, s0);
|
||||
FEQS(x4, s1, s1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FADDS(s0, s0, s1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x5, s0, s0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGS(s0, s0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVS(s0, s1);
|
||||
}
|
||||
FSW(s0, gback, gdoffset + i * 4);
|
||||
}
|
||||
break;
|
||||
case 0x59:
|
||||
@@ -1130,14 +1142,16 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x3, s0, s0);
|
||||
FEQS(x4, s1, s1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FMULS(s0, s0, s1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQS(x3, s0, s0);
|
||||
BNEZ(x3, 8);
|
||||
FEQS(x5, s0, s0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGS(s0, s0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVS(s0, s1);
|
||||
}
|
||||
FSW(s0, gback, gdoffset + i * 4);
|
||||
}
|
||||
@@ -1182,14 +1196,16 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x3, s0, s0);
|
||||
FEQS(x4, s1, s1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FSUBS(s0, s1, s0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQS(x3, s0, s0);
|
||||
BNEZ(x3, 8);
|
||||
FEQS(x5, s0, s0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGS(s0, s0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVS(s0, s1);
|
||||
}
|
||||
FSW(s0, gback, gdoffset + i * 4);
|
||||
}
|
||||
@@ -1227,14 +1243,16 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x3, s0, s0);
|
||||
FEQS(x4, s1, s1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FDIVS(s0, s1, s0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQS(x3, s0, s0);
|
||||
BNEZ(x3, 8);
|
||||
FEQS(x5, s0, s0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGS(s0, s0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVS(s0, s1);
|
||||
}
|
||||
FSW(s0, gback, gdoffset + i * 4);
|
||||
}
|
||||
@@ -2077,7 +2095,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 0);
|
||||
MOV32w(x2, rex.w ? 0 : 1);
|
||||
MOV32w(x2, rex.is32bits);
|
||||
CALL(const_fpu_xsave, -1, ed, x2);
|
||||
break;
|
||||
case 5:
|
||||
@@ -2085,7 +2103,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 0);
|
||||
MOV32w(x2, rex.w ? 0 : 1);
|
||||
MOV32w(x2, rex.is32bits);
|
||||
CALL(const_fpu_xrstor, -1, ed, x2);
|
||||
break;
|
||||
case 7:
|
||||
@@ -2359,14 +2377,21 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
ZEXTW2(x4, ed);
|
||||
ed = x4;
|
||||
}
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) MV(x3, xZR);
|
||||
}
|
||||
BNE_MARK(ed, xZR);
|
||||
IFX (X_ZF) ORI(xFlags, xFlags, 1 << F_ZF);
|
||||
if (!rex.w) ZEROUP(gd);
|
||||
B_MARK2_nocond;
|
||||
MARK;
|
||||
CTZxw(gd, ed, rex.w, x3, x5);
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) MV(x3, gd);
|
||||
}
|
||||
MARK2;
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) emit_pf(dyn, ninst, gd, x2, x5);
|
||||
IFX (X_PF) emit_pf(dyn, ninst, x3, x2, x5);
|
||||
}
|
||||
break;
|
||||
case 0xBD:
|
||||
@@ -2385,16 +2410,23 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
ZEXTW2(x4, ed);
|
||||
ed = x4;
|
||||
}
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) MV(x2, xZR);
|
||||
}
|
||||
BNE_MARK(ed, xZR);
|
||||
IFX (X_ZF) ORI(xFlags, xFlags, 1 << F_ZF);
|
||||
if (!rex.w) ZEROUP(gd);
|
||||
B_MARK2_nocond;
|
||||
MARK;
|
||||
CLZxw(gd, ed, rex.w, x3, x5, x7);
|
||||
ADDI(x3, xZR, rex.w ? 63 : 31);
|
||||
SUB(gd, x3, gd);
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) MV(x2, gd);
|
||||
}
|
||||
MARK2;
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) emit_pf(dyn, ninst, gd, x2, x5);
|
||||
IFX (X_PF) emit_pf(dyn, ninst, x2, x4, x5);
|
||||
}
|
||||
break;
|
||||
case 0xBE:
|
||||
|
||||
@@ -569,6 +569,10 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
|
||||
GETEX_vector(q0, 0, 0, VECTOR_SEW32);
|
||||
GETGX_vector(v0, 1, VECTOR_SEW32);
|
||||
if (v0 == q0) {
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
VMV_V_V(q0, v0);
|
||||
}
|
||||
VXOR_VI(v0, v0, 0x1f, VECTOR_UNMASKED);
|
||||
VAND_VV(v0, v0, q0, VECTOR_UNMASKED);
|
||||
break;
|
||||
@@ -596,6 +600,7 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
break;
|
||||
case 0x58:
|
||||
if (!BOX64ENV(dynarec_fastnan)) return 0;
|
||||
INST_NAME("ADDPS Gx, Ex");
|
||||
nextop = F8;
|
||||
SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1);
|
||||
|
||||
@@ -373,42 +373,56 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
case 0x58:
|
||||
INST_NAME("ADDPD Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(x1, 0, 8);
|
||||
GETGX();
|
||||
SSE_LOOP_FQ(x3, x4, {
|
||||
GETEX(x2, 0, 8);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
FLD(d0, wback, fixedaddress + 8 * i);
|
||||
FLD(d1, gback, gdoffset + 8 * i);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, d0, d0);
|
||||
FEQD(x4, d1, d1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FADDD(v0, v0, v1);
|
||||
FADDD(d0, d0, d1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FNEGD(v0, v0);
|
||||
FEQD(x5, d0, d0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(d0, d0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(d0, d1);
|
||||
}
|
||||
});
|
||||
FSD(d0, gback, gdoffset + 8 * i);
|
||||
}
|
||||
break;
|
||||
case 0x59:
|
||||
INST_NAME("MULPD Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(x1, 0, 8);
|
||||
GETGX();
|
||||
SSE_LOOP_FQ(x3, x4, {
|
||||
GETEX(x2, 0, 8);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
FLD(d0, wback, fixedaddress + 8 * i);
|
||||
FLD(d1, gback, gdoffset + 8 * i);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, d0, d0);
|
||||
FEQD(x4, d1, d1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FMULD(v0, v0, v1);
|
||||
FMULD(d0, d0, d1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FNEGD(v0, v0);
|
||||
FEQD(x5, d0, d0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(d0, d0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(d0, d1);
|
||||
}
|
||||
});
|
||||
FSD(d0, gback, gdoffset + 8 * i);
|
||||
}
|
||||
break;
|
||||
case 0x5A:
|
||||
INST_NAME("CVTPD2PS Gx, Ex");
|
||||
@@ -447,22 +461,29 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
case 0x5C:
|
||||
INST_NAME("SUBPD Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(x1, 0, 8);
|
||||
GETGX();
|
||||
SSE_LOOP_FQ(x3, x4, {
|
||||
GETEX(x2, 0, 8);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
FLD(d0, wback, fixedaddress + 8 * i);
|
||||
FLD(d1, gback, gdoffset + 8 * i);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, d0, d0);
|
||||
FEQD(x4, d1, d1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FSUBD(v0, v0, v1);
|
||||
FSUBD(d0, d1, d0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FNEGD(v0, v0);
|
||||
FEQD(x5, d0, d0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(d0, d0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(d0, d1);
|
||||
}
|
||||
});
|
||||
FSD(d0, gback, gdoffset + 8 * i);
|
||||
}
|
||||
break;
|
||||
case 0x5D:
|
||||
INST_NAME("MINPD Gx, Ex");
|
||||
@@ -486,22 +507,29 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
case 0x5E:
|
||||
INST_NAME("DIVPD Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(x1, 0, 8);
|
||||
GETGX();
|
||||
SSE_LOOP_FQ(x3, x4, {
|
||||
GETEX(x2, 0, 8);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
FLD(d0, wback, fixedaddress + 8 * i);
|
||||
FLD(d1, gback, gdoffset + 8 * i);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, d0, d0);
|
||||
FEQD(x4, d1, d1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FDIVD(v0, v0, v1);
|
||||
FDIVD(d0, d1, d0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FNEGD(v0, v0);
|
||||
FEQD(x5, d0, d0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(d0, d0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(d0, d1);
|
||||
}
|
||||
});
|
||||
FSD(d0, gback, gdoffset + 8 * i);
|
||||
}
|
||||
break;
|
||||
case 0x5F:
|
||||
INST_NAME("MAXPD Gx, Ex");
|
||||
@@ -1568,6 +1596,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
nextop = F8;
|
||||
GETEW(x5, 0);
|
||||
GETGW(x4);
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) MV(x2, xZR);
|
||||
}
|
||||
BNE_MARK(ed, xZR);
|
||||
IFX (X_ZF) ORI(xFlags, xFlags, 1 << F_ZF);
|
||||
B_MARK2_nocond;
|
||||
@@ -1575,10 +1606,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
IFXA (X_ZF, !BOX64DRENV(dynarec_safeflags))
|
||||
ANDI(xFlags, xFlags, ~(1 << F_ZF));
|
||||
CTZxw(gd, ed, 0, x1, x2);
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) MV(x2, gd);
|
||||
}
|
||||
GWBACK;
|
||||
MARK2;
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) emit_pf(dyn, ninst, gd, x1, x2);
|
||||
IFX (X_PF) emit_pf(dyn, ninst, x2, x1, x5);
|
||||
}
|
||||
break;
|
||||
case 0xBD:
|
||||
@@ -1592,6 +1626,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
nextop = F8;
|
||||
GETEW(x5, 0);
|
||||
GETGW(x4);
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) MV(x2, xZR);
|
||||
}
|
||||
BNE_MARK(ed, xZR);
|
||||
IFX (X_ZF) ORI(xFlags, xFlags, 1 << F_ZF);
|
||||
B_MARK2_nocond;
|
||||
@@ -1601,10 +1638,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
CLZxw(gd, ed, 1, x1, x2, x6);
|
||||
ADDI(x1, xZR, 63);
|
||||
SUB(gd, x1, gd);
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) MV(x2, gd);
|
||||
}
|
||||
GWBACK;
|
||||
MARK2;
|
||||
if (BOX64DRENV(dynarec_safeflags)) {
|
||||
IFX (X_PF) emit_pf(dyn, ninst, gd, x1, x2);
|
||||
IFX (X_PF) emit_pf(dyn, ninst, x2, x1, x5);
|
||||
}
|
||||
break;
|
||||
case 0xBE:
|
||||
|
||||
@@ -689,40 +689,6 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode,
|
||||
SW(x3, gback, gdoffset + i * 4);
|
||||
}
|
||||
break;
|
||||
case 0x61:
|
||||
INST_NAME("PCMPESTRI Gx, Ex, Ib");
|
||||
SETFLAGS(X_ALL, SF_SET_DF, NAT_FLAGS_NOFUSION);
|
||||
nextop = F8;
|
||||
GETG;
|
||||
sse_reflect_reg(dyn, ninst, x6, gd);
|
||||
ADDI(x3, xEmu, offsetof(x64emu_t, xmm[gd]));
|
||||
if (MODREG) {
|
||||
ed = (nextop & 7) + (rex.b << 3);
|
||||
sse_reflect_reg(dyn, ninst, x6, ed);
|
||||
ADDI(x1, xEmu, offsetof(x64emu_t, xmm[ed]));
|
||||
ed = x1;
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 1);
|
||||
}
|
||||
// prepare rest arguments
|
||||
MV(x2, xRDX);
|
||||
MV(x4, xRAX);
|
||||
u8 = F8;
|
||||
MOV32w(x5, u8);
|
||||
CALL6(const_sse42_compare_string_explicit_len, x1, ed, x2, x3, x4, x5, 0);
|
||||
ZEROUP(x1);
|
||||
BNEZ_MARK(x1);
|
||||
MOV32w(xRCX, (u8 & 1) ? 8 : 16);
|
||||
B_NEXT_nocond;
|
||||
MARK;
|
||||
if (u8 & 0b1000000) {
|
||||
CLZxw(xRCX, x1, 0, x2, x3, x4);
|
||||
ADDI(x2, xZR, 31);
|
||||
SUB(xRCX, x2, xRCX);
|
||||
} else {
|
||||
CTZxw(xRCX, x1, 0, x2, x3);
|
||||
}
|
||||
break;
|
||||
case 0xDB:
|
||||
INST_NAME("AESIMC Gx, Ex"); // AES-NI
|
||||
nextop = F8;
|
||||
@@ -1301,7 +1267,6 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode,
|
||||
GETG;
|
||||
sse_forget_reg(dyn, ninst, x6, gd);
|
||||
sse_forget_reg(dyn, ninst, x6, 0);
|
||||
ADDI(x2, xEmu, offsetof(x64emu_t, xmm[gd]));
|
||||
if (MODREG) {
|
||||
ed = (nextop & 7) + (rex.b << 3);
|
||||
sse_reflect_reg(dyn, ninst, x6, ed);
|
||||
@@ -1310,6 +1275,7 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode,
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 1);
|
||||
}
|
||||
ADDI(x2, xEmu, offsetof(x64emu_t, xmm[gd]));
|
||||
u8 = F8;
|
||||
ADDI(x3, xZR, u8);
|
||||
CALL4(const_sse42_compare_string_implicit_len, x1, ed, x2, x3, 0);
|
||||
|
||||
@@ -1119,6 +1119,10 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
|
||||
GETGX_vector(q0, 1, dyn->vector_eew);
|
||||
GETEX_vector(q1, 0, 0, dyn->vector_eew);
|
||||
if (q0 == q1) {
|
||||
q1 = fpu_get_scratch(dyn);
|
||||
VMV_V_V(q1, q0);
|
||||
}
|
||||
VXOR_VI(q0, q0, 0x1F, VECTOR_UNMASKED);
|
||||
VAND_VV(q0, q1, q0, VECTOR_UNMASKED);
|
||||
break;
|
||||
@@ -1146,44 +1150,22 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
VXOR_VV(q0, q1, q0, VECTOR_UNMASKED);
|
||||
break;
|
||||
case 0x58:
|
||||
if (!BOX64ENV(dynarec_fastnan)) return 0;
|
||||
INST_NAME("ADDPD Gx, Ex");
|
||||
nextop = F8;
|
||||
SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
|
||||
GETGX_vector(q0, 1, VECTOR_SEW64);
|
||||
GETEX_vector(q1, 0, 0, VECTOR_SEW64);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VMFEQ_VV(VMASK, q0, q0, VECTOR_UNMASKED);
|
||||
VMFEQ_VV(v0, q1, q1, VECTOR_UNMASKED);
|
||||
}
|
||||
VFADD_VV(q0, q0, q1, VECTOR_UNMASKED);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
VMAND_MM(VMASK, v0, VMASK);
|
||||
VMFEQ_VV(v0, q0, q0, VECTOR_UNMASKED);
|
||||
VXOR_VI(v0, v0, 0x1F, VECTOR_UNMASKED);
|
||||
VMAND_MM(VMASK, v0, VMASK);
|
||||
VFSGNJN_VV(q0, q0, q0, VECTOR_MASKED);
|
||||
}
|
||||
break;
|
||||
case 0x59:
|
||||
if (!BOX64ENV(dynarec_fastnan)) return 0;
|
||||
INST_NAME("MULPD Gx, Ex");
|
||||
nextop = F8;
|
||||
SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
|
||||
GETGX_vector(q0, 1, VECTOR_SEW64);
|
||||
GETEX_vector(q1, 0, 0, VECTOR_SEW64);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VMFEQ_VV(VMASK, q0, q0, VECTOR_UNMASKED);
|
||||
VMFEQ_VV(v0, q1, q1, VECTOR_UNMASKED);
|
||||
}
|
||||
VFMUL_VV(q0, q0, q1, VECTOR_UNMASKED);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
VMAND_MM(VMASK, v0, VMASK);
|
||||
VMFEQ_VV(v0, q0, q0, VECTOR_UNMASKED);
|
||||
VXOR_VI(v0, v0, 0x1F, VECTOR_UNMASKED);
|
||||
VMAND_MM(VMASK, v0, VMASK);
|
||||
VFSGNJN_VV(q0, q0, q0, VECTOR_MASKED);
|
||||
}
|
||||
break;
|
||||
case 0x5A:
|
||||
INST_NAME("CVTPD2PS Gx, Ex");
|
||||
@@ -1217,24 +1199,13 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
break;
|
||||
case 0x5C:
|
||||
if (!BOX64ENV(dynarec_fastnan)) return 0;
|
||||
INST_NAME("SUBPD Gx, Ex");
|
||||
nextop = F8;
|
||||
SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
|
||||
GETGX_vector(q0, 1, VECTOR_SEW64);
|
||||
GETEX_vector(q1, 0, 0, VECTOR_SEW64);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VMFEQ_VV(VMASK, q0, q0, VECTOR_UNMASKED);
|
||||
VMFEQ_VV(v0, q1, q1, VECTOR_UNMASKED);
|
||||
}
|
||||
VFSUB_VV(q0, q0, q1, VECTOR_UNMASKED);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
VMAND_MM(VMASK, v0, VMASK);
|
||||
VMFEQ_VV(v0, q0, q0, VECTOR_UNMASKED);
|
||||
VXOR_VI(v0, v0, 0x1F, VECTOR_UNMASKED);
|
||||
VMAND_MM(VMASK, v0, VMASK);
|
||||
VFSGNJN_VV(q0, q0, q0, VECTOR_MASKED);
|
||||
}
|
||||
break;
|
||||
case 0x5D:
|
||||
INST_NAME("MINPD Gx, Ex");
|
||||
@@ -1251,24 +1222,13 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
VADD_VX(q0, q1, xZR, VECTOR_MASKED);
|
||||
break;
|
||||
case 0x5E:
|
||||
if (!BOX64ENV(dynarec_fastnan)) return 0;
|
||||
INST_NAME("DIVPD Gx, Ex");
|
||||
nextop = F8;
|
||||
SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1);
|
||||
GETGX_vector(q0, 1, VECTOR_SEW64);
|
||||
GETEX_vector(q1, 0, 0, VECTOR_SEW64);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VMFEQ_VV(VMASK, q0, q0, VECTOR_UNMASKED);
|
||||
VMFEQ_VV(v0, q1, q1, VECTOR_UNMASKED);
|
||||
}
|
||||
VFDIV_VV(q0, q0, q1, VECTOR_UNMASKED);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
VMAND_MM(VMASK, v0, VMASK);
|
||||
VMFEQ_VV(v0, q0, q0, VECTOR_UNMASKED);
|
||||
VXOR_VI(v0, v0, 0x1F, VECTOR_UNMASKED);
|
||||
VMAND_MM(VMASK, v0, VMASK);
|
||||
VFSGNJN_VV(q0, q0, q0, VECTOR_MASKED);
|
||||
}
|
||||
break;
|
||||
case 0x5F:
|
||||
INST_NAME("MAXPD Gx, Ex");
|
||||
@@ -2078,6 +2038,10 @@ uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
SET_ELEMENT_WIDTH(x1, VECTOR_SEWANY, 1);
|
||||
GETGX_vector(q0, 1, dyn->vector_eew);
|
||||
GETEX_vector(q1, 0, 0, dyn->vector_eew);
|
||||
if (q0 == q1) {
|
||||
q1 = fpu_get_scratch(dyn);
|
||||
VMV_V_V(q1, q0);
|
||||
}
|
||||
VXOR_VI(q0, q0, 0x1F, VECTOR_UNMASKED);
|
||||
VAND_VV(q0, q1, q0, VECTOR_UNMASKED);
|
||||
break;
|
||||
|
||||
@@ -431,14 +431,16 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FADDD(v0, v0, v1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FEQD(x5, v0, v0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v0, v0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v0, v1);
|
||||
}
|
||||
FSD(v0, gback, gdoffset + 8 * i);
|
||||
}
|
||||
@@ -450,14 +452,16 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FADDD(v0, v0, v1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FEQD(x5, v0, v0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v0, v0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v0, v1);
|
||||
}
|
||||
FSD(v0, gback, gyoffset + 8 * i);
|
||||
}
|
||||
@@ -480,14 +484,16 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FMULD(v0, v0, v1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FEQD(x5, v0, v0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v0, v0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v0, v1);
|
||||
}
|
||||
FSD(v0, gback, gdoffset + 8 * i);
|
||||
}
|
||||
@@ -499,14 +505,16 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FMULD(v0, v0, v1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FEQD(x5, v0, v0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v0, v0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v0, v1);
|
||||
}
|
||||
FSD(v0, gback, gyoffset + 8 * i);
|
||||
}
|
||||
@@ -584,14 +592,16 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FSUBD(v0, v1, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FEQD(x5, v0, v0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v0, v0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v0, v1);
|
||||
}
|
||||
FSD(v0, gback, gdoffset + 8 * i);
|
||||
}
|
||||
@@ -603,14 +613,16 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FSUBD(v0, v1, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FEQD(x5, v0, v0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v0, v0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v0, v1);
|
||||
}
|
||||
FSD(v0, gback, gyoffset + 8 * i);
|
||||
}
|
||||
@@ -672,14 +684,16 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FDIVD(v0, v1, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FEQD(x5, v0, v0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v0, v0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v0, v1);
|
||||
}
|
||||
FSD(v0, gback, gdoffset + 8 * i);
|
||||
}
|
||||
@@ -691,14 +705,16 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FDIVD(v0, v1, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BEQZ(x3, 16);
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ(x3, 8);
|
||||
FEQD(x5, v0, v0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v0, v0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v0, v1);
|
||||
}
|
||||
FSD(v0, gback, gyoffset + 8 * i);
|
||||
}
|
||||
@@ -1336,6 +1352,7 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
d2 = d0;
|
||||
FLD(d0, gback, vxoffset + 0);
|
||||
FLD(d1, gback, vxoffset + 8);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
@@ -1375,6 +1392,7 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
if (vex.l) {
|
||||
GETEY();
|
||||
d0 = d2;
|
||||
if (gd == ed) {
|
||||
FLD(v0, gback, gyoffset + 0);
|
||||
}
|
||||
@@ -1432,6 +1450,7 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
d2 = d0;
|
||||
FLD(d0, gback, vxoffset + 0);
|
||||
FLD(d1, gback, vxoffset + 8);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
@@ -1471,6 +1490,7 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
if (vex.l) {
|
||||
GETEY();
|
||||
d0 = d2;
|
||||
if (gd == ed) {
|
||||
FLD(v0, gback, gyoffset + 0);
|
||||
}
|
||||
|
||||
@@ -78,8 +78,8 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
if (vex.l) {
|
||||
GETEY();
|
||||
if (gd == vex.v) {
|
||||
LD(x3, vback, vyoffset + 0);
|
||||
LD(x4, vback, vyoffset + 8);
|
||||
LD(x3, xEmu, vyoffset + 0);
|
||||
LD(x4, xEmu, vyoffset + 8);
|
||||
SD(x3, x5, 0);
|
||||
SD(x4, x5, 8);
|
||||
vback = x5;
|
||||
@@ -442,7 +442,7 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
case 0x08:
|
||||
INST_NAME("VPSIGNB Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(x1, 0, vex.l ? 31 : 15);
|
||||
GETEX(x6, 0, vex.l ? 31 : 15);
|
||||
GETGX();
|
||||
GETVX();
|
||||
GETGY();
|
||||
@@ -473,7 +473,7 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
case 0x09:
|
||||
INST_NAME("VPSIGNW Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(x1, 0, vex.l ? 30 : 14);
|
||||
GETEX(x6, 0, vex.l ? 30 : 14);
|
||||
GETGX();
|
||||
GETVX();
|
||||
GETGY();
|
||||
@@ -504,7 +504,7 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
case 0x0A:
|
||||
INST_NAME("VPSIGND Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(x1, 0, vex.l ? 28 : 12);
|
||||
GETEX(x6, 0, vex.l ? 28 : 12);
|
||||
GETGX();
|
||||
GETVX();
|
||||
GETGY();
|
||||
|
||||
@@ -347,6 +347,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
INST_NAME("VBLENDVPS Gx, Vx, Ex, XMMImm8");
|
||||
nextop = F8;
|
||||
u8 = geted_ib(dyn, addr, ninst, nextop) >> 4;
|
||||
sse_forget_reg(dyn, ninst, x3, u8);
|
||||
GETEX(x1, 1, vex.l ? 28 : 12);
|
||||
GETGX();
|
||||
GETVX();
|
||||
|
||||
@@ -106,22 +106,20 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
FLD(v0, vback, vxoffset + 0);
|
||||
FLD(v1, wback, fixedaddress + 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, v1, v1);
|
||||
FEQD(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FADDD(v0, v0, v1);
|
||||
FADDD(v1, v1, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
BNEZ_MARK2(x4);
|
||||
FMVD(v0, v1);
|
||||
B_MARK2_nocond;
|
||||
MARK;
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ_MARK2(x3);
|
||||
FNEGD(v0, v0);
|
||||
MARK2;
|
||||
FEQD(x5, v1, v1);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v1, v1);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v1, v0);
|
||||
}
|
||||
FMVD(v0, v1);
|
||||
FSD(v0, gback, gdoffset + 0);
|
||||
if (gd != vex.v) {
|
||||
LD(x3, vback, vxoffset + 8);
|
||||
@@ -140,22 +138,20 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
FLD(v0, vback, vxoffset + 0);
|
||||
FLD(v1, wback, fixedaddress + 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, v1, v1);
|
||||
FEQD(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FMULD(v0, v0, v1);
|
||||
FMULD(v1, v1, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
BNEZ_MARK2(x4);
|
||||
FMVD(v0, v1);
|
||||
B_MARK2_nocond;
|
||||
MARK;
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ_MARK2(x3);
|
||||
FNEGD(v0, v0);
|
||||
MARK2;
|
||||
FEQD(x5, v1, v1);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v1, v1);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v1, v0);
|
||||
}
|
||||
FMVD(v0, v1);
|
||||
FSD(v0, gback, gdoffset + 0);
|
||||
if (gd != vex.v) {
|
||||
LD(x3, vback, vxoffset + 8);
|
||||
@@ -174,22 +170,20 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
FLD(v0, vback, vxoffset + 0);
|
||||
FLD(v1, wback, fixedaddress + 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, v1, v1);
|
||||
FEQD(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FSUBD(v0, v0, v1);
|
||||
FSUBD(v1, v0, v1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
BNEZ_MARK2(x4);
|
||||
FMVD(v0, v1);
|
||||
B_MARK2_nocond;
|
||||
MARK;
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ_MARK2(x3);
|
||||
FNEGD(v0, v0);
|
||||
MARK2;
|
||||
FEQD(x5, v1, v1);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v1, v1);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v1, v0);
|
||||
}
|
||||
FMVD(v0, v1);
|
||||
FSD(v0, gback, gdoffset + 0);
|
||||
if (gd != vex.v) {
|
||||
LD(x3, vback, vxoffset + 8);
|
||||
@@ -234,22 +228,20 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
FLD(v0, vback, vxoffset + 0);
|
||||
FLD(v1, wback, fixedaddress + 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, v1, v1);
|
||||
FEQD(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FDIVD(v0, v0, v1);
|
||||
FDIVD(v1, v0, v1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
BNEZ_MARK2(x4);
|
||||
FMVD(v0, v1);
|
||||
B_MARK2_nocond;
|
||||
MARK;
|
||||
FEQD(x3, v0, v0);
|
||||
BNEZ_MARK2(x3);
|
||||
FNEGD(v0, v0);
|
||||
MARK2;
|
||||
FEQD(x5, v1, v1);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v1, v1);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v1, v0);
|
||||
}
|
||||
FMVD(v0, v1);
|
||||
FSD(v0, gback, gdoffset + 0);
|
||||
if (gd != vex.v) {
|
||||
LD(x3, vback, vxoffset + 8);
|
||||
|
||||
@@ -119,7 +119,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
} else {
|
||||
// not in cache, so check Empty status and load it
|
||||
i2 = -dyn->e.x87stack;
|
||||
LWU(x3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
LW(x3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
if (i2) {
|
||||
SUBI(x3, x3, i2);
|
||||
}
|
||||
@@ -152,6 +152,14 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// check if stack is empty (freed register will not count, but might work if using tags instead)
|
||||
i2 = -dyn->e.x87stack;
|
||||
LW(x3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
if (i2) {
|
||||
SUBI(x3, x3, i2);
|
||||
}
|
||||
MOV32w(x4, 0b100000100000000); // empty: C3,C2,C0 = 101
|
||||
BGE_MARK3(xZR, x3);
|
||||
// simply move from cache reg to x2
|
||||
v1 = dyn->e.x87reg[i1];
|
||||
FMVXD(x2, v1);
|
||||
|
||||
@@ -1040,7 +1040,7 @@ void emit_sbb16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4,
|
||||
CLEAR_FLAGS();
|
||||
SLLIW(s1, s1, 16);
|
||||
IFX (X_SF) {
|
||||
SET_FLAGS_LTZ(s1, F_SF, s4, s5);
|
||||
SET_FLAGS_LTZ(s1, F_SF, s3, s4);
|
||||
}
|
||||
SRLIW(s1, s1, 16);
|
||||
|
||||
@@ -1080,7 +1080,7 @@ void emit_sbb32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
|
||||
|
||||
CLEAR_FLAGS();
|
||||
IFX (X_SF) {
|
||||
SET_FLAGS_LTZ(s1, F_SF, s4, s5);
|
||||
SET_FLAGS_LTZ(s1, F_SF, s3, s4);
|
||||
}
|
||||
if (!rex.w && (IS_GPR(s1) || dyn->insts[ninst].nat_flags_fusion)) {
|
||||
ZEROUP(s1);
|
||||
|
||||
@@ -206,21 +206,20 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGXSD(v0);
|
||||
GETEXSD(v1, 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, v1, v1);
|
||||
FEQD(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FADDD(v0, v0, v1);
|
||||
FADDD(v1, v1, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
CBNZ_NEXT(x4);
|
||||
FMVD(v0, v1);
|
||||
B_NEXT_nocond;
|
||||
MARK;
|
||||
FEQD(x3, v0, v0);
|
||||
CBNZ_NEXT(x3);
|
||||
FNEGD(v0, v0);
|
||||
FEQD(x5, v1, v1);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v1, v1);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v1, v0);
|
||||
}
|
||||
FMVD(v0, v1);
|
||||
break;
|
||||
case 0x59:
|
||||
INST_NAME("MULSD Gx, Ex");
|
||||
@@ -228,21 +227,20 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGXSD(v0);
|
||||
GETEXSD(v1, 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, v1, v1);
|
||||
FEQD(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FMULD(v0, v0, v1);
|
||||
FMULD(v1, v1, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
CBNZ_NEXT(x4);
|
||||
FMVD(v0, v1);
|
||||
B_NEXT_nocond;
|
||||
MARK;
|
||||
FEQD(x3, v0, v0);
|
||||
CBNZ_NEXT(x3);
|
||||
FNEGD(v0, v0);
|
||||
FEQD(x5, v1, v1);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v1, v1);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v1, v0);
|
||||
}
|
||||
FMVD(v0, v1);
|
||||
break;
|
||||
case 0x5A:
|
||||
INST_NAME("CVTSD2SS Gx, Ex");
|
||||
@@ -263,21 +261,20 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGXSD(v0);
|
||||
GETEXSD(v1, 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, v1, v1);
|
||||
FEQD(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FSUBD(v0, v0, v1);
|
||||
FSUBD(v1, v0, v1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
CBNZ_NEXT(x4);
|
||||
FMVD(v0, v1);
|
||||
B_NEXT_nocond;
|
||||
MARK;
|
||||
FEQD(x3, v0, v0);
|
||||
CBNZ_NEXT(x3);
|
||||
FNEGD(v0, v0);
|
||||
FEQD(x5, v1, v1);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v1, v1);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v1, v0);
|
||||
}
|
||||
FMVD(v0, v1);
|
||||
break;
|
||||
case 0x5D:
|
||||
INST_NAME("MINSD Gx, Ex");
|
||||
@@ -300,21 +297,20 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGXSD(v0);
|
||||
GETEXSD(v1, 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQD(x3, v0, v0);
|
||||
FEQD(x4, v1, v1);
|
||||
FEQD(x3, v1, v1);
|
||||
FEQD(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FDIVD(v0, v0, v1);
|
||||
FDIVD(v1, v0, v1);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
CBNZ_NEXT(x4);
|
||||
FMVD(v0, v1);
|
||||
B_NEXT_nocond;
|
||||
MARK;
|
||||
FEQD(x3, v0, v0);
|
||||
CBNZ_NEXT(x3);
|
||||
FNEGD(v0, v0);
|
||||
FEQD(x5, v1, v1);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGD(v1, v1);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVD(v1, v0);
|
||||
}
|
||||
FMVD(v0, v1);
|
||||
break;
|
||||
case 0x5F:
|
||||
INST_NAME("MAXSD Gx, Ex");
|
||||
|
||||
@@ -237,17 +237,20 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGXSS(v0);
|
||||
GETEXSS(d0, 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x3, v0, v0);
|
||||
FEQS(x4, d0, d0);
|
||||
FEQS(x3, d0, d0);
|
||||
FEQS(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FADDS(v0, v0, d0);
|
||||
FADDS(d0, d0, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
CBNZ_NEXT(x4);
|
||||
FMVS(v0, d0);
|
||||
MARK;
|
||||
FEQS(x5, d0, d0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGS(d0, d0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVS(d0, v0);
|
||||
}
|
||||
FMVS(v0, d0);
|
||||
break;
|
||||
case 0x59:
|
||||
INST_NAME("MULSS Gx, Ex");
|
||||
@@ -255,21 +258,20 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGXSS(v0);
|
||||
GETEXSS(d0, 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x3, v0, v0);
|
||||
FEQS(x4, d0, d0);
|
||||
FEQS(x3, d0, d0);
|
||||
FEQS(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FMULS(v0, v0, d0);
|
||||
FMULS(d0, d0, v0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
CBNZ_NEXT(x4);
|
||||
FMVS(v0, d0);
|
||||
B_NEXT_nocond;
|
||||
MARK;
|
||||
FEQS(x3, v0, v0);
|
||||
CBNZ_NEXT(x3);
|
||||
FNEGS(v0, v0);
|
||||
FEQS(x5, d0, d0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGS(d0, d0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVS(d0, v0);
|
||||
}
|
||||
FMVS(v0, d0);
|
||||
break;
|
||||
case 0x5A:
|
||||
INST_NAME("CVTSS2SD Gx, Ex");
|
||||
@@ -311,17 +313,20 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGXSS(v0);
|
||||
GETEXSS(d0, 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x3, v0, v0);
|
||||
FEQS(x4, d0, d0);
|
||||
FEQS(x3, d0, d0);
|
||||
FEQS(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FSUBS(v0, v0, d0);
|
||||
FSUBS(d0, v0, d0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
CBNZ_NEXT(x4);
|
||||
FMVS(v0, d0);
|
||||
MARK;
|
||||
FEQS(x5, d0, d0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGS(d0, d0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVS(d0, v0);
|
||||
}
|
||||
FMVS(v0, d0);
|
||||
break;
|
||||
case 0x5D:
|
||||
INST_NAME("MINSS Gx, Ex");
|
||||
@@ -344,17 +349,20 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
GETGXSS(v0);
|
||||
GETEXSS(d0, 0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
FEQS(x3, v0, v0);
|
||||
FEQS(x4, d0, d0);
|
||||
FEQS(x3, d0, d0);
|
||||
FEQS(x4, v0, v0);
|
||||
AND(x5, x3, x4);
|
||||
BEQZ(x5, 4 + 4 * 4);
|
||||
}
|
||||
FDIVS(v0, v0, d0);
|
||||
FDIVS(d0, v0, d0);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
AND(x3, x3, x4);
|
||||
BNEZ_MARK(x3);
|
||||
CBNZ_NEXT(x4);
|
||||
FMVS(v0, d0);
|
||||
MARK;
|
||||
FEQS(x5, d0, d0);
|
||||
BNEZ(x5, 4 + 4);
|
||||
FNEGS(d0, d0);
|
||||
BNEZ(x4, 4 + 4);
|
||||
FMVS(d0, v0);
|
||||
}
|
||||
FMVS(v0, d0);
|
||||
break;
|
||||
case 0x5F:
|
||||
INST_NAME("MAXSS Gx, Ex");
|
||||
|
||||
@@ -632,13 +632,10 @@ void call_n(dynarec_rv64_t* dyn, int ninst, void* fnc, int w)
|
||||
}
|
||||
}
|
||||
// native call
|
||||
if (dyn->need_reloc) {
|
||||
// fnc is indirect, to help with relocation (but PltResolver might be an issue here)
|
||||
TABLE64(x3, (uintptr_t)fnc);
|
||||
LD(x3, x3, 0);
|
||||
} else {
|
||||
TABLE64_(x3, *(uintptr_t*)fnc); // using x16 as scratch regs for call address
|
||||
}
|
||||
TABLE64_(x3, *(uintptr_t*)fnc); // using x16 as scratch regs for call address
|
||||
// Note that if need_reloc is active, the TABLE64 will trigger cancel block,
|
||||
// because native function might be very different on a next run: different function address, different brick, different everything basicaly
|
||||
// and we don't have a relocation mecanism here, it's too complex
|
||||
JALR(xRA, x3);
|
||||
// put return value in x64 regs
|
||||
if (w > 0) {
|
||||
@@ -2418,11 +2415,11 @@ static void fpuCacheTransform(dynarec_rv64_t* dyn, int ninst, int s1, int s2, in
|
||||
MESSAGE(LOG_DUMP, "\t - adjust stack count %d -> %d -\n", stack_cnt, cache_i2.stack);
|
||||
int a = stack_cnt - cache_i2.stack;
|
||||
// Add x87stack to emu fpu_stack
|
||||
LWU(s3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
LW(s3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
ADDI(s3, s3, a);
|
||||
SW(s3, xEmu, offsetof(x64emu_t, fpu_stack));
|
||||
// Sub x87stack to top, with and 7
|
||||
LWU(s3, xEmu, offsetof(x64emu_t, top));
|
||||
LW(s3, xEmu, offsetof(x64emu_t, top));
|
||||
SUBI(s3, s3, a);
|
||||
ANDI(s3, s3, 7);
|
||||
SW(s3, xEmu, offsetof(x64emu_t, top));
|
||||
|
||||
@@ -216,6 +216,32 @@ int Table64(dynarec_rv64_t *dyn, uint64_t val, int pass); // add a value to tab
|
||||
|
||||
void CreateJmpNext(void* addr, void* next);
|
||||
|
||||
// While we could theoretically traverse forward to find the flags-consuming x86
|
||||
// instruction and get the exact scratch registers to save, this is too complicated.
|
||||
// So we went with the simpler approach of saving all scratch registers, this won't
|
||||
// add noticeable performance overhead in trace mode.
|
||||
#define SPILL_NF_REGISTERS \
|
||||
do { \
|
||||
SUBI(xSP, xSP, 6 * 8); \
|
||||
SD(x1, xSP, 0 * 8); \
|
||||
SD(x2, xSP, 1 * 8); \
|
||||
SD(x3, xSP, 2 * 8); \
|
||||
SD(x4, xSP, 3 * 8); \
|
||||
SD(x5, xSP, 4 * 8); \
|
||||
SD(x6, xSP, 5 * 8); \
|
||||
} while(0);
|
||||
|
||||
#define RESTORE_NF_REGISTERS \
|
||||
do { \
|
||||
LD(x1, xSP, 0 * 8); \
|
||||
LD(x2, xSP, 1 * 8); \
|
||||
LD(x3, xSP, 2 * 8); \
|
||||
LD(x4, xSP, 3 * 8); \
|
||||
LD(x5, xSP, 4 * 8); \
|
||||
LD(x6, xSP, 5 * 8); \
|
||||
ADDI(xSP, xSP, 6 * 8); \
|
||||
} while(0);
|
||||
|
||||
#define GO_TRACE(A, B, s0) \
|
||||
GETIP(addr, s0); \
|
||||
MV(x1, xRIP); \
|
||||
|
||||
@@ -69,6 +69,7 @@ x31 t6 x6 Temporary Scratch
|
||||
// convert a x86 register to native according to the register mapping
|
||||
#define TO_NAT(A) (((uint8_t[]) { 16, 13, 12, 24, 9, 8, 11, 10, 14, 15, 26, 27, 18, 19, 20, 21 })[(A)])
|
||||
#define IS_GPR(A) (((uint8_t[]) { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0 })[(A)])
|
||||
#define IS_SCRATCH(A) (((uint8_t[]) { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 })[(A)])
|
||||
|
||||
#define x1 6
|
||||
#define x2 7
|
||||
|
||||
@@ -843,6 +843,13 @@ static int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int
|
||||
tlsdescUndefweak = AddBridge(my_context->system, pFE, my__dl_tlsdesc_undefweak, 0, "_dl_tlsdesc_undefweak");
|
||||
td->entry = tlsdescUndefweak;
|
||||
td->arg = (uintptr_t)(head->tlsbase + rela[i].r_addend);
|
||||
} if(symname && sym_elf && elfsym) {
|
||||
printf_dump(LOG_NEVER, "Apply %s R_X86_64_TLSDESC @%p for %s with addend=%zu\n", BindSym(bind), p, symname, rela[i].r_addend);
|
||||
struct tlsdesc volatile *td = (struct tlsdesc volatile *)p;
|
||||
if(!tlsdescUndefweak)
|
||||
tlsdescUndefweak = AddBridge(my_context->system, pFE, my__dl_tlsdesc_undefweak, 0, "_dl_tlsdesc_undefweak");
|
||||
td->entry = tlsdescUndefweak;
|
||||
td->arg = (uintptr_t)(sym_elf->tlsbase + offs + rela[i].r_addend);
|
||||
} else {
|
||||
printf_log(LOG_INFO, "Warning, R_X86_64_TLSDESC used with Symbol %s(%p) not supported for now \n", symname, sym);
|
||||
}
|
||||
@@ -2100,7 +2107,7 @@ EXPORT void PltResolver64(x64emu_t* emu)
|
||||
GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
|
||||
}
|
||||
if (!offs) {
|
||||
printf_log(LOG_NONE, "Error: PltResolver: Symbol %s %s(%sver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p in %s (local_maplib=%p, global maplib=%p, deepbind=%d)\n", (bind==STB_LOCAL)?"Local":((bind==STB_WEAK)?"Weak":""), symname, veropt?"opt":"", version, symname, vername?"@":"", vername?vername:"", p, (h && h->name)?h->name:"???", local_maplib, my_context->maplib, deepbind);
|
||||
printf_log(LOG_NONE, "Error: PltResolver: Symbol %s%s(%sver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p in %s (local_maplib=%p, global maplib=%p, deepbind=%d)\n", (bind==STB_LOCAL)?"Local ":((bind==STB_WEAK)?"Weak ":""), symname, veropt?"opt":"", version, symname, vername?"@":"", vername?vername:"", p, (h && h->name)?h->name:"???", local_maplib, my_context->maplib, deepbind);
|
||||
emu->quit = 1;
|
||||
R_RIP = 0; //stop....
|
||||
return;
|
||||
|
||||
@@ -41,6 +41,17 @@ static uint32_t x86emu_parity_tab[8] =
|
||||
0x69969669,
|
||||
};
|
||||
|
||||
static void reset_deferred_signal(x64emu_t* emu)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
emu->critical_section = 0;
|
||||
emu->deferred_signal_processing = 0;
|
||||
emu->deferred_signal_count = 0;
|
||||
memset((void*)emu->deferred_signal_pending, 0, sizeof(emu->deferred_signal_pending));
|
||||
memset(emu->deferred_siginfo, 0, sizeof(emu->deferred_siginfo));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack)
|
||||
{
|
||||
emu->context = context;
|
||||
@@ -90,6 +101,7 @@ static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t s
|
||||
emu->mxcsr.x32 = 0x1f80;
|
||||
// want some new jmpbuf for error recovery
|
||||
emu->flags.need_jmpbuf = 1;
|
||||
reset_deferred_signal(emu);
|
||||
}
|
||||
|
||||
EXPORTDYN
|
||||
@@ -219,6 +231,7 @@ void CloneEmu(x64emu_t *newemu, const x64emu_t* emu)
|
||||
newemu->quit = emu->quit;
|
||||
newemu->error = emu->error;
|
||||
newemu->x64emu_parity_tab = emu->x64emu_parity_tab;
|
||||
reset_deferred_signal(newemu);
|
||||
}
|
||||
|
||||
void CopyEmu(x64emu_t *newemu, const x64emu_t* emu)
|
||||
@@ -247,6 +260,7 @@ void CopyEmu(x64emu_t *newemu, const x64emu_t* emu)
|
||||
newemu->mxcsr = emu->mxcsr;
|
||||
newemu->quit = emu->quit;
|
||||
newemu->error = emu->error;
|
||||
reset_deferred_signal(newemu);
|
||||
}
|
||||
|
||||
box64context_t* GetEmuContext(x64emu_t* emu)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "regs.h"
|
||||
#include "os.h"
|
||||
#include "box64context.h"
|
||||
#include <signal.h>
|
||||
|
||||
typedef struct x64_ucontext_s x64_ucontext_t;
|
||||
#ifdef BOX32
|
||||
@@ -135,6 +136,17 @@ typedef struct x64emu_s {
|
||||
tlsdatasize_t *tlsdata;
|
||||
// other informations
|
||||
int type; // EMUTYPE_xxx define
|
||||
uint8_t sud_enabled; // syscall_user_dispatch enabled for this thread?
|
||||
uint8_t* sud_selector; // Wine selector
|
||||
uintptr_t sud_offset; // always allowed range start
|
||||
uintptr_t sud_len; // always allowed range len
|
||||
#ifndef _WIN32
|
||||
volatile sig_atomic_t critical_section;
|
||||
volatile sig_atomic_t deferred_signal_processing;
|
||||
volatile sig_atomic_t deferred_signal_count;
|
||||
volatile sig_atomic_t deferred_signal_pending[MAX_SIGNAL+1];
|
||||
siginfo_t deferred_siginfo[MAX_SIGNAL+1];
|
||||
#endif
|
||||
#ifdef BOX32
|
||||
int libc_err; // copy of errno from libc
|
||||
int libc_herr; // copy of h_errno from libc
|
||||
|
||||
+1
-1
@@ -205,7 +205,7 @@ void x64Int3(x64emu_t* emu, uintptr_t* addr)
|
||||
} else if (strstr(s, "popen")==s) {
|
||||
tmp = (char*)(R_RDI);
|
||||
char* tmp2 = (char*)(R_RSI);
|
||||
snprintf(buff, 256, "%04d|%p: Calling %s(\"%s\")", tid, *(void**)(R_RSP), s, (tmp)?tmp:"(nil)", (tmp2)?tmp2:"nil");
|
||||
snprintf(buff, 256, "%04d|%p: Calling %s(\"%s\", \"%s\")", tid, *(void**)(R_RSP), s, (tmp)?tmp:"(nil)", (tmp2)?tmp2:"nil");
|
||||
perr = 5;
|
||||
} else if (!strcmp(s, "read") || !strcmp(s, "my_read")) {
|
||||
snprintf(buff, 256, "%04d|%p: Calling %s(%d, %p, %zu)", tid, *(void**)(R_RSP), s, R_EDI, (void*)R_RSI, R_RDX);
|
||||
|
||||
+194
-86
@@ -141,6 +141,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ")", tid, *(void**)(R_RSP), func, (uint64_t)R_RDI);
|
||||
} else if (w == uFd) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0]);
|
||||
} else if (w == uFl) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi64 ")", tid, *(void**)(R_RSP), func, (intptr_t)R_RDI);
|
||||
} else if (w == uFL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI);
|
||||
} else if (w == uFp) {
|
||||
@@ -299,8 +301,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI);
|
||||
} else if (w == vFUu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (uint64_t)R_RDI, (uint32_t)R_RSI);
|
||||
} else if (w == vFfi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], (int32_t)R_RDI);
|
||||
} else if (w == vFfC) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIu8 ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], (uint8_t)R_RDI);
|
||||
} else if (w == vFff) {
|
||||
@@ -355,10 +355,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI);
|
||||
} else if (w == iFEu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI);
|
||||
} else if (w == iFEf) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0]);
|
||||
} else if (w == iFEd) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0]);
|
||||
} else if (w == iFEp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI);
|
||||
} else if (w == iFwp) {
|
||||
@@ -477,12 +473,18 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (uint64_t)R_RSI);
|
||||
} else if (w == CFpi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI);
|
||||
} else if (w == CFpC) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu8 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint8_t)R_RSI);
|
||||
} else if (w == CFpu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI);
|
||||
} else if (w == CFpU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI);
|
||||
} else if (w == CFpL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI);
|
||||
} else if (w == CFpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI);
|
||||
} else if (w == WFEp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI);
|
||||
} else if (w == WFpi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI);
|
||||
} else if (w == WFpW) {
|
||||
@@ -563,6 +565,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], emu->xmm[1].f[0]);
|
||||
} else if (w == fFfD) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRILf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], LD2localLD((void*)(R_RSP + 8)));
|
||||
} else if (w == fFfl) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], (intptr_t)R_RDI);
|
||||
} else if (w == fFfp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIp ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], (void*)R_RDI);
|
||||
} else if (w == fFpi) {
|
||||
@@ -587,6 +591,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0], emu->xmm[1].d[0]);
|
||||
} else if (w == dFdD) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRILf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0], LD2localLD((void*)(R_RSP + 8)));
|
||||
} else if (w == dFdl) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0], (intptr_t)R_RDI);
|
||||
} else if (w == dFdp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIp ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0], (void*)R_RDI);
|
||||
} else if (w == dFll) {
|
||||
@@ -613,6 +619,10 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI);
|
||||
} else if (w == lFEi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI);
|
||||
} else if (w == lFEf) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0]);
|
||||
} else if (w == lFEd) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0]);
|
||||
} else if (w == lFii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI);
|
||||
} else if (w == lFiL) {
|
||||
@@ -621,8 +631,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI);
|
||||
} else if (w == lFui) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI);
|
||||
} else if (w == lFDD) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRILf ", %" PRILf ")", tid, *(void**)(R_RSP), func, LD2localLD((void*)(R_RSP + 8)), LD2localLD((void*)(R_RSP + 24)));
|
||||
} else if (w == lFll) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi64 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (intptr_t)R_RDI, (intptr_t)R_RSI);
|
||||
} else if (w == lFpi) {
|
||||
@@ -1003,6 +1011,10 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (uint64_t)R_RDI, (uint64_t)R_RSI);
|
||||
} else if (w == iFEpi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI);
|
||||
} else if (w == iFEpW) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu16 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint16_t)R_RSI);
|
||||
} else if (w == iFEpu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI);
|
||||
} else if (w == iFEpU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI);
|
||||
} else if (w == iFEpL) {
|
||||
@@ -1105,6 +1117,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint64_t)R_RDI, (void*)R_RSI, (void*)R_RDX);
|
||||
} else if (w == iFfff) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0]);
|
||||
} else if (w == iFLip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX);
|
||||
} else if (w == iFLpi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == iFLpL) {
|
||||
@@ -1215,8 +1229,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX);
|
||||
} else if (w == iFppU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint64_t)R_RDX);
|
||||
} else if (w == iFppf) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, emu->xmm[0].f[0]);
|
||||
} else if (w == iFppd) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, emu->xmm[0].d[0]);
|
||||
} else if (w == iFppl) {
|
||||
@@ -1257,12 +1269,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX);
|
||||
} else if (w == WFppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX);
|
||||
} else if (w == uFEpW) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu16 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint16_t)R_RSI);
|
||||
} else if (w == uFEpu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI);
|
||||
} else if (w == uFEpU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI);
|
||||
} else if (w == uFEpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI);
|
||||
} else if (w == uFiuu) {
|
||||
@@ -1389,8 +1395,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi64 ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (intptr_t)R_RDI, (void*)R_RSI, (intptr_t)R_RDX);
|
||||
} else if (w == fFppi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == fFppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX);
|
||||
} else if (w == fFppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX);
|
||||
} else if (w == dFuud) {
|
||||
@@ -1455,6 +1459,12 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX);
|
||||
} else if (w == lFppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX);
|
||||
} else if (w == LFEpW) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu16 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint16_t)R_RSI);
|
||||
} else if (w == LFEpu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI);
|
||||
} else if (w == LFEpU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI);
|
||||
} else if (w == LFEpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI);
|
||||
} else if (w == LFEpA) {
|
||||
@@ -1501,6 +1511,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == LFpLC) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu8 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uint8_t)R_RDX);
|
||||
} else if (w == LFpLu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uint32_t)R_RDX);
|
||||
} else if (w == LFpLL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX);
|
||||
} else if (w == LFpLp) {
|
||||
@@ -1619,8 +1631,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == pFLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX);
|
||||
} else if (w == pFpcU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi8 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int8_t)R_RSI, (uint64_t)R_RDX);
|
||||
} else if (w == pFpcL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi8 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int8_t)R_RSI, (uintptr_t)R_RDX);
|
||||
} else if (w == pFpii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == pFpiu) {
|
||||
@@ -1681,8 +1693,12 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi8 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int8_t)R_RDX);
|
||||
} else if (w == pFppi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == pFppI) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX);
|
||||
} else if (w == pFppu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX);
|
||||
} else if (w == pFppU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint64_t)R_RDX);
|
||||
} else if (w == pFppf) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, emu->xmm[0].f[0]);
|
||||
} else if (w == pFppd) {
|
||||
@@ -1725,8 +1741,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == vFEpLp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX);
|
||||
} else if (w == vFEppi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == vFEppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX);
|
||||
} else if (w == vFEppV) {
|
||||
@@ -2001,6 +2015,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == vFpLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == vFppww) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi16 ", %" PRIi16 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int16_t)R_RDX, (int16_t)R_RCX);
|
||||
} else if (w == vFppii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX);
|
||||
} else if (w == vFppiu) {
|
||||
@@ -2223,6 +2239,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == iFpiid) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, emu->xmm[0].d[0]);
|
||||
} else if (w == iFpiil) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (intptr_t)R_RCX);
|
||||
} else if (w == iFpiiL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == iFpiip) {
|
||||
@@ -2303,6 +2321,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == iFpuup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFpuUi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint64_t)R_RDX, (int32_t)R_RCX);
|
||||
} else if (w == iFpufp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIf ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, emu->xmm[0].f[0], (void*)R_RDX);
|
||||
} else if (w == iFpuLi) {
|
||||
@@ -2323,12 +2343,14 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == iFpupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFpupV) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)(R_RSP + 8));
|
||||
} else if (w == iFpUup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFpUUu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == iFpUUp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFpUpu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == iFpUpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFpfii) {
|
||||
@@ -2375,8 +2397,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFpLpi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (int32_t)R_RCX);
|
||||
} else if (w == iFpLpu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == iFpLpf) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, emu->xmm[0].f[0]);
|
||||
} else if (w == iFpLpd) {
|
||||
@@ -2387,6 +2407,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == iFpLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFpLpV) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (void*)(R_RSP + 8));
|
||||
} else if (w == iFppcc) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi8 ", %" PRIi8 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int8_t)R_RDX, (int8_t)R_RCX);
|
||||
} else if (w == iFppii) {
|
||||
@@ -2465,6 +2487,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint64_t)R_RCX);
|
||||
} else if (w == iFpppd) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, emu->xmm[0].d[0]);
|
||||
} else if (w == iFpppl) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (intptr_t)R_RCX);
|
||||
} else if (w == iFpppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == iFpppp) {
|
||||
@@ -2665,8 +2689,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX);
|
||||
} else if (w == lFEppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX);
|
||||
} else if (w == lFEppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX);
|
||||
} else if (w == lFiiLu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI, (uintptr_t)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == lFiipL) {
|
||||
@@ -2873,8 +2895,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0], emu->xmm[1].d[0], emu->xmm[2].d[0], emu->xmm[3].d[0]);
|
||||
} else if (w == pFDipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRILf ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, LD2localLD((void*)(R_RSP + 8)), (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX);
|
||||
} else if (w == pFlfff) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi64 ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, (intptr_t)R_RDI, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0]);
|
||||
} else if (w == pFLiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX);
|
||||
} else if (w == pFLupp) {
|
||||
@@ -2895,8 +2915,12 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (uint64_t)R_RCX);
|
||||
} else if (w == pFpiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX);
|
||||
} else if (w == pFpiui) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX);
|
||||
} else if (w == pFpiuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == pFpiuL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == pFpiUL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint64_t)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == pFpiLi) {
|
||||
@@ -2913,6 +2937,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == pFpipd) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, emu->xmm[0].d[0]);
|
||||
} else if (w == pFpipL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == pFpipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == pFpCip) {
|
||||
@@ -2987,6 +3013,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX);
|
||||
} else if (w == pFppuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == pFppuL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == pFppup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX);
|
||||
} else if (w == pFppdd) {
|
||||
@@ -3017,12 +3045,12 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == vFEippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == vFEpipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == vFEpipV) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)(R_RSP + 8));
|
||||
} else if (w == vFEpipA) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == vFEpuup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX);
|
||||
} else if (w == vFEpuuV) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)(R_RSP + 8));
|
||||
} else if (w == vFEpuuA) {
|
||||
@@ -3049,8 +3077,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX);
|
||||
} else if (w == vFEpppu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == vFEpppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == vFEpppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == vFiiiii) {
|
||||
@@ -3231,8 +3257,12 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8);
|
||||
} else if (w == vFLpppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFpwwip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi16 ", %" PRIi16 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int16_t)R_RSI, (int16_t)R_RDX, (int32_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFpwwWW) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi16 ", %" PRIi16 ", %" PRIu16 ", %" PRIu16 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int16_t)R_RSI, (int16_t)R_RDX, (uint16_t)R_RCX, (uint16_t)R_R8);
|
||||
} else if (w == vFpwiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi16 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int16_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFpiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8);
|
||||
} else if (w == vFpiiiu) {
|
||||
@@ -3443,6 +3473,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)(R_RSP + 8));
|
||||
} else if (w == iFEpipA) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFEpupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFEpLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == iFEpLpV) {
|
||||
@@ -3545,6 +3577,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFupupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFuppip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFuppLp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFupppp) {
|
||||
@@ -3561,8 +3595,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi16 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int16_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFpiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8);
|
||||
} else if (w == iFpiiiu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8);
|
||||
} else if (w == iFpiiiL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (uintptr_t)R_R8);
|
||||
} else if (w == iFpiiip) {
|
||||
@@ -3645,14 +3677,14 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (int32_t)R_R8);
|
||||
} else if (w == iFpuupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFpuUup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint64_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFpuUpU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint64_t)R_RDX, (void*)R_RCX, (uint64_t)R_R8);
|
||||
} else if (w == iFpulup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi64 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (intptr_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFpulpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (intptr_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFpuLup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uintptr_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFpuLpL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8);
|
||||
} else if (w == iFpuLpp) {
|
||||
@@ -3839,8 +3871,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == IFpLIII) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8);
|
||||
} else if (w == IFppIII) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8);
|
||||
} else if (w == uFEiupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == uFEippp) {
|
||||
@@ -4099,6 +4129,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX);
|
||||
} else if (w == pFEpppu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX);
|
||||
} else if (w == pFEpppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX);
|
||||
} else if (w == pFEpppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == pFEpppV) {
|
||||
@@ -4117,6 +4149,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8);
|
||||
} else if (w == pFuiiiu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8);
|
||||
} else if (w == pFuiipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (int32_t)R_R8);
|
||||
} else if (w == pFuiupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == pFuuiip) {
|
||||
@@ -4155,6 +4189,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint8_t)R_RDX, (uint8_t)R_RCX, (uint8_t)R_R8);
|
||||
} else if (w == pFpiuuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8);
|
||||
} else if (w == pFpiupL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8);
|
||||
} else if (w == pFpiupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == pFpiLip) {
|
||||
@@ -4193,6 +4229,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == pFpupuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8);
|
||||
} else if (w == pFpupuL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (uintptr_t)R_R8);
|
||||
} else if (w == pFpuppu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (uint32_t)R_R8);
|
||||
} else if (w == pFpuppp) {
|
||||
@@ -4267,6 +4305,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == pFpppui) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (int32_t)R_R8);
|
||||
} else if (w == pFpppuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8);
|
||||
} else if (w == pFpppup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (void*)R_R8);
|
||||
} else if (w == pFpppli) {
|
||||
@@ -4293,14 +4333,14 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFEpippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFEpuipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFEpuipV) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)(R_RSP + 8));
|
||||
} else if (w == vFEpuipA) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFEpuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFEpLipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFEpLLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == vFEppupp) {
|
||||
@@ -4327,6 +4367,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi64 ", %" PRIi32 ", %" PRIp ", %" PRIi64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (intptr_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (intptr_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == vFipiplp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (intptr_t)R_R8, (void*)R_R9);
|
||||
} else if (w == vFipippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == vFCCCCff) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, (uint8_t)R_RDI, (uint8_t)R_RSI, (uint8_t)R_RDX, (uint8_t)R_RCX, emu->xmm[0].f[0], emu->xmm[1].f[0]);
|
||||
} else if (w == vFuiiiii) {
|
||||
@@ -4345,8 +4387,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu8 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (uint8_t)R_R9);
|
||||
} else if (w == vFuiuiil) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (intptr_t)R_R9);
|
||||
} else if (w == vFuiuiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == vFuiuiuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == vFuiuiuU) {
|
||||
@@ -4459,6 +4499,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == vFpiilli) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi64 ", %" PRIi64 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (intptr_t)R_RCX, (intptr_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == vFpiipii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (int32_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == vFpiippi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == vFpiippp) {
|
||||
@@ -4479,6 +4521,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == vFpuiipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == vFpuuiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == vFpuuuiu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (int32_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == vFpuuuuu) {
|
||||
@@ -4505,6 +4549,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == vFpupppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == vFpUUUUu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == vFpdddii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, emu->xmm[0].d[0], emu->xmm[1].d[0], emu->xmm[2].d[0], (int32_t)R_RSI, (int32_t)R_RDX);
|
||||
} else if (w == vFpddddd) {
|
||||
@@ -4517,8 +4563,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == vFpLiipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == vFpLLLLu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == vFpLpLLL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == vFpLpppi) {
|
||||
@@ -4577,8 +4621,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == vFppLppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == vFpppiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == vFpppiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == vFpppiui) {
|
||||
@@ -4753,6 +4795,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == iFpiCCpu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu8 ", %" PRIu8 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint8_t)R_RDX, (uint8_t)R_RCX, (void*)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpiuipu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpiuuup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpiuupp) {
|
||||
@@ -4787,8 +4831,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu16 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint16_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpuiCpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIu8 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (uint8_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpuiLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpuiUpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (uint64_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpuippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpuuuii) {
|
||||
@@ -4811,8 +4855,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpuuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpuLuLu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIu32 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uintptr_t)R_RDX, (uint32_t)R_RCX, (uintptr_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpuUuUu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIu32 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint64_t)R_RDX, (uint32_t)R_RCX, (uint64_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpuLLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpupupi) {
|
||||
@@ -4827,6 +4871,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpupppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpUUUUu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpdpipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIf ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, emu->xmm[0].d[0], (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == iFpLiiiL) {
|
||||
@@ -4847,8 +4893,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu32 ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpLuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpLLLLu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpLLLLL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == iFpLLLLp) {
|
||||
@@ -4871,6 +4915,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == iFppiiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == iFppiiuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFppiipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == iFppiipL) {
|
||||
@@ -4907,6 +4953,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFppuIII) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (int64_t)R_R9);
|
||||
} else if (w == iFppuIup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi64 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (int64_t)R_RCX, (uint32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == iFppuuLp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uintptr_t)R_R8, (void*)R_R9);
|
||||
} else if (w == iFppuupL) {
|
||||
@@ -4915,8 +4963,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFppufff) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0]);
|
||||
} else if (w == iFppulup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi64 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (intptr_t)R_RCX, (uint32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == iFppulll) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (intptr_t)R_RCX, (intptr_t)R_R8, (intptr_t)R_R9);
|
||||
} else if (w == iFppuLpp) {
|
||||
@@ -4969,6 +5015,10 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (void*)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpppipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpppIIu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIi64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == iFpppIpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFpppuii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == iFpppuip) {
|
||||
@@ -5119,8 +5169,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == lFEippLL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8);
|
||||
} else if (w == lFEpippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == lFipipLu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == lFipLipu) {
|
||||
@@ -5145,6 +5193,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == LFELpppu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (uint32_t)R_R8);
|
||||
} else if (w == LFEpippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == LFEpuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
} else if (w == LFEpLppu) {
|
||||
@@ -5153,14 +5203,16 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (uint32_t)R_R8);
|
||||
} else if (w == LFpipipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == LFpuuupL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == LFplplpl) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (intptr_t)R_RSI, (void*)R_RDX, (intptr_t)R_RCX, (void*)R_R8, (intptr_t)R_R9);
|
||||
} else if (w == LFpLippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == LFpLLLLL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == LFppipLp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (void*)R_R9);
|
||||
} else if (w == LFppupLp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (void*)R_R9);
|
||||
} else if (w == LFpplplp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (intptr_t)R_RDX, (void*)R_RCX, (intptr_t)R_R8, (void*)R_R9);
|
||||
} else if (w == LFppLLpL) {
|
||||
@@ -5241,6 +5293,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpiippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpiuipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpiuuup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpidddd) {
|
||||
@@ -5257,6 +5311,10 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpipppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpuiipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpuiuuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == pFpuuiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpuuuuu) {
|
||||
@@ -5265,6 +5323,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpuuupu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == pFpuupuL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uint32_t)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == pFpupuui) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == pFpupuuu) {
|
||||
@@ -5297,6 +5357,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == pFppiiup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFppiipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == pFppiipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == pFppiIll) {
|
||||
@@ -5323,6 +5385,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIi64 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uintptr_t)R_RCX, (intptr_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == pFppupLi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu64 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (int32_t)R_R9);
|
||||
} else if (w == pFppupLp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFppuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpplplp) {
|
||||
@@ -5335,6 +5399,10 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == pFpppiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpppupu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == pFpppupL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == pFpppupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == pFpppLii) {
|
||||
@@ -5349,6 +5417,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == pFpppppu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uint32_t)R_R9);
|
||||
} else if (w == pFpppppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == pFpppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == vFEiipupV) {
|
||||
@@ -5389,6 +5459,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi64 ", %" PRIi32 ", %" PRIp ", %" PRIi64 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (intptr_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (intptr_t)R_R8, (int32_t)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == vFilulipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi64 ", %" PRIu32 ", %" PRIi64 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (intptr_t)R_RSI, (uint32_t)R_RDX, (intptr_t)R_RCX, (int32_t)R_R8, (void*)R_R9, *(int32_t*)(R_RSP + 8));
|
||||
} else if (w == vFippippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == vFCCCCfff) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, (uint8_t)R_RDI, (uint8_t)R_RSI, (uint8_t)R_RDX, (uint8_t)R_RCX, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0]);
|
||||
} else if (w == vFuiiiiii) {
|
||||
@@ -5491,6 +5563,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (intptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (intptr_t)R_RCX, (void*)R_R8, (void*)R_R9, *(intptr_t*)(R_RSP + 8));
|
||||
} else if (w == vFLpuLpLp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu64 ", %" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIp ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uintptr_t)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (uintptr_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == vFpiiiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8));
|
||||
} else if (w == vFpiiiipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == vFpiiliip) {
|
||||
@@ -5631,8 +5705,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFEilpppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (intptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFElppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (intptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFEpipupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFEpupppp) {
|
||||
@@ -5647,6 +5719,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (uintptr_t)R_R9);
|
||||
} else if (w == iFEppiipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == iFEppippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == iFEppupup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uint32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == iFEppuppp) {
|
||||
@@ -5699,8 +5773,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8));
|
||||
} else if (w == iFpiipppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFpiuiipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFpiuuuiu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (int32_t)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == iFpiuLiii) {
|
||||
@@ -5747,6 +5819,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (uintptr_t)R_R8, (void*)R_R9, *(uintptr_t*)(R_RSP + 8));
|
||||
} else if (w == iFpupupui) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (uint32_t)R_R9, *(int32_t*)(R_RSP + 8));
|
||||
} else if (w == iFpupupup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (uint32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFpuppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFpllpppp) {
|
||||
@@ -5779,8 +5853,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFppiiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8));
|
||||
} else if (w == iFppiiiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFppiiLll) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ", %" PRIi64 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (uintptr_t)R_R8, (intptr_t)R_R9, *(intptr_t*)(R_RSP + 8));
|
||||
} else if (w == iFppiipii) {
|
||||
@@ -5813,8 +5885,12 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == iFppupupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFppupLip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu64 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFppupppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFppUUUUu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (uint64_t)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == iFppliupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIi32 ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (intptr_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFppLiipp) {
|
||||
@@ -5827,8 +5903,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8));
|
||||
} else if (w == iFppLLupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFppLLLLu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (uintptr_t)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == iFppLpLpL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (void*)R_R9, *(uintptr_t*)(R_RSP + 8));
|
||||
} else if (w == iFppLpppp) {
|
||||
@@ -5849,10 +5923,10 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFpppuiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8));
|
||||
} else if (w == iFpppuIup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi64 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (int64_t)R_R8, (uint32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFpppuupu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == iFpppulup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi64 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (intptr_t)R_R8, (uint32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFpppLppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == iFppppilp) {
|
||||
@@ -5881,10 +5955,14 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == uFEiipppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == uFElppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (intptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == uFEpiuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == uFEpuuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == uFEpppLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == uFEpppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == uFiiiuuuu) {
|
||||
@@ -5925,6 +6003,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9, *(uintptr_t*)(R_RSP + 8));
|
||||
} else if (w == dFppppppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(uintptr_t*)(R_RSP + 8));
|
||||
} else if (w == lFppiiiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == lFpppplpl) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (intptr_t)R_R8, (void*)R_R9, *(intptr_t*)(R_RSP + 8));
|
||||
} else if (w == LFEppLppU) {
|
||||
@@ -5953,6 +6033,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8, (void*)R_R9);
|
||||
} else if (w == pFEpppppi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (int32_t)R_R9);
|
||||
} else if (w == pFEpppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
} else if (w == pFifffppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0], (void*)R_RSI, (void*)R_RDX, (void*)R_RCX);
|
||||
} else if (w == pFWpppppp) {
|
||||
@@ -5971,6 +6053,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, emu->xmm[0].d[0]);
|
||||
} else if (w == pFpiiippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == pFpiiLppu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (void*)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == pFpiipipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (int32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == pFpiiplui) {
|
||||
@@ -6033,10 +6117,14 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == pFppuuupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == pFppuuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == pFppuLLip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIu64 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == pFppupuuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9, *(uint32_t*)(R_RSP + 8));
|
||||
} else if (w == pFppupLip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu64 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == pFppliuip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (intptr_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8));
|
||||
} else if (w == pFpplipup) {
|
||||
@@ -6299,8 +6387,14 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(int32_t*)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFdiippppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0], (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(uintptr_t*)(R_RSP + 8));
|
||||
} else if (w == iFpiiiiiiu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(uint32_t*)(R_RSP + 16));
|
||||
} else if (w == iFpiiupppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFpiuiiLLL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (uintptr_t)R_R9, *(uintptr_t*)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16));
|
||||
} else if (w == iFpiuuuppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFpipiipip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (void*)R_R9, *(int32_t*)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFpippiiii) {
|
||||
@@ -6339,8 +6433,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFpuuppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFpuLLLppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16));
|
||||
} else if (w == iFpuUUUppU) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(uint64_t*)(R_RSP + 16));
|
||||
} else if (w == iFpupupuup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (uint32_t)R_R9, *(uint32_t*)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFpupppppp) {
|
||||
@@ -6373,8 +6467,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi64 ", %" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (intptr_t)R_RCX, (intptr_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFppipiipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8), *(int32_t*)(R_RSP + 16));
|
||||
} else if (w == iFppIIIppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == iFppuiiuuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (uint32_t)R_R9, *(uint32_t*)(R_RSP + 8), *(uint32_t*)(R_RSP + 16));
|
||||
} else if (w == iFppuuuuuu) {
|
||||
@@ -6623,14 +6715,14 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], emu->xmm[1].f[0], (uint8_t)R_RDI, (uint8_t)R_RSI, (uint8_t)R_RDX, (uint8_t)R_RCX, emu->xmm[2].f[0], emu->xmm[3].f[0], emu->xmm[4].f[0]);
|
||||
} else if (w == vFddddddddd) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].d[0], emu->xmm[1].d[0], emu->xmm[2].d[0], emu->xmm[3].d[0], emu->xmm[4].d[0], emu->xmm[5].d[0], emu->xmm[6].d[0], emu->xmm[7].d[0], *(double*)(R_RSP + 8));
|
||||
} else if (w == vFpiuiuiiLL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu64 ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16), *(uintptr_t*)(R_RSP + 24));
|
||||
} else if (w == vFpiuippppi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(int32_t*)(R_RSP + 24));
|
||||
} else if (w == vFpiLLpiipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu64 ", %" PRIu64 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(int32_t*)(R_RSP + 24));
|
||||
} else if (w == vFpiLpLiipi) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIu64 ", %" PRIp ", %" PRIu64 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(int32_t*)(R_RSP + 24));
|
||||
} else if (w == vFpipiuiipp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24));
|
||||
} else if (w == vFpuuCiuuuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu8 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uint32_t)R_RDX, (uint8_t)R_RCX, (int32_t)R_R8, (uint32_t)R_R9, *(uint32_t*)(R_RSP + 8), *(uint32_t*)(R_RSP + 16), *(uint32_t*)(R_RSP + 24));
|
||||
} else if (w == vFpuuuuuuuu) {
|
||||
@@ -6857,6 +6949,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9, *(uint32_t*)(R_RSP + 8), *(uint32_t*)(R_RSP + 16), *(uint32_t*)(R_RSP + 24));
|
||||
} else if (w == pFpiiiiuuuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (uint32_t)R_R9, *(uint32_t*)(R_RSP + 8), *(uint32_t*)(R_RSP + 16), *(uint32_t*)(R_RSP + 24));
|
||||
} else if (w == pFpiiuuuuii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9, *(uint32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24));
|
||||
} else if (w == pFpLpLLipui) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIi32 ", %" PRIp ", %" PRIu32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8), *(uint32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24));
|
||||
} else if (w == pFpLppLLiLi) {
|
||||
@@ -6939,6 +7033,10 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi64 ", %" PRIi64 ", %" PRIf ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (intptr_t)R_RSI, (intptr_t)R_RDX, emu->xmm[0].d[0], (void*)R_RCX, (intptr_t)R_R8, (void*)R_R9, *(intptr_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(intptr_t*)(R_RSP + 24));
|
||||
} else if (w == vFullpplplpl) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi64 ", %" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (intptr_t)R_RSI, (intptr_t)R_RDX, (void*)R_RCX, (void*)R_R8, (intptr_t)R_R9, *(void**)(R_RSP + 8), *(intptr_t*)(R_RSP + 16), *(void**)(R_RSP + 24), *(intptr_t*)(R_RSP + 32));
|
||||
} else if (w == vFuppiiiipip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(void**)(R_RSP + 32));
|
||||
} else if (w == vFuppuiiiiip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(void**)(R_RSP + 32));
|
||||
} else if (w == vFffffffffff) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0], emu->xmm[3].f[0], emu->xmm[4].f[0], emu->xmm[5].f[0], emu->xmm[6].f[0], emu->xmm[7].f[0], *(float*)(R_RSP + 8), *(float*)(R_RSP + 16));
|
||||
} else if (w == vFpiuippppip) {
|
||||
@@ -6989,8 +7087,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (uint32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24));
|
||||
} else if (w == iFEpupppLppL) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(uintptr_t*)(R_RSP + 24));
|
||||
} else if (w == iFEppiiiippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24));
|
||||
} else if (w == iFEppiippppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24));
|
||||
} else if (w == iFEppLuppupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (uint32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(uint32_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24));
|
||||
} else if (w == iFEppppLpppp) {
|
||||
@@ -7053,6 +7151,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIf ", %" PRIf ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, emu->xmm[0].d[0], emu->xmm[1].d[0], (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16));
|
||||
} else if (w == uFpppppppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32));
|
||||
} else if (w == lFEppiiiippp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24));
|
||||
} else if (w == lFpLppdddddd) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX, emu->xmm[0].d[0], emu->xmm[1].d[0], emu->xmm[2].d[0], emu->xmm[3].d[0], emu->xmm[4].d[0], emu->xmm[5].d[0]);
|
||||
} else if (w == pFEiuppppppp) {
|
||||
@@ -7165,6 +7265,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32));
|
||||
} else if (w == iFEpLppiiiiuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(uint32_t*)(R_RSP + 24), *(uint32_t*)(R_RSP + 32));
|
||||
} else if (w == iFEppiipppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32));
|
||||
} else if (w == iFEppLpLpLLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (void*)R_R9, *(uintptr_t*)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32));
|
||||
} else if (w == iFEpppupppppp) {
|
||||
@@ -7255,6 +7357,10 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIu32 ", %" PRIi64 ", %" PRIi64 ", %" PRIf ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ", %" PRIf ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (uint32_t)R_RSI, (intptr_t)R_RDX, (intptr_t)R_RCX, emu->xmm[0].d[0], (void*)R_R8, (intptr_t)R_R9, *(void**)(R_RSP + 8), *(intptr_t*)(R_RSP + 16), emu->xmm[1].d[0], *(void**)(R_RSP + 24), *(intptr_t*)(R_RSP + 32));
|
||||
} else if (w == vFuullpplplppl) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIu32 ", %" PRIi64 ", %" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIi64 ", %" PRIp ", %" PRIp ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (uint32_t)R_RSI, (intptr_t)R_RDX, (intptr_t)R_RCX, (void*)R_R8, (void*)R_R9, *(intptr_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(intptr_t*)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(intptr_t*)(R_RSP + 48));
|
||||
} else if (w == vFupppwwwwwwWW) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi16 ", %" PRIi16 ", %" PRIi16 ", %" PRIi16 ", %" PRIi16 ", %" PRIi16 ", %" PRIu16 ", %" PRIu16 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int16_t)R_R8, (int16_t)R_R9, *(int16_t*)(R_RSP + 8), *(int16_t*)(R_RSP + 16), *(int16_t*)(R_RSP + 24), *(int16_t*)(R_RSP + 32), *(uint16_t*)(R_RSP + 40), *(uint16_t*)(R_RSP + 48));
|
||||
} else if (w == vFupppiiiiiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(int32_t*)(R_RSP + 32), *(int32_t*)(R_RSP + 40), *(int32_t*)(R_RSP + 48));
|
||||
} else if (w == vFffffffffffff) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0], emu->xmm[3].f[0], emu->xmm[4].f[0], emu->xmm[5].f[0], emu->xmm[6].f[0], emu->xmm[7].f[0], *(float*)(R_RSP + 8), *(float*)(R_RSP + 16), *(float*)(R_RSP + 24), *(float*)(R_RSP + 32));
|
||||
} else if (w == vFpiLLpiiiipii) {
|
||||
@@ -7307,10 +7413,14 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIu64 ", %" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (uint32_t)R_R8, (uintptr_t)R_R9, *(void**)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(uintptr_t*)(R_RSP + 48));
|
||||
} else if (w == iFpLpppppppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48));
|
||||
} else if (w == iFppiiiiiiiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(int32_t*)(R_RSP + 32), *(int32_t*)(R_RSP + 40), *(int32_t*)(R_RSP + 48));
|
||||
} else if (w == iFppLlliLppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi32 ", %" PRIu64 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (intptr_t)R_RCX, (intptr_t)R_R8, (int32_t)R_R9, *(uintptr_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48));
|
||||
} else if (w == iFpppipipiipii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int32_t)R_RCX, (void*)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(void**)(R_RSP + 32), *(int32_t*)(R_RSP + 40), *(int32_t*)(R_RSP + 48));
|
||||
} else if (w == iFppppwwwwwwWW) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIi16 ", %" PRIi16 ", %" PRIi16 ", %" PRIi16 ", %" PRIi16 ", %" PRIi16 ", %" PRIu16 ", %" PRIu16 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int16_t)R_R8, (int16_t)R_R9, *(int16_t*)(R_RSP + 8), *(int16_t*)(R_RSP + 16), *(int16_t*)(R_RSP + 24), *(int16_t*)(R_RSP + 32), *(uint16_t*)(R_RSP + 40), *(uint16_t*)(R_RSP + 48));
|
||||
} else if (w == iFpppppppppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48));
|
||||
} else if (w == uFpuupppppuuuu) {
|
||||
@@ -7321,8 +7431,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu64 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (uint32_t)R_R8, (uint32_t)R_R9, *(uintptr_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(void**)(R_RSP + 24), *(int32_t*)(R_RSP + 32), *(int32_t*)(R_RSP + 40));
|
||||
} else if (w == pFEppppppppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40));
|
||||
} else if (w == pFWWiCCCCiipup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu16 ", %" PRIu16 ", %" PRIi32 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint16_t)R_RDI, (uint16_t)R_RSI, (int32_t)R_RDX, (uint8_t)R_RCX, (uint8_t)R_R8, (uint8_t)R_R9, *(uint8_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(void**)(R_RSP + 32), *(uint32_t*)(R_RSP + 40), *(void**)(R_RSP + 48));
|
||||
} else if (w == pFWWuCCCCuupup) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu16 ", %" PRIu16 ", %" PRIu32 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIu32 ", %" PRIu32 ", %" PRIp ", %" PRIu32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint16_t)R_RDI, (uint16_t)R_RSI, (uint32_t)R_RDX, (uint8_t)R_RCX, (uint8_t)R_R8, (uint8_t)R_R9, *(uint8_t*)(R_RSP + 8), *(uint32_t*)(R_RSP + 16), *(uint32_t*)(R_RSP + 24), *(void**)(R_RSP + 32), *(uint32_t*)(R_RSP + 40), *(void**)(R_RSP + 48));
|
||||
} else if (w == pFppippLLLiLpp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIi32 ", %" PRIu64 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9, *(uintptr_t*)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(uintptr_t*)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48));
|
||||
} else if (w == pFppuuppppuppp) {
|
||||
@@ -7437,14 +7547,16 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64));
|
||||
} else if (w == iFpipppppppppppp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64));
|
||||
} else if (w == iFpuLwwWWwwWWpuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ", %" PRIu64 ", %" PRIi16 ", %" PRIi16 ", %" PRIu16 ", %" PRIu16 ", %" PRIi16 ", %" PRIi16 ", %" PRIu16 ", %" PRIu16 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI, (uintptr_t)R_RDX, (int16_t)R_RCX, (int16_t)R_R8, (uint16_t)R_R9, *(uint16_t*)(R_RSP + 8), *(int16_t*)(R_RSP + 16), *(int16_t*)(R_RSP + 24), *(uint16_t*)(R_RSP + 32), *(uint16_t*)(R_RSP + 40), *(void**)(R_RSP + 48), *(uint32_t*)(R_RSP + 56), *(uint32_t*)(R_RSP + 64));
|
||||
} else if (w == iFppupppLLLLpupp) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIp ", %" PRIu32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(uintptr_t*)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16), *(uintptr_t*)(R_RSP + 24), *(uintptr_t*)(R_RSP + 32), *(void**)(R_RSP + 40), *(uint32_t*)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64));
|
||||
} else if (w == iFpppwwWWwwWWpuu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIi16 ", %" PRIi16 ", %" PRIu16 ", %" PRIu16 ", %" PRIi16 ", %" PRIi16 ", %" PRIu16 ", %" PRIu16 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int16_t)R_RCX, (int16_t)R_R8, (uint16_t)R_R9, *(uint16_t*)(R_RSP + 8), *(int16_t*)(R_RSP + 16), *(int16_t*)(R_RSP + 24), *(uint16_t*)(R_RSP + 32), *(uint16_t*)(R_RSP + 40), *(void**)(R_RSP + 48), *(uint32_t*)(R_RSP + 56), *(uint32_t*)(R_RSP + 64));
|
||||
} else if (w == vFuiiiiiuiiiiilll) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(uint32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(int32_t*)(R_RSP + 32), *(int32_t*)(R_RSP + 40), *(int32_t*)(R_RSP + 48), *(intptr_t*)(R_RSP + 56), *(intptr_t*)(R_RSP + 64), *(intptr_t*)(R_RSP + 72));
|
||||
} else if (w == vFuuiiiiuuiiiiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (uint32_t)R_RSI, (int32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(uint32_t*)(R_RSP + 8), *(uint32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(int32_t*)(R_RSP + 32), *(int32_t*)(R_RSP + 40), *(int32_t*)(R_RSP + 48), *(int32_t*)(R_RSP + 56), *(int32_t*)(R_RSP + 64), *(int32_t*)(R_RSP + 72));
|
||||
} else if (w == vFuppuiiiiiiiipip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIu32 ", %" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (uint32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(int32_t*)(R_RSP + 24), *(int32_t*)(R_RSP + 32), *(int32_t*)(R_RSP + 40), *(int32_t*)(R_RSP + 48), *(void**)(R_RSP + 56), *(int32_t*)(R_RSP + 64), *(void**)(R_RSP + 72));
|
||||
} else if (w == vFfffffffffffffff) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0], emu->xmm[3].f[0], emu->xmm[4].f[0], emu->xmm[5].f[0], emu->xmm[6].f[0], emu->xmm[7].f[0], *(float*)(R_RSP + 8), *(float*)(R_RSP + 16), *(float*)(R_RSP + 24), *(float*)(R_RSP + 32), *(float*)(R_RSP + 40), *(float*)(R_RSP + 48), *(float*)(R_RSP + 56));
|
||||
} else if (w == vFppUpUUpUUpUUuuu) {
|
||||
@@ -7507,8 +7619,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(uintptr_t*)(R_RSP + 88));
|
||||
} else if (w == pFppippipipipipipip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8, (int32_t)R_R9, *(void**)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(void**)(R_RSP + 24), *(int32_t*)(R_RSP + 32), *(void**)(R_RSP + 40), *(int32_t*)(R_RSP + 48), *(void**)(R_RSP + 56), *(int32_t*)(R_RSP + 64), *(void**)(R_RSP + 72), *(int32_t*)(R_RSP + 80), *(void**)(R_RSP + 88));
|
||||
} else if (w == vFppuiiiiipuiiiiiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (int32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(void**)(R_RSP + 24), *(uint32_t*)(R_RSP + 32), *(int32_t*)(R_RSP + 40), *(int32_t*)(R_RSP + 48), *(int32_t*)(R_RSP + 56), *(int32_t*)(R_RSP + 64), *(int32_t*)(R_RSP + 72), *(int32_t*)(R_RSP + 80), *(int32_t*)(R_RSP + 88), *(int32_t*)(R_RSP + 96));
|
||||
} else if (w == vFppuuiiiipuuiiiiiii) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIp ", %" PRIu32 ", %" PRIu32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uint32_t)R_RCX, (int32_t)R_R8, (int32_t)R_R9, *(int32_t*)(R_RSP + 8), *(int32_t*)(R_RSP + 16), *(void**)(R_RSP + 24), *(uint32_t*)(R_RSP + 32), *(uint32_t*)(R_RSP + 40), *(int32_t*)(R_RSP + 48), *(int32_t*)(R_RSP + 56), *(int32_t*)(R_RSP + 64), *(int32_t*)(R_RSP + 72), *(int32_t*)(R_RSP + 80), *(int32_t*)(R_RSP + 88), *(int32_t*)(R_RSP + 96));
|
||||
} else if (w == vFpppipppppppppppppp) {
|
||||
@@ -7642,8 +7752,6 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)R_RCX, (void*)R_R8);
|
||||
#endif
|
||||
#if !defined(STATICBUILD)
|
||||
} else if (w == iFEpu) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu32 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uint32_t)R_RSI);
|
||||
} else if (w == iFlip) {
|
||||
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi64 ", %" PRIi32 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (intptr_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX);
|
||||
} else if (w == iFLLi) {
|
||||
|
||||
+24
-7
@@ -166,7 +166,7 @@ x64emurun:
|
||||
goto fini;
|
||||
}
|
||||
#endif
|
||||
} else if(rex.is66) {
|
||||
} else if(rex.is66 && (!rex.w || opcode==0x0F)) {
|
||||
/* 16bits prefix */
|
||||
#ifdef TEST_INTERPRETER
|
||||
if(!(addr = Test66(test, rex, addr-1, &step)))
|
||||
@@ -504,9 +504,29 @@ x64emurun:
|
||||
goto fini;
|
||||
}
|
||||
break;
|
||||
case 0x62: /* BOUND Gd, Ed */
|
||||
case 0x62: /* EVEX prefix / BOUND Gd, Ed */
|
||||
nextop = F8;
|
||||
if(rex.is32bits && !MODREG) {
|
||||
if(!rex.is32bits) {
|
||||
vex_t vex = {0};
|
||||
tmp8u = F8;
|
||||
tmp8u2 = F8;
|
||||
if(!FillVEXFromEVEX(&vex, rex, nextop, tmp8u, tmp8u2)) {
|
||||
unimp = 1;
|
||||
goto fini;
|
||||
}
|
||||
#ifdef TEST_INTERPRETER
|
||||
if(!(addr = TestAVX(test, vex, addr, &step)))
|
||||
unimp = 1;
|
||||
#else
|
||||
if(!(addr = RunAVX(emu, vex, addr, &step))) {
|
||||
unimp = 1;
|
||||
goto fini;
|
||||
}
|
||||
if(step==2) {
|
||||
STEP2;
|
||||
}
|
||||
#endif
|
||||
} else if(!MODREG) {
|
||||
GETGD;
|
||||
int* bounds = (int*)GETEA(0);
|
||||
if((GD->sdword[0]<bounds[0]) || (GD->sdword[0]>bounds[1]))
|
||||
@@ -542,10 +562,7 @@ x64emurun:
|
||||
if(rex.w)
|
||||
GD->sq[0] = ED->sdword[0];
|
||||
else
|
||||
if(MODREG)
|
||||
GD->q[0] = ED->dword[0]; // not really a sign extension
|
||||
else
|
||||
GD->sdword[0] = ED->sdword[0]; // meh?
|
||||
GD->q[0] = ED->dword[0]; // zero upper 32 bits
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+21
-19
@@ -1403,12 +1403,12 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
#ifdef TEST_INTERPRETER
|
||||
emu->sw.f.F87_TOP = emu->top&7;
|
||||
#else
|
||||
fpu_xsave(emu, ED, rex.w?0:1);
|
||||
fpu_xsave(emu, ED, rex.is32bits);
|
||||
#endif
|
||||
break;
|
||||
case 5: /* XRSTOR Ed */
|
||||
_GETED(0);
|
||||
fpu_xrstor(emu, ED, rex.w?0:1);
|
||||
fpu_xrstor(emu, ED, rex.is32bits);
|
||||
break;
|
||||
case 7: /* CLFLUSH Ed */
|
||||
_GETED(0);
|
||||
@@ -1658,14 +1658,15 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
}
|
||||
} else {
|
||||
tmp32u = ED->dword[0];
|
||||
if(tmp32u) {
|
||||
CLEAR_FLAG(F_ZF);
|
||||
while(!(tmp32u&(1<<tmp8u))) ++tmp8u;
|
||||
GD->q[0] = tmp8u;
|
||||
} else {
|
||||
SET_FLAG(F_ZF);
|
||||
}
|
||||
}
|
||||
if(tmp32u) {
|
||||
CLEAR_FLAG(F_ZF);
|
||||
while(!(tmp32u&(1<<tmp8u))) ++tmp8u;
|
||||
GD->q[0] = tmp8u;
|
||||
} else {
|
||||
SET_FLAG(F_ZF);
|
||||
GD->dword[1] = 0;
|
||||
}
|
||||
}
|
||||
if(!BOX64ENV(cputype)) {
|
||||
CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF);
|
||||
CLEAR_FLAG(F_CF);
|
||||
@@ -1692,15 +1693,16 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
}
|
||||
} else {
|
||||
tmp32u = ED->dword[0];
|
||||
if(tmp32u) {
|
||||
CLEAR_FLAG(F_ZF);
|
||||
tmp8u = 31;
|
||||
while(!(tmp32u&(1<<tmp8u))) --tmp8u;
|
||||
GD->q[0] = tmp8u;
|
||||
} else {
|
||||
SET_FLAG(F_ZF);
|
||||
}
|
||||
}
|
||||
if(tmp32u) {
|
||||
CLEAR_FLAG(F_ZF);
|
||||
tmp8u = 31;
|
||||
while(!(tmp32u&(1<<tmp8u))) --tmp8u;
|
||||
GD->q[0] = tmp8u;
|
||||
} else {
|
||||
SET_FLAG(F_ZF);
|
||||
GD->dword[1] = 0;
|
||||
}
|
||||
}
|
||||
if(!BOX64ENV(cputype)) {
|
||||
CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF);
|
||||
CLEAR_FLAG(F_CF);
|
||||
|
||||
+124
-327
@@ -61,10 +61,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
nextop = F8; \
|
||||
GETEW(0); \
|
||||
GETGW; \
|
||||
if(rex.w) \
|
||||
EW->q[0] = OP##64(emu, EW->q[0], GW->q[0]); \
|
||||
else \
|
||||
EW->word[0] = OP##16(emu, EW->word[0], GW->word[0]); \
|
||||
EW->word[0] = OP##16(emu, EW->word[0], GW->word[0]); \
|
||||
break; \
|
||||
case B+2: \
|
||||
nextop = F8; \
|
||||
@@ -76,19 +73,13 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
nextop = F8; \
|
||||
GETEW(0); \
|
||||
GETGW; \
|
||||
if(rex.w) \
|
||||
GW->q[0] = OP##64(emu, GW->q[0], EW->q[0]); \
|
||||
else \
|
||||
GW->word[0] = OP##16(emu, GW->word[0], EW->word[0]); \
|
||||
GW->word[0] = OP##16(emu, GW->word[0], EW->word[0]); \
|
||||
break; \
|
||||
case B+4: \
|
||||
R_AL = OP##8(emu, R_AL, F8); \
|
||||
break; \
|
||||
case B+5: \
|
||||
if(rex.w) \
|
||||
R_RAX = OP##64(emu, R_RAX, F32S64); \
|
||||
else \
|
||||
R_AX = OP##16(emu, R_AX, F16); \
|
||||
R_AX = OP##16(emu, R_AX, F16); \
|
||||
break;
|
||||
|
||||
GO(0x00, add) /* ADD 0x01 ~> 0x05 */
|
||||
@@ -152,25 +143,16 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
nextop = F8;
|
||||
GETEW(0);
|
||||
GETGW;
|
||||
if(rex.w)
|
||||
cmp64(emu, EW->q[0], GW->q[0]);
|
||||
else
|
||||
cmp16(emu, EW->word[0], GW->word[0]);
|
||||
cmp16(emu, EW->word[0], GW->word[0]);
|
||||
break;
|
||||
case 0x3B:
|
||||
nextop = F8;
|
||||
GETEW(0);
|
||||
GETGW;
|
||||
if(rex.w)
|
||||
cmp64(emu, GW->q[0], EW->dword[0]);
|
||||
else
|
||||
cmp16(emu, GW->word[0], EW->word[0]);
|
||||
cmp16(emu, GW->word[0], EW->word[0]);
|
||||
break;
|
||||
case 0x3D:
|
||||
if(rex.w)
|
||||
cmp64(emu, R_RAX, F32S64);
|
||||
else
|
||||
cmp16(emu, R_AX, F16);
|
||||
cmp16(emu, R_AX, F16);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
@@ -261,15 +243,10 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
break;
|
||||
case 0x69: /* IMUL Gw,Ew,Iw */
|
||||
nextop = F8;
|
||||
GETEW(rex.w?4:2);
|
||||
GETEW(2);
|
||||
GETGW;
|
||||
if(rex.w) {
|
||||
tmp64u = F32S64;
|
||||
GW->q[0] = imul64(emu, EW->q[0], tmp64u);
|
||||
} else {
|
||||
tmp16u = F16;
|
||||
GW->word[0] = imul16(emu, EW->word[0], tmp16u);
|
||||
}
|
||||
tmp16u = F16;
|
||||
GW->word[0] = imul16(emu, EW->word[0], tmp16u);
|
||||
break;
|
||||
case 0x6A: /* PUSH u8 */
|
||||
tmp16s = F8S;
|
||||
@@ -279,13 +256,8 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
nextop = F8;
|
||||
GETEW(1);
|
||||
GETGW;
|
||||
if(rex.w) {
|
||||
tmp64s = F8S;
|
||||
GW->q[0] = imul64(emu, EW->q[0], (uint64_t)tmp64s);
|
||||
} else {
|
||||
tmp16s = F8S;
|
||||
GW->word[0] = imul16(emu, EW->word[0], (uint16_t)tmp16s);
|
||||
}
|
||||
tmp16s = F8S;
|
||||
GW->word[0] = imul16(emu, EW->word[0], (uint16_t)tmp16s);
|
||||
break;
|
||||
case 0x6C: /* INSB DX */
|
||||
case 0x6D: /* INSW DX */
|
||||
@@ -354,52 +326,34 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
nextop = F8;
|
||||
GETEW(0);
|
||||
GETGW;
|
||||
if(rex.w) {
|
||||
tmp64u = GW->q[0];
|
||||
GW->q[0] = EW->q[0];
|
||||
EW->q[0] = tmp64u;
|
||||
} else {
|
||||
tmp16u = GW->word[0];
|
||||
GW->word[0] = EW->word[0];
|
||||
EW->word[0] = tmp16u;
|
||||
}
|
||||
tmp16u = GW->word[0];
|
||||
GW->word[0] = EW->word[0];
|
||||
EW->word[0] = tmp16u;
|
||||
break;
|
||||
|
||||
case 0x89: /* MOV Ew,Gw */
|
||||
nextop = F8;
|
||||
GETEW(0);
|
||||
GETGW;
|
||||
if(rex.w)
|
||||
EW->q[0] = GW->q[0];
|
||||
else
|
||||
EW->word[0] = GW->word[0];
|
||||
EW->word[0] = GW->word[0];
|
||||
break;
|
||||
|
||||
case 0x8B: /* MOV Gw,Ew */
|
||||
nextop = F8;
|
||||
GETEW(0);
|
||||
GETGW;
|
||||
if(rex.w)
|
||||
GW->q[0] = EW->q[0];
|
||||
else
|
||||
GW->word[0] = EW->word[0];
|
||||
GW->word[0] = EW->word[0];
|
||||
break;
|
||||
case 0x8C: /* MOV Ed, Seg */
|
||||
nextop = F8;
|
||||
GETEW(0);
|
||||
if(rex.w)
|
||||
EW->q[0] = emu->segs[((nextop&0x38)>>3)];
|
||||
else
|
||||
EW->word[0] = emu->segs[((nextop&0x38)>>3)];
|
||||
EW->word[0] = emu->segs[((nextop&0x38)>>3)];
|
||||
break;
|
||||
case 0x8D: /* LEA Gw,M */
|
||||
nextop = F8;
|
||||
GETGW;
|
||||
tmp64u = GETEA(0);
|
||||
if(rex.w)
|
||||
GW->q[0] = tmp64u;
|
||||
else
|
||||
GW->word[0] = (uint16_t)tmp64u;
|
||||
GW->word[0] = (uint16_t)tmp64u;
|
||||
break;
|
||||
case 0x8E: /* MOV Seg,Ew */
|
||||
nextop = F8;
|
||||
@@ -430,15 +384,9 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
case 0x97: /* XCHG reg,AX */
|
||||
tmp8u = _AX+(opcode&7)+(rex.b<<3);
|
||||
if(tmp8u!=_AX) {
|
||||
if(rex.w) {
|
||||
tmp64u = R_RAX;
|
||||
R_RAX = emu->regs[tmp8u].q[0];
|
||||
emu->regs[tmp8u].q[0] = tmp64u;
|
||||
} else {
|
||||
tmp16u = R_AX;
|
||||
R_AX = emu->regs[tmp8u].word[0];
|
||||
emu->regs[tmp8u].word[0] = tmp16u;
|
||||
}
|
||||
tmp16u = R_AX;
|
||||
R_AX = emu->regs[tmp8u].word[0];
|
||||
emu->regs[tmp8u].word[0] = tmp16u;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -463,10 +411,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
if(rex.is32bits) {
|
||||
R_AX = *(uint16_t*)(uintptr_t)(ptr_t)(F32+rex.offset);
|
||||
} else {
|
||||
if(rex.w)
|
||||
R_RAX = *(uint64_t*)(F64+rex.offset);
|
||||
else
|
||||
R_AX = *(uint16_t*)(F64+rex.offset);
|
||||
R_AX = *(uint16_t*)(F64+rex.offset);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -474,10 +419,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
if(rex.is32bits) {
|
||||
*(uint16_t*)(uintptr_t)(ptr_t)(F32+rex.offset) = R_AX;
|
||||
} else {
|
||||
if(rex.w)
|
||||
*(uint64_t*)(F64+rex.offset) = R_RAX;
|
||||
else
|
||||
*(uint16_t*)(F64+rex.offset) = R_AX;
|
||||
*(uint16_t*)(F64+rex.offset) = R_AX;
|
||||
}
|
||||
break;
|
||||
case 0xA4: /* (REP) MOVSB */
|
||||
@@ -497,215 +439,115 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
case 0xA5: /* (REP) MOVSW */
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-1:+1;
|
||||
tmp64u = (rex.rep)?R_RCX:1L;
|
||||
if(rex.w) {
|
||||
tmp8s *= 8;
|
||||
while(tmp64u) {
|
||||
--tmp64u;
|
||||
*(uint64_t*)R_RDI = *(uint64_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
}
|
||||
} else {
|
||||
tmp8s *= 2;
|
||||
while(tmp64u) {
|
||||
--tmp64u;
|
||||
*(uint16_t*)R_RDI = *(uint16_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
}
|
||||
tmp8s *= 2;
|
||||
while(tmp64u) {
|
||||
--tmp64u;
|
||||
*(uint16_t*)R_RDI = *(uint16_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
}
|
||||
if(rex.rep)
|
||||
R_RCX = tmp64u;
|
||||
break;
|
||||
|
||||
case 0xA7: /* (REPZ/REPNE) CMPSW */
|
||||
if(rex.w)
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-8:+8;
|
||||
else
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-2:+2;
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-2:+2;
|
||||
switch(rex.rep) {
|
||||
case 1:
|
||||
if(R_RCX) {
|
||||
if(rex.w) {
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp64u3 = *(uint64_t*)R_RDI;
|
||||
tmp64u2 = *(uint64_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
if(tmp64u3==tmp64u2)
|
||||
break;
|
||||
}
|
||||
cmp64(emu, tmp64u2, tmp64u3);
|
||||
} else {
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
tmp16u2 = *(uint16_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
if(tmp16u==tmp16u2)
|
||||
break;
|
||||
}
|
||||
cmp16(emu, tmp16u2, tmp16u);
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
tmp16u2 = *(uint16_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
if(tmp16u==tmp16u2)
|
||||
break;
|
||||
}
|
||||
cmp16(emu, tmp16u2, tmp16u);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(R_RCX) {
|
||||
if(rex.w) {
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp64u3 = *(uint64_t*)R_RDI;
|
||||
tmp64u2 = *(uint64_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
if(tmp64u3!=tmp64u2)
|
||||
break;
|
||||
}
|
||||
cmp64(emu, tmp64u2, tmp64u3);
|
||||
} else {
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
tmp16u2 = *(uint16_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
if(tmp16u!=tmp16u2)
|
||||
break;
|
||||
}
|
||||
cmp16(emu, tmp16u2, tmp16u);
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
tmp16u2 = *(uint16_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
if(tmp16u!=tmp16u2)
|
||||
break;
|
||||
}
|
||||
cmp16(emu, tmp16u2, tmp16u);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(rex.w) {
|
||||
tmp64u = *(uint64_t*)R_RDI;
|
||||
tmp64u2 = *(uint64_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
cmp64(emu, tmp64u2, tmp64u);
|
||||
} else {
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
tmp16u2 = *(uint16_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
cmp16(emu, tmp16u2, tmp16u);
|
||||
}
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
tmp16u2 = *(uint16_t*)R_RSI;
|
||||
R_RDI += tmp8s;
|
||||
R_RSI += tmp8s;
|
||||
cmp16(emu, tmp16u2, tmp16u);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA9: /* TEST AX,Iw */
|
||||
if(rex.w)
|
||||
test64(emu, R_RAX, F32S64);
|
||||
else
|
||||
test16(emu, R_AX, F16);
|
||||
test16(emu, R_AX, F16);
|
||||
break;
|
||||
|
||||
case 0xAB: /* (REP) STOSW */
|
||||
if(rex.w)
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-8:+8;
|
||||
else
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-2:+2;
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-2:+2;
|
||||
tmp64u = (rex.rep)?R_RCX:1L;
|
||||
if((rex.w))
|
||||
while(tmp64u) {
|
||||
#ifndef TEST_INTERPRETER
|
||||
*(uint64_t*)R_RDI = R_RAX;
|
||||
#endif
|
||||
R_RDI += tmp8s;
|
||||
--tmp64u;
|
||||
}
|
||||
else
|
||||
while(tmp64u) {
|
||||
#ifndef TEST_INTERPRETER
|
||||
*(uint16_t*)R_RDI = R_AX;
|
||||
#endif
|
||||
R_RDI += tmp8s;
|
||||
--tmp64u;
|
||||
}
|
||||
while(tmp64u) {
|
||||
#ifndef TEST_INTERPRETER
|
||||
*(uint16_t*)R_RDI = R_AX;
|
||||
#endif
|
||||
R_RDI += tmp8s;
|
||||
--tmp64u;
|
||||
}
|
||||
if(rex.rep)
|
||||
R_RCX = tmp64u;
|
||||
break;
|
||||
case 0xAD: /* (REP) LODSW */
|
||||
if(rex.w)
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-8:+8;
|
||||
else
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-2:+2;
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-2:+2;
|
||||
tmp64u = (rex.rep)?R_RCX:1L;
|
||||
if((rex.w))
|
||||
while(tmp64u) {
|
||||
R_RAX = *(uint64_t*)R_RSI;
|
||||
R_RSI += tmp8s;
|
||||
--tmp64u;
|
||||
}
|
||||
else
|
||||
while(tmp64u) {
|
||||
R_AX = *(uint16_t*)R_RSI;
|
||||
R_RSI += tmp8s;
|
||||
--tmp64u;
|
||||
}
|
||||
while(tmp64u) {
|
||||
R_AX = *(uint16_t*)R_RSI;
|
||||
R_RSI += tmp8s;
|
||||
--tmp64u;
|
||||
}
|
||||
if(rex.rep)
|
||||
R_RCX = tmp64u;
|
||||
break;
|
||||
|
||||
case 0xAF: /* (REPZ/REPNE) SCASW */
|
||||
if(rex.w)
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-8:+8;
|
||||
else
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-2:+2;
|
||||
tmp8s = ACCESS_FLAG(F_DF)?-2:+2;
|
||||
switch(rex.rep) {
|
||||
case 1:
|
||||
if(R_RCX) {
|
||||
if(rex.w) {
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp64u2 = *(uint64_t*)R_RDI;
|
||||
R_RDI += tmp8s;
|
||||
if(R_RAX==tmp64u2)
|
||||
break;
|
||||
}
|
||||
cmp64(emu, R_RAX, tmp64u2);
|
||||
} else {
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
R_RDI += tmp8s;
|
||||
if(R_AX==tmp16u)
|
||||
break;
|
||||
}
|
||||
cmp16(emu, R_AX, tmp16u);
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
R_RDI += tmp8s;
|
||||
if(R_AX==tmp16u)
|
||||
break;
|
||||
}
|
||||
cmp16(emu, R_AX, tmp16u);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(R_RCX) {
|
||||
if(rex.w) {
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp64u2 = *(uint64_t*)R_RDI;
|
||||
R_RDI += tmp8s;
|
||||
if(R_RAX!=tmp64u2)
|
||||
break;
|
||||
}
|
||||
cmp64(emu, R_RAX, tmp64u2);
|
||||
} else {
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
R_RDI += tmp8s;
|
||||
if(R_AX!=tmp16u)
|
||||
break;
|
||||
}
|
||||
cmp16(emu, R_AX, tmp16u);
|
||||
while(R_RCX) {
|
||||
--R_RCX;
|
||||
tmp16u = *(uint16_t*)R_RDI;
|
||||
R_RDI += tmp8s;
|
||||
if(R_AX!=tmp16u)
|
||||
break;
|
||||
}
|
||||
cmp16(emu, R_AX, tmp16u);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(rex.w)
|
||||
cmp64(emu, R_RAX, *(uint64_t*)R_RDI);
|
||||
else
|
||||
cmp16(emu, R_AX, *(uint16_t*)R_RDI);
|
||||
cmp16(emu, R_AX, *(uint16_t*)R_RDI);
|
||||
R_RDI += tmp8s;
|
||||
}
|
||||
break;
|
||||
@@ -718,10 +560,7 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
case 0xBD:
|
||||
case 0xBE:
|
||||
case 0xBF:
|
||||
if(rex.w)
|
||||
emu->regs[(opcode&7)+(rex.b<<3)].q[0] = F64;
|
||||
else
|
||||
emu->regs[(opcode&7)+(rex.b<<3)].word[0] = F16;
|
||||
emu->regs[(opcode&7)+(rex.b<<3)].word[0] = F16;
|
||||
break;
|
||||
|
||||
case 0xC1: /* GRP2 Ew,Ib */
|
||||
@@ -771,28 +610,15 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
nextop = F8;
|
||||
GETEW(0);
|
||||
tmp8u=(opcode==0xD3)?R_CL:1;
|
||||
if(rex.w) {
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: EW->q[0] = rol64(emu, EW->q[0], tmp8u); break;
|
||||
case 1: EW->q[0] = ror64(emu, EW->q[0], tmp8u); break;
|
||||
case 2: EW->q[0] = rcl64(emu, EW->q[0], tmp8u); break;
|
||||
case 3: EW->q[0] = rcr64(emu, EW->q[0], tmp8u); break;
|
||||
case 4:
|
||||
case 6: EW->q[0] = shl64(emu, EW->q[0], tmp8u); break;
|
||||
case 5: EW->q[0] = shr64(emu, EW->q[0], tmp8u); break;
|
||||
case 7: EW->q[0] = sar64(emu, EW->q[0], tmp8u); break;
|
||||
}
|
||||
} else {
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: EW->word[0] = rol16(emu, EW->word[0], tmp8u); break;
|
||||
case 1: EW->word[0] = ror16(emu, EW->word[0], tmp8u); break;
|
||||
case 2: EW->word[0] = rcl16(emu, EW->word[0], tmp8u); break;
|
||||
case 3: EW->word[0] = rcr16(emu, EW->word[0], tmp8u); break;
|
||||
case 4:
|
||||
case 6: EW->word[0] = shl16(emu, EW->word[0], tmp8u); break;
|
||||
case 5: EW->word[0] = shr16(emu, EW->word[0], tmp8u); break;
|
||||
case 7: EW->word[0] = sar16(emu, EW->word[0], tmp8u); break;
|
||||
}
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: EW->word[0] = rol16(emu, EW->word[0], tmp8u); break;
|
||||
case 1: EW->word[0] = ror16(emu, EW->word[0], tmp8u); break;
|
||||
case 2: EW->word[0] = rcl16(emu, EW->word[0], tmp8u); break;
|
||||
case 3: EW->word[0] = rcr16(emu, EW->word[0], tmp8u); break;
|
||||
case 4:
|
||||
case 6: EW->word[0] = shl16(emu, EW->word[0], tmp8u); break;
|
||||
case 5: EW->word[0] = shr16(emu, EW->word[0], tmp8u); break;
|
||||
case 7: EW->word[0] = sar16(emu, EW->word[0], tmp8u); break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -865,65 +691,36 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
case 0xF7: /* GRP3 Ew(,Iw) */
|
||||
nextop = F8;
|
||||
tmp8u = (nextop>>3)&7;
|
||||
if(rex.w) {
|
||||
GETED((tmp8u<2)?4:0);
|
||||
switch(tmp8u) {
|
||||
case 0:
|
||||
case 1: /* TEST Ed,Id */
|
||||
tmp64u = F32S64;
|
||||
test64(emu, ED->q[0], tmp64u);
|
||||
break;
|
||||
case 2: /* NOT Ed */
|
||||
ED->q[0] = not64(emu, ED->q[0]);
|
||||
break;
|
||||
case 3: /* NEG Ed */
|
||||
ED->q[0] = neg64(emu, ED->q[0]);
|
||||
break;
|
||||
case 4: /* MUL RAX,Ed */
|
||||
mul64_rax(emu, ED->q[0]);
|
||||
break;
|
||||
case 5: /* IMUL RAX,Ed */
|
||||
imul64_rax(emu, ED->q[0]);
|
||||
break;
|
||||
case 6: /* DIV Ed */
|
||||
div64(emu, ED->q[0]);
|
||||
break;
|
||||
case 7: /* IDIV Ed */
|
||||
idiv64(emu, ED->q[0]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch(tmp8u) {
|
||||
case 0:
|
||||
case 1: /* TEST Ew,Iw */
|
||||
GETEW(2);
|
||||
test16(emu, EW->word[0], F16);
|
||||
break;
|
||||
case 2: /* NOT Ew */
|
||||
GETEW(0);
|
||||
EW->word[0] = not16(emu, EW->word[0]);
|
||||
break;
|
||||
case 3: /* NEG Ew */
|
||||
GETEW(0);
|
||||
EW->word[0] = neg16(emu, EW->word[0]);
|
||||
break;
|
||||
case 4: /* MUL AX,Ew */
|
||||
GETEW(0);
|
||||
mul16(emu, EW->word[0]);
|
||||
break;
|
||||
case 5: /* IMUL AX,Ew */
|
||||
GETEW(0);
|
||||
imul16_eax(emu, EW->word[0]);
|
||||
break;
|
||||
case 6: /* DIV Ew */
|
||||
GETEW(0);
|
||||
div16(emu, EW->word[0]);
|
||||
break;
|
||||
case 7: /* IDIV Ew */
|
||||
GETEW(0);
|
||||
idiv16(emu, EW->word[0]);
|
||||
break;
|
||||
}
|
||||
switch(tmp8u) {
|
||||
case 0:
|
||||
case 1: /* TEST Ew,Iw */
|
||||
GETEW(2);
|
||||
test16(emu, EW->word[0], F16);
|
||||
break;
|
||||
case 2: /* NOT Ew */
|
||||
GETEW(0);
|
||||
EW->word[0] = not16(emu, EW->word[0]);
|
||||
break;
|
||||
case 3: /* NEG Ew */
|
||||
GETEW(0);
|
||||
EW->word[0] = neg16(emu, EW->word[0]);
|
||||
break;
|
||||
case 4: /* MUL AX,Ew */
|
||||
GETEW(0);
|
||||
mul16(emu, EW->word[0]);
|
||||
break;
|
||||
case 5: /* IMUL AX,Ew */
|
||||
GETEW(0);
|
||||
imul16_eax(emu, EW->word[0]);
|
||||
break;
|
||||
case 6: /* DIV Ew */
|
||||
GETEW(0);
|
||||
div16(emu, EW->word[0]);
|
||||
break;
|
||||
case 7: /* IDIV Ew */
|
||||
GETEW(0);
|
||||
idiv16(emu, EW->word[0]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xF8: /* CLC */
|
||||
|
||||
+17
-17
@@ -86,29 +86,29 @@ uintptr_t Run66DD(x64emu_t *emu, rex_t rex, uintptr_t addr)
|
||||
GETEW(0);
|
||||
fpu_loadenv(emu, (char*)ED, 1);
|
||||
// get the STx
|
||||
{
|
||||
char* p =(char*)ED;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
LD2D(p, &emu->x87[7-i].d);
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
{
|
||||
char* p =(char*)ED;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
LD2D(p, &ST(i).d);
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6: /* FNSAVE m94byte */
|
||||
GETEW(0);
|
||||
// ENV first...
|
||||
#ifndef TEST_INTERPRETER
|
||||
fpu_savenv(emu, (char*)ED, 1);
|
||||
// save the STx
|
||||
{
|
||||
char* p =(char*)ED;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
D2LD(&emu->x87[7-i].d, p);
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
{
|
||||
char* p =(char*)ED;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
D2LD(&ST(i).d, p);
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
reset_fpu(emu);
|
||||
break;
|
||||
|
||||
@@ -42,8 +42,43 @@ typedef struct vex_s {
|
||||
uint16_t p:2; //0: none, 1: 0x66, 2:0xF3, 3: 0xF2
|
||||
uint16_t v:4; // src register
|
||||
uint16_t m:5; // opcode map
|
||||
uint16_t evex:1; // was decoded from an EVEX prefix
|
||||
} vex_t;
|
||||
|
||||
static inline int FillVEXFromEVEX(vex_t* vex, rex_t rex, uint8_t p0, uint8_t p1, uint8_t p2)
|
||||
{
|
||||
uint8_t m = p0 & 0x0f;
|
||||
uint8_t l = (p2 >> 5) & 0x03;
|
||||
|
||||
if(rex.is32bits || rex.is66 || rex.isf0 || rex.rep)
|
||||
return 0;
|
||||
if(!(p1 & 0x04)) // EVEX P1 bit 2 is reserved and must be 1
|
||||
return 0;
|
||||
if(m != VEX_M_0F && m != VEX_M_0F38 && m != VEX_M_0F3A)
|
||||
return 0;
|
||||
if(l > 1) // no ZMM state yet
|
||||
return 0;
|
||||
if(!(p0 & 0x10)) // no high-16 destination register state yet
|
||||
return 0;
|
||||
if(!(p2 & 0x08)) // no high-16 NDS/VIDX register state yet
|
||||
return 0;
|
||||
if(p2 & 0x97) // z, b and aaa need opmask/broadcast/SAE handling
|
||||
return 0;
|
||||
|
||||
*vex = (vex_t){0};
|
||||
vex->rex = rex;
|
||||
vex->rex.b = (p0 & 0x20) ? 0 : 1;
|
||||
vex->rex.x = (p0 & 0x40) ? 0 : 1;
|
||||
vex->rex.r = (p0 & 0x80) ? 0 : 1;
|
||||
vex->rex.w = (p1 >> 7) & 1;
|
||||
vex->p = p1 & 0x03;
|
||||
vex->l = l;
|
||||
vex->v = ((~p1) >> 3) & 0x0f;
|
||||
vex->m = m;
|
||||
vex->evex = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// the op code definition can be found here: http://ref.x86asm.net/geek32.html
|
||||
|
||||
reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta);
|
||||
|
||||
+2
-1
@@ -106,7 +106,8 @@ uintptr_t RunAVX(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
|
||||
else addr = 0;
|
||||
|
||||
if(!addr)
|
||||
printf_log(LOG_INFO, "Unimplemented AVX opcode size %d prefix %s map %s opcode %02X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
|
||||
printf_log(LOG_INFO, "Unimplemented %s opcode size %d prefix %s map %s opcode %02X ",
|
||||
vex.evex ? "EVEX" : "AVX", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
|
||||
#endif
|
||||
|
||||
return addr;
|
||||
|
||||
+19
-19
@@ -124,30 +124,30 @@ uintptr_t RunDD(x64emu_t *emu, rex_t rex, uintptr_t addr)
|
||||
_GETED(0);
|
||||
fpu_loadenv(emu, (char*)ED, 0);
|
||||
// get the STx
|
||||
{
|
||||
char* p =(char*)ED;
|
||||
p += 28;
|
||||
for (int i=0; i<8; ++i) {
|
||||
LD2D(p, &emu->x87[7-i].d);
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
{
|
||||
char* p =(char*)ED;
|
||||
p += 28;
|
||||
for (int i=0; i<8; ++i) {
|
||||
LD2D(p, &ST(i).d);
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6: /* FNSAVE m108byte */
|
||||
_GETED(0);
|
||||
// ENV first...
|
||||
// warning, incomplete
|
||||
#ifndef TEST_INTERPRETER
|
||||
fpu_savenv(emu, (char*)ED, 0);
|
||||
// save the STx
|
||||
{
|
||||
char* p =(char*)ED;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
D2LD(&emu->x87[7-i].d, p);
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
fpu_savenv(emu, (char*)ED, 0);
|
||||
// save the STx
|
||||
{
|
||||
char* p =(char*)ED;
|
||||
p += 28;
|
||||
for (int i=0; i<8; ++i) {
|
||||
D2LD(&ST(i).d, p);
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
reset_fpu(emu);
|
||||
break;
|
||||
|
||||
+13
-13
@@ -1108,20 +1108,20 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
|
||||
GD->q[0] = native_lock_xchg_dd(ED, GD->q[0]);
|
||||
}
|
||||
} else {
|
||||
if((uintptr_t)ED&3) {
|
||||
// unaligned
|
||||
do {
|
||||
tmp32u = ED->dword[0] & 0xffffff00;
|
||||
tmp32u |= native_lock_read_b(ED);
|
||||
if((uintptr_t)ED&3) {
|
||||
// unaligned
|
||||
do {
|
||||
tmp32u = ED->dword[0] & 0xffffff00;
|
||||
tmp32u |= native_lock_read_b(ED);
|
||||
|
||||
} while(native_lock_write_b(ED, GD->byte[0]));
|
||||
ED->dword[0] = GD->dword[0];
|
||||
GD->dword[0] = tmp32u;
|
||||
} else {
|
||||
GD->dword[0] = native_lock_xchg_d(ED, GD->dword[0]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
} while(native_lock_write_b(ED, GD->byte[0]));
|
||||
ED->dword[0] = GD->dword[0];
|
||||
GD->q[0] = tmp32u;
|
||||
} else {
|
||||
GD->q[0] = native_lock_xchg_d(ED, GD->dword[0]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
GETED(0);
|
||||
GETGD;
|
||||
pthread_mutex_lock(&my_context->mutex_lock);
|
||||
|
||||
@@ -428,6 +428,7 @@ uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
|
||||
case 0xBB:
|
||||
case 0xBC: // this one is still BSR, not TZCNT
|
||||
case 0xBD: // and this one is still BSF, not LZCNT
|
||||
case 0xBF:
|
||||
case 0xC1:
|
||||
case 0xCD:
|
||||
#ifdef TEST_INTERPRETER
|
||||
|
||||
+31
-1
@@ -19,6 +19,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
@@ -40,6 +41,7 @@
|
||||
#include "x64tls.h"
|
||||
#include "elfloader.h"
|
||||
#include "x64int_private.h"
|
||||
#include "syscall_user_dispatch.h"
|
||||
|
||||
typedef struct x64_sigaction_s x64_sigaction_t;
|
||||
typedef struct x64_stack_s x64_stack_t;
|
||||
@@ -212,6 +214,9 @@ static const scwrap_t syscallwrap[] = {
|
||||
[112] = {__NR_setsid, 0},
|
||||
[113] = {__NR_setreuid, 2},
|
||||
[114] = {__NR_setregid, 2},
|
||||
#ifdef __NR_setgroups
|
||||
[116] = {__NR_setgroups, 2},
|
||||
#endif
|
||||
[118] = {__NR_getresuid, 3},
|
||||
[120] = {__NR_getresgid, 3},
|
||||
[121] = {__NR_getpgid, 1},
|
||||
@@ -488,7 +493,8 @@ static int clone_fn_syscall(void* arg)
|
||||
void EXPORT x64Syscall(x64emu_t *emu)
|
||||
{
|
||||
// check if it's a wine process, then filter the syscall (simulate SECCMP)
|
||||
if(box64_wine && !box64_is32bits) {
|
||||
// Wine uses SUD (syscall user dispatch) since 11.5, bypass this hack if SUD is effective
|
||||
if(box64_wine && !box64_is32bits && (!emu || !emu->sud_enabled)) {
|
||||
//64bits only here...
|
||||
uintptr_t ret_addr = R_RIP-2;
|
||||
if(/*ret_addr<0x700000000000LL &&*/ (my_context->signals[X64_SIGSYS]>2) && !FindElfAddress(my_context, ret_addr)) {
|
||||
@@ -519,6 +525,12 @@ void EXPORT x64Syscall_linux(x64emu_t *emu)
|
||||
if(!BOX64ENV(rolling_log))
|
||||
printf_log(LOG_NONE, "%s", buff);
|
||||
}
|
||||
if(my_syscall_user_dispatch(emu, R_RIP - 2, s, 0))
|
||||
return;
|
||||
if (s == 157 && R_EDI == PR_SET_SYSCALL_USER_DISPATCH) {
|
||||
S_RAX = my_syscall_user_dispatch_prctl(emu, R_RSI, R_RDX, R_R10, (void*)R_R8);
|
||||
return;
|
||||
}
|
||||
// check wrapper first
|
||||
uint32_t cnt = sizeof(syscallwrap) / sizeof(scwrap_t);
|
||||
if(s<cnt && syscallwrap[s].nats) {
|
||||
@@ -1011,6 +1023,14 @@ long EXPORT my_syscall(x64emu_t *emu)
|
||||
static uint32_t warned = 0;
|
||||
uint32_t s = R_EDI;
|
||||
printf_dump(LOG_DEBUG, "%04d| %p: Calling libc syscall 0x%02X (%d) %p %p %p %p %p\n", GetTID(), (void*)R_RIP, s, s, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
|
||||
if (s == 157 && S_ESI == PR_SET_SYSCALL_USER_DISPATCH) {
|
||||
long ret = my_syscall_user_dispatch_prctl(emu, R_RDX, R_RCX, R_R8, (void*)R_R9);
|
||||
if(ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// check wrapper first
|
||||
uint32_t cnt = sizeof(syscallwrap) / sizeof(scwrap_t);
|
||||
if(s<cnt && syscallwrap[s].nats) {
|
||||
@@ -1213,6 +1233,16 @@ long EXPORT my_syscall(x64emu_t *emu)
|
||||
case 133: // sys_mknod
|
||||
return mknod((void*)R_RSI, R_EDX, R_RCX);
|
||||
#endif
|
||||
case 157: // sys_prctl
|
||||
if (S_ESI == PR_SET_SYSCALL_USER_DISPATCH) {
|
||||
long ret = my_syscall_user_dispatch_prctl(emu, R_RDX, R_RCX, R_R8, (void*)R_R9);
|
||||
if(ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return syscall(__NR_prctl, S_ESI, R_RDX, R_RCX, R_R8, R_R9);
|
||||
case 158: // sys_arch_prctl
|
||||
return my_arch_prctl(emu, S_ESI, (void*)R_RDX);
|
||||
#ifndef __NR_setrlimit
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "callback.h"
|
||||
#include "signals.h"
|
||||
#include "x64tls.h"
|
||||
#include "syscall_user_dispatch.h"
|
||||
|
||||
|
||||
// Syscall table for x86_64 can be found
|
||||
@@ -233,6 +234,13 @@ void EXPORT x86Syscall(x64emu_t *emu)
|
||||
{
|
||||
uint32_t s = R_EAX;
|
||||
printf_log(LOG_DEBUG, "%p: Calling 32bits syscall 0x%02X (%d) %p %p %p %p %p", (void*)R_RIP, s, s, (void*)(uintptr_t)R_EBX, (void*)(uintptr_t)R_ECX, (void*)(uintptr_t)R_EDX, (void*)(uintptr_t)R_ESI, (void*)(uintptr_t)R_EDI);
|
||||
if(my_syscall_user_dispatch(emu, R_RIP - 2, s, 1))
|
||||
return;
|
||||
if(s == 172 && R_EBX == PR_SET_SYSCALL_USER_DISPATCH) {
|
||||
S_EAX = my_syscall_user_dispatch_prctl(emu, R_ECX, R_EDX, R_ESI, R_EDI ? (void*)(uintptr_t)R_EDI : NULL);
|
||||
printf_log(LOG_DEBUG, " => 0x%x\n", R_EAX);
|
||||
return;
|
||||
}
|
||||
// check wrapper first
|
||||
int cnt = sizeof(syscallwrap) / sizeof(scwrap_t);
|
||||
for (int i=0; i<cnt; i++) {
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "box32.h"
|
||||
#include "converter32.h"
|
||||
#include "custommem.h"
|
||||
#include "syscall_user_dispatch.h"
|
||||
|
||||
|
||||
// Syscall table for x86_64 can be found
|
||||
@@ -309,6 +310,13 @@ void EXPORT x86Syscall(x64emu_t *emu)
|
||||
{
|
||||
uint32_t s = R_EAX;
|
||||
printf_log(LOG_DEBUG, "%04d|%p: Calling 32bits syscall 0x%02X (%d) %p %p %p %p %p", GetTID(), (void*)R_RIP, s, s, (void*)(uintptr_t)R_EBX, (void*)(uintptr_t)R_ECX, (void*)(uintptr_t)R_EDX, (void*)(uintptr_t)R_ESI, (void*)(uintptr_t)R_EDI);
|
||||
if(my_syscall_user_dispatch(emu, R_RIP - 2, s, 1))
|
||||
return;
|
||||
if(s == 172 && R_EBX == PR_SET_SYSCALL_USER_DISPATCH) {
|
||||
S_EAX = my_syscall_user_dispatch_prctl(emu, R_ECX, R_EDX, R_ESI, R_EDI ? from_ptrv(R_EDI) : NULL);
|
||||
printf_log(LOG_DEBUG, " => 0x%x\n", R_EAX);
|
||||
return;
|
||||
}
|
||||
// check wrapper first
|
||||
int cnt = sizeof(syscallwrap) / sizeof(scwrap_t);
|
||||
void* tmp;
|
||||
@@ -560,6 +568,14 @@ uint32_t EXPORT my32_syscall(x64emu_t *emu, uint32_t s, ptr_t* b)
|
||||
{
|
||||
static uint64_t warned[10] = {0};
|
||||
printf_log(LOG_DEBUG, "%p: Calling libc syscall 0x%02X (%d) %p %p %p %p %p\n", from_ptrv(R_EIP), s, s, from_ptrv(u32(0)), from_ptrv(u32(4)), from_ptrv(u32(8)), from_ptrv(u32(12)), from_ptrv(u32(16)));
|
||||
if(s == 172 && u32(0) == PR_SET_SYSCALL_USER_DISPATCH) {
|
||||
long ret = my_syscall_user_dispatch_prctl(emu, u32(4), u32(8), u32(12), u32(16) ? p(16) : NULL);
|
||||
if(ret < 0) {
|
||||
errno = -ret;
|
||||
return (uint32_t)-1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// check wrapper first
|
||||
int cnt = sizeof(syscallwrap) / sizeof(scwrap_t);
|
||||
size_t tmps;
|
||||
|
||||
+12
-25
@@ -32,30 +32,18 @@ void reset_fpu(x64emu_t* emu)
|
||||
}
|
||||
|
||||
void fpu_fbst(x64emu_t* emu, uint8_t* d) {
|
||||
// very aproximative... but should not be much used...
|
||||
uint8_t p;
|
||||
uint8_t sign = 0x00;
|
||||
double tmp, v = ST0.d;
|
||||
if(ST0.d<0.0)
|
||||
{
|
||||
sign = 0x80;
|
||||
v = -v;
|
||||
uint64_t tmp = 0;
|
||||
uint8_t sign = signbit(ST0.d) ? 0x80 : 0x00;
|
||||
double v = fpu_round(emu, ST0.d);
|
||||
if (isfinite(v))
|
||||
tmp = llabs((int64_t)v);
|
||||
memset(d, 0, 10);
|
||||
for (int i = 0; i < 9 && tmp; ++i) {
|
||||
uint8_t digit = tmp % 100;
|
||||
d[i] = ((digit / 10) << 4) | (digit % 10);
|
||||
tmp /= 100;
|
||||
}
|
||||
for (int i=0; i<9; ++i) {
|
||||
tmp = floor(v/10.0);
|
||||
p = (v - 10.0*tmp);
|
||||
v = tmp;
|
||||
tmp = floor(v/10.0);
|
||||
p |= ((uint8_t)(v - 10.0*tmp))<<4;
|
||||
v = tmp;
|
||||
|
||||
*(d++)=p;
|
||||
}
|
||||
tmp = floor(v/10.0);
|
||||
p = (v - 10.0*tmp);
|
||||
p |= sign;
|
||||
*(d++)=p;
|
||||
// no flags....
|
||||
d[9] = sign;
|
||||
}
|
||||
|
||||
void fpu_fbld(x64emu_t* emu, uint8_t* s) {
|
||||
@@ -70,8 +58,7 @@ void fpu_fbld(x64emu_t* emu, uint8_t* s) {
|
||||
m *= 10;
|
||||
}
|
||||
ST0.d = tmp;
|
||||
p =*(s++);
|
||||
ST0.d += m * (p&0x0f);
|
||||
p = *(s++);
|
||||
if(p&0x80)
|
||||
ST0.d = -ST0.d;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ typedef struct box64context_s {
|
||||
char* box64path; // path of current box64 executable
|
||||
char* box86path; // path of box86 executable (if present)
|
||||
char* bashpath; // path of x86_64 bash (defined with BOX64_BASH or by running bash directly)
|
||||
char* pythonpath; // path of x86_64 python3 (defined with BOX64_PYTHON3)
|
||||
char* pythonpath; // path of python helper (defined with BOX64_PYTHON3 or box64-python)
|
||||
|
||||
uint64_t stacksz;
|
||||
size_t stackalign;
|
||||
@@ -183,12 +183,16 @@ typedef struct box64context_s {
|
||||
#endif
|
||||
uintptr_t max_db_size; // the biggest (in x86_64 instructions bytes) built dynablock
|
||||
rbtree_t* db_sizes;
|
||||
#define DB_ZOMBIE_SIZE 64
|
||||
struct dynablock_s* db_zombie[DB_ZOMBIE_SIZE]; // ring queue of invalidated blocks pending free
|
||||
int db_zombie_head; // next write slot (also the oldest slot when full)
|
||||
int db_zombie_count; // number of entries currently queued
|
||||
int trace_dynarec;
|
||||
pthread_mutex_t mutex_lock; // this is for the Test interpreter
|
||||
#if defined(__riscv) || defined(__loongarch64) || defined(__powerpc64__)
|
||||
#if defined(__riscv) || defined(__loongarch64) || defined(__powerpc64__)
|
||||
uint32_t mutex_16b;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
library_t *libclib; // shortcut to libc library (if loaded, so probably yes)
|
||||
library_t *sdl1mixerlib;
|
||||
@@ -283,6 +287,7 @@ int AddTLSPartition(box64context_t* context, int tlssize);
|
||||
// defined in fact in threads.c
|
||||
void thread_set_emu(x64emu_t* emu);
|
||||
void thread_forget_emu();
|
||||
x64emu_t* thread_get_emu_no_create(void);
|
||||
x64emu_t* thread_get_emu(void);
|
||||
|
||||
// relock the muxtex that were unlocked
|
||||
|
||||
@@ -30,19 +30,22 @@ size_t customGetUsableSize(void* p);
|
||||
#endif
|
||||
|
||||
#ifdef DYNAREC
|
||||
#include "dynacache.h"
|
||||
typedef struct dynablock_s dynablock_t;
|
||||
typedef struct mmaplist_s mmaplist_t;
|
||||
typedef struct DynaCacheBlock_s DynaCacheBlock_t;
|
||||
// custom protection flag to mark Page that are Write protected for Dynarec purpose
|
||||
uintptr_t AllocDynarecMap(uintptr_t x64_addr, size_t size, int is_new);
|
||||
void FreeDynarecMap(uintptr_t addr);
|
||||
mmaplist_t* NewMmaplist();
|
||||
void DelMmaplist(mmaplist_t* list);
|
||||
int MmaplistHasNew(mmaplist_t* list, int clear);
|
||||
int MmaplistIsDirty(mmaplist_t* list);
|
||||
int MmaplistNBlocks(mmaplist_t* list);
|
||||
void MmaplistFillBlocks(mmaplist_t* list, DynaCacheBlock_t* blocks);
|
||||
size_t MmaplistTotalAlloc(mmaplist_t* list);
|
||||
void MmaplistFillBlocks(mmaplist_t* list, CompressedDynaCacheBlock_t* blocks);
|
||||
void MmaplistAddNBlocks(mmaplist_t* list, int nblocks);
|
||||
int MmaplistAddBlock(mmaplist_t* list, int fd, off_t offset, void* orig, size_t size, intptr_t delta_map, uintptr_t mapping_start);
|
||||
int MmaplistAddCompressedBlock(mmaplist_t* list, int type, void* src, size_t src_size, void* orig, size_t size, intptr_t delta_map, uintptr_t mapping_start);
|
||||
|
||||
void addDBFromAddressRange(uintptr_t addr, size_t size);
|
||||
// Will return 1 if at least 1 db in the address range
|
||||
|
||||
@@ -12,13 +12,14 @@ void MarkCRCRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size);
|
||||
int FreeRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size);
|
||||
void FreeInvalidDynablock(dynablock_t* db, int need_lock);
|
||||
dynablock_t* InvalidDynablock(dynablock_t* db, int need_lock);
|
||||
void DeferFreeDynablockClearRange(void* addr, size_t sz);
|
||||
|
||||
dynablock_t* FindDynablockFromNativeAddress(void* addr); // defined in box64context.h
|
||||
|
||||
// Handling of Dynarec block (i.e. an exectable chunk of x64 translated code)
|
||||
dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits); // return NULL if block is not found / cannot be created. Don't create if create==0
|
||||
dynablock_t* DBSwapInvalid(x64emu_t* emu, dynablock_t* db, uintptr_t addr, int is32bits, int need_lock);
|
||||
dynablock_t* DBSwitchPrevious(x64emu_t* emu, dynablock_t* db, uintptr_t addr, int need_lock);
|
||||
dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int need_lock, int is32bits, int is_new);
|
||||
void FlushZombieDynablocks(void);
|
||||
|
||||
// for use in signal handler
|
||||
void cancelFillBlock(void);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef __DYNACACHE_H__
|
||||
#define __DYNACACHE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct mapping_s mapping_t;
|
||||
|
||||
#ifdef DYNAREC
|
||||
typedef struct blocklist_s blocklist_t;
|
||||
|
||||
typedef struct DynaCacheBlock_s {
|
||||
blocklist_t* block;
|
||||
size_t size;
|
||||
size_t free_size;
|
||||
} DynaCacheBlock_t;
|
||||
|
||||
#define COMP_NONE 0
|
||||
#define COMP_Z 1
|
||||
#define COMP_Z_MAX 2
|
||||
typedef struct CompressedDynaCacheBlock_s {
|
||||
DynaCacheBlock_t block;
|
||||
size_t compsize;
|
||||
uint8_t type;
|
||||
} CompressedDynaCacheBlock_t;
|
||||
|
||||
void SerializeMmaplist(mapping_t* mapping);
|
||||
void MmapDynaCache(mapping_t* mapping);
|
||||
#endif
|
||||
|
||||
void DynaCacheList(const char* filter);
|
||||
void DynaCacheClean();
|
||||
|
||||
#endif // __DYNACACHE_H__
|
||||
Loaded 100 of 331 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user