Compare commits

...

30 commits

Author SHA1 Message Date
349622eb55
[dynarmic] use better boost::visitor
Some checks failed
eden-license / license-header (pull_request) Failing after 37s
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
c0da47528d
[dynarmic] regalloc use scratchimpl that uses all instead of iteraiting
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
1e90bd0263
[dynarmic] Implement constant folding for CountLeadingZeros, add readXX constnat folding for A64
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
75d762dcd5
[dynarmic] unconditional branches always take
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
2c2d264744
[dynarmic] fix hardcoded AVX512 registers, use xmm0 instead of xmm16 to align with spec
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
1acfd78ca1
[dynarmic] checked code alignment
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
f8844aeb98
[dynarmic] remove use of mcl reverse iterator
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
1eb98ddb0d
[dynarmic, docs] fastmem docs
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
cf3d417ec7
[dynarmic, cmake][ remove unusd frontends var
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
39edeb4f63
[dynarmic] fix android
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
8010f9ba01
[dynarmic] use ARCHITECTURE_ macros instead of MCL ones
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:09:25 +00:00
c7a45c9637
[dynarmic] add back encoding names (for print_info)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:46 +00:00
b7b3fe52b2
[dynarmic] fix ASIMD execution
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:46 +00:00
f92a05a470
[dynarmic] fix tests
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:46 +00:00
5c6bc93ae2
[dynarmic] reduce matcher table noise and cache misses
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:46 +00:00
025c8a3a91
[dynarmic] (prolly makes MSVC crash) - use 128MiB code cache
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:46 +00:00
0b1e8b0405
[docs] fastmem draft
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:46 +00:00
de376aab34
[dynarmic] fix tests_reader and tests_generator
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:45 +00:00
59b6f4a734
[dynarmic] reduce use 2 bits for LRU and 4 bits for clog2 of bit size
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:45 +00:00
17a27f4c22
[dynarmic] use small vector experiment
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:45 +00:00
cdab6090ab
Fix license headers 2025-09-16 20:07:45 +00:00
dba760b564
[dynarmic] reduce opt pass latency
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:07:45 +00:00
3b3278f44b
[jit, exception] use shared mutex to reduce thread contention of cached code blocks in fastmem trap handler (#320)
ankerl::unordered_dense::map will provide better lookup times, theoretically.
fastmem trap handler usually had mutex contention for non-linkable series of blocks (block linking failures); so just use shared_mutex

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #320
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:54:00 +02:00
3ca0bde0e9
[core/nvnflinger] Rewrite GetBufferHistory (#528)
This rewrite should improve performance with the buffer history by changing the complexity level to O(1).
Replace std::vector with std::array to ensure that elements are allocated on the stack rather than on the free store.
Avoid expensive resizing at runtime.
Adjust buffer states at the right locations.
Tightly pack the BufferHistoryInfo struct to ensure that it only occupies 28 bytes.

Reviewed-on: #528
Co-authored-by: SDK-Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK-Chan <sdkchan@eden-emu.dev>
2025-09-16 19:41:52 +02:00
6699361b7e
[cmake] fix freebsd and openbsd, remove CPMUtil Eden copyright (#496)
CPMUtil is technically a completely separate project created and maintained solely by me, so it should actually be copyrighted to me

Reviewed-on: #496
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2025-09-16 18:44:19 +02:00
19036c59b5
[video_core] Simplify DMA options (#525)
This simplifies DMA options in a clearer and more objective way.

Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Reviewed-on: #525
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-09-16 18:42:48 +02:00
80dfc3d76f
[fs] Remove remaining files from NCA bypass (#495)
Fix Android build after PR 94.

Reviewed-on: #495
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-09-15 17:47:19 +02:00
f4386423e8
[qt] refactor: qt_common lib (#94)
This is part of a series of PRs made in preparation for the QML rewrite. this PR specifically moves a bunch of utility functions from main.cpp into qt_common, with the biggest benefit being that QML can reuse the exact same code through ctx passthrough.

Also, QtCommon::Frontend is an abstraction layer over several previously Widgets-specific stuff like QMessageBox that gets used everywhere. The idea is that once QML is implemented, these functions can have a Quick version implemented for systems that don't work well with Widgets (sun) or for those on Plasma 6+ (reduces memory usage w/o Widgets linkage) although Quick from C++ is actually anal, but whatever.

Other than that this should also just kinda reduce the size of main.cpp which is a 6000-line behemoth rn, and clangd straight up gives up with it for me (likely caused by the massive amount of headers, which this DOES reduce).

In the future, I probably want to create a common strings lookup table that both Qt and QML can reference--though I'm not sure how much linguist likes that--which should give us a way to keep language consistent (use frozen-map).

TODO: Docs for Qt stuff

Co-authored-by: MaranBr <maranbr@outlook.com>
Reviewed-on: #94
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2025-09-15 17:21:18 +02:00
4c5d03f5de
[android / GameUI] Add grid compact layout and fix ugly borders on grid layout (#401)
Tis PR adds a new layout for the Game Adapter with shorter cards and fixes the ugly borders in Game Adapter's Grid layout.

Reviewed-on: #401
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Nixyn <contact@innix.space>
Co-committed-by: Nixyn <contact@innix.space>
2025-09-15 06:26:06 +02:00
d207df959a
[cmake, core] refactor: update mbedtls and make YUZU_USE_CPM better (#485)
update mbedtls functors to support mbedtls3 signatures

moved some vulkan stuff from externals to root, yuzu_use_cpm manages
them now

needs testing:
- all key/derivation related things
- nca verification
- game loading/updates/stuff

Reviewed-on: #485
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2025-09-15 04:22:15 +02:00
225 changed files with 5187 additions and 4737 deletions

View file

@ -5,10 +5,13 @@ HEADER_HASH="$(cat "$PWD/.ci/license/header-hash.txt")"
echo "Getting branch changes"
BRANCH=`git rev-parse --abbrev-ref HEAD`
COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"`
RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}"
FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r`
# BRANCH=`git rev-parse --abbrev-ref HEAD`
# COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"`
# RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}"
# FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r`
BASE=`git merge-base master HEAD`
FILES=`git diff --name-only $BASE`
#FILES=$(git diff --name-only master)

View file

@ -44,6 +44,13 @@ if (PLATFORM_SUN)
endif()
endif()
# Needed for FFmpeg w/ VAAPI and DRM
if (PLATFORM_OPENBSD)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/X11R6/include")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/X11R6/include")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/X11R6/lib")
endif()
# Detect current compilation architecture and create standard definitions
# =======================================================================
@ -88,7 +95,7 @@ message(STATUS "Target architecture: ${ARCHITECTURE}")
if (MSVC AND ARCHITECTURE_x86)
message(FATAL_ERROR "Attempting to build with the x86 environment is not supported. \
This can typically happen if you used the Developer Command Prompt from the start menu;\
This can typically happen if you used the Developer Command Prompt from the start menu; \
instead, run vcvars64.bat directly, located at C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat")
endif()
@ -122,7 +129,7 @@ include(CMakeDependentOption)
include(CTest)
# Disable Warnings as Errors for MSVC
if (CXX_CL)
if (MSVC AND NOT CXX_CLANG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-")
endif()
@ -159,8 +166,6 @@ option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
option(ENABLE_WIFI_SCAN "Enable WiFi scanning" OFF)
option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan Utility Headers from externals" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS "Use SPIRV-Tools from externals" ${EXT_DEFAULT})
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
@ -172,8 +177,6 @@ option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
CMAKE_DEPENDENT_OPTION(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF "ENABLE_QT" OFF)
option(ENABLE_MICROPROFILE "Enables microprofile capabilities" OFF)
option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}")
option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ${EXT_DEFAULT})
@ -455,6 +458,28 @@ if (YUZU_USE_CPM)
)
endif()
endif()
# VulkanUtilityHeaders - pulls in headers and utility libs
AddJsonPackage(vulkan-utility-headers)
# small hack
if (NOT VulkanUtilityLibraries_ADDED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
endif()
# SPIRV Headers
AddJsonPackage(spirv-headers)
# SPIRV Tools
AddJsonPackage(spirv-tools)
if (SPIRV-Tools_ADDED)
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools-static)
target_link_libraries(SPIRV-Tools-static PRIVATE SPIRV-Tools-opt SPIRV-Tools-link)
endif()
# mbedtls
AddJsonPackage(mbedtls)
else()
# Enforce the search mode of non-required packages for better and shorter failure messages
find_package(fmt 8 REQUIRED)
@ -467,7 +492,32 @@ else()
find_package(Opus 1.3 MODULE REQUIRED)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED MODULE)
find_package(Boost 1.79.0 REQUIRED headers context system fiber)
# wow
if (PLATFORM_LINUX)
find_package(Boost 1.57.0 REQUIRED headers context system fiber)
else()
find_package(Boost 1.57.0 REQUIRED)
endif()
# OpenBSD does not package mbedtls3 (only 2)
if (PLATFORM_OPENBSD)
AddJsonPackage(mbedtls)
else()
find_package(MbedTLS 3 REQUIRED)
endif()
find_package(VulkanUtilityLibraries REQUIRED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
# FreeBSD does not package spirv-headers
if (PLATFORM_FREEBSD)
AddJsonPackage(spirv-headers)
else()
find_package(SPIRV-Headers 1.3.274 REQUIRED)
endif()
find_package(SPIRV-Tools MODULE REQUIRED)
if (YUZU_TESTS)
find_package(Catch2 3.0.1 REQUIRED)
@ -594,10 +644,8 @@ endfunction()
add_subdirectory(externals)
# pass targets from externals
find_package(VulkanUtilityLibraries)
find_package(libusb)
find_package(VulkanMemoryAllocator)
find_package(SPIRV-Tools)
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
find_package(xbyak)

View file

@ -1,17 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
# Created-By: crueter
# Docs will come at a later date, mostly this is to just reduce boilerplate
# and some cmake magic to allow for runtime viewing of dependency versions
# Future crueter: Wow this was a lie and a half, at this point I might as well make my own CPN
# haha just kidding... unless?
# TODO(crueter): Remember to get more than 6 hours of sleep whenever making giant cmake changes
if (MSVC OR ANDROID)
set(BUNDLED_DEFAULT ON)
else()
@ -27,6 +16,7 @@ option(CPMUTIL_FORCE_SYSTEM
cmake_minimum_required(VERSION 3.22)
include(CPM)
# cpmfile parsing
set(CPMUTIL_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json")
if (EXISTS ${CPMUTIL_JSON_FILE})
@ -35,12 +25,11 @@ else()
message(WARNING "[CPMUtil] cpmfile ${CPMUTIL_JSON_FILE} does not exist, AddJsonPackage will be a no-op")
endif()
# utility
# Utility stuff
function(cpm_utils_message level name message)
message(${level} "[CPMUtil] ${name}: ${message}")
endfunction()
# utility
function(array_to_list array length out)
math(EXPR range "${length} - 1")
@ -53,7 +42,6 @@ function(array_to_list array length out)
set("${out}" "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# utility
function(get_json_element object out member default)
string(JSON out_type ERROR_VARIABLE err TYPE "${object}" ${member})
@ -73,14 +61,13 @@ function(get_json_element object out member default)
set("${out}" "${outvar}" PARENT_SCOPE)
endfunction()
# Kinda cancerous but whatever
# The preferred usage
function(AddJsonPackage)
set(oneValueArgs
NAME
# these are overrides that can be generated at runtime, so can be defined separately from the json
DOWNLOAD_ONLY
SYSTEM_PACKAGE
BUNDLED_PACKAGE
)
@ -90,6 +77,7 @@ function(AddJsonPackage)
"${ARGN}")
list(LENGTH ARGN argnLength)
# single name argument
if(argnLength EQUAL 1)
set(JSON_NAME "${ARGV0}")
@ -199,7 +187,6 @@ function(AddJsonPackage)
endif()
set(options ${options} ${JSON_OPTIONS})
# end options
# system/bundled
@ -241,7 +228,7 @@ endfunction()
function(AddPackage)
cpm_set_policies()
# TODO(crueter): docs, git clone
# TODO(crueter): git clone?
#[[
URL configurations, descending order of precedence:

View file

@ -1,17 +0,0 @@
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
include(FindPackageHandleStandardArgs)
find_package(PkgConfig QUIET)
pkg_search_module(mbedtls QUIET IMPORTED_TARGET mbedtls)
find_package_handle_standard_args(mbedtls
REQUIRED_VARS mbedtls_LINK_LIBRARIES
VERSION_VAR mbedtls_VERSION
)
pkg_search_module(mbedcrypto QUIET IMPORTED_TARGET mbedcrypto)
find_package_handle_standard_args(mbedcrypto
REQUIRED_VARS mbedcrypto_LINK_LIBRARIES
VERSION_VAR mbedcrypto_VERSION
)

View file

@ -91,6 +91,42 @@
"OPUS_PRESUME_NEON ON"
]
},
"vulkan-utility-headers": {
"package": "VulkanUtilityLibraries",
"repo": "scripts/VulkanUtilityHeaders",
"tag": "1.4.326",
"artifact": "VulkanUtilityHeaders.tar.zst",
"git_host": "git.crueter.xyz",
"hash": "5924629755cb1605c4aa4eee20ef7957a9dd8d61e4df548be656d98054f2730c4109693c1bd35811f401f4705d2ccff9fc849be32b0d8480bc3f73541a5e0964"
},
"spirv-tools": {
"package": "SPIRV-Tools",
"repo": "KhronosGroup/SPIRV-Tools",
"sha": "40eb301f32",
"hash": "58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa",
"find_args": "MODULE",
"options": [
"SPIRV_SKIP_EXECUTABLES ON"
]
},
"spirv-headers": {
"package": "SPIRV-Headers",
"repo": "KhronosGroup/SPIRV-Headers",
"sha": "4e209d3d7e",
"hash": "f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4",
"options": [
"SPIRV_WERROR OFF"
]
},
"mbedtls": {
"package": "MbedTLS",
"repo": "Mbed-TLS/mbedtls",
"tag": "mbedtls-%VERSION%",
"hash": "6671fb8fcaa832e5b115dfdce8f78baa6a4aea71f5c89a640583634cdee27aefe3bf4be075744da91f7c3ae5ea4e0c765c8fc3937b5cfd9ea73d87ef496524da",
"version": "3",
"git_version": "3.6.4",
"artifact": "%TAG%.tar.bz2"
},
"cubeb": {
"repo": "mozilla/cubeb",
"sha": "fa02160712",

View file

@ -245,6 +245,6 @@ include(CPMUtil)
Currently, `cpm-fetch.sh` defines the following directories for cpmfiles (max depth of 2, so subdirs are caught as well):
`externals src/yuzu src/dynarmic .`
`externals src/qt_common src/dynarmic .`
Whenever you add a new cpmfile, update the script accordingly

View file

@ -54,36 +54,27 @@ endif()
# Glad
add_subdirectory(glad)
# mbedtls
AddJsonPackage(mbedtls)
if (mbedtls_ADDED)
target_include_directories(mbedtls PUBLIC ${mbedtls_SOURCE_DIR}/include)
if (NOT MSVC)
target_compile_options(mbedcrypto PRIVATE
-Wno-unused-but-set-variable
-Wno-string-concatenation
)
elseif(CXX_CLANG)
foreach(TARGET mbedtls mbedcrypto mbedx509)
target_compile_options(${TARGET} PRIVATE
-w
)
endforeach()
endif()
endif()
# libusb
if (ENABLE_LIBUSB)
add_subdirectory(libusb)
endif()
# Sirit
# TODO(crueter): spirv-tools doesn't work w/ system
set(SPIRV_WERROR OFF)
AddJsonPackage(spirv-headers)
# VMA
AddJsonPackage(vulkan-memory-allocator)
if (VulkanMemoryAllocator_ADDED)
if (CXX_CLANG)
target_compile_options(VulkanMemoryAllocator INTERFACE
-Wno-unused-variable
)
elseif(MSVC)
target_compile_options(VulkanMemoryAllocator INTERFACE
/wd4189
)
endif()
endif()
# Sirit
AddJsonPackage(sirit)
if(MSVC AND USE_CCACHE AND sirit_ADDED)
@ -117,46 +108,9 @@ if (YUZU_USE_BUNDLED_FFMPEG)
set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
endif()
# VulkanUtilityHeaders - pulls in headers and utility libs
AddJsonPackage(
NAME vulkan-utility-headers
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES}
)
# small hack
if (NOT VulkanUtilityLibraries_ADDED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
endif()
# SPIRV Tools
AddJsonPackage(
NAME spirv-tools
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS}
)
if (SPIRV-Tools_ADDED)
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools-static)
target_link_libraries(SPIRV-Tools-static PRIVATE SPIRV-Tools-opt SPIRV-Tools-link)
endif()
# TZDB (Time Zone Database)
add_subdirectory(nx_tzdb)
# VMA
AddJsonPackage(vulkan-memory-allocator)
if (VulkanMemoryAllocator_ADDED)
if (CXX_CLANG)
target_compile_options(VulkanMemoryAllocator INTERFACE
-Wno-unused-variable
)
elseif(MSVC)
target_compile_options(VulkanMemoryAllocator INTERFACE
/wd4189
)
endif()
endif()
if (NOT TARGET LLVM::Demangle)
add_library(demangle demangle/ItaniumDemangle.cpp)
target_include_directories(demangle PUBLIC ./demangle)

View file

@ -1,15 +1,10 @@
{
"mbedtls": {
"repo": "eden-emulator/mbedtls",
"sha": "ce4f81f4a9",
"hash": "f2e7f887651b28745e508149214d409fd7cfdb92cb94b4146b47ff1e0fc09e47143f203ac18e34c2c1814b5bd031d04c74828676c0d4342920a2ddb7fd35e9a5",
"find_args": "MODULE"
},
"spirv-headers": {
"package": "SPIRV-Headers",
"repo": "KhronosGroup/SPIRV-Headers",
"sha": "4e209d3d7e",
"hash": "f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4"
"vulkan-memory-allocator": {
"package": "VulkanMemoryAllocator",
"repo": "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator",
"sha": "1076b348ab",
"hash": "a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772",
"find_args": "CONFIG"
},
"sirit": {
"repo": "eden-emulator/sirit",
@ -35,31 +30,6 @@
"CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF"
]
},
"vulkan-utility-headers": {
"package": "VulkanUtilityLibraries",
"repo": "scripts/VulkanUtilityHeaders",
"tag": "1.4.326",
"artifact": "VulkanUtilityHeaders.tar.zst",
"git_host": "git.crueter.xyz",
"hash": "5924629755cb1605c4aa4eee20ef7957a9dd8d61e4df548be656d98054f2730c4109693c1bd35811f401f4705d2ccff9fc849be32b0d8480bc3f73541a5e0964"
},
"vulkan-memory-allocator": {
"package": "VulkanMemoryAllocator",
"repo": "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator",
"sha": "1076b348ab",
"hash": "a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772",
"find_args": "CONFIG"
},
"spirv-tools": {
"package": "SPIRV-Tools",
"repo": "KhronosGroup/SPIRV-Tools",
"sha": "40eb301f32",
"hash": "58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa",
"find_args": "MODULE",
"options": [
"SPIRV_SKIP_EXECUTABLES ON"
]
},
"xbyak_sun": {
"package": "xbyak",
"repo": "herumi/xbyak",

View file

@ -1,14 +1,29 @@
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2020 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
include(CPMUtil)
AddJsonPackage(libusb)
# we love our libraries don't we folks
if (PLATFORM_SUN)
set(libusb_bundled ON)
else()
set(libusb_bundled OFF)
endif()
# TODO(crueter): Fix on Solaris
AddJsonPackage(
NAME libusb
BUNDLED_PACKAGE ${libusb_bundled}
)
if (NOT libusb_ADDED)
return()
endif()
# TODO: *BSD fails to compile--may need different configs/symbols
if (MINGW OR PLATFORM_LINUX OR APPLE)
set(LIBUSB_FOUND ON CACHE BOOL "libusb is present" FORCE)
set(LIBUSB_VERSION "1.0.24" CACHE STRING "libusb version string" FORCE)

View file

@ -234,6 +234,8 @@ if (YUZU_ROOM_STANDALONE)
endif()
if (ENABLE_QT)
add_definitions(-DYUZU_QT_WIDGETS)
add_subdirectory(qt_common)
add_subdirectory(yuzu)
endif()

View file

@ -36,17 +36,18 @@ import androidx.core.net.toUri
import androidx.core.content.edit
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.databinding.CardGameGridCompactBinding
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.utils.NativeConfig
class GameAdapter(private val activity: AppCompatActivity) :
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
companion object {
const val VIEW_TYPE_GRID = 0
const val VIEW_TYPE_LIST = 1
const val VIEW_TYPE_CAROUSEL = 2
const val VIEW_TYPE_GRID_COMPACT = 1
const val VIEW_TYPE_LIST = 2
const val VIEW_TYPE_CAROUSEL = 3
}
private var viewType = 0
@ -80,6 +81,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
listBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
listBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
}
VIEW_TYPE_GRID -> {
val gridBinding = holder.binding as CardGameGridBinding
gridBinding.cardGameGrid.scaleX = 1f
@ -89,6 +91,17 @@ class GameAdapter(private val activity: AppCompatActivity) :
gridBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
}
VIEW_TYPE_GRID_COMPACT -> {
val gridCompactBinding = holder.binding as CardGameGridCompactBinding
gridCompactBinding.cardGameGridCompact.scaleX = 1f
gridCompactBinding.cardGameGridCompact.scaleY = 1f
gridCompactBinding.cardGameGridCompact.alpha = 1f
// Reset layout params to XML defaults (same as normal grid)
gridCompactBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
gridCompactBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
}
VIEW_TYPE_CAROUSEL -> {
val carouselBinding = holder.binding as CardGameCarouselBinding
// soothens transient flickering
@ -105,16 +118,25 @@ class GameAdapter(private val activity: AppCompatActivity) :
parent,
false
)
VIEW_TYPE_GRID -> CardGameGridBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
VIEW_TYPE_GRID_COMPACT -> CardGameGridCompactBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
VIEW_TYPE_CAROUSEL -> CardGameCarouselBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
else -> throw IllegalArgumentException("Invalid view type")
}
return GameViewHolder(binding, viewType)
@ -130,6 +152,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
VIEW_TYPE_LIST -> bindListView(model)
VIEW_TYPE_GRID -> bindGridView(model)
VIEW_TYPE_CAROUSEL -> bindCarouselView(model)
VIEW_TYPE_GRID_COMPACT -> bindGridCompactView(model)
}
}
@ -168,6 +191,23 @@ class GameAdapter(private val activity: AppCompatActivity) :
gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
}
private fun bindGridCompactView(model: Game) {
val gridCompactBinding = binding as CardGameGridCompactBinding
gridCompactBinding.imageGameScreenCompact.scaleType = ImageView.ScaleType.CENTER_CROP
GameIconUtils.loadGameIcon(model, gridCompactBinding.imageGameScreenCompact)
gridCompactBinding.textGameTitleCompact.text = model.title.replace("[\\t\\n\\r]+".toRegex(), " ")
gridCompactBinding.textGameTitleCompact.marquee()
gridCompactBinding.cardGameGridCompact.setOnClickListener { onClick(model) }
gridCompactBinding.cardGameGridCompact.setOnLongClickListener { onLongClick(model) }
// Reset layout params to XML defaults (same as normal grid)
gridCompactBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
gridCompactBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
}
private fun bindCarouselView(model: Game) {
val carouselBinding = binding as CardGameCarouselBinding
@ -232,8 +272,6 @@ class GameAdapter(private val activity: AppCompatActivity) :
binding.root.findNavController().navigate(action)
}
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
if (NativeLibrary.gameRequiresFirmware(game.programId) && !NativeLibrary.isFirmwareAvailable()) {
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.loader_requires_firmware)
@ -248,23 +286,6 @@ class GameAdapter(private val activity: AppCompatActivity) :
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
} else if (BooleanSetting.DISABLE_NCA_VERIFICATION.getBoolean(false) && !preferences.getBoolean(
Settings.PREF_HIDE_NCA_POPUP, false)) {
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.nca_verification_disabled)
.setMessage(activity.getString(R.string.nca_verification_disabled_description))
.setPositiveButton(android.R.string.ok) { _, _ ->
launch()
}
.setNeutralButton(R.string.dont_show_again) { _, _ ->
preferences.edit {
putBoolean(Settings.PREF_HIDE_NCA_POPUP, true)
}
launch()
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
} else {
launch()
}

View file

@ -35,7 +35,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
RENDERER_SAMPLE_SHADING("sample_shading"),
PICTURE_IN_PICTURE("picture_in_picture"),
USE_CUSTOM_RTC("custom_rtc_enabled"),
DISABLE_NCA_VERIFICATION("disable_nca_verification"),
BLACK_BACKGROUNDS("black_backgrounds"),
JOYSTICK_REL_CENTER("joystick_rel_center"),
DPAD_SLIDE("dpad_slide"),

View file

@ -37,7 +37,6 @@ object Settings {
const val PREF_SHOULD_SHOW_PRE_ALPHA_WARNING = "ShouldShowPreAlphaWarning"
const val PREF_SHOULD_SHOW_EDENS_VEIL_DIALOG = "ShouldShowEdensVeilDialog"
const val PREF_MEMORY_WARNING_SHOWN = "MemoryWarningShown"
const val PREF_HIDE_NCA_POPUP = "HideNCAVerificationPopup"
const val SECTION_STATS_OVERLAY = "Stats Overlay"
// Deprecated input overlay preference keys

View file

@ -297,13 +297,6 @@ abstract class SettingsItem(
descriptionId = R.string.use_custom_rtc_description
)
)
put(
SwitchSetting(
BooleanSetting.DISABLE_NCA_VERIFICATION,
titleId = R.string.disable_nca_verification,
descriptionId = R.string.disable_nca_verification_description
)
)
put(
StringInputSetting(
StringSetting.WEB_TOKEN,

View file

@ -210,7 +210,6 @@ class SettingsFragmentPresenter(
add(IntSetting.LANGUAGE_INDEX.key)
add(BooleanSetting.USE_CUSTOM_RTC.key)
add(LongSetting.CUSTOM_RTC.key)
add(BooleanSetting.DISABLE_NCA_VERIFICATION.key)
add(HeaderSetting(R.string.network))
add(StringSetting.WEB_TOKEN.key)

View file

@ -194,6 +194,10 @@ class GamesFragment : Fragment() {
val columns = resources.getInteger(R.integer.game_columns_grid)
GridLayoutManager(context, columns)
}
GameAdapter.VIEW_TYPE_GRID_COMPACT -> {
val columns = resources.getInteger(R.integer.game_columns_grid)
GridLayoutManager(context, columns)
}
GameAdapter.VIEW_TYPE_LIST -> {
val columns = resources.getInteger(R.integer.game_columns_list)
GridLayoutManager(context, columns)
@ -300,6 +304,7 @@ class GamesFragment : Fragment() {
val currentViewType = getCurrentViewType()
when (currentViewType) {
GameAdapter.VIEW_TYPE_LIST -> popup.menu.findItem(R.id.view_list).isChecked = true
GameAdapter.VIEW_TYPE_GRID_COMPACT -> popup.menu.findItem(R.id.view_grid_compact).isChecked = true
GameAdapter.VIEW_TYPE_GRID -> popup.menu.findItem(R.id.view_grid).isChecked = true
GameAdapter.VIEW_TYPE_CAROUSEL -> popup.menu.findItem(R.id.view_carousel).isChecked = true
}
@ -314,6 +319,14 @@ class GamesFragment : Fragment() {
true
}
R.id.view_grid_compact -> {
if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause()
setCurrentViewType(GameAdapter.VIEW_TYPE_GRID_COMPACT)
applyGridGamesBinding()
item.isChecked = true
true
}
R.id.view_list -> {
if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause()
setCurrentViewType(GameAdapter.VIEW_TYPE_LIST)

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="270"
android:startColor="@android:color/transparent"
android:centerColor="#66000000"
android:endColor="#AA000000"
android:type="linear" />
</shape>

View file

@ -5,27 +5,32 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false">
android:focusableInTouchMode="false"
android:padding="4dp">
<org.yuzu.yuzu_emu.views.GradientBorderCardView
android:id="@+id/card_game_grid"
app:cardElevation="0dp"
app:cardBackgroundColor="@color/eden_card_background"
app:strokeWidth="1dp"
app:strokeColor="@color/eden_border"
app:strokeWidth="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="4dp"
android:clickable="true"
android:clipToPadding="true"
android:focusable="true"
android:transitionName="card_game"
app:cardCornerRadius="16dp">
app:cardCornerRadius="16dp"
android:foreground="@color/eden_border_gradient_start">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dp">
android:paddingTop="14dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingBottom="6dp">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/image_game_screen"

View file

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="4dp">
<org.yuzu.yuzu_emu.views.GradientBorderCardView
android:id="@+id/card_game_grid_compact"
app:cardElevation="0dp"
app:cardBackgroundColor="@color/eden_card_background"
app:strokeWidth="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="4dp"
android:clickable="true"
android:clipToPadding="true"
android:focusable="true"
android:transitionName="card_game_compact"
app:cardCornerRadius="16dp"
android:foreground="@color/eden_border_gradient_start">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="14dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingBottom="6dp">
<FrameLayout
android:id="@+id/image_container"
android:layout_width="150dp"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/image_game_screen_compact"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.Medium"
android:scaleType="centerCrop"
tools:src="@drawable/default_icon" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_overlay_bottom" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_game_title_compact"
style="@style/SynthwaveText.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_margin="6dp"
android:requiresFadingEdge="horizontal"
android:textAlignment="center"
android:textSize="12sp"
android:textStyle="bold"
android:textColor="@android:color/white"
android:shadowColor="@android:color/black"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
android:maxLines="2"
android:ellipsize="end"
tools:text="The Legend of Zelda: Skyward Sword" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</org.yuzu.yuzu_emu.views.GradientBorderCardView>
</FrameLayout>

View file

@ -4,6 +4,9 @@
<item
android:id="@+id/view_grid"
android:title="@string/view_grid"/>
<item
android:id="@+id/view_grid_compact"
android:title="@string/view_grid_compact"/>
<item
android:id="@+id/view_list"
android:title="@string/view_list"

View file

@ -119,8 +119,8 @@
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقت أثناء تحديثات الذاكرة، مما يقلل استخدام المعالج ويحسن أدائه. قد يسبب هذا أعطالاً أو تعطلًا في بعض الألعاب.</string>
<string name="cpuopt_unsafe_host_mmu">تمكين محاكاة MMU المضيف</string>
<string name="cpuopt_unsafe_host_mmu_description">يعمل هذا التحسين على تسريع وصول الذاكرة بواسطة البرنامج الضيف. يؤدي تمكينه إلى إجراء عمليات قراءة/كتابة ذاكرة الضيف مباشرة في الذاكرة والاستفادة من MMU المضيف. يؤدي تعطيل هذا إلى إجبار جميع عمليات الوصول إلى الذاكرة على استخدام محاكاة MMU البرمجية.</string>
<string name="dma_accuracy">مستوى DMA</string>
<string name="dma_accuracy_description">يتحكم في دقة تحديد مستوى DMA. الدقة الأعلى يمكنها إصلاح بعض المشاكل في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا كنت غير متأكد، اتركه على الوضع الافتراضي.</string>
<string name="dma_accuracy">دقة DMA</string>
<string name="dma_accuracy_description">يتحكم في دقة تحديد DMA. يمكن أن تصلح الدقة الآمنة المشاكل في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا كنت غير متأكد، اترك هذا على الوضع الافتراضي.</string>
<!-- Memory Layouts -->
<string name="memory_4gb">4 جيجابايت (موصى به)</string>
@ -498,8 +498,6 @@
<string name="use_custom_rtc">ساعة مخصصة في الوقت الحقيقي</string>
<string name="use_custom_rtc_description">يسمح لك بتعيين ساعة مخصصة في الوقت الفعلي منفصلة عن وقت النظام الحالي لديك</string>
<string name="set_custom_rtc">تعيين ساعة مخصصة في الوقت الحقيقي</string>
<string name="disable_nca_verification">تعطيل التحقق من NCA</string>
<string name="disable_nca_verification_description">يعطل التحقق من سلامة أرشيفات محتوى NCA. قد يحسن هذا من سرعة التحميل لكنه يخاطر بتلف البيانات أو تمرير ملفات غير صالحة دون اكتشاف. ضروري لجعل الألعاب والتحديثات التي تتطلب نظامًا أساسيًا 20+ تعمل.</string>
<!-- Network settings strings -->
<string name="generate">توليد</string>
@ -794,9 +792,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">افتراضي</string>
<string name="dma_accuracy_normal">عادي</string>
<string name="dma_accuracy_high">عالي</string>
<string name="dma_accuracy_extreme">مفرط</string>
<string name="dma_accuracy_unsafe">غير آمن (سريع)</string>
<string name="dma_accuracy_safe">آمن (مستقر)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">هەندێک لە بازنەکردنەکانی هەڵگر لە کاتی نوێکردنەوەی بیرگە دەنێرێت، کەمکردنەوەی بەکارهێنانی CPU و باشترکردنی کارایی. لەوانەیە لە هەندێک یاری کێشە درووست بکات.</string>
<string name="cpuopt_unsafe_host_mmu">چالاککردنی میمیکردنی MMU میواندە</string>
<string name="cpuopt_unsafe_host_mmu_description">ئەم باشکردنە خێرایی دەستکەوتنی بیرگە لەلایەن پرۆگرامی میوانەکە زیاد دەکات. چالاککردنی وای لێدەکات کە خوێندنەوە/نووسینەکانی بیرگەی میوانەکە ڕاستەوخۆ لە بیرگە ئەنجام بدرێت و میمیکردنی MMU میواندە بەکاربهێنێت. ناچالاککردنی ئەمە هەموو دەستکەوتنەکانی بیرگە ڕەت دەکاتەوە لە بەکارهێنانی میمیکردنی MMU نەرمەکاڵا.</string>
<string name="dma_accuracy">ئاستی DMA</string>
<string name="dma_accuracy_description">کۆنتڕۆڵی وردی ڕێکخستنی DMA دەکات. وردی زیاتر دەتوانێ هەندێک کێشە لە هەندێک یاری چارەسەر بکات، بەڵام لە هەندێک حاڵەتدا کاریگەری لەسەر کارایی هەیە. ئەگەر دڵنیا نیت، بە ڕێکخستنی بنەڕەتی بێڵە.</string>
<string name="dma_accuracy">وردیی DMA</string>
<string name="dma_accuracy_description">کۆنتڕۆڵی وردیی وردیی DMA دەکات. وردییی پارێزراو دەتوانێت کێشەکان لە هەندێک یاری چارەسەر بکات، بەڵام لە هەندێک حاڵەتدا کاریگەری لەسەر کارایی هەیە. ئەگەر دڵنیا نیت، ئەمە بە سەر ڕەھەوادا بهێڵە.</string>
<string name="memory_4gb">4GB (پێشنیارکراو)</string>
<string name="memory_6gb">6GB (نائاسایش)</string>
@ -482,8 +482,6 @@
<string name="use_custom_rtc">RTCی تایبەتمەند</string>
<string name="use_custom_rtc_description">ڕێگەت پێدەدات کاتژمێرێکی کاتی ڕاستەقینەی تایبەتمەند دابنێیت کە جیاوازە لە کاتی ئێستای سیستەمەکەت.</string>
<string name="set_custom_rtc">دانانی RTCی تایبەتمەند</string>
<string name="disable_nca_verification">ناچالاککردنی پشکنینی NCA</string>
<string name="disable_nca_verification_description">پشکنینی پێکهاتەی ئارشیڤەکانی ناوەڕۆکی NCA ناچالاک دەکات. ئەمە لەوانەیە خێرایی بارکردن به‌ره‌وپێش ببات، بەڵام مەترسی لەناوچوونی داتا یان ئەوەی فایلە نادروستەکان بەبێ ئەوەی دۆزرایەوە تێپەڕبن زیاتر دەکات. بۆ ئەوەی یاری و نوێکردنەوەکان کار بکەن کە پێویستی بە فریموێری 20+ هەیە زۆر پێویستە.</string>
<!-- Network settings strings -->
<string name="generate">بەرهەم هێنان</string>
@ -763,9 +761,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">بنەڕەتی</string>
<string name="dma_accuracy_normal">ئاسایی</string>
<string name="dma_accuracy_high">بەرز</string>
<string name="dma_accuracy_extreme">زۆر بەرز</string>
<string name="dma_accuracy_unsafe">نەپارێزراو (خێرا)</string>
<string name="dma_accuracy_safe">پارێزراو (جێگیر)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -127,8 +127,8 @@
<string name="skip_cpu_inner_invalidation_description">Přeskočí některé invalidace mezipaměti na straně CPU během aktualizací paměti, čímž sníží zatížení CPU a zlepší jeho výkon. Může způsobit chyby nebo pády v některých hrách.</string>
<string name="cpuopt_unsafe_host_mmu">Povolit emulaci hostitelské MMU</string>
<string name="cpuopt_unsafe_host_mmu_description">Tato optimalizace zrychluje přístup do paměti hostovaného programu. Její povolení způsobí, že čtení a zápisy do paměti hosta se provádějí přímo v paměti a využívají hostitelskou MMU. Zakázání této funkce vynutí použití softwarové emulace MMU pro všechny přístupy do paměti.</string>
<string name="dma_accuracy">Úroveň DMA</string>
<string name="dma_accuracy_description">Ovládá přesnost DMA. Vyšší přesnost může opravit problémy v některých hrách, ale může také ovlivnit výkon. Pokud si nejste jisti, ponechejte výchozí nastavení.</string>
<string name="dma_accuracy">Přesnost DMA</string>
<string name="dma_accuracy_description">Ovládá přesnost DMA. Bezpečná přesnost může opravit problémy v některých hrách, ale v některých případech může také ovlivnit výkon. Pokud si nejste jisti, ponechte to na výchozím nastavení.</string>
<string name="memory_4gb">4GB (Doporučeno)</string>
<string name="memory_6gb">6GB (Nebezpečné)</string>
@ -458,8 +458,6 @@
<string name="use_custom_rtc">Vlastní RTC</string>
<string name="use_custom_rtc_description">Vlastní nastavení času</string>
<string name="set_custom_rtc">Nastavit vlastní RTC</string>
<string name="disable_nca_verification">Zakázat ověřování NCA</string>
<string name="disable_nca_verification_description">Zakáže ověřování integrity archivů obsahu NCA. To může zlepšit rychlost načítání, ale hrozí poškození dat nebo neodhalení neplatných souborů. Je nutné, aby fungovaly hry a aktualizace vyžadující firmware 20+.</string>
<!-- Network settings strings -->
<string name="generate">Generovat</string>
@ -737,9 +735,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Výchozí</string>
<string name="dma_accuracy_normal">Normální</string>
<string name="dma_accuracy_high">Vysoká</string>
<string name="dma_accuracy_extreme">Extrémní</string>
<string name="dma_accuracy_unsafe">Nebezpečné (rychlé)</string>
<string name="dma_accuracy_safe">Bezpečné (stabilní)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Überspringt bestimmte Cache-Invalidierungen auf CPU-Seite während Speicherupdates, reduziert die CPU-Auslastung und verbessert die Leistung. Kann in einigen Spielen zu Fehlern oder Abstürzen führen.</string>
<string name="cpuopt_unsafe_host_mmu">Host-MMU-Emulation aktivieren</string>
<string name="cpuopt_unsafe_host_mmu_description">Diese Optimierung beschleunigt Speicherzugriffe durch das Gastprogramm. Wenn aktiviert, erfolgen Speicherlese- und -schreibvorgänge des Gastes direkt im Speicher und nutzen die MMU des Hosts. Das Deaktivieren erzwingt die Verwendung der Software-MMU-Emulation für alle Speicherzugriffe.</string>
<string name="dma_accuracy">DMA-Level</string>
<string name="dma_accuracy_description">Steuert die DMA-Präzisionsgenauigkeit. Eine höhere Präzision kann Probleme in einigen Spielen beheben, kann aber in einigen Fällen auch die Leistung beeinträchtigen. Im Zweifel auf „Standard“ belassen.</string>
<string name="dma_accuracy">DMA-Genauigkeit</string>
<string name="dma_accuracy_description">Steuert die DMA-Präzisionsgenauigkeit. Sichere Präzision kann Probleme in einigen Spielen beheben, kann aber in einigen Fällen auch die Leistung beeinträchtigen. Im Zweifel lassen Sie dies auf Standard stehen.</string>
<string name="memory_4gb">4 GB (Empfohlen)</string>
<string name="memory_6gb">6 GB (Unsicher)</string>
@ -486,8 +486,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="select_rtc_date">RTC-Datum auswählen</string>
<string name="select_rtc_time">RTC-Zeit auswählen</string>
<string name="use_custom_rtc">Benutzerdefinierte Echtzeituhr</string>
<string name="disable_nca_verification">NCA-Verifizierung deaktivieren</string>
<string name="disable_nca_verification_description">Deaktiviert die Integritätsprüfung von NCA-Inhaltsarchiven. Dies kann die Ladegeschwindigkeit verbessern, riskiert jedoch Datenbeschädigung oder dass ungültige Dateien unentdeckt bleiben. Ist notwendig, um Spiele und Updates, die Firmware 20+ benötigen, zum Laufen zu bringen.</string>
<!-- Network settings strings -->
<string name="generate">Generieren</string>
@ -829,9 +827,8 @@ Wirklich fortfahren?</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Standard</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Hoch</string>
<string name="dma_accuracy_extreme">Extrem</string>
<string name="dma_accuracy_unsafe">Unsicher (schnell)</string>
<string name="dma_accuracy_safe">Sicher (stabil)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché durante actualizaciones de memoria, reduciendo el uso de CPU y mejorando su rendimiento. Puede causar fallos en algunos juegos.</string>
<string name="cpuopt_unsafe_host_mmu">Habilitar emulación de MMU del host</string>
<string name="cpuopt_unsafe_host_mmu_description">Esta optimización acelera los accesos a la memoria por parte del programa invitado. Al habilitarla, las lecturas/escrituras de memoria del invitado se realizan directamente en la memoria y utilizan la MMU del host. Deshabilitar esto obliga a que todos los accesos a la memoria utilicen la emulación de MMU por software.</string>
<string name="dma_accuracy">Nivel de DMA</string>
<string name="dma_accuracy_description">Controla la precisión del DMA. Una mayor precisión puede solucionar problemas en algunos juegos, pero también puede afectar el rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado.</string>
<string name="dma_accuracy">Precisión de DMA</string>
<string name="dma_accuracy_description">Controla la precisión de DMA. La precisión segura puede solucionar problemas en algunos juegos, pero también puede afectar al rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado.</string>
<string name="memory_4gb">4GB (Recomendado)</string>
<string name="memory_6gb">6GB (Inseguro)</string>
@ -506,8 +506,6 @@
<string name="use_custom_rtc">RTC personalizado</string>
<string name="use_custom_rtc_description">Te permite tener un reloj personalizado en tiempo real diferente del tiempo del propio sistema.</string>
<string name="set_custom_rtc">Configurar RTC personalizado</string>
<string name="disable_nca_verification">Desactivar verificación NCA</string>
<string name="disable_nca_verification_description">Desactiva la verificación de integridad de los archivos de contenido NCA. Esto puede mejorar la velocidad de carga, pero arriesga corrupción de datos o que archivos inválidos pasen desapercibidos. Es necesario para que funcionen juegos y actualizaciones que requieren firmware 20+.</string>
<!-- Network settings strings -->
<string name="generate">Generar</string>
@ -872,9 +870,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Predeterminado</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Extremo</string>
<string name="dma_accuracy_unsafe">Inseguro (rápido)</string>
<string name="dma_accuracy_safe">Seguro (estable)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">بعضی ابطال‌های حافظه نهان در هنگام به‌روزرسانی‌های حافظه را رد می‌کند، استفاده از CPU را کاهش داده و عملکرد آن را بهبود می‌بخشد. ممکن است در برخی بازی‌ها باعث مشکلات یا خرابی شود.</string>
<string name="cpuopt_unsafe_host_mmu">فعال‌سازی شبیه‌سازی MMU میزبان</string>
<string name="cpuopt_unsafe_host_mmu_description">این بهینه‌سازی دسترسی‌های حافظه توسط برنامه میهمان را تسریع می‌کند. فعال‌سازی آن باعث می‌شود خواندن/نوشتن حافظه میهمان مستقیماً در حافظه انجام شود و از MMU میزبان استفاده کند. غیرفعال کردن این قابلیت، همه دسترسی‌های حافظه را مجبور به استفاده از شبیه‌سازی نرم‌افزاری MMU می‌کند.</string>
<string name="dma_accuracy">سطح DMA</string>
<string name="dma_accuracy_description">دقت صحت DMA را کنترل می کند. دقت بالاتر می تواند مشکلات برخی بازی ها را برطرف کند، اما در برخی موارد نیز می تواند بر عملکرد تأثیر بگذارد. اگر مطمئن نیستید، آن را روی پیش فرض بگذارید.</string>
<string name="dma_accuracy">دقت DMA</string>
<string name="dma_accuracy_description">دقت صحت DMA را کنترل می کند. دقت ایمن می تواند مشکلات برخی بازی ها را برطرف کند، اما در برخی موارد نیز ممکن است بر عملکرد تأثیر بگذارد. اگر مطمئن نیستید، این گزینه را روی پیش فرض بگذارید.</string>
<string name="memory_4gb">4 گیگابایت (توصیه شده)</string>
<string name="memory_6gb">6 گیگابایت (ناامن)</string>
@ -504,8 +504,6 @@
<string name="use_custom_rtc">زمان سفارشی</string>
<string name="use_custom_rtc_description">به شما امکان می‌دهد یک ساعت سفارشی جدا از زمان فعلی سیستم خود تنظیم کنید.</string>
<string name="set_custom_rtc">تنظیم زمان سفارشی</string>
<string name="disable_nca_verification">غیرفعال کردن تأیید اعتبار NCA</string>
<string name="disable_nca_verification_description">بررسی صحت آرشیوهای محتوای NCA را غیرفعال می‌کند. این ممکن است سرعت بارگذاری را بهبود بخشد اما خطر خرابی داده یا تشخیص داده نشدن فایل‌های نامعتبر را به همراه دارد. برای کار کردن بازی‌ها و به‌روزرسانی‌هایی که به فرمور ۲۰+ نیاز دارند، ضروری است.</string>
<!-- Network settings strings -->
<string name="generate">تولید</string>
@ -871,9 +869,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">پیش فرض</string>
<string name="dma_accuracy_normal">معمولی</string>
<string name="dma_accuracy_high">بالا</string>
<string name="dma_accuracy_extreme">فوق العاده</string>
<string name="dma_accuracy_unsafe">ناایمن (سریع)</string>
<string name="dma_accuracy_safe">ایمن (پایدار)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Ignore certaines invalidations de cache côté CPU lors des mises à jour mémoire, réduisant l\'utilisation du CPU et améliorant ses performances. Peut causer des bugs ou plantages sur certains jeux.</string>
<string name="cpuopt_unsafe_host_mmu">Activer l\'émulation de la MMU hôte</string>
<string name="cpuopt_unsafe_host_mmu_description">Cette optimisation accélère les accès mémoire par le programme invité. L\'activer entraîne que les lectures/écritures mémoire de l\'invité sont effectuées directement en mémoire et utilisent la MMU de l\'hôte. Désactiver cela force tous les accès mémoire à utiliser l\'émulation logicielle de la MMU.</string>
<string name="dma_accuracy">Niveau DMA</string>
<string name="dma_accuracy_description">Contrôle la précision du DMA. Une précision plus élevée peut résoudre les problèmes dans certains jeux, mais peut aussi affecter les performances dans certains cas. Si vous n\'êtes pas sûr, laissez-la sur Défaut.</string>
<string name="dma_accuracy">Précision DMA</string>
<string name="dma_accuracy_description">Contrôle la précision du DMA. Une précision sûre peut résoudre les problèmes dans certains jeux, mais peut aussi affecter les performances dans certains cas. Si vous n\'êtes pas sûr, laissez ce paramètre sur Par défaut.</string>
<string name="memory_4gb">4 Go (Recommandé)</string>
<string name="memory_6gb">6 Go (Dangereux)</string>
@ -506,8 +506,6 @@
<string name="use_custom_rtc">RTC personnalisé</string>
<string name="use_custom_rtc_description">Vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système.</string>
<string name="set_custom_rtc">Définir l\'horloge RTC personnalisée</string>
<string name="disable_nca_verification">Désactiver la vérification NCA</string>
<string name="disable_nca_verification_description">Désactive la vérification d\'intégrité des archives de contenu NCA. Cela peut améliorer la vitesse de chargement mais risque une corruption des données ou que des fichiers invalides ne soient pas détectés. Est nécessaire pour faire fonctionner les jeux et mises à jour nécessitant un firmware 20+.</string>
<!-- Network settings strings -->
<string name="generate">Générer</string>
@ -920,9 +918,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Défaut</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Élevé</string>
<string name="dma_accuracy_extreme">Extrême</string>
<string name="dma_accuracy_unsafe">Dangereux (rapide)</string>
<string name="dma_accuracy_safe">Sûr (stable)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -129,8 +129,8 @@
<string name="skip_cpu_inner_invalidation_description">מדלג על איפוסי מטמון מסוימים במהלך עדכוני זיכרון, מפחית שימוש במעבד ומשפר ביצועים. עלול לגרום לתקלות או קריסות בחלק מהמשחקים.</string>
<string name="cpuopt_unsafe_host_mmu">הפעל אמולציית MMU מארח</string>
<string name="cpuopt_unsafe_host_mmu_description">אופטימיזציה זו מאיצה את גישת הזיכרון על ידי התוכנית האורחת. הפעלתה גורמת לכך שפעולות קריאה/כתיבה לזיכרון האורח מתבצעות ישירות לזיכרון ומשתמשות ב-MMU של המארח. השבתת זאת מאלצת את כל גישות הזיכרון להשתמש באמולציית MMU תוכנתית.</string>
<string name="dma_accuracy">רמת DMA</string>
<string name="dma_accuracy_description">שולטת בדיוק הדיוק של DMA. דיוק גבוה יותר יכול לתקן בעיות בחלק מהמשחקים, אך הוא עלול גם להשפיע על הביצועים במקרים מסוימים. אם אינך בטוח, השאר ברירת מחדל.</string>
<string name="dma_accuracy">דיוק DMA</string>
<string name="dma_accuracy_description">שולט בדיוק הדיוק של DMA. דיוק בטוח יכול לתקן בעיות בחלק מהמשחקים, אך הוא עלול גם להשפיע על הביצועים במקרים מסוימים. אם אינך בטוח, השאר זאת על ברירת מחדל.</string>
<string name="memory_4gb">4GB (מומלץ)</string>
<string name="memory_6gb">6GB (לא בטוח)</string>
@ -505,8 +505,6 @@
<string name="use_custom_rtc">RTC מותאם אישית</string>
<string name="use_custom_rtc_description">מאפשר לך לקבוע שעון זמן אמת נפרד משעון המערכת שלך.</string>
<string name="set_custom_rtc">קבע RTC מותאם אישית</string>
<string name="disable_nca_verification">השבת אימות NCA</string>
<string name="disable_nca_verification_description">משבית את אימות השלמות של ארכיוני התוכן של NCA. זה עשוי לשפר את מהירות הטעינה אך מסתכן בשחיקת נתונים או שמא קבצים לא חוקיים יעברו ללא זיהוי. זה הכרחי כדי לגרום למשחקים ועדכונים הדורשים firmware 20+ לעבוד.</string>
<!-- Network settings strings -->
<string name="generate">יצירה</string>
@ -802,9 +800,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">ברירת מחדל</string>
<string name="dma_accuracy_normal">רגיל</string>
<string name="dma_accuracy_high">גבוה</string>
<string name="dma_accuracy_extreme">קיצוני</string>
<string name="dma_accuracy_unsafe">לא בטוח (מהיר)</string>
<string name="dma_accuracy_safe">בטוח (יציב)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Kihagy néhány CPU-oldali gyorsítótár-érvénytelenítést memóriafrissítések közben, csökkentve a CPU használatát és javítva a teljesítményt. Néhány játékban hibákat vagy összeomlást okozhat.</string>
<string name="cpuopt_unsafe_host_mmu">Gazda MMU emuláció engedélyezése</string>
<string name="cpuopt_unsafe_host_mmu_description">Ez az optimalizáció gyorsítja a vendégprogram memória-hozzáférését. Engedélyezése esetén a vendég memóriaolvasási/írási műveletei közvetlenül a memóriában történnek, és kihasználják a gazda MMU-ját. Letiltás esetén minden memória-hozzáférés a szoftveres MMU emulációt használja.</string>
<string name="dma_accuracy">DMA szint</string>
<string name="dma_accuracy_description">Szabályozza a DMA pontosságát. A magasabb pontosság megoldhat néhány játék problémáit, de bizonyos esetekben befolyásolhatja a teljesítményt. Ha bizonytalan, hagyja Alapértelmezett beállításnál.</string>
<string name="dma_accuracy">DMA pontosság</string>
<string name="dma_accuracy_description">Szabályozza a DMA pontosságát. A biztonságos pontosság megoldhat néhány játék problémáit, de bizonyos esetekben befolyásolhatja a teljesítményt. Ha bizonytalan, hagyja Alapértelmezett beállításon.</string>
<string name="memory_4gb">4GB (Ajánlott)</string>
<string name="memory_6gb">6GB (Nem biztonságos)</string>
@ -501,8 +501,6 @@
<string name="use_custom_rtc">Egyéni RTC</string>
<string name="use_custom_rtc_description">Megadhatsz egy valós idejű órát, amely eltér a rendszer által használt órától.</string>
<string name="set_custom_rtc">Egyéni RTC beállítása</string>
<string name="disable_nca_verification">NCA ellenőrzés letiltása</string>
<string name="disable_nca_verification_description">Letiltja az NCA tartalomarchívumok integritás-ellenőrzését. Ez javíthatja a betöltési sebességet, de az adatsérülés vagy az érvénytelen fájlok észrevétlen maradásának kockázatával jár. Elengedhetetlen a 20+ firmware-et igénylő játékok és frissítések működtetéséhez.</string>
<!-- Network settings strings -->
<string name="generate">Generálás</string>
@ -909,9 +907,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Alapértelmezett</string>
<string name="dma_accuracy_normal">Normál</string>
<string name="dma_accuracy_high">Magas</string>
<string name="dma_accuracy_extreme">Extrém</string>
<string name="dma_accuracy_unsafe">Nem biztonságos (gyors)</string>
<string name="dma_accuracy_safe">Biztonságos (stabil)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Melewati beberapa pembatalan cache sisi CPU selama pembaruan memori, mengurangi penggunaan CPU dan meningkatkan kinerjanya. Mungkin menyebabkan gangguan atau crash pada beberapa game.</string>
<string name="cpuopt_unsafe_host_mmu">Aktifkan Emulasi MMU Host</string>
<string name="cpuopt_unsafe_host_mmu_description">Optimasi ini mempercepat akses memori oleh program tamu. Mengaktifkannya menyebabkan pembacaan/penulisan memori tamu dilakukan langsung ke memori dan memanfaatkan MMU Host. Menonaktifkan ini memaksa semua akses memori menggunakan Emulasi MMU Perangkat Lunak.</string>
<string name="dma_accuracy">Level DMA</string>
<string name="dma_accuracy_description">Mengontrol akurasi presisi DMA. Presisi yang lebih tinggi dapat memperbaiki masalah di beberapa game, tetapi juga dapat memengaruhi performa dalam beberapa kasus. Jika tidak yakin, biarkan di Bawaan.</string>
<string name="dma_accuracy">Akurasi DMA</string>
<string name="dma_accuracy_description">Mengontrol keakuratan presisi DMA. Presisi aman dapat memperbaiki masalah di beberapa game, tetapi juga dapat memengaruhi kinerja dalam beberapa kasus. Jika tidak yakin, biarkan ini pada Bawaan.</string>
<string name="memory_4gb">4GB (Direkomendasikan)</string>
<string name="memory_6gb">6GB (Tidak Aman)</string>
@ -502,8 +502,6 @@
<string name="use_custom_rtc">RTC Kustom</string>
<string name="use_custom_rtc_description">Memungkinkan Anda untuk mengatur jam waktu nyata kustom yang terpisah dari waktu sistem saat ini Anda.</string>
<string name="set_custom_rtc">Setel RTC Kustom</string>
<string name="disable_nca_verification">Nonaktifkan Verifikasi NCA</string>
<string name="disable_nca_verification_description">Menonaktifkan verifikasi integritas arsip konten NCA. Ini dapat meningkatkan kecepatan pemuatan tetapi berisiko kerusakan data atau file yang tidak valid tidak terdeteksi. Diperlukan untuk membuat game dan pembaruan yang membutuhkan firmware 20+ bekerja.</string>
<!-- Network settings strings -->
<string name="generate">Hasilkan</string>
@ -864,9 +862,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Bawaan</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Tinggi</string>
<string name="dma_accuracy_extreme">Ekstrem</string>
<string name="dma_accuracy_unsafe">Tidak Aman (cepat)</string>
<string name="dma_accuracy_safe">Aman (stabil)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Salta alcuni invalidamenti della cache lato CPU durante gli aggiornamenti di memoria, riducendo l\'uso della CPU e migliorandone le prestazioni. Potrebbe causare glitch o crash in alcuni giochi.</string>
<string name="cpuopt_unsafe_host_mmu">Abilita emulazione MMU host</string>
<string name="cpuopt_unsafe_host_mmu_description">Questa ottimizzazione accelera gli accessi alla memoria da parte del programma guest. Abilitandola, le letture/scritture della memoria guest vengono eseguite direttamente in memoria e sfruttano la MMU host. Disabilitandola, tutti gli accessi alla memoria sono costretti a utilizzare l\'emulazione software della MMU.</string>
<string name="dma_accuracy">Livello DMA</string>
<string name="dma_accuracy_description">Controlla la precisione del DMA. Una precisione più alta può risolvere problemi in alcuni giochi, ma in alcuni casi può influire sulle prestazioni. Se non sei sicuro, lascia su Predefinito.</string>
<string name="dma_accuracy">Precisione DMA</string>
<string name="dma_accuracy_description">Controlla la precisione del DMA. La precisione sicura può risolvere problemi in alcuni giochi, ma in alcuni casi può anche influire sulle prestazioni. In caso di dubbi, lascia questo su Predefinito.</string>
<string name="memory_4gb">4GB (Consigliato)</string>
<string name="memory_6gb">6GB (Non sicuro)</string>
@ -505,8 +505,6 @@
<string name="use_custom_rtc">RTC Personalizzato</string>
<string name="use_custom_rtc_description">Ti permette di impostare un orologio in tempo reale personalizzato, completamente separato da quello di sistema.</string>
<string name="set_custom_rtc">Imposta un orologio in tempo reale personalizzato</string>
<string name="disable_nca_verification">Disabilita verifica NCA</string>
<string name="disable_nca_verification_description">Disabilita la verifica dell\'integrità degli archivi di contenuto NCA. Può migliorare la velocità di caricamento ma rischia il danneggiamento dei dati o che file non validi passino inosservati. Necessario per far funzionare giochi e aggiornamenti che richiedono il firmware 20+.</string>
<!-- Network settings strings -->
<string name="generate">Genera</string>
@ -833,9 +831,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Predefinito</string>
<string name="dma_accuracy_normal">Normale</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Estremo</string>
<string name="dma_accuracy_unsafe">Non sicuro (veloce)</string>
<string name="dma_accuracy_safe">Sicuro (stabile)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">メモリ更新時のCPU側キャッシュ無効化をスキップし、CPU使用率を減らして性能を向上させます。一部のゲームで不具合やクラッシュが発生する可能性があります。</string>
<string name="cpuopt_unsafe_host_mmu">ホストMMUエミュレーションを有効化</string>
<string name="cpuopt_unsafe_host_mmu_description">この最適化により、ゲストプログラムによるメモリアクセスが高速化されます。有効にすると、ゲストのメモリ読み書きが直接メモリ内で実行され、ホストのMMUを利用します。無効にすると、すべてのメモリアクセスでソフトウェアMMUエミュレーションが使用されます。</string>
<string name="dma_accuracy">DMAレベル</string>
<string name="dma_accuracy_description">DMAの精度を制御します。精度を高くすると一部のゲームの問題が修正される場合がありますが、場合によってはパフォーマンスに影響を与える可能性もあります。不明な場合は、デフォルトのままにしてください。</string>
<string name="dma_accuracy">DMA精度</string>
<string name="dma_accuracy_description">DMAの精度を制御します。安全な精度は一部のゲームの問題を修正できる場合がありますが、場合によってはパフォーマンスに影響を与える可能性もあります。不明な場合は、これをデフォルトのままにしてください。</string>
<string name="memory_4gb">4GB (推奨)</string>
<string name="memory_6gb">6GB (安全でない)</string>
@ -491,8 +491,6 @@
<string name="use_custom_rtc">カスタム RTC</string>
<string name="use_custom_rtc_description">現在のシステム時間とは別に、任意のリアルタイムクロックを設定できます。</string>
<string name="set_custom_rtc">カスタムRTCを設定</string>
<string name="disable_nca_verification">NCA検証を無効化</string>
<string name="disable_nca_verification_description">NCAコンテンツアーカイブの整合性検証を無効にします。読み込み速度が向上する可能性がありますが、データ破損や不正なファイルが検出されないリスクがあります。ファームウェア20以上が必要なゲームや更新を動作させるために必要です。</string>
<!-- Network settings strings -->
<string name="generate">生成</string>
@ -792,9 +790,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">デフォルト</string>
<string name="dma_accuracy_normal">標準</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">最高</string>
<string name="dma_accuracy_unsafe">安全でない(高速)</string>
<string name="dma_accuracy_safe">安全(安定)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">메모리 업데이트 시 일부 CPU 측 캐시 무효화를 건너뛰어 CPU 사용량을 줄이고 성능을 향상시킵니다. 일부 게임에서 오류 또는 충돌을 일으킬 수 있습니다.</string>
<string name="cpuopt_unsafe_host_mmu">호스트 MMU 에뮬레이션 사용</string>
<string name="cpuopt_unsafe_host_mmu_description">이 최적화는 게스트 프로그램의 메모리 접근 속도를 높입니다. 활성화하면 게스트의 메모리 읽기/쓰기가 메모리에서 직접 수행되고 호스트의 MMU를 활용합니다. 비활성화하면 모든 메모리 접근에 소프트웨어 MMU 에뮬레이션을 사용하게 됩니다.</string>
<string name="dma_accuracy">DMA 수준</string>
<string name="dma_accuracy_description">DMA 정밀도를 제어합니다. 높은 정밀도는 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능에 영향을 미칠 수도 있습니다. 확실하지 않다면 기본값으로 두세요.</string>
<string name="dma_accuracy">DMA 정확도</string>
<string name="dma_accuracy_description">DMA 정밀도 정확도를 제어합니다. 안전한 정밀도는 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능에 영향을 미칠 수도 있습니다. 확실하지 않은 경우 기본값으로 두십시오.</string>
<string name="memory_4gb">4GB (권장)</string>
<string name="memory_6gb">6GB (안전하지 않음)</string>
@ -501,8 +501,6 @@
<string name="use_custom_rtc">사용자 지정 RTC</string>
<string name="use_custom_rtc_description">현재 시스템 시간과 별도로 사용자 지정 RTC를 설정할 수 있습니다.</string>
<string name="set_custom_rtc">사용자 지정 RTC 설정</string>
<string name="disable_nca_verification">NCA 검증 비활성화</string>
<string name="disable_nca_verification_description">NCA 콘텐츠 아카이브의 무결성 검증을 비활성화합니다. 로딩 속도를 향상시킬 수 있지만 데이터 손상이나 유효하지 않은 파일이 미검증될 위험이 있습니다. 펌웨어 20+가 필요한 게임 및 업데이트를 실행하려면 필요합니다.</string>
<!-- Network settings strings -->
<string name="generate">생성</string>
@ -863,9 +861,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">기본값</string>
<string name="dma_accuracy_normal">보통</string>
<string name="dma_accuracy_high">높음</string>
<string name="dma_accuracy_extreme">극단적</string>
<string name="dma_accuracy_unsafe">안전하지 않음(빠름)</string>
<string name="dma_accuracy_safe">안전함(안정적)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Hopper over enkelte CPU-side cache-invalideringer under minneoppdateringer, reduserer CPU-bruk og forbedrer ytelsen. Kan forårsake feil eller krasj i noen spill.</string>
<string name="cpuopt_unsafe_host_mmu">Aktiver verts-MMU-emulering</string>
<string name="cpuopt_unsafe_host_mmu_description">Denne optimaliseringen fremskynder minnetilgang av gjesteprogrammet. Hvis aktivert, utføres gjestens minnelesing/skriving direkte i minnet og bruker vertens MMU. Deaktivering tvinger alle minnetilganger til å bruke programvarebasert MMU-emulering.</string>
<string name="dma_accuracy">DMA-nivå</string>
<string name="dma_accuracy_description">Styrer DMA-presisjonsnøyaktigheten. Høyere presisjon kan fikse problemer i noen spill, men kan også påvirke ytelsen i noen tilfeller. Hvis du er usikker, la den stå på Standard.</string>
<string name="dma_accuracy">DMA-nøyaktighet</string>
<string name="dma_accuracy_description">Kontrollerer DMA-presisjonsnøyaktigheten. Sikker presisjon kan fikse problemer i noen spill, men kan også påvirke ytelsen i noen tilfeller. Hvis du er usikker, la dette stå på Standard.</string>
<string name="memory_4gb">4GB (Anbefalt)</string>
<string name="memory_6gb">6GB (Usikkert)</string>
@ -482,8 +482,6 @@
<string name="use_custom_rtc">Tilpasset Sannhetstidsklokke</string>
<string name="use_custom_rtc_description">Gjør det mulig å stille inn en egendefinert sanntidsklokke separat fra den gjeldende systemtiden.</string>
<string name="set_custom_rtc">Angi tilpasset RTC</string>
<string name="disable_nca_verification">Deaktiver NCA-verifisering</string>
<string name="disable_nca_verification_description">Deaktiverer integritetsverifisering av NCA-innholdsarkiv. Dette kan forbedre lastehastigheten, men medfører risiko for datakorrupsjon eller at ugyldige filer ikke oppdages. Er nødvendig for å få spill og oppdateringer som trenger firmware 20+ til å fungere.</string>
<!-- Network settings strings -->
<string name="generate">Generer</string>
@ -773,9 +771,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Standard</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Høy</string>
<string name="dma_accuracy_extreme">Ekstrem</string>
<string name="dma_accuracy_unsafe">Usikker (rask)</string>
<string name="dma_accuracy_safe">Sikker (stabil)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Pomija niektóre unieważnienia pamięci podręcznej po stronie CPU podczas aktualizacji pamięci, zmniejszając użycie CPU i poprawiając jego wydajność. Może powodować błędy lub awarie w niektórych grach.</string>
<string name="cpuopt_unsafe_host_mmu">Włącz emulację MMU hosta</string>
<string name="cpuopt_unsafe_host_mmu_description">Ta optymalizacja przyspiesza dostęp do pamięci przez program gościa. Włączenie powoduje, że odczyty/zapisy pamięci gościa są wykonywane bezpośrednio w pamięci i wykorzystują MMU hosta. Wyłączenie wymusza użycie programowej emulacji MMU dla wszystkich dostępów do pamięci.</string>
<string name="dma_accuracy">Poziom DMA</string>
<string name="dma_accuracy_description">Kontroluje dokładność precyzji DMA. Wyższy poziom może naprawić problemy w niektórych grach, ale może również wpłynąć na wydajność. Jeśli nie jesteś pewien, pozostaw wartość «Domyślny».</string>
<string name="dma_accuracy">Dokładność DMA</string>
<string name="dma_accuracy_description">Kontroluje dokładność precyzji DMA. Bezpieczna precyzja może naprawić problemy w niektórych grach, ale w niektórych przypadkach może również wpłynąć na wydajność. Jeśli nie jesteś pewien, pozostaw wartość Domyślną.</string>
<string name="memory_4gb">4GB (Zalecane)</string>
<string name="memory_6gb">6GB (Niebezpieczne)</string>
@ -482,8 +482,6 @@
<string name="use_custom_rtc">Niestandardowy RTC</string>
<string name="use_custom_rtc_description">Ta opcja pozwala na wybranie własnych ustawień czasu używanych w czasie emulacji, innych niż czas systemu Android.</string>
<string name="set_custom_rtc">Ustaw niestandardowy czas RTC</string>
<string name="disable_nca_verification">Wyłącz weryfikację NCA</string>
<string name="disable_nca_verification_description">Wyłącza weryfikację integralności archiwów zawartości NCA. Może to poprawić szybkość ładowania, ale niesie ryzyko uszkodzenia danych lub niezauważenia nieprawidłowych plików. Konieczne, aby działały gry i aktualizacje wymagające firmware\'u 20+.</string>
<!-- Network settings strings -->
<string name="generate">Generuj</string>
@ -770,9 +768,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">預設</string>
<string name="dma_accuracy_normal">普通</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">極高</string>
<string name="dma_accuracy_unsafe">Niezabezpieczone (szybkie)</string>
<string name="dma_accuracy_safe">Bezpieczne (stabilne)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Ignora algumas invalidações de cache do lado da CPU durante atualizações de memória, reduzindo o uso da CPU e melhorando seu desempenho. Pode causar falhas ou travamentos em alguns jogos.</string>
<string name="cpuopt_unsafe_host_mmu">Ativar Emulação de MMU do Host</string>
<string name="cpuopt_unsafe_host_mmu_description">Esta otimização acelera os acessos à memória pelo programa convidado. Ativar isso faz com que as leituras/gravações de memória do convidado sejam feitas diretamente na memória e utilizem a MMU do Host. Desativar isso força todos os acessos à memória a usarem a Emulação de MMU por Software.</string>
<string name="dma_accuracy">Nível DMA</string>
<string name="dma_accuracy_description">Controla a precisão do DMA. Maior precisão pode corrigir problemas em alguns jogos, mas também pode impactar o desempenho em alguns casos. Se não tiver certeza, deixe em Padrão.</string>
<string name="dma_accuracy">Precisão de DMA</string>
<string name="dma_accuracy_description">Controla a precisão do DMA. A precisão segura pode corrigir problemas em alguns jogos, mas também pode afetar o desempenho em alguns casos. Se não tiver certeza, deixe isso como Padrão.</string>
<string name="memory_4gb">4GB (Recomendado)</string>
<string name="memory_6gb">6GB (Inseguro)</string>
@ -506,8 +506,6 @@
<string name="use_custom_rtc">Data e hora personalizadas</string>
<string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
<string name="set_custom_rtc">Definir um relógio em tempo real personalizado</string>
<string name="disable_nca_verification">Desativar verificação NCA</string>
<string name="disable_nca_verification_description">Desativa a verificação de integridade de arquivos de conteúdo NCA. Pode melhorar a velocidade de carregamento, mas arrisica corromper dados ou que arquivos inválidos passem despercebidos. É necessário para fazer jogos e atualizações que exigem firmware 20+ funcionarem.</string>
<!-- Network settings strings -->
<string name="generate">Gerar</string>
@ -921,9 +919,8 @@ uma tentativa de mapeamento automático</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Padrão</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Extremo</string>
<string name="dma_accuracy_unsafe">Inseguro (rápido)</string>
<string name="dma_accuracy_safe">Seguro (estável)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Ignora algumas invalidações de cache do lado da CPU durante atualizações de memória, reduzindo a utilização da CPU e melhorando o desempenho. Pode causar falhas ou crashes em alguns jogos.</string>
<string name="cpuopt_unsafe_host_mmu">Ativar Emulação de MMU do Anfitrião</string>
<string name="cpuopt_unsafe_host_mmu_description">Esta otimização acelera os acessos à memória pelo programa convidado. Ativar faz com que as leituras/escritas de memória do convidado sejam efetuadas diretamente na memória e utilizem a MMU do Anfitrião. Desativar força todos os acessos à memória a usar a Emulação de MMU por Software.</string>
<string name="dma_accuracy">Nível DMA</string>
<string name="dma_accuracy_description">Controla a precisão do DMA. Maior precisão pode corrigir problemas em alguns jogos, mas também pode afetar o desempenho nalguns casos. Se não tiver a certeza, deixe em Predefinido.</string>
<string name="dma_accuracy">Precisão da DMA</string>
<string name="dma_accuracy_description">Controla a precisão da DMA. A precisão segura pode resolver problemas em alguns jogos, mas também pode afetar o desempenho nalguns casos. Se não tiver a certeza, deixe esta opção em Predefinido.</string>
<string name="memory_4gb">4GB (Recomendado)</string>
<string name="memory_6gb">6GB (Inseguro)</string>
@ -506,8 +506,6 @@
<string name="use_custom_rtc">RTC personalizado</string>
<string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
<string name="set_custom_rtc">Defina um relógio em tempo real personalizado</string>
<string name="disable_nca_verification">Desativar verificação NCA</string>
<string name="disable_nca_verification_description">Desativa a verificação de integridade dos arquivos de conteúdo NCA. Pode melhorar a velocidade de carregamento, mas arrisca a corrupção de dados ou que ficheiros inválidos passem despercebidos. É necessário para que jogos e atualizações que necessitam de firmware 20+ funcionem.</string>
<!-- Network settings strings -->
<string name="generate">Gerar</string>
@ -921,9 +919,8 @@ uma tentativa de mapeamento automático</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Predefinido</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Extremo</string>
<string name="dma_accuracy_unsafe">Inseguro (rápido)</string>
<string name="dma_accuracy_safe">Seguro (estável)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
<string name="cpuopt_unsafe_host_mmu">Включить эмуляцию MMU хоста</string>
<string name="cpuopt_unsafe_host_mmu_description">Эта оптимизация ускоряет доступ к памяти гостевой программой. При включении операции чтения/записи памяти гостя выполняются напрямую в памяти с использованием MMU хоста. Отключение заставляет все обращения к памяти использовать программную эмуляцию MMU.</string>
<string name="dma_accuracy">Уровень DMA</string>
<string name="dma_accuracy_description">Управляет точностью DMA. Более высокий уровень может исправить проблемы в некоторых играх, но также может повлиять на производительность. Если не уверены, оставьте значение «По умолчанию».</string>
<string name="dma_accuracy">Точность DMA</string>
<string name="dma_accuracy_description">Управляет точностью DMA. Безопасная точность может исправить проблемы в некоторых играх, но в некоторых случаях также может повлиять на производительность. Если не уверены, оставьте значение По умолчанию.</string>
<string name="memory_4gb">4 ГБ (Рекомендуется)</string>
<string name="memory_6gb">6 ГБ (Небезопасно)</string>
@ -508,8 +508,6 @@
<string name="use_custom_rtc">Пользовательский RTC</string>
<string name="use_custom_rtc_description">Позволяет установить пользовательские часы реального времени отдельно от текущего системного времени.</string>
<string name="set_custom_rtc">Установить пользовательский RTC</string>
<string name="disable_nca_verification">Отключить проверку NCA</string>
<string name="disable_nca_verification_description">Отключает проверку целостности архивов содержимого NCA. Может улучшить скорость загрузки, но есть риск повреждения данных или того, что недействительные файлы останутся незамеченными. Необходимо для работы игр и обновлений, требующих прошивку 20+.</string>
<!-- Network settings strings -->
<string name="generate">Создать</string>
@ -922,9 +920,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">По умолчанию</string>
<string name="dma_accuracy_normal">Нормальный</string>
<string name="dma_accuracy_high">Высокий</string>
<string name="dma_accuracy_extreme">Экстремальный</string>
<string name="dma_accuracy_unsafe">Небезопасно (быстро)</string>
<string name="dma_accuracy_safe">Безопасно (стабильно)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
@ -958,7 +955,7 @@
<!-- Screen Layouts -->
<string name="screen_layout_auto">Авто</string>
<string name="screen_layout_sensor_landscape">Альбомная (сенсор)</string>
<string name="screen_layout_landscape">Пейзаж</string>
<string name="screen_layout_landscape">Альбомная</string>
<string name="screen_layout_reverse_landscape">Обратная альбомная</string>
<string name="screen_layout_sensor_portrait">Портретная (сенсор)</string>
<string name="screen_layout_portrait">Портрет</string>

View file

@ -121,8 +121,8 @@
<string name="skip_cpu_inner_invalidation_description">Preskače određena poništavanja keša na strani CPU-a tokom ažuriranja memorije, smanjujući opterećenje procesora i poboljšavajući performanse. Može izazvati greške u nekim igrama.</string>
<string name="cpuopt_unsafe_host_mmu">Омогући емулацију MMU домаћина</string>
<string name="cpuopt_unsafe_host_mmu_description">Ова оптимизација убрзава приступ меморији од стране гостујућег програма. Укључивање изазива да се читања/уписа меморије госта обављају директно у меморији и користе MMU домаћина. Искључивање присиљава све приступе меморији да користе софтверску емулацију MMU.</string>
<string name="dma_accuracy">DMA ниво</string>
<string name="dma_accuracy_description">Контролише тачност DMA прецизности. Виши ниво може да поправи проблеме у неким играма, али може и да утиче на перформансе. Ако нисте сигурни, оставите на «Подразумевано».</string>
<string name="dma_accuracy">DMA тачност</string>
<string name="dma_accuracy_description">Управља прецизношћу DMA-а. Сигурна прецизност може да исправи проблеме у неким играма, али у неким случајевима може да утиче и на перформансе. Ако нисте сигурни, оставите ово на Подразумевано.</string>
<!-- Shader Backend -->
<string name="shader_backend">Схадер Бацкенд</string>
@ -457,8 +457,6 @@
<string name="use_custom_rtc">Цустом РТЦ</string>
<string name="use_custom_rtc_description">Омогућава вам да поставите прилагођени сат у реалном времену одвојено од тренутног времена система.</string>
<string name="set_custom_rtc">Подесите прилагођени РТЦ</string>
<string name="disable_nca_verification">Искључи верификацију НЦА</string>
<string name="disable_nca_verification_description">Искључује верификацију интегритета НЦА архива садржаја. Ово може побољшати брзину учитавања, али ризикује оштећење података или да неважећи фајлови прођу незапажено. Неопходно је да би игре и ажурирања која захтевају firmware 20+ радили.</string>
<!-- Network settings strings -->
<string name="generate">Генериши</string>
@ -917,9 +915,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Подразумевано</string>
<string name="dma_accuracy_normal">Нормално</string>
<string name="dma_accuracy_high">Високо</string>
<string name="dma_accuracy_extreme">Екстремно</string>
<string name="dma_accuracy_unsafe">Небезбедно (брзо)</string>
<string name="dma_accuracy_safe">Безбедно (стабилно)</string>
<!-- ASTC Decoding Method -->
<string name="accelerate_astc">АСТЦ метода декодирања</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
<string name="cpuopt_unsafe_host_mmu">Увімкнути емуляцію MMU хоста</string>
<string name="cpuopt_unsafe_host_mmu_description">Ця оптимізація пришвидшує доступ до пам\'яті гостьовою програмою. Увімкнення призводить до того, що читання/запис пам\'яті гостя виконуються безпосередньо в пам\'яті та використовують MMU хоста. Вимкнення змушує всі звернення до пам\'яті використовувати програмну емуляцію MMU.</string>
<string name="dma_accuracy">Рівень DMA</string>
<string name="dma_accuracy_description">Керує точністю DMA. Вищий рівень може виправити проблеми в деяких іграх, але також може вплинути на продуктивність. Якщо не впевнені, залиште значення «Типово».</string>
<string name="dma_accuracy">Точність DMA</string>
<string name="dma_accuracy_description">Керує точністю DMA. Безпечна точність може виправити проблеми в деяких іграх, але в деяких випадках також може вплинути на продуктивність. Якщо не впевнені, залиште це значення за замовчуванням.</string>
<string name="memory_4gb">4 ГБ (Рекомендовано)</string>
<string name="memory_6gb">6 ГБ (Небезпечно)</string>
@ -495,8 +495,6 @@
<string name="use_custom_rtc">Свій RTC</string>
<string name="use_custom_rtc_description">Дозволяє встановити власний час (Real-time clock, або RTC), відмінний від системного.</string>
<string name="set_custom_rtc">Встановити RTC</string>
<string name="disable_nca_verification">Вимкнути перевірку NCA</string>
<string name="disable_nca_verification_description">Вимкає перевірку цілісності архівів вмісту NCA. Може покращити швидкість завантаження, але ризикує пошкодженням даних або тим, що недійсні файли залишаться непоміченими. Необхідно для роботи ігор та оновлень, які вимагають прошивки 20+.</string>
<!-- Network settings strings -->
<string name="generate">Створити</string>
@ -811,9 +809,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Типово</string>
<string name="dma_accuracy_normal">Нормальний</string>
<string name="dma_accuracy_high">Високий</string>
<string name="dma_accuracy_extreme">Екстремальний</string>
<string name="dma_accuracy_unsafe">Небезпечно (швидко)</string>
<string name="dma_accuracy_safe">Безпечно (стабільно)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Bỏ qua một số lần vô hiệu hóa bộ nhớ đệm phía CPU trong khi cập nhật bộ nhớ, giảm mức sử dụng CPU và cải thiện hiệu suất. Có thể gây ra lỗi hoặc treo máy trong một số trò chơi.</string>
<string name="cpuopt_unsafe_host_mmu">Bật giả lập MMU Máy chủ</string>
<string name="cpuopt_unsafe_host_mmu_description">Tối ưu hóa này tăng tốc độ truy cập bộ nhớ của chương trình khách. Bật nó lên khiến các thao tác đọc/ghi bộ nhớ khách được thực hiện trực tiếp vào bộ nhớ và sử dụng MMU của Máy chủ. Tắt tính năng này buộc tất cả quyền truy cập bộ nhớ phải sử dụng Giả lập MMU Phần mềm.</string>
<string name="dma_accuracy">Cấp độ DMA</string>
<string name="dma_accuracy_description">Điều khiển độ chính xác của DMA. Độ chính xác cao hơn có thể sửa lỗi trong một số trò chơi, nhưng cũng có thể ảnh hưởng đến hiệu suất trong một số trường hợp. Nếu không chắc chắn, hãy để ở Mặc định.</string>
<string name="dma_accuracy">Độ chính xác DMA</string>
<string name="dma_accuracy_description">Điều khiển độ chính xác của DMA. Độ chính xác an toàn có thể khắc phục sự cố trong một số trò chơi, nhưng trong một số trường hợp cũng có thể ảnh hưởng đến hiệu suất. Nếu không chắc chắn, hãy để giá trị này ở Mặc định.</string>
<string name="memory_4gb">4GB (Được đề xuất)</string>
<string name="memory_6gb">6GB (Không an toàn)</string>
@ -482,8 +482,6 @@
<string name="use_custom_rtc">RTC tuỳ chỉnh</string>
<string name="use_custom_rtc_description">Cho phép bạn thiết lập một đồng hồ thời gian thực tùy chỉnh riêng biệt so với thời gian hệ thống hiện tại.</string>
<string name="set_custom_rtc">Thiết lập RTC tùy chỉnh</string>
<string name="disable_nca_verification">Tắt xác minh NCA</string>
<string name="disable_nca_verification_description">Tắt xác minh tính toàn vẹn của kho lưu trữ nội dung NCA. Có thể cải thiện tốc độ tải nhưng có nguy cơ hỏng dữ liệu hoặc các tệp không hợp lệ không bị phát hiện. Cần thiết để các trò chơi và bản cập nhật yêu cầu firmware 20+ hoạt động.</string>
<!-- Network settings strings -->
<string name="generate">Tạo</string>
@ -776,9 +774,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Mặc định</string>
<string name="dma_accuracy_normal">Bình thường</string>
<string name="dma_accuracy_high">Cao</string>
<string name="dma_accuracy_extreme">Cực cao</string>
<string name="dma_accuracy_unsafe">Không an toàn (nhanh)</string>
<string name="dma_accuracy_safe">An toàn (ổn định)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -127,8 +127,8 @@
<string name="skip_cpu_inner_invalidation_description">在内存更新期间跳过某些CPU端缓存无效化减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
<string name="cpuopt_unsafe_host_mmu">启用主机 MMU 模拟</string>
<string name="cpuopt_unsafe_host_mmu_description">此优化可加速来宾程序的内存访问。启用后,来宾内存读取/写入将直接在内存中执行并利用主机的 MMU。禁用此功能将强制所有内存访问使用软件 MMU 模拟。</string>
<string name="dma_accuracy">DMA 级别</string>
<string name="dma_accuracy_description">控制 DMA 精度。更高的精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。</string>
<string name="dma_accuracy">DMA 精度</string>
<string name="dma_accuracy_description">控制 DMA 精度。安全精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。</string>
<string name="memory_4gb">4GB (推荐)</string>
<string name="memory_6gb">6GB (不安全)</string>
@ -500,8 +500,6 @@
<string name="use_custom_rtc">自定义系统时间</string>
<string name="use_custom_rtc_description">此选项允许您设置与目前系统时间相独立的自定义系统时钟。</string>
<string name="set_custom_rtc">设置自定义系统时间</string>
<string name="disable_nca_verification">禁用NCA验证</string>
<string name="disable_nca_verification_description">禁用NCA内容存档的完整性验证。可能会提高加载速度但存在数据损坏或无效文件未被检测到的风险。对于需要固件20+的游戏和更新是必需的。</string>
<!-- Network settings strings -->
<string name="generate">生成</string>
@ -914,9 +912,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">默认</string>
<string name="dma_accuracy_normal">普通</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">极高</string>
<string name="dma_accuracy_unsafe">不安全(快速)</string>
<string name="dma_accuracy_safe">安全(稳定)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -120,8 +120,8 @@
<string name="skip_cpu_inner_invalidation_description">在記憶體更新期間跳過某些CPU端快取無效化減少CPU使用率並提高其性能。可能會導致某些遊戲出現故障或崩潰。</string>
<string name="cpuopt_unsafe_host_mmu">啟用主機 MMU 模擬</string>
<string name="cpuopt_unsafe_host_mmu_description">此最佳化可加速來賓程式的記憶體存取。啟用後,來賓記憶體讀取/寫入將直接在記憶體中執行並利用主機的 MMU。停用此功能將強制所有記憶體存取使用軟體 MMU 模擬。</string>
<string name="dma_accuracy">DMA 級別</string>
<string name="dma_accuracy_description">控制 DMA 精確度。更高的精確度可以修復某些遊戲中的問題,但在某些情況下也可能影響效能。如果不確定,請保留為「預設」。</string>
<string name="dma_accuracy">DMA 精度</string>
<string name="dma_accuracy_description">控制 DMA 精度。安全精度可以修復某些遊戲中的問題,但在某些情況下也可能影響效能。如果不確定,請保留為「預設」。</string>
<!-- Memory Layouts -->
<string name="memory_4gb">4GB (推薦)</string>
@ -505,8 +505,6 @@
<string name="use_custom_rtc">自訂 RTC</string>
<string name="use_custom_rtc_description">允許您設定與您的目前系統時間相互獨立的自訂即時時鐘。</string>
<string name="set_custom_rtc">設定自訂 RTC</string>
<string name="disable_nca_verification">停用NCA驗證</string>
<string name="disable_nca_verification_description">停用NCA內容存檔的完整性驗證。可能會提高載入速度但存在資料損毀或無效檔案未被偵測到的風險。對於需要韌體20+的遊戲和更新是必需的。</string>
<!-- Network settings strings -->
<string name="generate">生成</string>
@ -919,9 +917,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">預設</string>
<string name="dma_accuracy_normal">普通</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">極高</string>
<string name="dma_accuracy_unsafe">不安全(快速)</string>
<string name="dma_accuracy_safe">安全(穩定)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -454,15 +454,13 @@
<string-array name="dmaAccuracyNames">
<item>@string/dma_accuracy_default</item>
<item>@string/dma_accuracy_normal</item>
<item>@string/dma_accuracy_high</item>
<item>@string/dma_accuracy_extreme</item>
<item>@string/dma_accuracy_unsafe</item>
<item>@string/dma_accuracy_safe</item>
</string-array>
<integer-array name="dmaAccuracyValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</integer-array>
<string-array name="appletEntries">

View file

@ -115,8 +115,8 @@
<string name="fast_cpu_time_description">Use Boost (1700MHz) to run at the Switch\'s highest native clock, or Fast (2000MHz) to run at 2x clock.</string>
<string name="memory_layout">Memory Layout</string>
<string name="memory_layout_description">(EXPERIMENTAL) Change the emulated memory layout. This setting will not increase performance, but may help with games utilizing high resolutions via mods. Do not use on phones with 8GB of RAM or less. Only works on the Dynarmic (JIT) backend.</string>
<string name="dma_accuracy">DMA Level</string>
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Higher precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave it at Default.</string>
<string name="dma_accuracy">DMA Accuracy</string>
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default.</string>
<!-- Shader Backend -->
<string name="shader_backend">Shader Backend</string>
@ -266,6 +266,7 @@
<string name="alphabetical">Alphabetical</string>
<string name="view_list">List</string>
<string name="view_grid">Grid</string>
<string name="view_grid_compact">Compact Grid</string>
<string name="view_carousel">Carousel</string>
<string name="game_image_desc">Screenshot for %1$s</string>
<string name="folder">Folder</string>
@ -474,8 +475,6 @@
<string name="use_custom_rtc">Custom RTC</string>
<string name="use_custom_rtc_description">Allows you to set a custom real-time clock separate from your current system time.</string>
<string name="set_custom_rtc">Set custom RTC</string>
<string name="disable_nca_verification">Disable NCA Verification</string>
<string name="disable_nca_verification_description">Disables integrity verification of NCA content archives. This may improve loading speed but risks data corruption or invalid files going undetected. Some games that require firmware versions 20+ may need this as well.</string>
<string name="generate">Generate</string>
@ -784,9 +783,6 @@
<string name="loader_requires_firmware">Game Requires Firmware</string>
<string name="loader_requires_firmware_description"><![CDATA[The game you are trying to launch requires firmware to boot or to get past the opening menu. Please <a href="https://yuzu-mirror.github.io/help/quickstart"> dump and install firmware</a>, or press "OK" to launch anyways.]]></string>
<string name="nca_verification_disabled">NCA Verification Disabled</string>
<string name="nca_verification_disabled_description">This is required to run new games and updates, but may cause instability or crashes if NCA files are corrupt, modified, or tampered with. If unsure, re-enable verification in Advanced Settings -> System, and use firmware versions of 19.0.1 or below.</string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Searching for game...</string>
<string name="game_not_found_for_title_id">Game not found for Title ID: %1$s</string>
@ -944,9 +940,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Default</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">High</string>
<string name="dma_accuracy_extreme">Extreme</string>
<string name="dma_accuracy_unsafe">Unsafe (fast)</string>
<string name="dma_accuracy_safe">Safe (stable)</string>
<!-- ASTC Decoding Method -->
<string name="accelerate_astc">ASTC Decoding Method</string>

View file

@ -154,11 +154,19 @@ bool IsGPULevelHigh() {
values.current_gpu_accuracy == GpuAccuracy::High;
}
bool IsDMALevelDefault() {
return values.dma_accuracy.GetValue() == DmaAccuracy::Default;
}
bool IsDMALevelSafe() {
return values.dma_accuracy.GetValue() == DmaAccuracy::Safe;
}
bool IsFastmemEnabled() {
if (values.cpu_debug_mode) {
return static_cast<bool>(values.cpuopt_fastmem);
}
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) {
if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) {
return static_cast<bool>(values.cpuopt_unsafe_host_mmu);
}
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__)

View file

@ -443,7 +443,7 @@ struct Values {
SwitchableSetting<DmaAccuracy, true> dma_accuracy{linkage,
DmaAccuracy::Default,
DmaAccuracy::Default,
DmaAccuracy::Extreme,
DmaAccuracy::Safe,
"dma_accuracy",
Category::RendererAdvanced,
Specialization::Default,
@ -626,10 +626,6 @@ struct Values {
true, true, &rng_seed_enabled};
Setting<std::string> device_name{
linkage, "Eden", "device_name", Category::System, Specialization::Default, true, true};
SwitchableSetting<bool> disable_nca_verification{linkage, true, "disable_nca_verification",
Category::System, Specialization::Default};
Setting<bool> hide_nca_verification_popup{
linkage, false, "hide_nca_verification_popup", Category::System, Specialization::Default};
Setting<s32> current_user{linkage, 0, "current_user", Category::System};
@ -787,6 +783,9 @@ void UpdateGPUAccuracy();
bool IsGPULevelExtreme();
bool IsGPULevelHigh();
bool IsDMALevelDefault();
bool IsDMALevelSafe();
bool IsFastmemEnabled();
void SetNceEnabled(bool is_64bit);
bool IsNceEnabled();

View file

@ -136,7 +136,7 @@ ENUM(ShaderBackend, Glsl, Glasm, SpirV);
ENUM(GpuAccuracy, Normal, High, Extreme);
ENUM(DmaAccuracy, Default, Normal, High, Extreme);
ENUM(DmaAccuracy, Default, Unsafe, Safe);
ENUM(CpuBackend, Dynarmic, Nce);

View file

@ -1200,7 +1200,7 @@ else()
target_link_libraries(core PUBLIC Boost::headers)
endif()
target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API mbedtls mbedcrypto)
target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API MbedTLS::mbedcrypto MbedTLS::mbedtls)
if (MINGW)
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
endif()

View file

@ -210,12 +210,8 @@ std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* pa
config.wall_clock_cntpct = m_uses_wall_clock;
config.enable_cycle_counting = !m_uses_wall_clock;
// Code cache size
#ifdef ARCHITECTURE_arm64
// Code cache size - max in ARM is 128MiB, max in x86_64 is 2GiB
config.code_cache_size = std::uint32_t(128_MiB);
#else
config.code_cache_size = std::uint32_t(512_MiB);
#endif
// Allow memory fault handling to work
if (m_system.DebuggerEnabled()) {
@ -305,7 +301,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* pa
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
}
// Paranoid mode for debugging optimizations
// Paranoia mode for debugging optimizations
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) {
config.unsafe_optimizations = false;
config.optimizations = Dynarmic::no_optimizations;

View file

@ -269,12 +269,8 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
config.wall_clock_cntpct = m_uses_wall_clock;
config.enable_cycle_counting = !m_uses_wall_clock;
// Code cache size
#ifdef ARCHITECTURE_arm64
// Code cache size - max in ARM is 128MiB, max in x86_64 is 2GiB
config.code_cache_size = std::uint32_t(128_MiB);
#else
config.code_cache_size = std::uint32_t(512_MiB);
#endif
// Allow memory fault handling to work
if (m_system.DebuggerEnabled()) {

View file

@ -16,7 +16,7 @@ struct CipherContext;
enum class Mode {
CTR = 11,
ECB = 2,
XTS = 70,
XTS = 74,
};
enum class Op {

View file

@ -539,7 +539,7 @@ static std::array<u8, target_size> MGF1(const std::array<u8, in_size>& seed) {
while (out.size() < target_size) {
out.resize(out.size() + 0x20);
seed_exp[in_size + 3] = static_cast<u8>(i);
mbedtls_sha256_ret(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0);
mbedtls_sha256(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0);
++i;
}

View file

@ -178,7 +178,7 @@ std::array<u8, key_size> FindKeyFromHex(const std::vector<u8>& binary,
std::array<u8, 0x20> temp{};
for (size_t i = 0; i < binary.size() - key_size; ++i) {
mbedtls_sha256_ret(binary.data() + i, key_size, temp.data(), 0);
mbedtls_sha256(binary.data() + i, key_size, temp.data(), 0);
if (temp != hash)
continue;
@ -206,7 +206,7 @@ static std::array<Key128, 0x20> FindEncryptedMasterKeyFromHex(const std::vector<
AESCipher<Key128> cipher(key, Mode::ECB);
for (size_t i = 0; i < binary.size() - 0x10; ++i) {
cipher.Transcode(binary.data() + i, dec_temp.size(), dec_temp.data(), Op::Decrypt);
mbedtls_sha256_ret(dec_temp.data(), dec_temp.size(), temp.data(), 0);
mbedtls_sha256(dec_temp.data(), dec_temp.size(), temp.data(), 0);
for (size_t k = 0; k < out.size(); ++k) {
if (temp == master_key_hashes[k]) {

View file

@ -238,9 +238,7 @@ void BucketTree::Initialize(size_t node_size, s64 end_offset) {
ASSERT(NodeSizeMin <= node_size && node_size <= NodeSizeMax);
ASSERT(Common::IsPowerOfTwo(node_size));
if (!Settings::values.disable_nca_verification.GetValue()) {
ASSERT(end_offset > 0);
}
ASSERT(end_offset > 0);
ASSERT(!this->IsInitialized());
m_node_size = node_size;

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@ -1296,91 +1296,65 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl(
ASSERT(base_storage != nullptr);
ASSERT(layer_info_offset >= 0);
if (!Settings::values.disable_nca_verification.GetValue()) {
// Define storage types.
using VerificationStorage = HierarchicalIntegrityVerificationStorage;
using StorageInfo = VerificationStorage::HierarchicalStorageInformation;
// Define storage types.
using VerificationStorage = HierarchicalIntegrityVerificationStorage;
using StorageInfo = VerificationStorage::HierarchicalStorageInformation;
// Validate the meta info.
HierarchicalIntegrityVerificationInformation level_hash_info;
std::memcpy(std::addressof(level_hash_info), std::addressof(meta_info.level_hash_info),
sizeof(level_hash_info));
// Validate the meta info.
HierarchicalIntegrityVerificationInformation level_hash_info;
std::memcpy(std::addressof(level_hash_info),
std::addressof(meta_info.level_hash_info),
sizeof(level_hash_info));
R_UNLESS(IntegrityMinLayerCount <= level_hash_info.max_layers,
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
R_UNLESS(level_hash_info.max_layers <= IntegrityMaxLayerCount,
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
R_UNLESS(IntegrityMinLayerCount <= level_hash_info.max_layers,
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
R_UNLESS(level_hash_info.max_layers <= IntegrityMaxLayerCount,
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
// Get the base storage size.
s64 base_storage_size = base_storage->GetSize();
// Get the base storage size.
s64 base_storage_size = base_storage->GetSize();
// Create storage info.
StorageInfo storage_info;
for (s32 i = 0; i < static_cast<s32>(level_hash_info.max_layers - 2); ++i) {
const auto& layer_info = level_hash_info.info[i];
R_UNLESS(layer_info_offset + layer_info.offset + layer_info.size <= base_storage_size,
ResultNcaBaseStorageOutOfRangeD);
storage_info[i + 1] = std::make_shared<OffsetVfsFile>(
base_storage, layer_info.size, layer_info_offset + layer_info.offset);
}
// Set the last layer info.
const auto& layer_info = level_hash_info.info[level_hash_info.max_layers - 2];
const s64 last_layer_info_offset = layer_info_offset > 0 ? 0LL : layer_info.offset.Get();
R_UNLESS(last_layer_info_offset + layer_info.size <= base_storage_size,
// Create storage info.
StorageInfo storage_info;
for (s32 i = 0; i < static_cast<s32>(level_hash_info.max_layers - 2); ++i) {
const auto& layer_info = level_hash_info.info[i];
R_UNLESS(layer_info_offset + layer_info.offset + layer_info.size <= base_storage_size,
ResultNcaBaseStorageOutOfRangeD);
if (layer_info_offset > 0) {
R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset,
ResultRomNcaInvalidIntegrityLayerInfoOffset);
}
storage_info[level_hash_info.max_layers - 1] = std::make_shared<OffsetVfsFile>(
std::move(base_storage), layer_info.size, last_layer_info_offset);
// Make the integrity romfs storage.
auto integrity_storage = std::make_shared<IntegrityRomFsStorage>();
R_UNLESS(integrity_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
// Initialize the integrity storage.
R_TRY(integrity_storage->Initialize(level_hash_info, meta_info.master_hash, storage_info,
max_data_cache_entries, max_hash_cache_entries,
buffer_level));
// Set the output.
*out = std::move(integrity_storage);
R_SUCCEED();
} else {
// Read IVFC layout
HierarchicalIntegrityVerificationInformation lhi{};
std::memcpy(std::addressof(lhi), std::addressof(meta_info.level_hash_info), sizeof(lhi));
R_UNLESS(IntegrityMinLayerCount <= lhi.max_layers,
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
R_UNLESS(lhi.max_layers <= IntegrityMaxLayerCount,
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
const auto& data_li = lhi.info[lhi.max_layers - 2];
const s64 base_size = base_storage->GetSize();
// Compute the data layer window
const s64 data_off = (layer_info_offset > 0) ? 0LL : data_li.offset.Get();
R_UNLESS(data_off + data_li.size <= base_size, ResultNcaBaseStorageOutOfRangeD);
if (layer_info_offset > 0) {
R_UNLESS(data_off + data_li.size <= layer_info_offset,
ResultRomNcaInvalidIntegrityLayerInfoOffset);
}
// TODO: Passthrough (temporary compatibility: integrity disabled)
auto data_view = std::make_shared<OffsetVfsFile>(base_storage, data_li.size, data_off);
R_UNLESS(data_view != nullptr, ResultAllocationMemoryFailedAllocateShared);
auto passthrough = std::make_shared<PassthroughStorage>(std::move(data_view));
R_UNLESS(passthrough != nullptr, ResultAllocationMemoryFailedAllocateShared);
*out = std::move(passthrough);
R_SUCCEED();
storage_info[i + 1] = std::make_shared<OffsetVfsFile>(base_storage,
layer_info.size,
layer_info_offset + layer_info.offset);
}
// Set the last layer info.
const auto& layer_info = level_hash_info.info[level_hash_info.max_layers - 2];
const s64 last_layer_info_offset = layer_info_offset > 0 ? 0LL : layer_info.offset.Get();
R_UNLESS(last_layer_info_offset + layer_info.size <= base_storage_size,
ResultNcaBaseStorageOutOfRangeD);
if (layer_info_offset > 0) {
R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset,
ResultRomNcaInvalidIntegrityLayerInfoOffset);
}
storage_info[level_hash_info.max_layers - 1]
= std::make_shared<OffsetVfsFile>(std::move(base_storage),
layer_info.size,
last_layer_info_offset);
// Make the integrity romfs storage.
auto integrity_storage = std::make_shared<IntegrityRomFsStorage>();
R_UNLESS(integrity_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
// Initialize the integrity storage.
R_TRY(integrity_storage->Initialize(level_hash_info,
meta_info.master_hash,
storage_info,
max_data_cache_entries,
max_hash_cache_entries,
buffer_level));
// Set the output.
*out = std::move(integrity_storage);
R_SUCCEED();
}
Result NcaFileSystemDriver::CreateRegionSwitchStorage(VirtualFile* out,

View file

@ -64,7 +64,7 @@ static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bo
}
Core::Crypto::SHA256Hash hash{};
mbedtls_sha256_ret(nca_id.data(), nca_id.size(), hash.data(), 0);
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
const auto format_str =
fmt::runtime(cnmt_suffix ? "/000000{:02X}/{}.cnmt.nca" : "/000000{:02X}/{}.nca");
@ -146,7 +146,7 @@ bool PlaceholderCache::Create(const NcaID& id, u64 size) const {
}
Core::Crypto::SHA256Hash hash{};
mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0);
mbedtls_sha256(id.data(), id.size(), hash.data(), 0);
const auto dirname = fmt::format("000000{:02X}", hash[0]);
const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname);
@ -170,7 +170,7 @@ bool PlaceholderCache::Delete(const NcaID& id) const {
}
Core::Crypto::SHA256Hash hash{};
mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0);
mbedtls_sha256(id.data(), id.size(), hash.data(), 0);
const auto dirname = fmt::format("000000{:02X}", hash[0]);
const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname);
@ -665,7 +665,7 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
const OptionalHeader opt_header{0, 0};
ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca.GetType()), {}};
const auto& data = nca.GetBaseFile()->ReadBytes(0x100000);
mbedtls_sha256_ret(data.data(), data.size(), c_rec.hash.data(), 0);
mbedtls_sha256(data.data(), data.size(), c_rec.hash.data(), 0);
std::memcpy(&c_rec.nca_id, &c_rec.hash, 16);
const CNMT new_cnmt(header, opt_header, {c_rec}, {});
if (!RawInstallYuzuMeta(new_cnmt)) {
@ -776,7 +776,7 @@ InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFuncti
id = *override_id;
} else {
const auto& data = in->ReadBytes(0x100000);
mbedtls_sha256_ret(data.data(), data.size(), hash.data(), 0);
mbedtls_sha256(data.data(), data.size(), hash.data(), 0);
memcpy(id.data(), hash.data(), 16);
}

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 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
@ -126,6 +129,10 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir,
std::string out = GetSaveDataSpaceIdPath(space);
LOG_INFO(Common_Filesystem, "Save ID: {:016X}", save_id);
LOG_INFO(Common_Filesystem, "User ID[1]: {:016X}", user_id[1]);
LOG_INFO(Common_Filesystem, "User ID[0]: {:016X}", user_id[0]);
switch (type) {
case SaveDataType::System:
return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]);

View file

@ -68,7 +68,7 @@ NAX::NAX(VirtualFile file_, std::array<u8, 0x10> nca_id)
: header(std::make_unique<NAXHeader>()),
file(std::move(file_)), keys{Core::Crypto::KeyManager::Instance()} {
Core::Crypto::SHA256Hash hash{};
mbedtls_sha256_ret(nca_id.data(), nca_id.size(), hash.data(), 0);
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
status = Parse(fmt::format("/registered/000000{:02X}/{}.nca", hash[0],
Common::HexToString(nca_id, false)));
}

View file

@ -15,7 +15,7 @@ namespace Service::BCAT {
static BcatDigest DigestFile(const FileSys::VirtualFile& file) {
BcatDigest out{};
const auto bytes = file->ReadAllBytes();
mbedtls_md5_ret(bytes.data(), bytes.size(), out.data());
mbedtls_md5(bytes.data(), bytes.size(), out.data());
return out;
}

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -97,18 +100,18 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
slots[slot].needs_cleanup_on_release = false;
slots[slot].buffer_state = BufferState::Acquired;
// Mark tracked buffer history records as acquired
for (auto& buffer_history_record : core->buffer_history) {
if (buffer_history_record.frame_number == core->frame_counter) {
buffer_history_record.state = BufferState::Acquired;
break;
}
}
// TODO: for now, avoid resetting the fence, so that when we next return this
// slot to the producer, it will wait for the fence to pass. We should fix this
// by properly waiting for the fence in the BufferItemConsumer.
// slots[slot].fence = Fence::NoFence();
const auto target_frame_number = slots[slot].frame_number;
for (size_t i = 0; i < core->history.size(); i++) {
if (core->history[i].frame_number == target_frame_number) {
core->history[i].state = BufferState::Acquired;
break;
}
}
}
// If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -10,12 +13,19 @@
namespace Service::android {
BufferQueueCore::BufferQueueCore() {
history.resize(8);
};
BufferQueueCore::BufferQueueCore() = default;
BufferQueueCore::~BufferQueueCore() = default;
void BufferQueueCore::PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state) {
buffer_history_pos = (buffer_history_pos + 1) % BUFFER_HISTORY_SIZE;
buffer_history[buffer_history_pos] = BufferHistoryInfo{
.frame_number = frame_number,
.queue_time = queue_time,
.presentation_time = presentation_time,
.state = state,
};
}
void BufferQueueCore::SignalDequeueCondition() {
dequeue_possible.store(true);
dequeue_condition.notify_all();
@ -47,7 +57,7 @@ s32 BufferQueueCore::GetMinMaxBufferCountLocked(bool async) const {
s32 BufferQueueCore::GetMaxBufferCountLocked(bool async) const {
const auto min_buffer_count = GetMinMaxBufferCountLocked(async);
auto max_buffer_count = (std::max)(default_max_buffer_count, min_buffer_count);
auto max_buffer_count = std::max(default_max_buffer_count, min_buffer_count);
if (override_max_buffer_count != 0) {
ASSERT(override_max_buffer_count >= min_buffer_count);

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -15,6 +18,7 @@
#include "core/hle/service/nvnflinger/buffer_item.h"
#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
#include "core/hle/service/nvnflinger/buffer_slot.h"
#include "core/hle/service/nvnflinger/pixel_format.h"
#include "core/hle/service/nvnflinger/status.h"
#include "core/hle/service/nvnflinger/window.h"
@ -23,22 +27,19 @@ namespace Service::android {
#ifdef _MSC_VER
#pragma pack(push, 1)
struct BufferHistoryInfo {
#elif defined(__GNUC__) || defined(__clang__)
struct __attribute__((packed)) BufferHistoryInfo {
#endif
struct BufferInfo {
u64 frame_number;
s64 queue_time;
s64 presentation_time{};
BufferState state{BufferState::Free};
}
#if defined(__GNUC__) || defined(__clang__)
__attribute__((packed))
#endif
;
s64 presentation_time;
BufferState state;
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
static_assert(sizeof(BufferInfo) == 0x1C,
"BufferInfo is an invalid size");
static_assert(sizeof(BufferHistoryInfo) == 0x1C, "BufferHistoryInfo must be 28 bytes");
class IConsumerListener;
class IProducerListener;
@ -49,10 +50,13 @@ class BufferQueueCore final {
public:
static constexpr s32 INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT;
static constexpr u32 BUFFER_HISTORY_SIZE = 8;
BufferQueueCore();
~BufferQueueCore();
void PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state);
private:
void SignalDequeueCondition();
bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk);
@ -88,11 +92,11 @@ private:
const s32 max_acquired_buffer_count{}; // This is always zero on HOS
bool buffer_has_been_queued{};
u64 frame_counter{};
std::array<BufferHistoryInfo, BUFFER_HISTORY_SIZE> buffer_history{};
u32 buffer_history_pos{BUFFER_HISTORY_SIZE-1};
u32 transform_hint{};
bool is_allocating{};
mutable std::condition_variable_any is_allocating_condition;
std::vector<BufferInfo> history{8};
};
} // namespace Service::android

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -530,11 +533,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
item.is_droppable = core->dequeue_buffer_cannot_block || async;
item.swap_interval = swap_interval;
position = (position + 1) % 8;
core->history[position] = {.frame_number = core->frame_counter,
.queue_time = slots[slot].queue_time,
.state = BufferState::Queued};
sticky_transform = sticky_transform_;
if (core->queue.empty()) {
@ -551,6 +549,15 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
// mark it as freed
if (core->StillTracking(*front)) {
slots[front->slot].buffer_state = BufferState::Free;
// Mark tracked buffer history records as free
for (auto& buffer_history_record : core->buffer_history) {
if (buffer_history_record.frame_number == front->frame_number) {
buffer_history_record.state = BufferState::Free;
break;
}
}
// Reset the frame number of the freed buffer so that it is the first in line to
// be dequeued again
slots[front->slot].frame_number = 0;
@ -564,6 +571,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
}
}
core->PushHistory(core->frame_counter, slots[slot].queue_time, slots[slot].presentation_time, BufferState::Queued);
core->buffer_has_been_queued = true;
core->SignalDequeueCondition();
output->Inflate(core->default_width, core->default_height, core->transform_hint,
@ -938,33 +946,46 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
break;
}
case TransactionId::GetBufferHistory: {
LOG_WARNING(Service_Nvnflinger, "called, transaction=GetBufferHistory");
LOG_DEBUG(Service_Nvnflinger, "called, transaction=GetBufferHistory");
std::scoped_lock lock{core->mutex};
auto buffer_history_count = (std::min)(parcel_in.Read<s32>(), (s32)core->history.size());
if (buffer_history_count <= 0) {
const s32 request = parcel_in.Read<s32>();
if (request <= 0) {
parcel_out.Write(Status::BadValue);
parcel_out.Write<s32>(0);
status = Status::None;
break;
}
auto info = new BufferInfo[buffer_history_count];
auto pos = position;
for (int i = 0; i < buffer_history_count; i++) {
info[i] = core->history[(pos - i) % core->history.size()];
LOG_WARNING(Service_Nvnflinger, "frame_number={}, state={}",
core->history[(pos - i) % core->history.size()].frame_number,
(u32)core->history[(pos - i) % core->history.size()].state);
pos--;
constexpr u32 history_max = BufferQueueCore::BUFFER_HISTORY_SIZE;
std::array<BufferHistoryInfo, history_max> buffer_history_snapshot{};
s32 valid_index{};
{
std::scoped_lock lk(core->mutex);
const u32 current_history_pos = core->buffer_history_pos;
u32 index_reversed{};
for (u32 i = 0; i < history_max; ++i) {
// Wrap values backwards e.g. 7, 6, 5, etc. in the range of 0-7
index_reversed = (current_history_pos + history_max - i) % history_max;
const auto& current_history_buffer = core->buffer_history[index_reversed];
// Here we use the frame number as a terminator.
// Because a buffer without frame_number is not considered complete
if (current_history_buffer.frame_number == 0) {
break;
}
buffer_history_snapshot[valid_index] = current_history_buffer;
++valid_index;
}
}
const s32 limit = std::min(request, valid_index);
parcel_out.Write(Status::NoError);
parcel_out.Write(buffer_history_count);
parcel_out.WriteFlattenedObject<BufferInfo>(info);
status = Status::None;
parcel_out.Write<s32>(limit);
for (s32 i = 0; i < limit; ++i) {
parcel_out.Write(buffer_history_snapshot[i]);
}
break;
}
default:
@ -972,9 +993,7 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
break;
}
if (status != Status::None) {
parcel_out.Write(status);
}
parcel_out.Write(status);
const auto serialized = parcel_out.Serialize();
std::memcpy(parcel_reply.data(), serialized.data(),

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -15,7 +18,7 @@ namespace Service::android {
class GraphicBuffer;
enum class BufferState : s32 {
enum class BufferState : u32 {
Free = 0,
Dequeued = 1,
Queued = 2,

View file

@ -178,7 +178,7 @@ struct ProcessContext {
std::vector<u8> nro_data(size);
m_process->GetMemory().ReadBlock(base_address, nro_data.data(), size);
mbedtls_sha256_ret(nro_data.data(), size, hash.data(), 0);
mbedtls_sha256(nro_data.data(), size, hash.data(), 0);
}
for (size_t i = 0; i < MaxNrrInfos; i++) {

View file

@ -150,7 +150,7 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function<bool(size_t, size_t)>
// Initialize sha256 verification context.
mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
mbedtls_sha256_starts_ret(&ctx, 0);
mbedtls_sha256_starts(&ctx, 0);
// Ensure we maintain a clean state on exit.
SCOPE_EXIT {
@ -168,7 +168,7 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function<bool(size_t, size_t)>
const size_t read_size = file->Read(buffer.data(), intended_read_size, processed_size);
// Update the hash function with the buffer contents.
mbedtls_sha256_update_ret(&ctx, buffer.data(), read_size);
mbedtls_sha256_update(&ctx, buffer.data(), read_size);
// Update counters.
processed_size += read_size;
@ -181,7 +181,7 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function<bool(size_t, size_t)>
// Finalize context and compute the output hash.
std::array<u8, NcaSha256HashLength> output_hash;
mbedtls_sha256_finish_ret(&ctx, output_hash.data());
mbedtls_sha256_finish(&ctx, output_hash.data());
// Compare to expected.
if (std::memcmp(input_hash.data(), output_hash.data(), NcaSha256HalfHashLength) != 0) {

View file

@ -20,7 +20,7 @@ if (ENABLE_WEB_SERVICE)
target_link_libraries(yuzu-room PRIVATE web_service)
endif()
target_link_libraries(yuzu-room PRIVATE mbedtls mbedcrypto)
target_link_libraries(yuzu-room PRIVATE MbedTLS::mbedcrypto MbedTLS::mbedtls)
if (MSVC)
target_link_libraries(yuzu-room PRIVATE getopt)
endif()

View file

@ -39,9 +39,6 @@ option(DYNARMIC_INSTALL "Install dynarmic headers and CMake files" OFF)
option(DYNARMIC_USE_BUNDLED_EXTERNALS "Use all bundled externals (useful when e.g. cross-compiling)" OFF)
option(DYNARMIC_WARNINGS_AS_ERRORS "Warnings as errors" ${MASTER_PROJECT})
option(DYNARMIC_ENABLE_LTO "Enable LTO" OFF)
if (NOT DEFINED DYNARMIC_FRONTENDS)
set(DYNARMIC_FRONTENDS "A32;A64" CACHE STRING "Selects which frontends to enable")
endif()
# Default to a Release build
if (NOT CMAKE_BUILD_TYPE)

View file

@ -273,52 +273,73 @@ Exclusive OR (i.e.: XOR)
### Callback: {Read,Write}Memory{8,16,32,64}
<u8> ReadMemory8(<u32> vaddr)
<u8> ReadMemory16(<u32> vaddr)
<u8> ReadMemory32(<u32> vaddr)
<u8> ReadMemory64(<u32> vaddr)
<void> WriteMemory8(<u32> vaddr, <u8> value_to_store)
<void> WriteMemory16(<u32> vaddr, <u16> value_to_store)
<void> WriteMemory32(<u32> vaddr, <u32> value_to_store)
<void> WriteMemory64(<u32> vaddr, <u64> value_to_store)
```c++
<u8> ReadMemory8(<u32> vaddr)
<u8> ReadMemory16(<u32> vaddr)
<u8> ReadMemory32(<u32> vaddr)
<u8> ReadMemory64(<u32> vaddr)
<void> WriteMemory8(<u32> vaddr, <u8> value_to_store)
<void> WriteMemory16(<u32> vaddr, <u16> value_to_store)
<void> WriteMemory32(<u32> vaddr, <u32> value_to_store)
<void> WriteMemory64(<u32> vaddr, <u64> value_to_store)
```
Memory access.
### Terminal: Interpret
SetTerm(IR::Term::Interpret{next})
```c++
SetTerm(IR::Term::Interpret{next})
```
This terminal instruction calls the interpreter, starting at `next`.
The interpreter must interpret exactly one instruction.
### Terminal: ReturnToDispatch
SetTerm(IR::Term::ReturnToDispatch{})
```c++
SetTerm(IR::Term::ReturnToDispatch{})
```
This terminal instruction returns control to the dispatcher.
The dispatcher will use the value in R15 to determine what comes next.
### Terminal: LinkBlock
SetTerm(IR::Term::LinkBlock{next})
```c++
SetTerm(IR::Term::LinkBlock{next})
```
This terminal instruction jumps to the basic block described by `next` if we have enough
cycles remaining. If we do not have enough cycles remaining, we return to the
dispatcher, which will return control to the host.
### Terminal: LinkBlockFast
```c++
SetTerm(IR::Term::LinkBlockFast{next})
```
This terminal instruction jumps to the basic block described by `next` unconditionally.
This promises guarantees that must be held at runtime - i.e that the program wont hang,
### Terminal: PopRSBHint
SetTerm(IR::Term::PopRSBHint{})
```c++
SetTerm(IR::Term::PopRSBHint{})
```
This terminal instruction checks the top of the Return Stack Buffer against R15.
If RSB lookup fails, control is returned to the dispatcher.
This is an optimization for faster function calls. A backend that doesn't support
this optimization or doesn't have a RSB may choose to implement this exactly as
ReturnToDispatch.
`ReturnToDispatch`.
### Terminal: If
SetTerm(IR::Term::If{cond, term_then, term_else})
```c++
SetTerm(IR::Term::If{cond, term_then, term_else})
```
This terminal instruction conditionally executes one terminal or another depending
on the run-time state of the ARM flags.

View file

@ -0,0 +1,19 @@
# Fast memory (Fastmem)
The main way of accessing memory in JITed programs is via an invoked function, say "Read()" and "Write()". On our translator, such functions usually take a sizable amounts of code space (push + call + pop). Trash the i-cache (due to an indirect call) and overall make code emission more bloated.
The solution? Delegate invalid accesses to a dedicated arena, similar to a swap. The main idea behind such mechanism is to allow the OS to transmit page faults from invalid accesses into the JIT translator directly, bypassing address space calls, while this sacrifices i-cache coherency, it allows for smaller code-size and "faster" throguhput.
Many kernels however, do not support fast signal dispatching (Solaris, OpenBSD, FreeBSD). Only Linux and Windows support relatively "fast" signal dispatching. Hence this feature is better suited for them only.
![Host to guest translation](./HostToGuest.svg)
![Fastmem translation](./Fastmem.svg)
In x86_64 for example, when a page fault occurs, the CPU will transmit via control registers and the stack (see `IRETQ`) the appropriate arguments for a page fault handler, the OS then will transform that into something that can be sent into userspace.
Most modern OSes implement kernel-page-table-isolation, which means a set of system calls will invoke a context switch (not often used syscalls), whereas others are handled by the same process address space (the smaller kernel portion, often used syscalls) without needing a context switch. This effect can be negated on systems with PCID (up to 4096 unique IDs).
Signal dispatching takes a performance hit from reloading `%cr3` - but Linux does something more clever to avoid reloads: VDSO will take care of the entire thing in the same address space. Making dispatching as costly as an indirect call - without the hazards of increased code size.
The main downside from this is the constant i-cache trashing and pipeline hazards introduced by the VDSO signal handlers. However on most benchmarks fastmem does perform faster than without (Linux only). This also abuses the fact of continous address space emulation by using an arena - which can then be potentially transparently mapped into a hugepage, reducing TLB walk times.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 128 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 98 KiB

View file

@ -16,19 +16,34 @@ Note that `Use`ing a value decrements its `use_count` by one. When the `use_coun
The member functions on `RegAlloc` are just a combination of the above concepts.
The following registers are reserved for internal use and should NOT participate in register allocation:
- `%xmm0`, `%xmm1`, `%xmm2`: Used as scratch in exclusive memory access.
- `%rsp`: Stack pointer.
- `%r15`: JIT pointer
- `%r14`: Page table pointer.
- `%r13`: Fastmem pointer.
The layout convenes `%r15` as the JIT state pointer - while it may be tempting to turn it into a synthetic pointer, keeping an entire register (out of 12 available) is preferable over inlining a directly computed immediate.
Do NEVER modify `%r15`, we must make it clear that this register is "immutable" for the entirety of the JIT block duration.
### `Scratch`
Xbyak::Reg64 ScratchGpr(HostLocList desired_locations = any_gpr)
Xbyak::Xmm ScratchXmm(HostLocList desired_locations = any_xmm)
```c++
Xbyak::Reg64 ScratchGpr(HostLocList desired_locations = any_gpr);
Xbyak::Xmm ScratchXmm(HostLocList desired_locations = any_xmm);
```
At runtime, allocate one of the registers in `desired_locations`. You are free to modify the register. The register is discarded at the end of the allocation scope.
### Pure `Use`
Xbyak::Reg64 UseGpr(Argument& arg);
Xbyak::Xmm UseXmm(Argument& arg);
OpArg UseOpArg(Argument& arg);
void Use(Argument& arg, HostLoc host_loc);
```c++
Xbyak::Reg64 UseGpr(Argument& arg);
Xbyak::Xmm UseXmm(Argument& arg);
OpArg UseOpArg(Argument& arg);
void Use(Argument& arg, HostLoc host_loc);
```
At runtime, the value corresponding to `arg` will be placed a register. The actual register is determined by
which one of the above functions is called. `UseGpr` places it in an unused GPR, `UseXmm` places it
@ -39,9 +54,11 @@ This register **must not** have it's value changed.
### `UseScratch`
Xbyak::Reg64 UseScratchGpr(Argument& arg);
Xbyak::Xmm UseScratchXmm(Argument& arg);
void UseScratch(Argument& arg, HostLoc host_loc);
```c++
Xbyak::Reg64 UseScratchGpr(Argument& arg);
Xbyak::Xmm UseScratchXmm(Argument& arg);
void UseScratch(Argument& arg, HostLoc host_loc);
```
At runtime, the value corresponding to `arg` will be placed a register. The actual register is determined by
which one of the above functions is called. `UseScratchGpr` places it in an unused GPR, `UseScratchXmm` places it
@ -55,7 +72,9 @@ You are free to modify the value in the register. The register is discarded at t
A `Define` is the defintion of a value. This is the only time when a value may be set.
void DefineValue(IR::Inst* inst, const Xbyak::Reg& reg);
```c++
void DefineValue(IR::Inst* inst, const Xbyak::Reg& reg);
```
By calling `DefineValue`, you are stating that you wish to define the value for `inst`, and you have written the
value to the specified register `reg`.
@ -64,7 +83,9 @@ value to the specified register `reg`.
Adding a `Define` to an existing value.
void DefineValue(IR::Inst* inst, Argument& arg);
```c++
void DefineValue(IR::Inst* inst, Argument& arg);
```
You are declaring that the value for `inst` is the same as the value for `arg`. No host machine instructions are
emitted.

View file

@ -23,15 +23,17 @@ One complication dynarmic has is that a compiled block is not uniquely identifia
the PC alone, but bits in the FPSCR and CPSR are also relevant. We resolve this by
computing a 64-bit `UniqueHash` that is guaranteed to uniquely identify a block.
u64 LocationDescriptor::UniqueHash() const {
// This value MUST BE UNIQUE.
// This calculation has to match up with EmitX64::EmitTerminalPopRSBHint
u64 pc_u64 = u64(arm_pc) << 32;
u64 fpscr_u64 = u64(fpscr.Value());
u64 t_u64 = cpsr.T() ? 1 : 0;
u64 e_u64 = cpsr.E() ? 2 : 0;
return pc_u64 | fpscr_u64 | t_u64 | e_u64;
}
```c++
u64 LocationDescriptor::UniqueHash() const {
// This value MUST BE UNIQUE.
// This calculation has to match up with EmitX64::EmitTerminalPopRSBHint
u64 pc_u64 = u64(arm_pc) << 32;
u64 fpscr_u64 = u64(fpscr.Value());
u64 t_u64 = cpsr.T() ? 1 : 0;
u64 e_u64 = cpsr.E() ? 2 : 0;
return pc_u64 | fpscr_u64 | t_u64 | e_u64;
}
```
## Our implementation isn't actually a stack
@ -49,97 +51,107 @@ host addresses for the corresponding the compiled blocks.
size of the real RSB in hardware (which has 3 entries). Larger RSBs than 8
showed degraded performance.
struct JitState {
// ...
```c++
struct JitState {
// ...
static constexpr size_t RSBSize = 8; // MUST be a power of 2.
u32 rsb_ptr = 0;
std::array<u64, RSBSize> rsb_location_descriptors;
std::array<u64, RSBSize> rsb_codeptrs;
void ResetRSB();
static constexpr size_t RSBSize = 8; // MUST be a power of 2.
u32 rsb_ptr = 0;
std::array<u64, RSBSize> rsb_location_descriptors;
std::array<u64, RSBSize> rsb_codeptrs;
void ResetRSB();
// ...
};
// ...
};
```
### RSB Push
We insert our prediction at the insertion point iff the RSB doesn't already
contain a prediction with the same `UniqueHash`.
void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) {
using namespace Xbyak::util;
```c++
void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) {
using namespace Xbyak::util;
ASSERT(inst->GetArg(0).IsImmediate());
u64 imm64 = inst->GetArg(0).GetU64();
ASSERT(inst->GetArg(0).IsImmediate());
u64 imm64 = inst->GetArg(0).GetU64();
Xbyak::Reg64 code_ptr_reg = reg_alloc.ScratchGpr({HostLoc::RCX});
Xbyak::Reg64 loc_desc_reg = reg_alloc.ScratchGpr();
Xbyak::Reg32 index_reg = reg_alloc.ScratchGpr().cvt32();
u64 code_ptr = unique_hash_to_code_ptr.find(imm64) != unique_hash_to_code_ptr.end()
? u64(unique_hash_to_code_ptr[imm64])
: u64(code->GetReturnFromRunCodeAddress());
Xbyak::Reg64 code_ptr_reg = reg_alloc.ScratchGpr({HostLoc::RCX});
Xbyak::Reg64 loc_desc_reg = reg_alloc.ScratchGpr();
Xbyak::Reg32 index_reg = reg_alloc.ScratchGpr().cvt32();
u64 code_ptr = unique_hash_to_code_ptr.find(imm64) != unique_hash_to_code_ptr.end()
? u64(unique_hash_to_code_ptr[imm64])
: u64(code->GetReturnFromRunCodeAddress());
code->mov(index_reg, dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)]);
code->add(index_reg, 1);
code->and_(index_reg, u32(JitState::RSBSize - 1));
code->mov(index_reg, dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)]);
code->add(index_reg, 1);
code->and_(index_reg, u32(JitState::RSBSize - 1));
code->mov(loc_desc_reg, u64(imm64));
CodePtr patch_location = code->getCurr<CodePtr>();
patch_unique_hash_locations[imm64].emplace_back(patch_location);
code->mov(code_ptr_reg, u64(code_ptr)); // This line has to match up with EmitX64::Patch.
code->EnsurePatchLocationSize(patch_location, 10);
code->mov(loc_desc_reg, u64(imm64));
CodePtr patch_location = code->getCurr<CodePtr>();
patch_unique_hash_locations[imm64].emplace_back(patch_location);
code->mov(code_ptr_reg, u64(code_ptr)); // This line has to match up with EmitX64::Patch.
code->EnsurePatchLocationSize(patch_location, 10);
Xbyak::Label label;
for (size_t i = 0; i < JitState::RSBSize; ++i) {
code->cmp(loc_desc_reg, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]);
code->je(label, code->T_SHORT);
}
code->mov(dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)], index_reg);
code->mov(qword[code.ABI_JIT_PTR + index_reg.cvt64() * 8 + offsetof(JitState, rsb_location_descriptors)], loc_desc_reg);
code->mov(qword[code.ABI_JIT_PTR + index_reg.cvt64() * 8 + offsetof(JitState, rsb_codeptrs)], code_ptr_reg);
code->L(label);
Xbyak::Label label;
for (size_t i = 0; i < JitState::RSBSize; ++i) {
code->cmp(loc_desc_reg, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]);
code->je(label, code->T_SHORT);
}
code->mov(dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)], index_reg);
code->mov(qword[code.ABI_JIT_PTR + index_reg.cvt64() * 8 + offsetof(JitState, rsb_location_descriptors)], loc_desc_reg);
code->mov(qword[code.ABI_JIT_PTR + index_reg.cvt64() * 8 + offsetof(JitState, rsb_codeptrs)], code_ptr_reg);
code->L(label);
}
```
In pseudocode:
for (i := 0 .. RSBSize-1)
if (rsb_location_descriptors[i] == imm64)
goto label;
rsb_ptr++;
rsb_ptr %= RSBSize;
rsb_location_desciptors[rsb_ptr] = imm64; //< The UniqueHash
rsb_codeptr[rsb_ptr] = /* codeptr corresponding to the UniqueHash */;
label:
```c++
for (i := 0 .. RSBSize-1)
if (rsb_location_descriptors[i] == imm64)
goto label;
rsb_ptr++;
rsb_ptr %= RSBSize;
rsb_location_desciptors[rsb_ptr] = imm64; //< The UniqueHash
rsb_codeptr[rsb_ptr] = /* codeptr corresponding to the UniqueHash */;
label:
```
## RSB Pop
To check if a predicition is in the RSB, we linearly scan the RSB.
void EmitX64::EmitTerminalPopRSBHint(IR::Term::PopRSBHint, IR::LocationDescriptor initial_location) {
using namespace Xbyak::util;
```c++
void EmitX64::EmitTerminalPopRSBHint(IR::Term::PopRSBHint, IR::LocationDescriptor initial_location) {
using namespace Xbyak::util;
// This calculation has to match up with IREmitter::PushRSB
code->mov(ecx, MJitStateReg(Arm::Reg::PC));
code->shl(rcx, 32);
code->mov(ebx, dword[code.ABI_JIT_PTR + offsetof(JitState, FPSCR_mode)]);
code->or_(ebx, dword[code.ABI_JIT_PTR + offsetof(JitState, CPSR_et)]);
code->or_(rbx, rcx);
// This calculation has to match up with IREmitter::PushRSB
code->mov(ecx, MJitStateReg(Arm::Reg::PC));
code->shl(rcx, 32);
code->mov(ebx, dword[code.ABI_JIT_PTR + offsetof(JitState, FPSCR_mode)]);
code->or_(ebx, dword[code.ABI_JIT_PTR + offsetof(JitState, CPSR_et)]);
code->or_(rbx, rcx);
code->mov(rax, u64(code->GetReturnFromRunCodeAddress()));
for (size_t i = 0; i < JitState::RSBSize; ++i) {
code->cmp(rbx, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]);
code->cmove(rax, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_codeptrs) + i * sizeof(u64)]);
}
code->jmp(rax);
code->mov(rax, u64(code->GetReturnFromRunCodeAddress()));
for (size_t i = 0; i < JitState::RSBSize; ++i) {
code->cmp(rbx, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]);
code->cmove(rax, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_codeptrs) + i * sizeof(u64)]);
}
code->jmp(rax);
}
```
In pseudocode:
rbx := ComputeUniqueHash()
rax := ReturnToDispatch
for (i := 0 .. RSBSize-1)
if (rbx == rsb_location_descriptors[i])
rax = rsb_codeptrs[i]
goto rax
```c++
rbx := ComputeUniqueHash()
rax := ReturnToDispatch
for (i := 0 .. RSBSize-1)
if (rbx == rsb_location_descriptors[i])
rax = rsb_codeptrs[i]
goto rax
```

View file

@ -56,14 +56,11 @@ add_library(dynarmic
common/lut_from_list.h
common/math_util.cpp
common/math_util.h
common/memory_pool.cpp
common/memory_pool.h
common/safe_ops.h
common/spin_lock.h
common/string_util.h
common/u128.cpp
common/u128.h
common/variant_util.h
frontend/A32/a32_types.cpp
frontend/A32/a32_types.h
frontend/A64/a64_types.cpp
@ -78,7 +75,6 @@ add_library(dynarmic
ir/basic_block.cpp
ir/basic_block.h
ir/cond.h
ir/ir_emitter.cpp
ir/ir_emitter.h
ir/location_descriptor.cpp
ir/location_descriptor.h
@ -87,78 +83,59 @@ add_library(dynarmic
ir/opcodes.cpp
ir/opcodes.h
ir/opcodes.inc
ir/opt/constant_propagation_pass.cpp
ir/opt/dead_code_elimination_pass.cpp
ir/opt/identity_removal_pass.cpp
ir/opt/ir_matcher.h
ir/opt/naming_pass.cpp
ir/opt/passes.h
ir/opt/polyfill_pass.cpp
ir/opt/verification_pass.cpp
ir/opt_passes.cpp
ir/opt_passes.h
ir/terminal.h
ir/type.cpp
ir/type.h
ir/value.cpp
ir/value.h
# A32
frontend/A32/a32_ir_emitter.cpp
frontend/A32/a32_ir_emitter.h
frontend/A32/a32_location_descriptor.cpp
frontend/A32/a32_location_descriptor.h
frontend/A32/decoder/arm.h
frontend/A32/decoder/arm.inc
frontend/A32/decoder/asimd.h
frontend/A32/decoder/asimd.inc
frontend/A32/decoder/thumb16.h
frontend/A32/decoder/thumb16.inc
frontend/A32/decoder/thumb32.h
frontend/A32/decoder/thumb32.inc
frontend/A32/decoder/vfp.h
frontend/A32/decoder/vfp.inc
frontend/A32/disassembler/disassembler.h
frontend/A32/disassembler/disassembler_arm.cpp
frontend/A32/disassembler/disassembler_thumb.cpp
frontend/A32/FPSCR.h
frontend/A32/ITState.h
frontend/A32/PSR.h
frontend/A32/translate/a32_translate.cpp
frontend/A32/translate/a32_translate.h
frontend/A32/translate/conditional_state.cpp
frontend/A32/translate/conditional_state.h
frontend/A32/translate/translate_arm.cpp
frontend/A32/translate/translate_thumb.cpp
interface/A32/a32.h
interface/A32/arch_version.h
interface/A32/config.h
interface/A32/coprocessor.h
interface/A32/coprocessor_util.h
interface/A32/disassembler.h
# A64
frontend/A64/a64_ir_emitter.cpp
frontend/A64/a64_ir_emitter.h
frontend/A64/a64_location_descriptor.cpp
frontend/A64/a64_location_descriptor.h
frontend/A64/decoder/a64.h
frontend/A64/decoder/a64.inc
frontend/A64/translate/a64_translate.cpp
frontend/A64/translate/a64_translate.h
interface/A64/a64.h
interface/A64/config.h
)
if ("A32" IN_LIST DYNARMIC_FRONTENDS)
target_sources(dynarmic PRIVATE
frontend/A32/a32_ir_emitter.cpp
frontend/A32/a32_ir_emitter.h
frontend/A32/a32_location_descriptor.cpp
frontend/A32/a32_location_descriptor.h
frontend/A32/decoder/arm.h
frontend/A32/decoder/arm.inc
frontend/A32/decoder/asimd.h
frontend/A32/decoder/asimd.inc
frontend/A32/decoder/thumb16.h
frontend/A32/decoder/thumb16.inc
frontend/A32/decoder/thumb32.h
frontend/A32/decoder/thumb32.inc
frontend/A32/decoder/vfp.h
frontend/A32/decoder/vfp.inc
frontend/A32/disassembler/disassembler.h
frontend/A32/disassembler/disassembler_arm.cpp
frontend/A32/disassembler/disassembler_thumb.cpp
frontend/A32/FPSCR.h
frontend/A32/ITState.h
frontend/A32/PSR.h
frontend/A32/translate/a32_translate.cpp
frontend/A32/translate/a32_translate.h
frontend/A32/translate/conditional_state.cpp
frontend/A32/translate/conditional_state.h
frontend/A32/translate/translate_arm.cpp
frontend/A32/translate/translate_thumb.cpp
interface/A32/a32.h
interface/A32/arch_version.h
interface/A32/config.h
interface/A32/coprocessor.h
interface/A32/coprocessor_util.h
interface/A32/disassembler.h
ir/opt/a32_constant_memory_reads_pass.cpp
ir/opt/a32_get_set_elimination_pass.cpp
)
endif()
if ("A64" IN_LIST DYNARMIC_FRONTENDS)
target_sources(dynarmic PRIVATE
frontend/A64/a64_ir_emitter.cpp
frontend/A64/a64_ir_emitter.h
frontend/A64/a64_location_descriptor.cpp
frontend/A64/a64_location_descriptor.h
frontend/A64/decoder/a64.h
frontend/A64/decoder/a64.inc
frontend/A64/translate/a64_translate.cpp
frontend/A64/translate/a64_translate.h
interface/A64/a64.h
interface/A64/config.h
ir/opt/a64_callback_config_pass.cpp
ir/opt/a64_get_set_elimination_pass.cpp
ir/opt/a64_merge_interpret_blocks.cpp
)
endif()
if ("x86_64" IN_LIST ARCHITECTURE)
# Newer versions of xbyak (>= 7.25.0) have stricter checks that currently
# fail in dynarmic
@ -215,29 +192,21 @@ if ("x86_64" IN_LIST ARCHITECTURE)
common/spin_lock_x64.h
common/x64_disassemble.cpp
common/x64_disassemble.h
# A32
backend/x64/a32_emit_x64.cpp
backend/x64/a32_emit_x64.h
backend/x64/a32_emit_x64_memory.cpp
backend/x64/a32_interface.cpp
backend/x64/a32_jitstate.cpp
backend/x64/a32_jitstate.h
# A64
backend/x64/a64_emit_x64.cpp
backend/x64/a64_emit_x64.h
backend/x64/a64_emit_x64_memory.cpp
backend/x64/a64_interface.cpp
backend/x64/a64_jitstate.cpp
backend/x64/a64_jitstate.h
)
if ("A32" IN_LIST DYNARMIC_FRONTENDS)
target_architecture_specific_sources(dynarmic "x86_64"
backend/x64/a32_emit_x64.cpp
backend/x64/a32_emit_x64.h
backend/x64/a32_emit_x64_memory.cpp
backend/x64/a32_interface.cpp
backend/x64/a32_jitstate.cpp
backend/x64/a32_jitstate.h
)
endif()
if ("A64" IN_LIST DYNARMIC_FRONTENDS)
target_architecture_specific_sources(dynarmic "x86_64"
backend/x64/a64_emit_x64.cpp
backend/x64/a64_emit_x64.h
backend/x64/a64_emit_x64_memory.cpp
backend/x64/a64_interface.cpp
backend/x64/a64_jitstate.cpp
backend/x64/a64_jitstate.h
)
endif()
endif()
if ("arm64" IN_LIST ARCHITECTURE)
@ -281,25 +250,17 @@ if ("arm64" IN_LIST ARCHITECTURE)
backend/arm64/verbose_debugging_output.h
common/spin_lock_arm64.cpp
common/spin_lock_arm64.h
# A32
backend/arm64/a32_address_space.cpp
backend/arm64/a32_address_space.h
backend/arm64/a32_core.h
backend/arm64/a32_interface.cpp
# A64
backend/arm64/a64_address_space.cpp
backend/arm64/a64_address_space.h
backend/arm64/a64_core.h
backend/arm64/a64_interface.cpp
)
if ("A32" IN_LIST DYNARMIC_FRONTENDS)
target_architecture_specific_sources(dynarmic "arm64"
backend/arm64/a32_address_space.cpp
backend/arm64/a32_address_space.h
backend/arm64/a32_core.h
backend/arm64/a32_interface.cpp
)
endif()
if ("A64" IN_LIST DYNARMIC_FRONTENDS)
target_architecture_specific_sources(dynarmic "arm64"
backend/arm64/a64_address_space.cpp
backend/arm64/a64_address_space.h
backend/arm64/a64_core.h
backend/arm64/a64_interface.cpp
)
endif()
endif()
if ("riscv" IN_LIST ARCHITECTURE)
@ -328,21 +289,14 @@ if ("riscv" IN_LIST ARCHITECTURE)
backend/riscv64/reg_alloc.cpp
backend/riscv64/reg_alloc.h
backend/riscv64/stack_layout.h
# A32
backend/riscv64/a32_address_space.cpp
backend/riscv64/a32_address_space.h
backend/riscv64/a32_core.h
backend/riscv64/a32_interface.cpp
backend/riscv64/code_block.h
)
if ("A32" IN_LIST DYNARMIC_FRONTENDS)
target_sources(dynarmic PRIVATE
backend/riscv64/a32_address_space.cpp
backend/riscv64/a32_address_space.h
backend/riscv64/a32_core.h
backend/riscv64/a32_interface.cpp
backend/riscv64/code_block.h
)
endif()
if ("A64" IN_LIST DYNARMIC_FRONTENDS)
message(FATAL_ERROR "TODO: Unimplemented frontend for this host architecture")
endif()
message(FATAL_ERROR "TODO: Unimplemented frontend for this host architecture")
endif()
if (WIN32)
@ -420,7 +374,7 @@ target_link_libraries(dynarmic
)
if (BOOST_NO_HEADERS)
target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
else()
target_link_libraries(dynarmic PRIVATE Boost::headers)
endif()

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@ -16,7 +19,7 @@
#include "dynarmic/frontend/A32/translate/a32_translate.h"
#include "dynarmic/interface/A32/config.h"
#include "dynarmic/interface/exclusive_monitor.h"
#include "dynarmic/ir/opt/passes.h"
#include "dynarmic/ir/opt_passes.h"
namespace Dynarmic::Backend::Arm64 {
@ -163,21 +166,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const {
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
Optimization::PolyfillPass(ir_block, {});
Optimization::NamingPass(ir_block);
if (conf.HasOptimization(OptimizationFlag::GetSetElimination)) {
Optimization::A32GetSetElimination(ir_block, {.convert_nzc_to_nz = true});
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::ConstProp)) {
Optimization::A32ConstantMemoryReads(ir_block, conf.callbacks);
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
Optimization::IdentityRemovalPass(ir_block);
Optimization::VerificationPass(ir_block);
Optimization::Optimize(ir_block, conf, {});
return ir_block;
}

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@ -15,7 +18,7 @@
#include "dynarmic/frontend/A64/translate/a64_translate.h"
#include "dynarmic/interface/A64/config.h"
#include "dynarmic/interface/exclusive_monitor.h"
#include "dynarmic/ir/opt/passes.h"
#include "dynarmic/ir/opt_passes.h"
namespace Dynarmic::Backend::Arm64 {
@ -331,22 +334,7 @@ IR::Block A64AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const {
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{descriptor}, get_code,
{conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
Optimization::A64CallbackConfigPass(ir_block, conf);
Optimization::NamingPass(ir_block);
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
Optimization::A64GetSetElimination(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::ConstProp)) {
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) {
Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks);
}
Optimization::VerificationPass(ir_block);
Optimization::Optimize(ir_block, conf, {});
return ir_block;
}

View file

@ -15,15 +15,15 @@
#include <mcl/macro/architecture.hpp>
#include "dynarmic/common/common_types.h"
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
namespace Dynarmic::Backend::X64 {
class BlockOfCode;
} // namespace Dynarmic::Backend::X64
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
namespace oaknut {
class CodeBlock;
} // namespace oaknut
#elif defined(MCL_ARCHITECTURE_RISCV)
#elif defined(ARCHITECTURE_riscv64)
namespace Dynarmic::Backend::RV64 {
class CodeBlock;
} // namespace Dynarmic::Backend::RV64
@ -33,16 +33,16 @@ class CodeBlock;
namespace Dynarmic::Backend {
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
struct FakeCall {
u64 call_rip;
u64 ret_rip;
};
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
struct FakeCall {
u64 call_pc;
};
#elif defined(MCL_ARCHITECTURE_RISCV)
#elif defined(ARCHITECTURE_riscv64)
struct FakeCall {
};
#else
@ -54,11 +54,11 @@ public:
ExceptionHandler();
~ExceptionHandler();
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
void Register(X64::BlockOfCode& code);
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
void Register(oaknut::CodeBlock& mem, std::size_t mem_size);
#elif defined(MCL_ARCHITECTURE_RISCV)
#elif defined(ARCHITECTURE_riscv64)
void Register(RV64::CodeBlock& mem, std::size_t mem_size);
#else
# error "Invalid architecture"

View file

@ -13,15 +13,15 @@ struct ExceptionHandler::Impl final {
ExceptionHandler::ExceptionHandler() = default;
ExceptionHandler::~ExceptionHandler() = default;
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
void ExceptionHandler::Register(X64::BlockOfCode&) {
// Do nothing
}
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
void ExceptionHandler::Register(oaknut::CodeBlock&, std::size_t) {
// Do nothing
}
#elif defined(MCL_ARCHITECTURE_RISCV)
#elif defined(ARCHITECTURE_riscv64)
void ExceptionHandler::Register(RV64::CodeBlock&, std::size_t) {
// Do nothing
}

View file

@ -25,7 +25,7 @@
#include "dynarmic/backend/exception_handler.h"
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
# include "dynarmic/backend/x64/block_of_code.h"
# define mig_external extern "C"
@ -36,7 +36,7 @@
using dynarmic_thread_state_t = x86_thread_state64_t;
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
# include <oaknut/code_block.hpp>
# define mig_external extern "C"
@ -133,7 +133,7 @@ void MachHandler::MessagePump() {
}
}
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
kern_return_t MachHandler::HandleRequest(x86_thread_state64_t* ts) {
std::lock_guard<std::mutex> guard(code_block_infos_mutex);
@ -151,7 +151,7 @@ kern_return_t MachHandler::HandleRequest(x86_thread_state64_t* ts) {
return KERN_SUCCESS;
}
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
kern_return_t MachHandler::HandleRequest(arm_thread_state64_t* ts) {
std::lock_guard<std::mutex> guard(code_block_infos_mutex);
@ -269,13 +269,13 @@ private:
ExceptionHandler::ExceptionHandler() = default;
ExceptionHandler::~ExceptionHandler() = default;
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
void ExceptionHandler::Register(X64::BlockOfCode& code) {
const u64 code_begin = mcl::bit_cast<u64>(code.getCode());
const u64 code_end = code_begin + code.GetTotalCodeSize();
impl = std::make_unique<Impl>(code_begin, code_end);
}
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) {
const u64 code_begin = mcl::bit_cast<u64>(mem.ptr());
const u64 code_end = code_begin + size;

View file

@ -5,9 +5,9 @@
#include <mcl/macro/architecture.hpp>
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
# include "dynarmic/backend/x64/mig/mach_exc_server.c"
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
# include "dynarmic/backend/arm64/mig/mach_exc_server.c"
#else
# error "Invalid architecture"

View file

@ -6,79 +6,99 @@
* SPDX-License-Identifier: 0BSD
*/
#include "dynarmic/backend/exception_handler.h"
#ifdef __APPLE__
# include <signal.h>
# include <sys/ucontext.h>
#else
# include <signal.h>
# ifndef __OpenBSD__
# include <ucontext.h>
# endif
# ifdef __sun__
# include <sys/regset.h>
# endif
#endif
#include <cstring>
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <vector>
#include "dynarmic/backend/exception_handler.h"
#include "dynarmic/common/assert.h"
#include "dynarmic/common/context.h"
#include <mcl/bit_cast.hpp>
#include "dynarmic/common/common_types.h"
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
# include "dynarmic/backend/x64/block_of_code.h"
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
# include <oaknut/code_block.hpp>
# include "dynarmic/backend/arm64/abi.h"
#elif defined(MCL_ARCHITECTURE_RISCV)
#elif defined(ARCHITECTURE_riscv64)
# include "dynarmic/backend/riscv64/code_block.h"
#else
# error "Invalid architecture"
#endif
#include <mcl/bit_cast.hpp>
namespace Dynarmic::Backend {
namespace {
struct CodeBlockInfo {
u64 code_begin, code_end;
u64 size;
std::function<FakeCall(u64)> cb;
};
class SigHandler {
public:
SigHandler();
~SigHandler();
void AddCodeBlock(CodeBlockInfo info);
void RemoveCodeBlock(u64 host_pc);
bool SupportsFastmem() const { return supports_fast_mem; }
private:
auto FindCodeBlockInfo(u64 host_pc) {
return std::find_if(code_block_infos.begin(), code_block_infos.end(), [&](const auto& x) { return x.code_begin <= host_pc && x.code_end > host_pc; });
auto FindCodeBlockInfo(u64 offset) noexcept {
return std::find_if(code_block_infos.begin(), code_block_infos.end(), [&](auto const& e) {
return e.first <= offset && e.first + e.second.size > offset;
});
}
static void SigAction(int sig, siginfo_t* info, void* raw_context);
bool supports_fast_mem = true;
void* signal_stack_memory = nullptr;
std::vector<CodeBlockInfo> code_block_infos;
std::mutex code_block_infos_mutex;
ankerl::unordered_dense::map<u64, CodeBlockInfo> code_block_infos;
std::shared_mutex code_block_infos_mutex;
struct sigaction old_sa_segv;
struct sigaction old_sa_bus;
std::size_t signal_stack_size;
public:
SigHandler() noexcept {
signal_stack_size = std::max<size_t>(SIGSTKSZ, 2 * 1024 * 1024);
signal_stack_memory = mmap(nullptr, signal_stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
static void SigAction(int sig, siginfo_t* info, void* raw_context);
stack_t signal_stack{};
signal_stack.ss_sp = signal_stack_memory;
signal_stack.ss_size = signal_stack_size;
signal_stack.ss_flags = 0;
if (sigaltstack(&signal_stack, nullptr) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: init failure at sigaltstack\n");
supports_fast_mem = false;
return;
}
struct sigaction sa{};
sa.sa_handler = nullptr;
sa.sa_sigaction = &SigHandler::SigAction;
sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGSEGV, &sa, &old_sa_segv) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGSEGV handler\n");
supports_fast_mem = false;
return;
}
#ifdef __APPLE__
if (sigaction(SIGBUS, &sa, &old_sa_bus) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGBUS handler\n");
supports_fast_mem = false;
return;
}
#endif
}
~SigHandler() noexcept {
munmap(signal_stack_memory, signal_stack_size);
}
void AddCodeBlock(u64 offset, CodeBlockInfo cbi) noexcept {
std::unique_lock guard(code_block_infos_mutex);
code_block_infos.insert_or_assign(offset, cbi);
}
void RemoveCodeBlock(u64 offset) noexcept {
std::unique_lock guard(code_block_infos_mutex);
code_block_infos.erase(offset);
}
bool SupportsFastmem() const noexcept { return supports_fast_mem; }
};
std::mutex handler_lock;
@ -131,139 +151,50 @@ SigHandler::~SigHandler() {
void SigHandler::AddCodeBlock(CodeBlockInfo cbi) {
std::lock_guard<std::mutex> guard(code_block_infos_mutex);
if (auto iter = FindCodeBlockInfo(cbi.code_begin); iter != code_block_infos.end()) {
if (auto const iter = FindCodeBlockInfo(cbi.code_begin); iter != code_block_infos.end())
code_block_infos.erase(iter);
}
code_block_infos.push_back(cbi);
}
void SigHandler::RemoveCodeBlock(u64 host_pc) {
std::lock_guard<std::mutex> guard(code_block_infos_mutex);
const auto iter = FindCodeBlockInfo(host_pc);
if (iter == code_block_infos.end()) {
return;
}
code_block_infos.erase(iter);
if (iter != code_block_infos.end())
code_block_infos.erase(iter);
}
void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
ASSERT(sig == SIGSEGV || sig == SIGBUS);
#ifndef MCL_ARCHITECTURE_RISCV
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
#ifndef __OpenBSD__
auto& mctx = ucontext->uc_mcontext;
#endif
#endif
#if defined(MCL_ARCHITECTURE_X86_64)
# if defined(__APPLE__)
# define CTX_RIP (mctx->__ss.__rip)
# define CTX_RSP (mctx->__ss.__rsp)
# elif defined(__linux__)
# define CTX_RIP (mctx.gregs[REG_RIP])
# define CTX_RSP (mctx.gregs[REG_RSP])
# elif defined(__FreeBSD__)
# define CTX_RIP (mctx.mc_rip)
# define CTX_RSP (mctx.mc_rsp)
# elif defined(__NetBSD__)
# define CTX_RIP (mctx.__gregs[_REG_RIP])
# define CTX_RSP (mctx.__gregs[_REG_RSP])
# elif defined(__OpenBSD__)
# define CTX_RIP (ucontext->sc_rip)
# define CTX_RSP (ucontext->sc_rsp)
# elif defined(__sun__)
# define CTX_RIP (mctx.gregs[REG_RIP])
# define CTX_RSP (mctx.gregs[REG_RSP])
# else
# error "Unknown platform"
# endif
CTX_DECLARE(raw_context);
#if defined(ARCHITECTURE_x86_64)
{
std::lock_guard<std::mutex> guard(sig_handler->code_block_infos_mutex);
const auto iter = sig_handler->FindCodeBlockInfo(CTX_RIP);
if (iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->cb(CTX_RIP);
CTX_RSP -= sizeof(u64);
*mcl::bit_cast<u64*>(CTX_RSP) = fc.ret_rip;
CTX_RIP = fc.call_rip;
return;
}
}
fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_RIP);
#elif defined(MCL_ARCHITECTURE_ARM64)
# if defined(__APPLE__)
# define CTX_PC (mctx->__ss.__pc)
# define CTX_SP (mctx->__ss.__sp)
# define CTX_LR (mctx->__ss.__lr)
# define CTX_X(i) (mctx->__ss.__x[i])
# define CTX_Q(i) (mctx->__ns.__v[i])
# elif defined(__linux__)
# define CTX_PC (mctx.pc)
# define CTX_SP (mctx.sp)
# define CTX_LR (mctx.regs[30])
# define CTX_X(i) (mctx.regs[i])
# define CTX_Q(i) (fpctx->vregs[i])
[[maybe_unused]] const auto fpctx = [&mctx] {
_aarch64_ctx* header = (_aarch64_ctx*)&mctx.__reserved;
while (header->magic != FPSIMD_MAGIC) {
ASSERT(header->magic && header->size);
header = (_aarch64_ctx*)((char*)header + header->size);
}
return (fpsimd_context*)header;
}();
# elif defined(__FreeBSD__)
# define CTX_PC (mctx.mc_gpregs.gp_elr)
# define CTX_SP (mctx.mc_gpregs.gp_sp)
# define CTX_LR (mctx.mc_gpregs.gp_lr)
# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
# elif defined(__NetBSD__)
# define CTX_PC (mctx.mc_gpregs.gp_elr)
# define CTX_SP (mctx.mc_gpregs.gp_sp)
# define CTX_LR (mctx.mc_gpregs.gp_lr)
# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
# elif defined(__OpenBSD__)
# define CTX_PC (ucontext->sc_elr)
# define CTX_SP (ucontext->sc_sp)
# define CTX_LR (ucontext->sc_lr)
# define CTX_X(i) (ucontext->sc_x[i])
# define CTX_Q(i) (ucontext->sc_q[i])
# else
# error "Unknown platform"
# endif
#elif defined(ARCHITECTURE_arm64)
{
std::lock_guard<std::mutex> guard(sig_handler->code_block_infos_mutex);
const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC);
if (iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->cb(CTX_PC);
CTX_PC = fc.call_pc;
return;
}
}
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
#elif defined(MCL_ARCHITECTURE_RISCV)
#elif defined(ARCHITECTURE_riscv64)
ASSERT_FALSE("Unimplemented");
#else
# error "Invalid architecture"
#endif
struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler->old_sa_segv : &sig_handler->old_sa_bus;
@ -284,55 +215,49 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
} // anonymous namespace
struct ExceptionHandler::Impl final {
Impl(u64 code_begin_, u64 code_end_)
: code_begin(code_begin_)
, code_end(code_end_) {
Impl(u64 offset_, u64 size_)
: offset(offset_)
, size(size_) {
RegisterHandler();
}
void SetCallback(std::function<FakeCall(u64)> cb) {
CodeBlockInfo cbi;
cbi.code_begin = code_begin;
cbi.code_end = code_end;
cbi.cb = cb;
sig_handler->AddCodeBlock(cbi);
sig_handler->AddCodeBlock(offset, CodeBlockInfo{
.size = size,
.cb = cb
});
}
~Impl() {
sig_handler->RemoveCodeBlock(code_begin);
sig_handler->RemoveCodeBlock(offset);
}
private:
u64 code_begin, code_end;
u64 offset;
u64 size;
};
ExceptionHandler::ExceptionHandler() = default;
ExceptionHandler::~ExceptionHandler() = default;
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
void ExceptionHandler::Register(X64::BlockOfCode& code) {
const u64 code_begin = mcl::bit_cast<u64>(code.getCode());
const u64 code_end = code_begin + code.GetTotalCodeSize();
impl = std::make_unique<Impl>(code_begin, code_end);
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(code.getCode()), code.GetTotalCodeSize());
}
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) {
const u64 code_begin = mcl::bit_cast<u64>(mem.ptr());
const u64 code_end = code_begin + size;
impl = std::make_unique<Impl>(code_begin, code_end);
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(mem.ptr()), size);
}
#elif defined(MCL_ARCHITECTURE_RISCV)
#elif defined(ARCHITECTURE_riscv64)
void ExceptionHandler::Register(RV64::CodeBlock& mem, std::size_t size) {
const u64 code_begin = mcl::bit_cast<u64>(mem.ptr<u64>());
const u64 code_end = code_begin + size;
impl = std::make_unique<Impl>(code_begin, code_end);
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(mem.ptr<u64>()), size);
}
#else
# error "Invalid architecture"
#endif
bool ExceptionHandler::SupportsFastmem() const noexcept {
return static_cast<bool>(impl) && sig_handler->SupportsFastmem();
return bool(impl) && sig_handler->SupportsFastmem();
}
void ExceptionHandler::SetFastmemCallback(std::function<FakeCall(u64)> cb) {

View file

@ -5,9 +5,9 @@
#include <mcl/macro/architecture.hpp>
#if defined(MCL_ARCHITECTURE_X86_64)
#if defined(ARCHITECTURE_x86_64)
# include "dynarmic/backend/x64/exception_handler_windows.cpp"
#elif defined(MCL_ARCHITECTURE_ARM64)
#elif defined(ARCHITECTURE_arm64)
# include "dynarmic/backend/exception_handler_generic.cpp"
#else
# error "Invalid architecture"

View file

@ -15,7 +15,7 @@
#include "dynarmic/backend/riscv64/stack_layout.h"
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
#include "dynarmic/frontend/A32/translate/a32_translate.h"
#include "dynarmic/ir/opt/passes.h"
#include "dynarmic/ir/opt_passes.h"
namespace Dynarmic::Backend::RV64 {
@ -28,19 +28,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const {
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
Optimization::PolyfillPass(ir_block, {});
if (conf.HasOptimization(OptimizationFlag::GetSetElimination)) {
Optimization::A32GetSetElimination(ir_block, {.convert_nzc_to_nz = true});
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::ConstProp)) {
Optimization::A32ConstantMemoryReads(ir_block, conf.callbacks);
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
Optimization::VerificationPass(ir_block);
Optimization::Optimize(ir_block, conf, {});
return ir_block;
}

View file

@ -28,7 +28,6 @@
#include "dynarmic/backend/x64/nzcv_util.h"
#include "dynarmic/backend/x64/perf_map.h"
#include "dynarmic/backend/x64/stack_layout.h"
#include "dynarmic/common/variant_util.h"
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
#include "dynarmic/frontend/A32/a32_types.h"
#include "dynarmic/interface/A32/coprocessor.h"

View file

@ -29,7 +29,7 @@
#include "dynarmic/interface/A32/a32.h"
#include "dynarmic/ir/basic_block.h"
#include "dynarmic/ir/location_descriptor.h"
#include "dynarmic/ir/opt/passes.h"
#include "dynarmic/ir/opt_passes.h"
namespace Dynarmic::A32 {
@ -217,19 +217,7 @@ private:
block_of_code.EnsureMemoryCommitted(MINIMUM_REMAINING_CODESIZE);
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
Optimization::PolyfillPass(ir_block, polyfill_options);
Optimization::NamingPass(ir_block);
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
Optimization::A32GetSetElimination(ir_block, {.convert_nz_to_nzc = true});
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::ConstProp)) {
Optimization::A32ConstantMemoryReads(ir_block, conf.callbacks);
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
Optimization::IdentityRemovalPass(ir_block);
Optimization::VerificationPass(ir_block);
Optimization::Optimize(ir_block, conf, polyfill_options);
return emitter.Emit(ir_block);
}

View file

@ -122,9 +122,9 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) noexcept {
auto const opcode = inst.GetOpcode();
// Call the relevant Emit* member function.
switch (opcode) {
#define OPCODE(name, type, ...) [[likely]] case IR::Opcode::name: goto opcode_branch;
#define OPCODE(name, type, ...) case IR::Opcode::name: goto opcode_branch;
#define A32OPC(name, type, ...)
#define A64OPC(name, type, ...) [[likely]] case IR::Opcode::A64##name: goto a64_branch;
#define A64OPC(name, type, ...) case IR::Opcode::A64##name: goto a64_branch;
#include "dynarmic/ir/opcodes.inc"
#undef OPCODE
#undef A32OPC
@ -764,7 +764,7 @@ void A64EmitX64::EmitPatchMovRcx(CodePtr target_code_ptr) {
target_code_ptr = code.GetReturnFromRunCodeAddress();
}
const CodePtr patch_location = code.getCurr();
code.mov(code.rcx, reinterpret_cast<u64>(target_code_ptr));
code.mov(code.rcx, u64(target_code_ptr));
code.EnsurePatchLocationSize(patch_location, 10);
}

View file

@ -25,7 +25,7 @@
#include "dynarmic/frontend/A64/translate/a64_translate.h"
#include "dynarmic/interface/A64/a64.h"
#include "dynarmic/ir/basic_block.h"
#include "dynarmic/ir/opt/passes.h"
#include "dynarmic/ir/opt_passes.h"
namespace Dynarmic::A64 {
@ -80,16 +80,16 @@ public:
};
// TODO: Check code alignment
const CodePtr current_code_ptr = [this] {
const CodePtr aligned_code_ptr = CodePtr((uintptr_t(GetCurrentBlock()) + 15) & ~uintptr_t(15));
const CodePtr current_code_ptr = [this, aligned_code_ptr] {
// RSB optimization
const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A64JitState::RSBPtrMask;
if (jit_state.GetUniqueHash() == jit_state.rsb_location_descriptors[new_rsb_ptr]) {
jit_state.rsb_ptr = new_rsb_ptr;
return reinterpret_cast<CodePtr>(jit_state.rsb_codeptrs[new_rsb_ptr]);
return CodePtr(jit_state.rsb_codeptrs[new_rsb_ptr]);
}
return GetCurrentBlock();
return aligned_code_ptr;
//return GetCurrentBlock();
}();
const HaltReason hr = block_of_code.RunCode(&jit_state, current_code_ptr);
@ -275,21 +275,7 @@ private:
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{current_location}, get_code,
{conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
Optimization::PolyfillPass(ir_block, polyfill_options);
Optimization::A64CallbackConfigPass(ir_block, conf);
Optimization::NamingPass(ir_block);
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
Optimization::A64GetSetElimination(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::ConstProp)) {
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) {
Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks);
}
Optimization::VerificationPass(ir_block);
Optimization::Optimize(ir_block, conf, polyfill_options);
return emitter.Emit(ir_block).entrypoint;
}

View file

@ -10,7 +10,6 @@
#include <algorithm>
#include <mcl/iterator/reverse.hpp>
#include "dynarmic/common/common_types.h"
#include <xbyak/xbyak.h>
@ -76,7 +75,8 @@ void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size,
const FrameInfo frame_info = CalculateFrameInfo(num_gprs, num_xmms, frame_size);
size_t xmm_offset = frame_info.xmm_offset + (num_xmms * XMM_SIZE);
for (auto const xmm : mcl::iterator::reverse(regs)) {
for (auto it = regs.rbegin(); it != regs.rend(); ++it) {
auto const xmm = *it;
if (HostLocIsXMM(xmm)) {
xmm_offset -= XMM_SIZE;
if (code.HasHostFeature(HostFeature::AVX)) {
@ -88,9 +88,11 @@ void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size,
}
if (frame_info.stack_subtraction != 0)
code.add(rsp, u32(frame_info.stack_subtraction));
for (auto const gpr : mcl::iterator::reverse(regs))
for (auto it = regs.rbegin(); it != regs.rend(); ++it) {
auto const gpr = *it;
if (HostLocIsGPR(gpr))
code.pop(HostLocToReg64(gpr));
}
}
void ABI_PushCalleeSaveRegistersAndAdjustStack(BlockOfCode& code, const std::size_t frame_size) {

View file

@ -364,8 +364,7 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
cmp(dword[ABI_JIT_PTR + jsi.offsetof_halt_reason], 0);
jne(return_to_caller_mxcsr_already_exited, T_NEAR);
lock();
or_(dword[ABI_JIT_PTR + jsi.offsetof_halt_reason], static_cast<u32>(HaltReason::Step));
lock(); or_(dword[ABI_JIT_PTR + jsi.offsetof_halt_reason], static_cast<u32>(HaltReason::Step));
SwitchMxcsrOnEntry();
jmp(ABI_PARAM2);
@ -415,7 +414,6 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
}
xor_(eax, eax);
lock();
xchg(dword[ABI_JIT_PTR + jsi.offsetof_halt_reason], eax);
ABI_PopCalleeSaveRegistersAndAdjustStack(*this, sizeof(StackLayout));

View file

@ -11,6 +11,7 @@
#include <iterator>
#include "dynarmic/common/assert.h"
#include <boost/variant/detail/apply_visitor_binary.hpp>
#include <mcl/bit/bit_field.hpp>
#include <mcl/scope_exit.hpp>
#include "dynarmic/common/common_types.h"
@ -21,7 +22,6 @@
#include "dynarmic/backend/x64/perf_map.h"
#include "dynarmic/backend/x64/stack_layout.h"
#include "dynarmic/backend/x64/verbose_debugging_output.h"
#include "dynarmic/common/variant_util.h"
#include "dynarmic/ir/basic_block.h"
#include "dynarmic/ir/microinstruction.h"
#include "dynarmic/ir/opcodes.h"
@ -347,14 +347,14 @@ EmitX64::BlockDescriptor EmitX64::RegisterBlock(const IR::LocationDescriptor& de
}
void EmitX64::EmitTerminal(IR::Terminal terminal, IR::LocationDescriptor initial_location, bool is_single_step) {
Common::VisitVariant<void>(terminal, [this, initial_location, is_single_step](auto x) {
boost::apply_visitor([this, initial_location, is_single_step](auto x) {
using T = std::decay_t<decltype(x)>;
if constexpr (!std::is_same_v<T, IR::Term::Invalid>) {
this->EmitTerminalImpl(x, initial_location, is_single_step);
} else {
ASSERT_MSG(false, "Invalid terminal");
}
});
}, terminal);
}
void EmitX64::Patch(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr) {

View file

@ -92,13 +92,10 @@ void ForceDenormalsToZero(BlockOfCode& code, std::initializer_list<Xbyak::Xmm> t
FpFixup::Norm_Src,
FpFixup::Norm_Src,
FpFixup::Norm_Src);
const Xbyak::Xmm tmp = xmm16;
const Xbyak::Xmm tmp = xmm0;
FCODE(vmovap)(tmp, code.BConst<fsize>(xword, denormal_to_zero));
for (const Xbyak::Xmm& xmm : to_daz) {
for (const Xbyak::Xmm& xmm : to_daz)
FCODE(vfixupimms)(xmm, xmm, tmp, u8(0));
}
return;
}

View file

@ -609,8 +609,8 @@ void EmitX64::EmitVectorArithmeticVShift16(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm left_shift = ctx.reg_alloc.UseScratchXmm(args[1]);
const Xbyak::Xmm right_shift = xmm16;
const Xbyak::Xmm tmp = xmm17;
const Xbyak::Xmm right_shift = ctx.reg_alloc.ScratchXmm();
const Xbyak::Xmm tmp = ctx.reg_alloc.ScratchXmm();
code.vmovdqa32(tmp, code.Const(xword, 0x00FF00FF00FF00FF, 0x00FF00FF00FF00FF));
code.vpxord(right_shift, right_shift, right_shift);
@ -674,8 +674,8 @@ void EmitX64::EmitVectorArithmeticVShift64(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm left_shift = ctx.reg_alloc.UseScratchXmm(args[1]);
const Xbyak::Xmm right_shift = xmm16;
const Xbyak::Xmm tmp = xmm17;
const Xbyak::Xmm right_shift = ctx.reg_alloc.ScratchXmm();
const Xbyak::Xmm tmp = ctx.reg_alloc.ScratchXmm();
code.vmovdqa32(tmp, code.Const(xword, 0x00000000000000FF, 0x00000000000000FF));
code.vpxorq(right_shift, right_shift, right_shift);
@ -1955,8 +1955,8 @@ void EmitX64::EmitVectorLogicalVShift16(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm left_shift = ctx.reg_alloc.UseScratchXmm(args[1]);
const Xbyak::Xmm right_shift = xmm16;
const Xbyak::Xmm tmp = xmm17;
const Xbyak::Xmm right_shift = ctx.reg_alloc.ScratchXmm();
const Xbyak::Xmm tmp = ctx.reg_alloc.ScratchXmm();
code.vmovdqa32(tmp, code.Const(xword, 0x00FF00FF00FF00FF, 0x00FF00FF00FF00FF));
code.vpxord(right_shift, right_shift, right_shift);
@ -2737,7 +2737,7 @@ void EmitX64::EmitVectorPairedAddSignedWiden32(EmitContext& ctx, IR::Inst* inst)
const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(args[0]);
if (code.HasHostFeature(HostFeature::AVX512_Ortho)) {
const Xbyak::Xmm c = xmm16;
const Xbyak::Xmm c = ctx.reg_alloc.ScratchXmm();
code.vpsraq(c, a, 32);
code.vpsllq(a, a, 32);
code.vpsraq(a, a, 32);
@ -5461,7 +5461,7 @@ void EmitX64::EmitVectorTableLookup128(EmitContext& ctx, IR::Inst* inst) {
if (code.HasHostFeature(HostFeature::AVX512_Ortho | HostFeature::AVX512BW)) {
const Xbyak::Xmm indicies = ctx.reg_alloc.UseXmm(args[2]);
const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm masked = xmm16;
const Xbyak::Xmm masked = ctx.reg_alloc.ScratchXmm();
code.vpandd(masked, indicies, code.Const(xword_b, 0xF0F0F0F0F0F0F0F0, 0xF0F0F0F0F0F0F0F0));

View file

@ -9,6 +9,7 @@
#include "dynarmic/backend/x64/reg_alloc.h"
#include <algorithm>
#include <limits>
#include <numeric>
#include <utility>
@ -118,7 +119,7 @@ void HostLocInfo::AddValue(IR::Inst* inst) noexcept {
values.push_back(inst);
ASSERT(size_t(total_uses) + inst->UseCount() < (std::numeric_limits<uint16_t>::max)());
total_uses += inst->UseCount();
max_bit_width = std::max<uint8_t>(max_bit_width, GetBitWidth(inst->GetType()));
max_bit_width = std::max<uint8_t>(max_bit_width, std::countr_zero(GetBitWidth(inst->GetType())));
}
void HostLocInfo::EmitVerboseDebuggingOutput(BlockOfCode* code, size_t host_loc_index) const noexcept {
@ -152,19 +153,19 @@ bool Argument::GetImmediateU1() const noexcept {
u8 Argument::GetImmediateU8() const noexcept {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x100);
ASSERT(imm <= u64(std::numeric_limits<u8>::max()));
return u8(imm);
}
u16 Argument::GetImmediateU16() const noexcept {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x10000);
ASSERT(imm <= u64(std::numeric_limits<u16>::max()));
return u16(imm);
}
u32 Argument::GetImmediateU32() const noexcept {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x100000000);
ASSERT(imm <= u64(std::numeric_limits<u32>::max()));
return u32(imm);
}
@ -366,10 +367,20 @@ void RegAlloc::HostCall(IR::Inst* result_def,
if (result_def) {
DefineValueImpl(result_def, ABI_RETURN);
}
for (size_t i = 0; i < args.size(); i++) {
if (args[i]) {
UseScratch(*args[i], args_hostloc[i]);
} else {
ScratchGpr(args_hostloc[i]); // TODO: Force spill
}
}
// Must match with with ScratchImpl
for (auto const gpr : other_caller_save) {
MoveOutOfTheWay(gpr);
LocInfo(gpr).WriteLock();
}
for (size_t i = 0; i < args.size(); i++) {
if (args[i] && !args[i]->get().IsVoid()) {
UseScratch(*args[i], args_hostloc[i]);
// LLVM puts the burden of zero-extension of 8 and 16 bit values on the caller instead of the callee
const Xbyak::Reg64 reg = HostLocToReg64(args_hostloc[i]);
switch (args[i]->get().GetType()) {
@ -389,14 +400,6 @@ void RegAlloc::HostCall(IR::Inst* result_def,
}
}
}
for (size_t i = 0; i < args.size(); i++)
if (!args[i]) {
// TODO: Force spill
ScratchGpr(args_hostloc[i]);
}
for (auto const caller_saved : other_caller_save)
ScratchImpl({caller_saved});
}
void RegAlloc::AllocStackSpace(const size_t stack_space) noexcept {
@ -559,13 +562,12 @@ void RegAlloc::SpillRegister(HostLoc loc) noexcept {
}
HostLoc RegAlloc::FindFreeSpill(bool is_xmm) const noexcept {
#if 0
// TODO(lizzie): Ok, Windows hates XMM spills, this means less perf for windows
// but it's fine anyways. We can find other ways to cheat it later - but which?!?!
// we should NOT save xmm each block entering... MAYBE xbyak has a bug on start/end?
// TODO(lizzie): This needs to be investigated further later.
// Do not spill XMM into other XMM silly
if (!is_xmm) {
/*if (!is_xmm) {
// TODO(lizzie): Using lower (xmm0 and such) registers results in issues/crashes - INVESTIGATE WHY
// Intel recommends to spill GPR onto XMM registers IF POSSIBLE
// TODO(lizzie): Issues on DBZ, theory: Scratch XMM not properly restored after a function call?
@ -573,8 +575,9 @@ HostLoc RegAlloc::FindFreeSpill(bool is_xmm) const noexcept {
for (size_t i = size_t(HostLoc::XMM15); i >= size_t(HostLoc::XMM3); --i)
if (const auto loc = HostLoc(i); LocInfo(loc).IsEmpty())
return loc;
}
#endif
}*/
// TODO: Doing this would mean saving XMM on each call... need to benchmark the benefits
// of spilling on XMM versus the potential cost of using XMM registers.....
// Otherwise go to stack spilling
for (size_t i = size_t(HostLoc::FirstSpill); i < hostloc_info.size(); ++i)
if (const auto loc = HostLoc(i); LocInfo(loc).IsEmpty())

View file

@ -12,6 +12,7 @@
#include <functional>
#include <optional>
#include "boost/container/small_vector.hpp"
#include "dynarmic/common/common_types.h"
#include <xbyak/xbyak.h>
#include <boost/container/static_vector.hpp>
@ -77,13 +78,13 @@ public:
return std::find(values.begin(), values.end(), inst) != values.end();
}
inline size_t GetMaxBitWidth() const noexcept {
return max_bit_width;
return 1 << max_bit_width;
}
void AddValue(IR::Inst* inst) noexcept;
void EmitVerboseDebuggingOutput(BlockOfCode* code, size_t host_loc_index) const noexcept;
private:
//non trivial
std::vector<IR::Inst*> values; //24
boost::container::small_vector<IR::Inst*, 3> values; //24
// Block state
uint16_t total_uses = 0; //8
//sometimes zeroed
@ -93,10 +94,10 @@ private:
uint16_t is_being_used_count = 0; //8
uint16_t current_references = 0; //8
// Value state
uint8_t max_bit_width = 0; //Valid values: 1,2,4,8,16,32,128
uint8_t max_bit_width : 4 = 0; //Valid values: log2(1,2,4,8,16,32,128) = (0, 1, 2, 3, 4, 5, 6)
uint8_t lru_counter : 2 = 0; //1
bool is_scratch : 1 = false; //1
bool is_set_last_use : 1 = false; //1
alignas(16) uint8_t lru_counter = 0; //1
friend class RegAlloc;
};
static_assert(sizeof(HostLocInfo) == 64);

View file

@ -0,0 +1,120 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#ifdef __APPLE__
# include <signal.h>
# include <sys/ucontext.h>
#else
# include <signal.h>
# ifndef __OpenBSD__
# include <ucontext.h>
# endif
# ifdef __sun__
# include <sys/regset.h>
# endif
# ifdef __linux__
# include <sys/syscall.h>
# endif
#endif
#ifdef ARCHITECTURE_x86_64
# ifdef __OpenBSD__
# define CTX_DECLARE(raw_context) ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
# else
# define CTX_DECLARE(raw_context) \
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context); \
[[maybe_unused]] auto& mctx = ucontext->uc_mcontext;
# endif
#elif defined(ARCHITECTURE_arm64)
# ifdef __OpenBSD__
# define CTX_DECLARE(raw_context) ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
# else
# define CTX_DECLARE(raw_context) \
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context); \
[[maybe_unused]] auto& mctx = ucontext->uc_mcontext; \
[[maybe_unused]] const auto fpctx = GetFloatingPointState(mctx);
# endif
#endif
#if defined(ARCHITECTURE_x86_64)
# if defined(__APPLE__)
# define CTX_RIP (mctx->__ss.__rip)
# define CTX_RSP (mctx->__ss.__rsp)
# elif defined(__linux__)
# define CTX_RIP (mctx.gregs[REG_RIP])
# define CTX_RSP (mctx.gregs[REG_RSP])
# elif defined(__FreeBSD__)
# define CTX_RIP (mctx.mc_rip)
# define CTX_RSP (mctx.mc_rsp)
# elif defined(__NetBSD__)
# define CTX_RIP (mctx.__gregs[_REG_RIP])
# define CTX_RSP (mctx.__gregs[_REG_RSP])
# elif defined(__OpenBSD__)
# define CTX_RIP (ucontext->sc_rip)
# define CTX_RSP (ucontext->sc_rsp)
# elif defined(__sun__)
# define CTX_RIP (mctx.gregs[REG_RIP])
# define CTX_RSP (mctx.gregs[REG_RSP])
# else
# error "Unknown platform"
# endif
#elif defined(ARCHITECTURE_arm64)
# if defined(__APPLE__)
# define CTX_PC (mctx->__ss.__pc)
# define CTX_SP (mctx->__ss.__sp)
# define CTX_LR (mctx->__ss.__lr)
# define CTX_PSTATE (mctx->__ss.__cpsr)
# define CTX_X(i) (mctx->__ss.__x[i])
# define CTX_Q(i) (mctx->__ns.__v[i])
# define CTX_FPSR (mctx->__ns.__fpsr)
# define CTX_FPCR (mctx->__ns.__fpcr)
# elif defined(__linux__)
# define CTX_PC (mctx.pc)
# define CTX_SP (mctx.sp)
# define CTX_LR (mctx.regs[30])
# define CTX_PSTATE (mctx.pstate)
# define CTX_X(i) (mctx.regs[i])
# define CTX_Q(i) (fpctx->vregs[i])
# define CTX_FPSR (fpctx->fpsr)
# define CTX_FPCR (fpctx->fpcr)
# elif defined(__FreeBSD__)
# define CTX_PC (mctx.mc_gpregs.gp_elr)
# define CTX_SP (mctx.mc_gpregs.gp_sp)
# define CTX_LR (mctx.mc_gpregs.gp_lr)
# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
# elif defined(__NetBSD__)
# define CTX_PC (mctx.mc_gpregs.gp_elr)
# define CTX_SP (mctx.mc_gpregs.gp_sp)
# define CTX_LR (mctx.mc_gpregs.gp_lr)
# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
# elif defined(__OpenBSD__)
# define CTX_PC (ucontext->sc_elr)
# define CTX_SP (ucontext->sc_sp)
# define CTX_LR (ucontext->sc_lr)
# define CTX_X(i) (ucontext->sc_x[i])
# define CTX_Q(i) (ucontext->sc_q[i])
# else
# error "Unknown platform"
# endif
#else
# error "unimplemented"
#endif
#ifdef ARCHITECTURE_arm64
#ifdef __APPLE__
inline _STRUCT_ARM_NEON_STATE64* GetFloatingPointState(mcontext_t& host_ctx) {
return &(host_ctx->__ns);
}
#elif defined(__linux__)
inline fpsimd_context* GetFloatingPointState(mcontext_t& host_ctx) {
_aarch64_ctx* header = reinterpret_cast<_aarch64_ctx*>(&host_ctx.__reserved);
while (header->magic != FPSIMD_MAGIC)
header = reinterpret_cast<_aarch64_ctx*>(reinterpret_cast<char*>(header) + header->size);
return reinterpret_cast<fpsimd_context*>(header);
}
#endif
#endif

View file

@ -1,13 +0,0 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#include "dynarmic/common/memory_pool.h"
#include <cstdlib>
namespace Dynarmic::Common {
} // namespace Dynarmic::Common

View file

@ -1,61 +0,0 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <cstddef>
#include <vector>
namespace Dynarmic::Common {
/// @tparam object_size Byte-size of objects to construct
/// @tparam slab_size Number of objects to have per slab
template<size_t object_size, size_t slab_size>
class Pool {
public:
inline Pool() noexcept {
AllocateNewSlab();
}
inline ~Pool() noexcept {
std::free(current_slab);
for (char* slab : slabs) {
std::free(slab);
}
}
Pool(const Pool&) = delete;
Pool(Pool&&) = delete;
Pool& operator=(const Pool&) = delete;
Pool& operator=(Pool&&) = delete;
/// @brief Returns a pointer to an `object_size`-bytes block of memory.
[[nodiscard]] void* Alloc() noexcept {
if (remaining == 0) {
slabs.push_back(current_slab);
AllocateNewSlab();
}
void* ret = static_cast<void*>(current_ptr);
current_ptr += object_size;
remaining--;
return ret;
}
private:
/// @brief Allocates a completely new memory slab.
/// Used when an entirely new slab is needed
/// due the current one running out of usable space.
void AllocateNewSlab() noexcept {
current_slab = static_cast<char*>(std::malloc(object_size * slab_size));
current_ptr = current_slab;
remaining = slab_size;
}
std::vector<char*> slabs;
char* current_slab = nullptr;
char* current_ptr = nullptr;
size_t remaining = 0;
};
} // namespace Dynarmic::Common

Some files were not shown because too many files have changed in this diff Show more