mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-05 13:42:00 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f963035133 | |||
| bf236de610 | |||
| 2025483ef3 | |||
| cc5c8635e5 | |||
| eda3fb776f | |||
| d72c2e90b9 | |||
| 6a6b64a83c | |||
| 94723686ea | |||
| cf1cf6b5f5 | |||
| 0a68665a7c | |||
| d06beb71a1 | |||
| 19852c453f | |||
| 9195b1ede4 | |||
| 04243947f1 | |||
| 63b08471ce | |||
| 33093c2207 | |||
| f2983604a1 | |||
| f51932477b | |||
| a0bb051641 | |||
| 494fe96308 | |||
| 391f69d70a | |||
| 968bc20e95 | |||
| 815325ccec |
+8
-18
@@ -24,20 +24,8 @@ include(CMakeDependentOption)
|
||||
include(CTest)
|
||||
include(CPMUtil)
|
||||
|
||||
if (NOT DEFINED ARCHITECTURE)
|
||||
message(FATAL_ERROR "Architecture didn't make it out of scope, did you delete DetectArchitecture.cmake?")
|
||||
endif()
|
||||
|
||||
# Needed for FFmpeg w/ VAAPI and DRM
|
||||
if (OPENBSD)
|
||||
# OpenBSD 7.8 broke libcxx when upgrading, so we must define the PSTL backend manually
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R6/lib")
|
||||
elseif (NETBSD)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R7/lib")
|
||||
if (CXX_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "14.0")
|
||||
message(FATAL_ERROR "GCC versions older than 14.0 are not supported. Update your system, or use clang/clang++ instead.")
|
||||
endif()
|
||||
|
||||
# NetBSD: Fun for the whole family!
|
||||
@@ -85,7 +73,7 @@ option(ENABLE_WERROR "Enable -Werror diagnostics" ON)
|
||||
# Lossless Scaling frame generation. Only Android.
|
||||
cmake_dependent_option(ENABLE_LSFG "Enable Lossless Scaling frame generation" ON "ANDROID" OFF)
|
||||
|
||||
option(ENABLE_RESHADE "Enable ReShade FX post-processing effects" ON)
|
||||
cmake_dependent_option(ENABLE_RESHADE "Enable ReShade FX post-processing effects" ON "WIN32 OR ANDROID OR APPLE OR LINUX OR FREEBSD" OFF)
|
||||
|
||||
# non-linux bundled qt are static
|
||||
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
||||
@@ -276,7 +264,7 @@ cmake_dependent_option(YUZU_USE_BUNDLED_MOLTENVK "Download bundled MoltenVK lib"
|
||||
option(YUZU_DISABLE_LLVM "Disable LLVM (useful for CI)" OFF)
|
||||
|
||||
set(DEFAULT_YUZU_USE_BUNDLED_OPENSSL OFF)
|
||||
if (EXT_DEFAULT OR SOLARIS OR OPENBSD)
|
||||
if (EXT_DEFAULT)
|
||||
set(DEFAULT_YUZU_USE_BUNDLED_OPENSSL ON)
|
||||
endif()
|
||||
|
||||
@@ -309,10 +297,12 @@ if (YUZU_ROOM)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT (LINUX OR WIN32))
|
||||
if(CXX_APPLE OR CXX_CLANG)
|
||||
if(CXX_APPLE OR (CXX_CLANG AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "20.0"))
|
||||
# libc++ has stop_token and jthread as experimental
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexperimental-library")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexperimental-library")
|
||||
elseif(CXX_CLANG)
|
||||
# New clang >=20.0, so do nothing
|
||||
else()
|
||||
# Uses glibc, mostly?
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCPP_ENABLE_EXPERIMENTAL=1")
|
||||
@@ -618,7 +608,7 @@ if (ENABLE_QT)
|
||||
|
||||
# Best practice is to ask for all components at once, so they are from the same version
|
||||
set(YUZU_QT_COMPONENTS Core Widgets Charts Concurrent Gui)
|
||||
if (LINUX OR FREEBSD)
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
list(APPEND YUZU_QT_COMPONENTS DBus)
|
||||
# yes Qt, we get it
|
||||
set(QT_NO_PRIVATE_MODULE_WARNING ON)
|
||||
|
||||
@@ -333,6 +333,11 @@
|
||||
"repo": "herumi/xbyak",
|
||||
"version": "v7.40.1"
|
||||
},
|
||||
"zbic": {
|
||||
"hash": "fbe2f37986377d7f0d96ae3224c80b5971df6e8b6961f68061f1975ebb2e8cb78f07b90f014b007be4023dbf5513581504e7f7d61a5237cb2a8a7a61ae11e482",
|
||||
"repo": "kinnay/zbic",
|
||||
"version": "11b08f2712264bbed731545085cbd9702096ceb7"
|
||||
},
|
||||
"zlib": {
|
||||
"hash": "16fea4df307a68cf0035858abe2fd550250618a97590e202037acd18a666f57afc10f8836cbbd472d54a0e76539d0e558cb26f059d53de52ff90634bbf4f47d4",
|
||||
"min_version": "1.2",
|
||||
|
||||
+11
-17
@@ -65,7 +65,7 @@ export LIBGL_ALWAYS_SOFTWARE=1
|
||||
|
||||
## OmniOS
|
||||
|
||||
Install `developer/gcc14` on OmniOS using pkgsrc.
|
||||
Install `developer/gcc15` on OmniOS using pkgsrc.
|
||||
|
||||
Since so many dependencies are missing on `OmniOS`, you may wish to use `-DCPMUTIL_FORCE_BUNDLED=ON` and `-DYUZU_USE_BUNDLED_OPENSSL=OFF`.
|
||||
|
||||
@@ -74,21 +74,15 @@ For OmniOS you are required to build glslang yourself:
|
||||
sudo pkg install python-313
|
||||
git clone --depth=1 https://github.com/KhronosGroup/glslang.git
|
||||
cd glslang
|
||||
python3.13 ./update_glslang_sources.py
|
||||
python3 ./update_glslang_sources.py
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build -- -j `nproc`
|
||||
cmake --build build -- -j`nproc`
|
||||
cmake --install build
|
||||
```
|
||||
|
||||
It may be tempting to specify `-t glslang`, but this will cause installation to fail. So don't.
|
||||
Use `gmake` to properly build all utilities. You require an X11 server, [this guide](https://web.archive.org/web/20260424200928/https://geekblood.wordpress.com/2017/10/26/installing-x11-and-a-desktop-environment-on-omnios/) details how to attain one, the links to pkgsrc on said guide [are better found here](https://pkgsrc.smartos.org/install-on-illumos/).
|
||||
|
||||
Using `--parallel` on CMake incorrectly passes `dmake ... -jn` instead of `dmake ... -j n`, this is a bug with OmniOS's CMake, it's recommended to not use this option until it's fixed.
|
||||
|
||||
You may also need to install `gmake` in order to properly build FFmpeg, this is provided by the `build-essential` package.
|
||||
|
||||
If it wasn't obvious already, you require a X11 server to properly run the emulator within OmniOS, [this guide](https://web.archive.org/web/20260424200928/https://geekblood.wordpress.com/2017/10/26/installing-x11-and-a-desktop-environment-on-omnios/) is a great starting point for that, the links to pkgsrc are outdated so follow [this exemplar](https://pkgsrc.smartos.org/install-on-illumos/) as well.
|
||||
|
||||
For Solaris based OSes, `${CMAKE_SYSTEM_NAME}` isn't properly set on CMake (it's set to i686 on AMD64), you may find issues when building OpenSSL from `openssl-cmake`.
|
||||
For Solaris based OSes, `${CMAKE_SYSTEM_PROCESSOR}` isn't properly set on CMake (it's set to i686 on AMD64, must be `amd64`), you may find issues when building OpenSSL from `openssl-cmake`.
|
||||
|
||||
## HaikuOS
|
||||
|
||||
@@ -108,6 +102,8 @@ If you have `quazip1_qt6_devel`, uninstall it. It may call `Core5Compat` on CMak
|
||||
|
||||
## OpenBSD
|
||||
|
||||
OpenSSL 4.0 is available via ports, needs to be pointed to directly via `-DOPENSSL_ROOT_DIR=/usr/local/include/eopenssl40`.
|
||||
|
||||
System boost doesn't have `context` (as of 7.8); so you may need to specify `-DYUZU_USE_CPM=ON -DBoost_FORCE_BUNDLED=ON`.
|
||||
|
||||
After configuration, you may need to modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`.
|
||||
@@ -147,15 +143,13 @@ System provides a default `g++-10` which doesn't support the current C++ codebas
|
||||
|
||||
Make may error out when generating C++ headers of SPIRV shaders, hence it's recommended to use `gmake` over the default system one.
|
||||
|
||||
[parallel/spirv-tools](https://iso.us.netbsd.org/pub/pkgsrc/current/pkgsrc/parallel/spirv-tools/index.html) isn't available in binary form and must be built from source.
|
||||
|
||||
glslang is not available on NetBSD, to circumvent this simply build glslang by yourself:
|
||||
If [parallel/spirv-tools](https://iso.us.netbsd.org/pub/pkgsrc/current/pkgsrc/parallel/spirv-tools/index.html) isn't available in binary, build from source:
|
||||
|
||||
```sh
|
||||
pkgin python313
|
||||
pkgin install python314
|
||||
git clone --depth=1 https://github.com/KhronosGroup/glslang.git
|
||||
cd glslang
|
||||
python3.13 ./update_glslang_sources.py
|
||||
python3.14 ./update_glslang_sources.py
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build -- -j`nproc`
|
||||
cmake --install build
|
||||
@@ -163,7 +157,7 @@ cmake --install build
|
||||
|
||||
However, pkgsrc is highly recommended, see [getting pkgsrc](https://iso.us.netbsd.org/pub/pkgsrc/current/pkgsrc/doc/pkgsrc.html#getting). You must get `current` not the `2025Q2` version.
|
||||
|
||||
`QtCore` on NetBSD is included, but due to misconfigurations(!) we MUST include one of the standard headers that include `bits/c++config.h`, since source_location (required by `QtCore`) isn't properly configured to intake `bits/c++config.h` (none of the experimental library is). This is a bug with NetBSD packaging and not our fault, but alas.
|
||||
`QtCore` on NetBSD is included, but due to misconfigurations you must include `bits/c++config.h`, since source_location (required by `QtCore`) isn't properly configured to intake `bits/c++config.h` (none of the experimental library is).
|
||||
|
||||
## DragonFlyBSD
|
||||
|
||||
|
||||
+3
-3
@@ -213,7 +213,7 @@ First, enable the community repository; [see here](https://wiki.alpinelinux.org/
|
||||
# Enable the community repository
|
||||
setup-apkrepos -c
|
||||
# Install
|
||||
apk add g++ git cmake make mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libquazip1-qt6 ffmpeg-dev qt6-charts-dev libusb-dev libtool boost-dev sdl3-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev opus-dev jq patch
|
||||
apk add g++ git cmake make mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libquazip1-qt6 ffmpeg-dev qt6-qtcharts-dev libusb-dev boost-dev sdl3-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev opus-dev enet-dev glslang libtool jq patch
|
||||
```
|
||||
|
||||
</details>
|
||||
@@ -286,7 +286,7 @@ pkgin install git cmake boost fmtlib SDL3 catch2 libjwt spirv-headers spirv-tool
|
||||
|
||||
```sh
|
||||
pkg_add -u
|
||||
pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl3 libusb1-1.0.29 quazip-qt6
|
||||
pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl3 libusb1-1.0.29 quazip-qt6 openssl-4.0.2v0
|
||||
```
|
||||
|
||||
[Caveats](./Caveats.md#openbsd).
|
||||
@@ -316,7 +316,7 @@ sudo pkg install git cmake qt6 boost glslang libzip library/lz4 libusb-1 nlohman
|
||||
<summary>OmniOS</summary>
|
||||
|
||||
```sh
|
||||
sudo pkgin install git cmake autoconf build-essential libusb-1 nasm gcc13
|
||||
sudo pkg install git cmake autoconf build-essential libusb-1 nasm gcc15 ffmpeg lz4 pkg-config unzip bash jq xsvc
|
||||
```
|
||||
|
||||
[Caveats](./Caveats.md#omnios).
|
||||
|
||||
Vendored
+1
-1
@@ -15,7 +15,7 @@
|
||||
## Cloning Eden with Git
|
||||
|
||||
```sh
|
||||
git clone --recursive https://git.eden-emu.dev/eden-emu/eden.git
|
||||
git clone --depth=1 https://git.eden-emu.dev/eden-emu/eden.git
|
||||
```
|
||||
|
||||
Eden by default will be cloned into:
|
||||
|
||||
Vendored
+5
@@ -48,6 +48,11 @@ if (NOT TARGET stb::headers)
|
||||
add_library(stb::headers ALIAS stb)
|
||||
endif()
|
||||
|
||||
AddJsonPackage(NAME zbic DOWNLOAD_ONLY)
|
||||
set(ZBIC_INCLUDE_DIR
|
||||
"${zbic_SOURCE_DIR}/src"
|
||||
PARENT_SCOPE)
|
||||
|
||||
# ItaniumDemangle (Windows only)
|
||||
if (WIN32 AND NOT TARGET LLVM::Demangle)
|
||||
add_library(demangle demangle/ItaniumDemangle.cpp)
|
||||
|
||||
@@ -137,6 +137,8 @@ add_library(
|
||||
uuid.cpp
|
||||
uuid.h
|
||||
vector_math.h
|
||||
zbic_compression.cpp
|
||||
zbic_compression.h
|
||||
zstd_compression.cpp
|
||||
zstd_compression.h
|
||||
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
|
||||
@@ -147,6 +149,10 @@ add_library(
|
||||
net/net.h net/net.cpp
|
||||
container/unordered_map.h container/unordered_set.h)
|
||||
|
||||
set_source_files_properties(zbic_compression.cpp PROPERTIES
|
||||
INCLUDE_DIRECTORIES "${ZBIC_INCLUDE_DIR}"
|
||||
COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:Clang,GNU>:-Wno-unused-function;-Wno-missing-declarations;-Wno-shadow>")
|
||||
|
||||
if(WIN32)
|
||||
target_sources(common PRIVATE windows/timer_resolution.cpp
|
||||
windows/timer_resolution.h)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "common/zbic_compression.h"
|
||||
|
||||
#define ZSTD_ZBIC_SUPPORT 1
|
||||
#define ZSTDLIB_VISIBLE static
|
||||
#define ZSTDLIB_HIDDEN static
|
||||
#define ZSTDERRORLIB_VISIBLE static
|
||||
#define ZSTDERRORLIB_HIDDEN static
|
||||
#undef ZSTD_MULTITHREAD
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#undef _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "zstd.h"
|
||||
#define g_ZSTD_threading_useless_symbol g_ZSTD_zbic_threading_useless_symbol
|
||||
#include "zstd.c"
|
||||
#undef g_ZSTD_threading_useless_symbol
|
||||
|
||||
namespace Common::Compression {
|
||||
|
||||
bool IsZBIC(std::span<const u8> src) {
|
||||
if (src.size() < sizeof(u32)) {
|
||||
return false;
|
||||
}
|
||||
u32 magic = 0;
|
||||
std::memcpy(&magic, src.data(), sizeof(u32));
|
||||
return magic == ZSTD_MAGICNUMBER; // 0x4349425A ("ZBIC")
|
||||
}
|
||||
|
||||
int DecompressDataZBIC(std::span<u8> dst, std::span<const u8> src) {
|
||||
if (dst.empty() || src.empty()) {
|
||||
return -1;
|
||||
}
|
||||
const size_t res = ZSTD_decompress(dst.data(), dst.size(), src.data(), src.size());
|
||||
if (ZSTD_isError(res)) {
|
||||
return -1;
|
||||
}
|
||||
return static_cast<int>(res);
|
||||
}
|
||||
|
||||
} // namespace Common::Compression
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Common::Compression {
|
||||
|
||||
[[nodiscard]] bool IsZBIC(std::span<const u8> src);
|
||||
|
||||
[[nodiscard]] int DecompressDataZBIC(std::span<u8> dst, std::span<const u8> src);
|
||||
|
||||
} // namespace Common::Compression
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/file_sys/vfs/vfs_types.h"
|
||||
|
||||
+31
-4
@@ -7,12 +7,14 @@
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/lz4_compression.h"
|
||||
#include "common/zbic_compression.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/core.h"
|
||||
@@ -104,11 +106,36 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
|
||||
for (std::size_t i = 0; i < nso_header.segments.size(); ++i) {
|
||||
nso_file.Read(compressed_data.data(), nso_header.segments_compressed_size[i], nso_header.segments[i].offset);
|
||||
if (nso_header.IsSegmentCompressed(i)) {
|
||||
int r = Common::Compression::DecompressDataLZ4(decompressed_size.data(), nso_header.segments[i].size, compressed_data.data(), nso_header.segments_compressed_size[i]);
|
||||
ASSERT(r == int(nso_header.segments[i].size));
|
||||
std::memcpy(codeset.memory.data() + module_start + nso_header.segments[i].location, decompressed_size.data(), nso_header.segments[i].size);
|
||||
if (nso_header.IsZBICCompressed()) {
|
||||
// ZBIC compression
|
||||
const int r = Common::Compression::DecompressDataZBIC(
|
||||
std::span<u8>{decompressed_size}.first(nso_header.segments[i].size),
|
||||
std::span<const u8>{compressed_data}.first(nso_header.segments_compressed_size[i])
|
||||
);
|
||||
ASSERT(r > 0);
|
||||
} else {
|
||||
// LZ4 compression
|
||||
int r = Common::Compression::DecompressDataLZ4(
|
||||
decompressed_size.data(),
|
||||
nso_header.segments[i].size,
|
||||
compressed_data.data(),
|
||||
nso_header.segments_compressed_size[i]
|
||||
);
|
||||
ASSERT(r == int(nso_header.segments[i].size));
|
||||
}
|
||||
|
||||
std::memcpy(
|
||||
codeset.memory.data() + module_start + nso_header.segments[i].location,
|
||||
decompressed_size.data(),
|
||||
nso_header.segments[i].size
|
||||
);
|
||||
} else {
|
||||
std::memcpy(codeset.memory.data() + module_start + nso_header.segments[i].location, compressed_data.data(), nso_header.segments[i].size);
|
||||
// Not compressed
|
||||
std::memcpy(
|
||||
codeset.memory.data() + module_start + nso_header.segments[i].location,
|
||||
compressed_data.data(),
|
||||
nso_header.segments[i].size
|
||||
);
|
||||
}
|
||||
codeset.segments[i].addr = module_start + nso_header.segments[i].location;
|
||||
codeset.segments[i].offset = module_start + nso_header.segments[i].location;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -58,6 +61,9 @@ struct NSOHeader {
|
||||
std::array<SHA256Hash, 3> segment_hashes;
|
||||
|
||||
bool IsSegmentCompressed(size_t segment_num) const;
|
||||
bool IsZBICCompressed() const {
|
||||
return ((flags >> 7) & 1) != 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(NSOHeader) == 0x100, "NSOHeader has incorrect size.");
|
||||
static_assert(std::is_trivially_copyable_v<NSOHeader>, "NSOHeader must be trivially copyable.");
|
||||
|
||||
@@ -201,7 +201,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
|
||||
|
||||
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
||||
ir_block.Reset(descriptor);
|
||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf);
|
||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
Optimization::Optimize(ir_block, conf, {});
|
||||
}
|
||||
|
||||
|
||||
@@ -366,7 +366,8 @@ A64AddressSpace::A64AddressSpace(const A64::UserConfig& conf)
|
||||
|
||||
void A64AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
||||
ir_block.Reset(descriptor);
|
||||
A64::Translate(ir_block, A64::LocationDescriptor{descriptor}, conf);
|
||||
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
|
||||
A64::Translate(ir_block, A64::LocationDescriptor{descriptor}, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||
Optimization::Optimize(ir_block, conf, {});
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
|
||||
}
|
||||
|
||||
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf);
|
||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
Optimization::Optimize(ir_block, conf, {.sha256 = true});
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
|
||||
}
|
||||
|
||||
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf);
|
||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
Optimization::Optimize(ir_block, conf, {});
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ private:
|
||||
// LocationDescriptor ctor() does important ops (like tflags) do not skip
|
||||
auto const arch_descriptor = A32::LocationDescriptor{descriptor};
|
||||
ir_block.Reset(arch_descriptor);
|
||||
A32::Translate(ir_block, arch_descriptor, conf);
|
||||
A32::Translate(ir_block, arch_descriptor, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
Optimization::Optimize(ir_block, conf, polyfill_options);
|
||||
return emitter.Emit(ir_block);
|
||||
}
|
||||
|
||||
@@ -254,10 +254,11 @@ private:
|
||||
block_of_code.EnsureMemoryCommitted(MINIMUM_REMAINING_CODESIZE);
|
||||
|
||||
// JIT Compile
|
||||
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
|
||||
// LocationDescriptor ctor() does important ops (like tflags) do not skip
|
||||
auto const arch_descriptor = A64::LocationDescriptor{descriptor};
|
||||
ir_block.Reset(arch_descriptor);
|
||||
A64::Translate(ir_block, arch_descriptor, conf);
|
||||
A64::Translate(ir_block, arch_descriptor, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||
Optimization::Optimize(ir_block, conf, polyfill_options);
|
||||
return emitter.Emit(ir_block).entrypoint;
|
||||
}
|
||||
|
||||
@@ -67,9 +67,7 @@
|
||||
#else
|
||||
# define CTX_SP (_UC_MACHINE_SP(ucontext))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ARCHITECTURE_arm64)
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
# if defined(__APPLE__)
|
||||
# define CTX_PC (mctx->__ss.__pc)
|
||||
# define CTX_SP (mctx->__ss.__sp)
|
||||
|
||||
@@ -9,16 +9,15 @@
|
||||
#include "dynarmic/frontend/A32/translate/a32_translate.h"
|
||||
|
||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||
#include "dynarmic/interface/A32/config.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf);
|
||||
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf);
|
||||
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) {
|
||||
return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(block, descriptor, conf);
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(block, descriptor, tcb, options);
|
||||
}
|
||||
|
||||
bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/interface/A32/arch_version.h"
|
||||
#include "dynarmic/interface/A32/config.h"
|
||||
|
||||
namespace Dynarmic::IR {
|
||||
class Block;
|
||||
@@ -21,14 +20,28 @@ namespace Dynarmic::A32 {
|
||||
class LocationDescriptor;
|
||||
struct TranslateCallbacks;
|
||||
|
||||
struct TranslationOptions {
|
||||
ArchVersion arch_version;
|
||||
|
||||
/// This changes what IR we emit when we translate an unpredictable instruction.
|
||||
/// If this is false, the ExceptionRaised IR instruction is emitted.
|
||||
/// If this is true, we define some behaviour for some instructions.
|
||||
bool define_unpredictable_behaviour = false;
|
||||
|
||||
/// This changes what IR we emit when we translate a hint instruction.
|
||||
/// If this is false, we treat the instruction as a NOP.
|
||||
/// If this is true, we emit an ExceptionRaised instruction.
|
||||
bool hook_hint_instructions = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* This function translates instructions in memory into our intermediate representation.
|
||||
* @param descriptor The starting location of the basic block. Includes information like PC, Thumb state, &c.
|
||||
* @param tcb The callbacks we should use to read emulated memory.
|
||||
* @param conf Configures how certain instructions are translated.
|
||||
* @param options Configures how certain instructions are translated.
|
||||
* @return A translated basic block in the intermediate representation.
|
||||
*/
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf);
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
||||
|
||||
/**
|
||||
* This function translates a single provided instruction into our intermediate representation.
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2016 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
@@ -13,7 +10,7 @@ namespace Dynarmic::A32 {
|
||||
|
||||
// BKPT #<imm16>
|
||||
bool TranslatorVisitor::arm_BKPT(Cond cond, Imm<12> /*imm12*/, Imm<4> /*imm4*/) {
|
||||
if (cond != Cond::AL && !conf.define_unpredictable_behaviour) {
|
||||
if (cond != Cond::AL && !options.define_unpredictable_behaviour) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
// UNPREDICTABLE: The instruction executes conditionally.
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/interface/A32/config.h"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
|
||||
#include "dynarmic/frontend/A32/a32_ir_emitter.h"
|
||||
@@ -26,14 +25,12 @@ enum class Exception;
|
||||
struct TranslatorVisitor final {
|
||||
using instruction_return_type = bool;
|
||||
|
||||
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf)
|
||||
: ir(block, descriptor, conf.arch_version)
|
||||
, conf(conf)
|
||||
{}
|
||||
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const TranslationOptions& options)
|
||||
: ir(block, descriptor, options.arch_version), options(options) {}
|
||||
|
||||
A32::IREmitter ir;
|
||||
ConditionalState cond_state = ConditionalState::None;
|
||||
A32::UserConfig const& conf;
|
||||
TranslationOptions options;
|
||||
|
||||
size_t current_instruction_size;
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2019 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
@@ -12,7 +9,7 @@
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
bool TranslatorVisitor::arm_PLD_imm(bool /*add*/, bool R, Reg /*n*/, Imm<12> /*imm12*/) {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,7 +18,7 @@ bool TranslatorVisitor::arm_PLD_imm(bool /*add*/, bool R, Reg /*n*/, Imm<12> /*i
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::arm_PLD_reg(bool /*add*/, bool R, Reg /*n*/, Imm<5> /*imm5*/, ShiftType /*shift*/, Reg /*m*/) {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -30,7 +27,7 @@ bool TranslatorVisitor::arm_PLD_reg(bool /*add*/, bool R, Reg /*n*/, Imm<5> /*im
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::arm_SEV() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,7 +35,7 @@ bool TranslatorVisitor::arm_SEV() {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::arm_SEVL() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,7 +43,7 @@ bool TranslatorVisitor::arm_SEVL() {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::arm_WFE() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -54,7 +51,7 @@ bool TranslatorVisitor::arm_WFE() {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::arm_WFI() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -62,7 +59,7 @@ bool TranslatorVisitor::arm_WFI() {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::arm_YIELD() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -642,7 +642,7 @@ bool TranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) {
|
||||
|
||||
// SEV<c>
|
||||
bool TranslatorVisitor::thumb16_SEV() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::SendEvent);
|
||||
@@ -650,7 +650,7 @@ bool TranslatorVisitor::thumb16_SEV() {
|
||||
|
||||
// SEVL<c>
|
||||
bool TranslatorVisitor::thumb16_SEVL() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::SendEventLocal);
|
||||
@@ -658,7 +658,7 @@ bool TranslatorVisitor::thumb16_SEVL() {
|
||||
|
||||
// WFE<c>
|
||||
bool TranslatorVisitor::thumb16_WFE() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::WaitForEvent);
|
||||
@@ -666,7 +666,7 @@ bool TranslatorVisitor::thumb16_WFE() {
|
||||
|
||||
// WFI<c>
|
||||
bool TranslatorVisitor::thumb16_WFI() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::WaitForInterrupt);
|
||||
@@ -674,7 +674,7 @@ bool TranslatorVisitor::thumb16_WFI() {
|
||||
|
||||
// YIELD<c>
|
||||
bool TranslatorVisitor::thumb16_YIELD() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::Yield);
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2021 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
@@ -11,7 +8,7 @@
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
static bool PLDHandler(TranslatorVisitor& v, bool W) {
|
||||
if (!v.conf.hook_hint_instructions) {
|
||||
if (!v.options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,7 +18,7 @@ static bool PLDHandler(TranslatorVisitor& v, bool W) {
|
||||
}
|
||||
|
||||
static bool PLIHandler(TranslatorVisitor& v) {
|
||||
if (!v.conf.hook_hint_instructions) {
|
||||
if (!v.options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,12 +22,10 @@
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) {
|
||||
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
const bool single_step = descriptor.SingleStepping();
|
||||
TranslatorVisitor visitor{block, descriptor, conf};
|
||||
TranslatorVisitor visitor{block, descriptor, options};
|
||||
bool should_continue = true;
|
||||
|
||||
auto tcb = conf.callbacks;
|
||||
do {
|
||||
const u32 arm_pc = visitor.ir.current_location.PC();
|
||||
u64 ticks_for_instruction = 1;
|
||||
|
||||
@@ -103,12 +103,10 @@ inline bool MaybeVFPOrASIMDInstruction(u32 thumb_instruction) noexcept {
|
||||
|
||||
} // namespace
|
||||
|
||||
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) {
|
||||
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
||||
const bool single_step = descriptor.SingleStepping();
|
||||
TranslatorVisitor visitor{block, descriptor, conf};
|
||||
TranslatorVisitor visitor{block, descriptor, options};
|
||||
bool should_continue = true;
|
||||
|
||||
auto tcb = conf.callbacks;
|
||||
do {
|
||||
const u32 arm_pc = visitor.ir.current_location.PC();
|
||||
u64 ticks_for_instruction = 1;
|
||||
|
||||
@@ -11,20 +11,19 @@
|
||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||
#include "dynarmic/frontend/A64/decoder/a64.h"
|
||||
#include "dynarmic/frontend/A64/translate/impl/impl.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
#include "dynarmic/ir/terminal.h"
|
||||
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf) {
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options) {
|
||||
const bool single_step = descriptor.SingleStepping();
|
||||
TranslatorVisitor visitor{block, descriptor, conf};
|
||||
TranslatorVisitor visitor{block, descriptor, std::move(options)};
|
||||
|
||||
bool should_continue = true;
|
||||
do {
|
||||
const u64 pc = visitor.ir.current_location->PC();
|
||||
if (const auto instruction = conf.callbacks->MemoryReadCode(pc)) {
|
||||
if (const auto instruction = memory_read_code(pc)) {
|
||||
if (auto decoder = Decode<TranslatorVisitor, bool>(visitor, *instruction)) {
|
||||
should_continue = *decoder;
|
||||
} else {
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <optional>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
|
||||
@@ -23,14 +22,32 @@ namespace A64 {
|
||||
|
||||
class LocationDescriptor;
|
||||
|
||||
using MemoryReadCodeFuncType = std::function<std::optional<u32>(u64 vaddr)>;
|
||||
|
||||
struct TranslationOptions {
|
||||
/// This changes what IR we emit when we translate an unpredictable instruction.
|
||||
/// If this is false, the ExceptionRaised IR instruction is emitted.
|
||||
/// If this is true, we define some behaviour for some instructions.
|
||||
bool define_unpredictable_behaviour = false;
|
||||
|
||||
/// This tells the translator a wall clock will be used, thus allowing it
|
||||
/// to avoid writting certain unnecessary code only needed for cycle timers.
|
||||
bool wall_clock_cntpct = false;
|
||||
|
||||
/// This changes what IR we emit when we translate a hint instruction.
|
||||
/// If this is false, we treat the instruction as a NOP.
|
||||
/// If this is true, we emit an ExceptionRaised instruction.
|
||||
bool hook_hint_instructions = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* This function translates instructions in memory into our intermediate representation.
|
||||
* @param descriptor The starting location of the basic block. Includes information like PC, FPCR state, &c.
|
||||
* @param memory_read_code The function we should use to read emulated memory.
|
||||
* @param conf Configures how certain instructions are translated.
|
||||
* @param options Configures how certain instructions are translated.
|
||||
* @return A translated basic block in the intermediate representation.
|
||||
*/
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf);
|
||||
void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options);
|
||||
|
||||
/**
|
||||
* This function translates a single provided instruction into our intermediate representation.
|
||||
|
||||
@@ -15,20 +15,17 @@
|
||||
#include "dynarmic/frontend/A64/a64_types.h"
|
||||
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
||||
#include "dynarmic/frontend/imm.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
struct TranslatorVisitor final {
|
||||
using instruction_return_type = bool;
|
||||
|
||||
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf)
|
||||
: ir(block, descriptor)
|
||||
, conf(conf)
|
||||
{}
|
||||
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, TranslationOptions options)
|
||||
: ir(block, descriptor), options(std::move(options)) {}
|
||||
|
||||
A64::IREmitter ir;
|
||||
A64::UserConfig const& conf;
|
||||
TranslationOptions options;
|
||||
|
||||
bool UnpredictableInstruction();
|
||||
bool DecodeError();
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2018 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
@@ -28,7 +25,7 @@ static bool ExclusiveSharedDecodeAndOperation(TranslatorVisitor& v, bool pair, s
|
||||
if (memop == IR::MemOp::LOAD && pair && Rt == *Rt2) {
|
||||
return v.UnpredictableInstruction();
|
||||
} else if (memop == IR::MemOp::STORE && (*Rs == Rt || (pair && *Rs == *Rt2))) {
|
||||
if (!v.conf.define_unpredictable_behaviour) {
|
||||
if (!v.options.define_unpredictable_behaviour) {
|
||||
return v.UnpredictableInstruction();
|
||||
}
|
||||
// UNPREDICTABLE: The Constraint_NONE case is executed.
|
||||
|
||||
@@ -42,35 +42,35 @@ bool TranslatorVisitor::NOP() {
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::YIELD() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::Yield);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::WFE() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::WaitForEvent);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::WFI() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::WaitForInterrupt);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SEV() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::SendEvent);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SEVL() {
|
||||
if (!conf.hook_hint_instructions) {
|
||||
if (!options.hook_hint_instructions) {
|
||||
return true;
|
||||
}
|
||||
return RaiseException(Exception::SendEventLocal);
|
||||
@@ -129,7 +129,7 @@ bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3
|
||||
return true;
|
||||
case SystemRegisterEncoding::CNTPCT_EL0:
|
||||
// HACK: Ensure that this is the first instruction in the block it's emitted in, so the cycle count is most up-to-date.
|
||||
if (!ir.block.instructions.empty() && !conf.wall_clock_cntpct) {
|
||||
if (!ir.block.instructions.empty() && !options.wall_clock_cntpct) {
|
||||
ir.block.CycleCount()--;
|
||||
ir.SetTerm(IR::Term::LinkBlock{*ir.current_location});
|
||||
return false;
|
||||
|
||||
@@ -180,7 +180,7 @@ static void RunInstance(size_t run_number, ThumbTestEnv& test_env, A32::UserConf
|
||||
while (num_insts < instructions_to_execute_count) {
|
||||
A32::LocationDescriptor descriptor = {u32(num_insts * 4), cpsr, A32::FPSCR{}};
|
||||
ir_block.Reset(descriptor);
|
||||
A32::Translate(ir_block, descriptor, config);
|
||||
A32::Translate(ir_block, descriptor, &test_env, {});
|
||||
Optimization::Optimize(ir_block, config, {});
|
||||
printf("\n\nIR:\n%s", IR::DumpBlock(ir_block).c_str());
|
||||
printf("\n\nx86_64:\n");
|
||||
|
||||
@@ -268,7 +268,7 @@ static void RunTestInstance(Dynarmic::A64::Jit& jit, A64Unicorn& uni, A64TestEnv
|
||||
// const auto get_code = [&jit_env](u64 vaddr) { return jit_env.MemoryReadCode(vaddr); };
|
||||
// const A64::LocationDescriptor location{instructions_start, FP::FPCR{fpcr}};
|
||||
// IR::Block ir_block{location};
|
||||
// A64::Translate(ir_block, location, config);
|
||||
// A64::Translate(ir_block, location, get_code, {});
|
||||
// fmt::print("IR:\n{}\n", IR::DumpBlock(ir_block));
|
||||
// Optimization::Optimize(ir_block, conf, {});
|
||||
// fmt::print("Optimized IR:\n{}\n", IR::DumpBlock(ir_block));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
@@ -92,7 +92,7 @@ if (ENABLE_OPENGL)
|
||||
target_compile_definitions(qt_common PUBLIC HAS_OPENGL)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
if (LINUX OR FREEBSD)
|
||||
if (DEFINED Qt6Gui_PRIVATE_INCLUDE_DIRS)
|
||||
target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
else()
|
||||
|
||||
@@ -43,26 +43,32 @@ namespace {
|
||||
switch (window_type) {
|
||||
case Core::Frontend::WindowSystemType::Headless:
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
case Core::Frontend::WindowSystemType::Windows:
|
||||
extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif defined(__APPLE__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
case Core::Frontend::WindowSystemType::Cocoa:
|
||||
extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif defined(__ANDROID__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
case Core::Frontend::WindowSystemType::Android:
|
||||
extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif defined(__HAIKU__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
case Core::Frontend::WindowSystemType::Xcb:
|
||||
extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#else
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
case Core::Frontend::WindowSystemType::X11:
|
||||
extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
case Core::Frontend::WindowSystemType::Wayland:
|
||||
extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "video_core/vulkan_common/vulkan_surface.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
#include "video_core/vulkan_common/vulkan.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
@@ -17,7 +18,7 @@ vk::SurfaceKHR CreateSurface(
|
||||
[[maybe_unused]] const vk::InstanceDispatch& dld = instance.Dispatch();
|
||||
VkSurfaceKHR unsafe_surface = VkSurfaceKHR{};
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Windows) {
|
||||
const HWND hWnd = static_cast<HWND>(window_info.render_surface);
|
||||
const VkWin32SurfaceCreateInfoKHR win32_ci{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
|
||||
@@ -30,7 +31,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Cocoa) {
|
||||
const VkMetalSurfaceCreateInfoEXT metal_ci = {
|
||||
.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT,
|
||||
@@ -45,7 +47,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#elif defined(__ANDROID__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Android) {
|
||||
const VkAndroidSurfaceCreateInfoKHR android_ci{
|
||||
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
||||
@@ -59,7 +62,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#elif defined(__HAIKU__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Xcb) {
|
||||
const VkXcbSurfaceCreateInfoKHR xcb_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
|
||||
@@ -76,7 +80,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::X11) {
|
||||
const VkXlibSurfaceCreateInfoKHR xlib_ci{
|
||||
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
||||
@@ -90,6 +95,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Wayland) {
|
||||
const VkWaylandSurfaceCreateInfoKHR wayland_ci{
|
||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
||||
@@ -105,7 +112,6 @@ vk::SurfaceKHR CreateSurface(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!unsafe_surface) {
|
||||
LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform");
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
|
||||
Reference in New Issue
Block a user