Compare commits

..

5 Commits

Author SHA1 Message Date
lizzie 5679d20e2a 2026-09-11 20:03:41
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-11 20:03:41 +00:00
lizzie 64cec648f5 2026-09-11 19:36:26
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-11 19:36:26 +00:00
lizzie ea11b44946 2026-09-11 19:25:01
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-11 19:25:01 +00:00
lizzie 8a22f1845b [hle] Enforce max_sessions, add bpc:ams service (#4394)
As per switchbrew, as per atmosphere, and some poking around.

bpc:ams stubbed for now.

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

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4394
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-09-11 21:38:52 +02:00
xbzk 301da63a15 [audio] hint openslES as audio driver on android to fix mute screen recording issue (#4397)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------
After audio backend migration some android devices screen captures became mute.
Liz instructed to enable openSL ES via some SDL hint.
Found the proper one in https://wiki.libsdl.org/SDL3/SDL_HINT_AUDIO_DRIVER.
Added it restricted to android.

UPDATE:
Got myself wondering how things work on SDL after using that hint, and checked that one must provide a list of drivers "opensles,aaudio,..." to be attempted.
Afraid of some devices failing on openSL ES, and to avoid hand providing entire list, i've added fallback logic so entire SDL's driver list can be tried just in case.
Default list in https://github.com/libsdl-org/SDL/blob/release-3.4.14/src/audio/SDL_audio.c.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4397
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: lizzie <lizzie@eden-emu.dev>
2026-09-11 21:38:12 +02:00
141 changed files with 2293 additions and 1797 deletions
@@ -0,0 +1,28 @@
From cc15da16e533b2a801934eab2dfeaf3c3949a1dc Mon Sep 17 00:00:00 2001
From: crueter <crueter@eden-emu.dev>
Date: Mon, 8 Sep 2025 12:28:55 -0400
Subject: [PATCH] [cmake] disable NEON runtime check on clang-cl
When enabling runtime NEON checking for clang-cl, the linker would error out with `undefined symbol: __emit`, since clang doesn't actually implement this instruction. Therefore it makes sense to disable the runtime check by default on this platform, until either this is fixed or a clang-cl compatible intrinsic check is added (I don't have enough knowledge of MSVC to do this)
---
cmake/OpusConfig.cmake | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/cmake/OpusConfig.cmake b/cmake/OpusConfig.cmake
index e9319fbad..d0f459e88 100644
--- a/cmake/OpusConfig.cmake
+++ b/cmake/OpusConfig.cmake
@@ -71,7 +71,12 @@ elseif(OPUS_CPU_ARM AND NOT OPUS_DISABLE_INTRINSICS)
opus_detect_neon(COMPILER_SUPPORT_NEON)
if(COMPILER_SUPPORT_NEON)
option(OPUS_USE_NEON "Option to enable NEON" ON)
- option(OPUS_MAY_HAVE_NEON "Does runtime check for neon support" ON)
+ if (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ set(NEON_RUNTIME_CHECK_DEFAULT OFF)
+ else()
+ set(NEON_RUNTIME_CHECK_DEFAULT ON)
+ endif()
+ option(OPUS_MAY_HAVE_NEON "Does runtime check for neon support" ${NEON_RUNTIME_CHECK_DEFAULT})
option(OPUS_PRESUME_NEON "Assume target CPU has NEON support" OFF)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
set(OPUS_PRESUME_NEON ON)
+153
View File
@@ -0,0 +1,153 @@
From bf455b67b4eaa446ffae5d25410b141b7b1b1082 Mon Sep 17 00:00:00 2001
From: crueter <crueter@eden-emu.dev>
Date: Mon, 8 Sep 2025 12:08:20 -0400
Subject: [PATCH] [cmake] `OPUS_INSTALL` option; only default install if root
project
Signed-off-by: crueter <crueter@eden-emu.dev>
---
CMakeLists.txt | 112 ++++++++++++++++++++++++++++---------------------
1 file changed, 64 insertions(+), 48 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fcf034b19..08b5e16f8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,13 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(OpusPackageVersion)
get_package_version(PACKAGE_VERSION PROJECT_VERSION)
+# root project detection
+if(DEFINED PROJECT_NAME)
+ set(root_project OFF)
+else()
+ set(root_project ON)
+endif()
+
project(Opus LANGUAGES C VERSION ${PROJECT_VERSION})
include(OpusFunctions)
@@ -83,12 +90,16 @@ set(OPUS_DNN_FLOAT_DEBUG_HELP_STR "Run DNN computations as float for debugging p
option(OPUS_DNN_FLOAT_DEBUG ${OPUS_DNN_FLOAT_DEBUG_HELP_STR} OFF)
add_feature_info(OPUS_DNN_FLOAT_DEBUG OPUS_DNN_FLOAT_DEBUG ${OPUS_DNN_FLOAT_DEBUG_HELP_STR})
+set(OPUS_INSTALL_HELP_STR "Install Opus targets")
+option(OPUS_INSTALL ${OPUS_INSTALL_HELP_STR} ${root_project})
+add_feature_info(OPUS_INSTALL OPUS_INSTALL ${OPUS_INSTALL_HELP_STR})
+
set(OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR "install pkg-config module.")
-option(OPUS_INSTALL_PKG_CONFIG_MODULE ${OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR} ON)
+option(OPUS_INSTALL_PKG_CONFIG_MODULE ${OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR} ${OPUS_INSTALL})
add_feature_info(OPUS_INSTALL_PKG_CONFIG_MODULE OPUS_INSTALL_PKG_CONFIG_MODULE ${OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR})
set(OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR "install CMake package config module.")
-option(OPUS_INSTALL_CMAKE_CONFIG_MODULE ${OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR} ON)
+option(OPUS_INSTALL_CMAKE_CONFIG_MODULE ${OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR} ${OPUS_INSTALL})
add_feature_info(OPUS_INSTALL_CMAKE_CONFIG_MODULE OPUS_INSTALL_CMAKE_CONFIG_MODULE ${OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR})
set(OPUS_DRED_HELP_STR "enable DRED.")
@@ -613,53 +624,58 @@ if(OPUS_BUILD_FRAMEWORK)
OUTPUT_NAME Opus)
endif()
-install(TARGETS opus
- EXPORT OpusTargets
- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
- FRAMEWORK DESTINATION ${CMAKE_INSTALL_PREFIX}
- PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opus)
-
-if(OPUS_INSTALL_PKG_CONFIG_MODULE)
- set(prefix ${CMAKE_INSTALL_PREFIX})
- set(exec_prefix ${CMAKE_INSTALL_PREFIX})
- set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
- set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
- set(VERSION ${PACKAGE_VERSION})
- if(HAVE_LIBM)
- set(LIBM "-lm")
+if (OPUS_INSTALL)
+ install(TARGETS opus
+ EXPORT OpusTargets
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ FRAMEWORK DESTINATION ${CMAKE_INSTALL_PREFIX}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opus)
+
+ if(OPUS_INSTALL_PKG_CONFIG_MODULE)
+ set(prefix ${CMAKE_INSTALL_PREFIX})
+ set(exec_prefix ${CMAKE_INSTALL_PREFIX})
+ set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
+ set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
+ set(VERSION ${PACKAGE_VERSION})
+ if(HAVE_LIBM)
+ set(LIBM "-lm")
+ endif()
+ configure_file(opus.pc.in opus.pc)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/opus.pc
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+ endif()
+
+ if(OPUS_INSTALL_CMAKE_CONFIG_MODULE)
+ set(CPACK_GENERATOR TGZ)
+ include(CPack)
+ set(CMAKE_INSTALL_PACKAGEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
+ install(EXPORT OpusTargets
+ NAMESPACE Opus::
+ DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
+
+ include(CMakePackageConfigHelpers)
+
+ set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
+ configure_package_config_file(
+ ${PROJECT_SOURCE_DIR}/cmake/OpusConfig.cmake.in
+ OpusConfig.cmake
+ INSTALL_DESTINATION
+ ${CMAKE_INSTALL_PACKAGEDIR}
+ PATH_VARS
+ INCLUDE_INSTALL_DIR
+ INSTALL_PREFIX
+ ${CMAKE_INSTALL_PREFIX})
+
+ write_basic_package_version_file(OpusConfigVersion.cmake
+ VERSION ${PROJECT_VERSION}
+ COMPATIBILITY SameMajorVersion)
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpusConfig.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/OpusConfigVersion.cmake
+ DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
endif()
- configure_file(opus.pc.in opus.pc)
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/opus.pc
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
-endif()
-
-if(OPUS_INSTALL_CMAKE_CONFIG_MODULE)
- set(CPACK_GENERATOR TGZ)
- include(CPack)
- set(CMAKE_INSTALL_PACKAGEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
- install(EXPORT OpusTargets
- NAMESPACE Opus::
- DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
-
- include(CMakePackageConfigHelpers)
-
- set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
- configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/OpusConfig.cmake.in
- OpusConfig.cmake
- INSTALL_DESTINATION
- ${CMAKE_INSTALL_PACKAGEDIR}
- PATH_VARS
- INCLUDE_INSTALL_DIR
- INSTALL_PREFIX
- ${CMAKE_INSTALL_PREFIX})
- write_basic_package_version_file(OpusConfigVersion.cmake
- VERSION ${PROJECT_VERSION}
- COMPATIBILITY SameMajorVersion)
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpusConfig.cmake
- ${CMAKE_CURRENT_BINARY_DIR}/OpusConfigVersion.cmake
- DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
endif()
if(OPUS_BUILD_PROGRAMS)
+15
View File
@@ -464,6 +464,21 @@ if (NOT YUZU_STATIC_ROOM)
if (ZLIB_ADDED)
add_library(ZLIB::ZLIB ALIAS zlibstatic)
endif()
# Opus
AddJsonPackage(opus)
if (Opus_ADDED)
if (MSVC AND CXX_CLANG)
target_compile_options(opus PRIVATE
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-function-declaration>
)
endif()
endif()
if (NOT TARGET Opus::opus)
add_library(Opus::opus ALIAS opus)
endif()
endif()
if(NOT TARGET Boost::headers)
+22
View File
@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
find_package(PkgConfig QUIET)
pkg_search_module(OPUS QUIET IMPORTED_TARGET opus)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Opus
REQUIRED_VARS OPUS_LINK_LIBRARIES
VERSION_VAR OPUS_VERSION
)
if (MSYS2)
FixMsysPath(PkgConfig::OPUS)
endif()
if (Opus_FOUND AND NOT TARGET Opus::opus)
add_library(Opus::opus ALIAS PkgConfig::OPUS)
endif()
+16 -1
View File
@@ -82,7 +82,7 @@
"name": "ffmpeg",
"package": "FFmpeg",
"repo": "crueter-ci/FFmpeg",
"version": "9.0.1-1788303113-bf1b838f2a"
"version": "9.0.1-1788120736-bf1b838f2a"
},
"fmt": {
"hash": "f0da82c545b01692e9fd30fdfb613dbb8dd9716983dcd0ff19ac2a8d36f74beb5540ef38072fdecc1e34191b3682a8542ecbf3a61ef287dbba0a2679d4e023f2",
@@ -210,6 +210,21 @@
"repo": "jimmy-park/openssl-cmake",
"version": "3.6.2"
},
"opus": {
"find_args": "MODULE",
"hash": "9506147b0de35befda8633ff272981cc2575c860874791bd455b752f797fd7dbd1079f0ba42ccdd7bb1fe6773fa5e84b3d75667c2883dd1fb2d0e4a5fa4f8387",
"min_version": "1.3",
"options": [
"OPUS_PRESUME_NEON ON"
],
"package": "Opus",
"patches": [
"0001-disable-clang-runtime-neon.patch",
"0002-no-install.patch"
],
"repo": "xiph/opus",
"version": "a3f0ec02b3"
},
"quazip": {
"hash": "609c240c7f029ac26a37d8fbab51bc16284e05e128b78b9b9c0e95d083538c36047a67d682759ac990e4adb0eeb90f04f1ea7fe2253bbda7e7e3bcce32e53dd8",
"min_version": "1.3",
+10 -9
View File
@@ -60,6 +60,7 @@ All other dependencies will be downloaded and built by [CPM](https://github.com/
* [ZLIB](https://www.zlib.net/) 1.2+
* [zstd](https://facebook.github.io/zstd/) 1.5+
* [enet](http://enet.bespin.org/) 1.3+
* [Opus](https://opus-codec.org/) 1.3+
Vulkan 1.3.274+ is also needed:
@@ -120,7 +121,7 @@ sudo emerge -a \
dev-libs/boost dev-libs/openssl dev-libs/discord-rpc \
dev-util/spirv-tools dev-util/spirv-headers dev-util/vulkan-headers \
dev-util/vulkan-utility-libraries dev-util/glslang \
media-gfx/renderdoc media-libs/libva media-video/ffmpeg \
media-gfx/renderdoc media-libs/libva media-libs/opus media-video/ffmpeg \
media-libs/VulkanMemoryAllocator media-libs/libsdl3 media-libs/cubeb \
net-libs/enet \
sys-libs/zlib \
@@ -152,7 +153,7 @@ Required USE flags:
<summary>Arch Linux</summary>
```sh
sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 ninja nlohmann-json openssl qt6-base qt6-multimedia qt6-charts sdl3 zlib zstd zip unzip vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers
sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 ninja nlohmann-json openssl opus qt6-base qt6-multimedia qt6-charts sdl3 zlib zstd zip unzip vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers
```
* Building with QT Web Engine requires `qt6-webengine` as well.
@@ -165,7 +166,7 @@ sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glsl
<summary>Ubuntu, Debian, Mint Linux</summary>
```sh
sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev qt6-charts-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev libboost-dev libboost-fiber-dev libboost-context-dev libsdl3-dev libasound2t64 vulkan-utility-libraries-dev
sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev qt6-charts-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev libboost-dev libboost-fiber-dev libboost-context-dev libsdl3-dev libopus-dev libasound2t64 vulkan-utility-libraries-dev
```
* Ubuntu 26.04, Linux Mint 22.3, or Debian 13 or later is required.
@@ -212,7 +213,7 @@ First, enable the community repository; [see here](https://wiki.alpinelinux.org/
# Enable the community repository
setup-apkrepos -c
# Install
apk add g++ git cmake make mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libquazip1-qt6 ffmpeg-dev qt6-charts-dev libusb-dev libtool boost-dev sdl3-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev jq patch
apk add g++ git cmake make mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libquazip1-qt6 ffmpeg-dev qt6-charts-dev libusb-dev libtool boost-dev sdl3-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev opus-dev jq patch
```
</details>
@@ -260,7 +261,7 @@ brew install molten-vk
As root run:
```sh
pkg install devel/cmake devel/sdl3 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base x11-toolkits/qt6-charts devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib graphics/vulkan-utility-libraries graphics/vulkan-headers graphics/spirv-headers quazip-qt6
pkg install devel/cmake devel/sdl3 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base x11-toolkits/qt6-charts devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib graphics/vulkan-utility-libraries graphics/vulkan-headers graphics/spirv-headers quazip-qt6
```
If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
@@ -274,7 +275,7 @@ If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
For NetBSD +10.1:
```sh
pkgin install git cmake boost fmtlib SDL3 catch2 libjwt spirv-headers spirv-tools ffmpeg7 libva nlohmann-json jq qt6-qtbase qt6-qtcharts qt6-qtmultimedia qt6-qttools cpp-httplib lz4 vulkan-headers nasm autoconf enet pkg-config libusb1 libcxx frozen
pkgin install git cmake boost fmtlib SDL3 catch2 libjwt spirv-headers spirv-tools ffmpeg7 libva nlohmann-json jq libopus qt6-qtbase qt6-qtcharts qt6-qtmultimedia qt6-qttools cpp-httplib lz4 vulkan-headers nasm autoconf enet pkg-config libusb1 libcxx frozen
```
[Caveats](./Caveats.md#netbsd).
@@ -305,7 +306,7 @@ pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmak
<summary>OpenIndiana</summary>
```sh
sudo pkg install git cmake qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json openssl sdl3 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt
sudo pkg install git cmake qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json openssl opus sdl3 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt
```
[Caveats](./Caveats.md#openindiana).
@@ -329,7 +330,7 @@ sudo pkgin install git cmake autoconf build-essential libusb-1 nasm gcc13
```sh
BASE="git make autoconf libtool automake-wrapper jq patch"
MINGW="qt6-base qt6-charts qt6-tools qt6-translations qt6-svg cmake toolchain clang python-pip openssl vulkan-memory-allocator vulkan-devel glslang boost fmt lz4 nlohmann-json zlib zstd enet libusb openssl SDL3"
MINGW="qt6-base qt6-charts qt6-tools qt6-translations qt6-svg cmake toolchain clang python-pip openssl vulkan-memory-allocator vulkan-devel glslang boost fmt lz4 nlohmann-json zlib zstd enet opus libusb openssl SDL3"
# Either x86_64 or clang-aarch64 (Windows on ARM)
packages="$BASE"
for pkg in $MINGW; do
@@ -355,7 +356,7 @@ pacman -Syuu --needed --noconfirm $packages
<summary>HaikuOS</summary>
```sh
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel boost1.90_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl3_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel glslang qt6_devel qt6_charts_devel cubeb_devel simpleini quazip_qt6_devel
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.90_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl3_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel glslang qt6_devel qt6_charts_devel cubeb_devel simpleini quazip_qt6_devel
```
[Caveats](./Caveats.md#haikuos).
+1 -1
View File
@@ -12,7 +12,7 @@ pkgs.mkShellNoCC {
git cmake clang gnumake patch jq pkg-config
# libraries
openssl boost fmt nlohmann_json lz4 zlib zstd
enet vulkan-headers vulkan-utility-libraries
enet libopus vulkan-headers vulkan-utility-libraries
spirv-tools spirv-headers vulkan-loader unzip
glslang python3 httplib cpp-jwt ffmpeg-headless
libusb1 cubeb
@@ -79,6 +79,13 @@ class LicensesFragment : Fragment() {
R.string.license_ffmpeg_copyright,
R.string.license_ffmpeg_text
),
License(
R.string.license_opus,
R.string.license_opus_description,
R.string.license_opus_link,
R.string.license_opus_copyright,
R.string.license_opus_text
),
License(
R.string.license_sirit,
R.string.license_sirit_description,
@@ -1783,6 +1783,51 @@ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
</string>
<string name="license_opus" translatable="false">Opus</string>
<string name="license_opus_description" translatable="false">Modern audio compression for the internet</string>
<string name="license_opus_link" translatable="false">https://github.com/xiph/opus</string>
<string name="license_opus_copyright" translatable="false">Copyright 20012011 Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo</string>
<string name="license_opus_text" translatable="false">
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:\n\n
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.\n\n
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.\n\n
- Neither the name of Internet Society, IETF or IETF Trust, nor the
names of specific contributors, may be used to endorse or promote
products derived from this software without specific prior written
permission.\n\n
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS\'\' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n
Opus is subject to the royalty-free patent licenses which are
specified at:\n\n
Xiph.Org Foundation:
https://datatracker.ietf.org/ipr/1524/ \n\n
Microsoft Corporation:
https://datatracker.ietf.org/ipr/1914/ \n\n
Broadcom Corporation:
https://datatracker.ietf.org/ipr/1526/
</string>
<string name="license_sirit" translatable="false">Sirit</string>
<string name="license_sirit_description" translatable="false">A runtime SPIR-V assembler</string>
+6 -8
View File
@@ -15,6 +15,10 @@ add_library(audio_core STATIC
adsp/apps/audio_renderer/command_list_processor.h
adsp/apps/opus/opus_decoder.cpp
adsp/apps/opus/opus_decoder.h
adsp/apps/opus/opus_decode_object.cpp
adsp/apps/opus/opus_decode_object.h
adsp/apps/opus/opus_multistream_decode_object.cpp
adsp/apps/opus/opus_multistream_decode_object.h
adsp/apps/opus/shared_memory.h
audio_core.cpp
audio_core.h
@@ -222,14 +226,8 @@ else()
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-sign-conversion>)
endif()
if (YUZU_USE_EXTERNAL_FFMPEG)
add_dependencies(audio_core ffmpeg-build)
endif()
target_include_directories(audio_core PUBLIC ${FFmpeg_INCLUDE_DIR})
target_link_libraries(audio_core PRIVATE ${FFmpeg_LIBRARIES})
target_link_options(audio_core PRIVATE ${FFmpeg_LDFLAGS})
target_link_libraries(audio_core PUBLIC common core)
target_include_directories(audio_core PRIVATE ${OPUS_INCLUDE_DIRS})
target_link_libraries(audio_core PUBLIC common core Opus::opus)
if (ENABLE_CUBEB)
target_sources(audio_core PRIVATE
@@ -0,0 +1,107 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "audio_core/adsp/apps/opus/opus_decode_object.h"
#include "common/assert.h"
namespace AudioCore::ADSP::OpusDecoder {
namespace {
bool IsValidChannelCount(u32 channel_count) {
return channel_count == 1 || channel_count == 2;
}
} // namespace
u32 OpusDecodeObject::GetWorkBufferSize(u32 channel_count) {
if (!IsValidChannelCount(channel_count)) {
return 0;
}
return static_cast<u32>(sizeof(OpusDecodeObject)) + opus_decoder_get_size(channel_count);
}
OpusDecodeObject& OpusDecodeObject::Initialize(u64 buffer, u64 buffer2) {
auto* new_decoder = reinterpret_cast<OpusDecodeObject*>(buffer);
auto* comparison = reinterpret_cast<OpusDecodeObject*>(buffer2);
if (new_decoder->magic == DecodeObjectMagic) {
if (!new_decoder->initialized ||
(new_decoder->initialized && new_decoder->self == comparison)) {
new_decoder->state_valid = true;
}
} else {
new_decoder->initialized = false;
new_decoder->state_valid = true;
}
return *new_decoder;
}
s32 OpusDecodeObject::InitializeDecoder(u32 sample_rate, u32 channel_count) {
if (!state_valid) {
return OPUS_INVALID_STATE;
}
if (initialized) {
return OPUS_OK;
}
// Unfortunately libopus does not expose the OpusDecoder struct publicly, so we can't include
// it in this class. Nintendo does not allocate memory, which is why we have a workbuffer
// provided.
// We could use _create and have libopus allocate it for us, but then we have to separately
// track which decoder is being used between this and multistream in order to call the correct
// destroy from the host side.
// This is a bit cringe, but is safe as these objects are only ever initialized inside the given
// workbuffer, and GetWorkBufferSize will guarantee there's enough space to follow.
decoder = (LibOpusDecoder*)(this + 1);
s32 ret = opus_decoder_init(decoder, sample_rate, channel_count);
if (ret == OPUS_OK) {
magic = DecodeObjectMagic;
initialized = true;
state_valid = true;
self = this;
final_range = 0;
}
return ret;
}
s32 OpusDecodeObject::Shutdown() {
if (!state_valid) {
return OPUS_INVALID_STATE;
}
if (initialized) {
magic = 0x0;
initialized = false;
state_valid = false;
self = nullptr;
final_range = 0;
decoder = nullptr;
}
return OPUS_OK;
}
s32 OpusDecodeObject::ResetDecoder() {
return opus_decoder_ctl(decoder, OPUS_RESET_STATE);
}
s32 OpusDecodeObject::Decode(u32& out_sample_count, u64 output_data, u64 output_data_size,
u64 input_data, u64 input_data_size) {
ASSERT(initialized);
out_sample_count = 0;
if (!state_valid) {
return OPUS_INVALID_STATE;
}
auto ret_code_or_samples = opus_decode(
decoder, reinterpret_cast<const u8*>(input_data), static_cast<opus_int32>(input_data_size),
reinterpret_cast<opus_int16*>(output_data), static_cast<opus_int32>(output_data_size), 0);
if (ret_code_or_samples < OPUS_OK) {
return ret_code_or_samples;
}
out_sample_count = ret_code_or_samples;
return opus_decoder_ctl(decoder, OPUS_GET_FINAL_RANGE_REQUEST, &final_range);
}
} // namespace AudioCore::ADSP::OpusDecoder
@@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <opus.h>
#include "common/common_types.h"
namespace AudioCore::ADSP::OpusDecoder {
using LibOpusDecoder = ::OpusDecoder;
static constexpr u32 DecodeObjectMagic = 0xDEADBEEF;
class OpusDecodeObject {
public:
static u32 GetWorkBufferSize(u32 channel_count);
static OpusDecodeObject& Initialize(u64 buffer, u64 buffer2);
s32 InitializeDecoder(u32 sample_rate, u32 channel_count);
s32 Shutdown();
s32 ResetDecoder();
s32 Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, u64 input_data,
u64 input_data_size);
u32 GetFinalRange() const noexcept {
return final_range;
}
private:
u32 magic;
bool initialized;
bool state_valid;
OpusDecodeObject* self;
u32 final_range;
LibOpusDecoder* decoder;
};
static_assert(std::is_trivially_constructible_v<OpusDecodeObject>);
} // namespace AudioCore::ADSP::OpusDecoder
+228 -359
View File
@@ -5,388 +5,55 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <array>
#include <chrono>
extern "C" {
#include <libswresample/swresample.h>
#include <libavcodec/avcodec.h>
#include <libavcodec/codec.h>
#include <libavcodec/packet.h>
#include <libavutil/channel_layout.h>
#include <libavutil/frame.h>
#include <libavutil/opt.h>
#include <libavutil/samplefmt.h>
}
#include "audio_core/adsp/apps/opus/opus_decode_object.h"
#include "audio_core/adsp/apps/opus/opus_multistream_decode_object.h"
#include "audio_core/adsp/apps/opus/shared_memory.h"
#include "audio_core/audio_core.h"
#include "audio_core/common/common.h"
#include "common/logging.h"
#include "common/thread.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/service/audio/errors.h"
namespace AudioCore::ADSP::OpusDecoder {
namespace {
constexpr u32 OPUS_STREAM_COUNT_MAX = 255;
// https://git.ffmpeg.org/gitweb/ffmpeg.git/blob_plain/HEAD:/libavcodec/libopusdec.c
constexpr u32 OPUS_HEAD_SIZE = 19;
constexpr u32 OPUS_MAX_CHANNELS = 2;
constexpr size_t OpusStreamCountMax = 255;
bool IsValidChannelCount(u32 channel_count) {
return channel_count >= 1 || channel_count <= OPUS_MAX_CHANNELS;
return channel_count == 1 || channel_count == 2;
}
bool IsValidStreamCounts(u32 total_stream_count, u32 stereo_stream_count) {
return total_stream_count > 0 && total_stream_count <= OPUS_STREAM_COUNT_MAX
&& s32(stereo_stream_count) >= 0 && stereo_stream_count <= total_stream_count;
bool IsValidMultiStreamChannelCount(u32 channel_count) {
return channel_count <= OpusStreamCountMax;
}
class OpusGenericDecodeObject {
public:
static u32 GetWorkBufferSizeMultistream(u32 total_stream_count, u32 stereo_stream_count) {
if (IsValidStreamCounts(total_stream_count, stereo_stream_count))
return 48 + 2556 * (total_stream_count * stereo_stream_count);
return 0;
}
static u32 GetWorkBufferSize(u32 channel_count) {
if (channel_count == 1 || channel_count == 2)
return 48 + 16 * channel_count;
return 0;
}
/// idempotency of initialize is guaranteed
Result InitializeDecoder(u32 sample_rate, u32 total_stream_count, u32 channel_count, u32 stereo_stream_count, u8 const* mappings) {
// prefer libopus, ffmpeg docs say to use libopus **if** available
// However, native opus can also work with swrescale:
// it uses planarfloat, we can resample to s16
AVCodec const* codec = avcodec_find_decoder_by_name("libopus");
bool is_libopus = codec != nullptr;
if (!codec) {
LOG_WARNING(Audio_DSP, "using ffmpeg native opus decoder");
codec = avcodec_find_decoder(AV_CODEC_ID_OPUS);
}
if (codec) {
if ((avc = avc ? avc : avcodec_alloc_context3(codec))) {
if (is_libopus) {
const std::array<u8, 2> mapping_arr{0, 1};
mappings = mappings ? mappings : mapping_arr.data();
// freed by avcodec_context_free()
u8 *edata = reinterpret_cast<u8*>(av_mallocz(OPUS_HEAD_SIZE + 2 * OPUS_MAX_CHANNELS + AV_INPUT_BUFFER_PADDING_SIZE));
ASSERT(edata);
edata[9] = u8(channel_count); //channels
edata[10] = u8(0); //opus->pre_skip
edata[16] = u8(0); //gain_db
edata[18] = u8(0); //channel_map
edata[OPUS_HEAD_SIZE + 0] = u8(total_stream_count);
edata[OPUS_HEAD_SIZE + 1] = u8(stereo_stream_count);
if (channel_count >= 1) edata[OPUS_HEAD_SIZE + 2] = mappings[0];
if (channel_count >= 2) edata[OPUS_HEAD_SIZE + 3] = mappings[1];
avc->extradata = edata;
avc->extradata_size = OPUS_HEAD_SIZE + 2 * channel_count;
}
// FFmpeg hardcodes sample rate
avc->sample_rate = sample_rate;
avc->request_sample_fmt = AV_SAMPLE_FMT_S16;
av_channel_layout_default(&avc->ch_layout, channel_count);
if (avcodec_open2(avc, codec, nullptr) >= 0) {
avpkt = av_packet_alloc();
frame = av_frame_alloc();
return ResultSuccess;
} else {
avcodec_free_context(&avc);
}
}
}
return Service::Audio::ResultLibOpusInternalError;
}
Result Shutdown() {
avcodec_free_context(&avc);
av_frame_free(&frame);
av_packet_free(&avpkt);
return ResultSuccess;
}
Result ResetDecoder() {
if (avc) {
if (avcodec_is_open(avc)) avcodec_flush_buffers(avc);
return ResultSuccess;
}
return Service::Audio::ResultLibOpusInvalidState;
}
Result Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, u64 input_data, u64 input_data_size) {
out_sample_count = 0;
if (avc) {
int rem_output_bytes = int(output_data_size);
while (rem_output_bytes > 0) {
int r = avcodec_receive_frame(avc, frame);
if (r == AVERROR(EAGAIN)) {
av_packet_unref(avpkt);
av_new_packet(avpkt, int(input_data_size));
std::memcpy(avpkt->data, reinterpret_cast<const u8*>(input_data), input_data_size);
r = avcodec_send_packet(avc, avpkt);
ASSERT(r >= 0);
} else if (r == AVERROR_EOF) {
break;
} else if (r >= 0) {
auto const bsize = av_samples_get_buffer_size(nullptr, frame->ch_layout.nb_channels, frame->nb_samples, AV_SAMPLE_FMT_S16, 1);
if (frame->format == AV_SAMPLE_FMT_S16) {
std::memcpy(reinterpret_cast<s16*>(output_data) + (int(output_data_size) - rem_output_bytes), frame->data[0], size_t(bsize));
} else {
SwrContext *swr = nullptr;
if (swr_alloc_set_opts2(
&swr,
&avc->ch_layout,
AV_SAMPLE_FMT_S16,
48000,
&avc->ch_layout,
(enum AVSampleFormat)frame->format,
48000,
0,
nullptr
) >= 0) {
if (swr_init(swr) >= 0) {
AVFrame *s16_frame = av_frame_alloc();
s16_frame->format = AV_SAMPLE_FMT_S16;
s16_frame->sample_rate = frame->sample_rate;
av_channel_layout_copy(&s16_frame->ch_layout, &frame->ch_layout);
s16_frame->nb_samples = frame->nb_samples;
av_frame_get_buffer(s16_frame, 0);
swr_convert(swr, s16_frame->data, s16_frame->nb_samples, (const uint8_t **)frame->data, frame->nb_samples);
std::memcpy(reinterpret_cast<s16*>(output_data) + (int(output_data_size) - rem_output_bytes), s16_frame->data[0], size_t(bsize));
swr_free(&swr);
}
}
}
out_sample_count += frame->nb_samples;
rem_output_bytes -= bsize;
} else {
LOG_ERROR(Audio_DSP, "{}", r);
break;
}
}
ASSERT(rem_output_bytes == 0 && "remaining bytes!");
return ResultSuccess;
}
return Service::Audio::ResultLibOpusInvalidState;
}
AVCodecContext* avc = nullptr;
AVPacket* avpkt = nullptr;
AVFrame* frame = nullptr;
};
bool IsValidMultiStreamStreamCounts(s32 total_stream_count, s32 stereo_stream_count) {
return IsValidMultiStreamChannelCount(total_stream_count) && total_stream_count > 0 &&
stereo_stream_count >= 0 && stereo_stream_count <= total_stream_count;
}
} // namespace
OpusDecoder::OpusDecoder(Core::System& system) {
dsp_thread = std::jthread([this, &system](std::stop_token stop_token) {
Common::SetCurrentThreadName("DSP_OpusDecoder");
if (Receive(Direction::DSP, stop_token) != Message::Start) {
LOG_ERROR(Service_Audio, "DSP OpusDecoder failed to receive Start message. Opus initialization failed.");
return;
}
Send(Direction::Host, Message::StartOK);
// Main OpusDecoder thread, responsible for processing the incoming Opus packets.
::Common::unordered_map<u64, OpusGenericDecodeObject> decode_objects;
while (!stop_token.stop_requested()) {
auto msg = Receive(Direction::DSP, stop_token);
switch (msg) {
case Shutdown:
Send(Direction::Host, Message::ShutdownOK);
return;
case GetWorkBufferSize: {
auto channel_count = s32(shared_memory->host_send_data[0]);
ASSERT(IsValidChannelCount(channel_count));
shared_memory->dsp_return_data[0] = OpusGenericDecodeObject::GetWorkBufferSize(channel_count);
Send(Direction::Host, Message::GetWorkBufferSizeOK);
break;
}
case InitializeDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
auto buffer_size = shared_memory->host_send_data[1];
auto sample_rate = s32(shared_memory->host_send_data[2]);
auto channel_count = s32(shared_memory->host_send_data[3]);
ASSERT(sample_rate >= 0);
ASSERT(IsValidChannelCount(channel_count));
ASSERT(buffer_size >= OpusGenericDecodeObject::GetWorkBufferSize(channel_count));
if (auto const it = decode_objects.find(buffer); it != decode_objects.end()) {
it->second.Shutdown();
shared_memory->dsp_return_data[0] = it->second.InitializeDecoder(sample_rate, 1, channel_count, channel_count == 2 ? 1 : 0, nullptr).raw;
} else {
OpusGenericDecodeObject obj{};
shared_memory->dsp_return_data[0] = obj.InitializeDecoder(sample_rate, 1, channel_count, channel_count == 2 ? 1 : 0, nullptr).raw;
decode_objects.insert_or_assign(buffer, obj);
}
Send(Direction::Host, Message::InitializeDecodeObjectOK);
break;
}
case ShutdownDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
//[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
if (auto const it = decode_objects.find(buffer); it != decode_objects.end()) {
shared_memory->dsp_return_data[0] = it->second.Shutdown().raw;
} else {
LOG_ERROR(Audio_DSP, "operating unregistered buffer {}", buffer);
shared_memory->dsp_return_data[0] = Service::Audio::ResultLibOpusInvalidState.raw;
}
Send(Direction::Host, Message::ShutdownDecodeObjectOK);
break;
}
case DecodeInterleaved: {
auto start_time = system.CoreTiming().GetGlobalTimeUs();
auto buffer = shared_memory->host_send_data[0];
auto input_data = shared_memory->host_send_data[1];
auto input_data_size = shared_memory->host_send_data[2];
auto output_data = shared_memory->host_send_data[3];
auto output_data_size = shared_memory->host_send_data[4];
//auto final_range = static_cast<u32>(shared_memory->host_send_data[5]);
auto reset_requested = shared_memory->host_send_data[6];
u32 decoded_samples{0};
if (auto const it = decode_objects.find(buffer); it != decode_objects.end()) {
auto res = ResultSuccess;
if (reset_requested)
res = it->second.ResetDecoder();
if (res == ResultSuccess)
res = it->second.Decode(decoded_samples, output_data, output_data_size, input_data, input_data_size);
auto end_time = system.CoreTiming().GetGlobalTimeUs();
shared_memory->dsp_return_data[0] = res.raw;
shared_memory->dsp_return_data[1] = decoded_samples;
shared_memory->dsp_return_data[2] = (end_time - start_time).count();
} else {
LOG_ERROR(Audio_DSP, "operating unregistered buffer {}", buffer);
shared_memory->dsp_return_data[0] = Service::Audio::ResultLibOpusInvalidState.raw;
}
Send(Direction::Host, Message::DecodeInterleavedOK);
break;
}
case MapMemory: {
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
Send(Direction::Host, Message::MapMemoryOK);
break;
}
case UnmapMemory: {
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
Send(Direction::Host, Message::UnmapMemoryOK);
break;
}
case GetWorkBufferSizeForMultiStream: {
auto total_stream_count = s32(shared_memory->host_send_data[0]);
auto stereo_stream_count = s32(shared_memory->host_send_data[1]);
ASSERT(IsValidStreamCounts(total_stream_count, stereo_stream_count));
shared_memory->dsp_return_data[0] = OpusGenericDecodeObject::GetWorkBufferSizeMultistream(total_stream_count, stereo_stream_count);
Send(Direction::Host, Message::GetWorkBufferSizeForMultiStreamOK);
break;
}
case InitializeMultiStreamDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
auto buffer_size = shared_memory->host_send_data[1];
auto sample_rate = s32(shared_memory->host_send_data[2]);
auto channel_count = s32(shared_memory->host_send_data[3]);
auto total_stream_count = s32(shared_memory->host_send_data[4]);
auto stereo_stream_count = s32(shared_memory->host_send_data[5]);
// Nintendo seem to have a bug here, they try to use &host_send_data[6] for the channel
// mappings, but [6] is never set, and there is not enough room in the argument data for
// more than 40 channels, when 255 are possible.
// It also means the mapping values are undefined, though likely always 0,
// and the mappings given by the game are ignored. The mappings are copied to this
// dedicated buffer host side, so let's do as intended.
auto mappings = shared_memory->channel_mapping.data();
ASSERT(IsValidStreamCounts(total_stream_count, stereo_stream_count));
ASSERT(sample_rate >= 0);
ASSERT(buffer_size >= OpusGenericDecodeObject::GetWorkBufferSizeMultistream(total_stream_count, stereo_stream_count));
if (auto const it = decode_objects.find(buffer); it != decode_objects.end()) {
it->second.Shutdown();
shared_memory->dsp_return_data[0] = it->second.InitializeDecoder(sample_rate, total_stream_count, channel_count, stereo_stream_count, mappings).raw;
} else {
OpusGenericDecodeObject obj{};
shared_memory->dsp_return_data[0] = obj.InitializeDecoder(sample_rate, total_stream_count, channel_count, stereo_stream_count, mappings).raw;
decode_objects.insert_or_assign(buffer, obj);
}
Send(Direction::Host, Message::InitializeMultiStreamDecodeObjectOK);
break;
}
case ShutdownMultiStreamDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
//[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
if (auto const it = decode_objects.find(buffer); it != decode_objects.end()) {
shared_memory->dsp_return_data[0] = it->second.Shutdown().raw;
} else {
LOG_ERROR(Audio_DSP, "operating unregistered buffer {}", buffer);
shared_memory->dsp_return_data[0] = Service::Audio::ResultLibOpusInvalidState.raw;
}
Send(Direction::Host, Message::ShutdownMultiStreamDecodeObjectOK);
break;
}
case DecodeInterleavedForMultiStream: {
auto start_time = system.CoreTiming().GetGlobalTimeUs();
auto buffer = shared_memory->host_send_data[0];
auto input_data = shared_memory->host_send_data[1];
auto input_data_size = shared_memory->host_send_data[2];
auto output_data = shared_memory->host_send_data[3];
auto output_data_size = shared_memory->host_send_data[4];
//auto final_range = static_cast<u32>(shared_memory->host_send_data[5]);
auto reset_requested = shared_memory->host_send_data[6];
u32 decoded_samples{0};
if (auto const it = decode_objects.find(buffer); it != decode_objects.end()) {
auto res = ResultSuccess;
if (reset_requested)
res = it->second.ResetDecoder();
if (res == ResultSuccess)
res = it->second.Decode(decoded_samples, output_data, output_data_size, input_data, input_data_size);
auto end_time = system.CoreTiming().GetGlobalTimeUs();
shared_memory->dsp_return_data[0] = res.raw;
shared_memory->dsp_return_data[1] = decoded_samples;
shared_memory->dsp_return_data[2] = (end_time - start_time).count();
} else {
LOG_ERROR(Audio_DSP, "operating unregistered buffer {}", buffer);
shared_memory->dsp_return_data[0] = Service::Audio::ResultLibOpusInvalidState.raw;
}
Send(Direction::Host, Message::DecodeInterleavedForMultiStreamOK);
break;
}
default:
LOG_ERROR(Audio_DSP, "Invalid OpusDecoder command {}", msg);
continue;
}
}
for (auto e : decode_objects)
e.second.Shutdown();
});
OpusDecoder::OpusDecoder(Core::System& system_) : system{system_} {
init_thread = std::jthread([this](std::stop_token stop_token) { Init(stop_token); });
}
OpusDecoder::~OpusDecoder() {
if (dsp_thread.joinable()) {
// Shutdown the thread
auto const stop_token = dsp_thread.get_stop_token();
Send(Direction::DSP, Message::Shutdown);
auto msg = Receive(Direction::Host, stop_token);
ASSERT_MSG(msg == Message::ShutdownOK, "Expected Opus shutdown code {}, got {}", Message::ShutdownOK, msg);
dsp_thread.request_stop();
dsp_thread.join();
if (!running) {
init_thread.request_stop();
return;
}
// Shutdown the thread
Send(Direction::DSP, Message::Shutdown);
auto msg = Receive(Direction::Host);
ASSERT_MSG(msg == Message::ShutdownOK, "Expected Opus shutdown code {}, got {}",
Message::ShutdownOK, msg);
main_thread.request_stop();
main_thread.join();
running = false;
}
void OpusDecoder::Send(Direction dir, u32 message) {
@@ -397,4 +64,206 @@ u32 OpusDecoder::Receive(Direction dir, std::stop_token stop_token) {
return mailbox.Receive(dir, stop_token);
}
void OpusDecoder::Init(std::stop_token stop_token) {
Common::SetCurrentThreadName("DSP_OpusDecoder_Init");
if (Receive(Direction::DSP, stop_token) != Message::Start) {
LOG_ERROR(Service_Audio,
"DSP OpusDecoder failed to receive Start message. Opus initialization failed.");
return;
}
main_thread = std::jthread([this](std::stop_token st) { Main(st); });
running = true;
Send(Direction::Host, Message::StartOK);
}
void OpusDecoder::Main(std::stop_token stop_token) {
Common::SetCurrentThreadName("DSP_OpusDecoder_Main");
while (!stop_token.stop_requested()) {
auto msg = Receive(Direction::DSP, stop_token);
switch (msg) {
case Shutdown:
Send(Direction::Host, Message::ShutdownOK);
return;
case GetWorkBufferSize: {
auto channel_count = static_cast<s32>(shared_memory->host_send_data[0]);
ASSERT(IsValidChannelCount(channel_count));
shared_memory->dsp_return_data[0] = OpusDecodeObject::GetWorkBufferSize(channel_count);
Send(Direction::Host, Message::GetWorkBufferSizeOK);
} break;
case InitializeDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
auto buffer_size = shared_memory->host_send_data[1];
auto sample_rate = static_cast<s32>(shared_memory->host_send_data[2]);
auto channel_count = static_cast<s32>(shared_memory->host_send_data[3]);
ASSERT(sample_rate >= 0);
ASSERT(IsValidChannelCount(channel_count));
ASSERT(buffer_size >= OpusDecodeObject::GetWorkBufferSize(channel_count));
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
shared_memory->dsp_return_data[0] =
decoder_object.InitializeDecoder(sample_rate, channel_count);
Send(Direction::Host, Message::InitializeDecodeObjectOK);
} break;
case ShutdownDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
shared_memory->dsp_return_data[0] = decoder_object.Shutdown();
Send(Direction::Host, Message::ShutdownDecodeObjectOK);
} break;
case DecodeInterleaved: {
auto start_time = system.CoreTiming().GetGlobalTimeUs();
auto buffer = shared_memory->host_send_data[0];
auto input_data = shared_memory->host_send_data[1];
auto input_data_size = shared_memory->host_send_data[2];
auto output_data = shared_memory->host_send_data[3];
auto output_data_size = shared_memory->host_send_data[4];
auto final_range = static_cast<u32>(shared_memory->host_send_data[5]);
auto reset_requested = shared_memory->host_send_data[6];
u32 decoded_samples{0};
auto& decoder_object = OpusDecodeObject::Initialize(buffer, buffer);
s32 error_code{OPUS_OK};
if (reset_requested) {
error_code = decoder_object.ResetDecoder();
}
if (error_code == OPUS_OK) {
error_code = decoder_object.Decode(decoded_samples, output_data, output_data_size,
input_data, input_data_size);
}
if (error_code == OPUS_OK) {
if (final_range && decoder_object.GetFinalRange() != final_range) {
error_code = OPUS_INVALID_PACKET;
}
}
auto end_time = system.CoreTiming().GetGlobalTimeUs();
shared_memory->dsp_return_data[0] = error_code;
shared_memory->dsp_return_data[1] = decoded_samples;
shared_memory->dsp_return_data[2] = (end_time - start_time).count();
Send(Direction::Host, Message::DecodeInterleavedOK);
} break;
case MapMemory: {
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
Send(Direction::Host, Message::MapMemoryOK);
} break;
case UnmapMemory: {
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
Send(Direction::Host, Message::UnmapMemoryOK);
} break;
case GetWorkBufferSizeForMultiStream: {
auto total_stream_count = static_cast<s32>(shared_memory->host_send_data[0]);
auto stereo_stream_count = static_cast<s32>(shared_memory->host_send_data[1]);
ASSERT(IsValidMultiStreamStreamCounts(total_stream_count, stereo_stream_count));
shared_memory->dsp_return_data[0] = OpusMultiStreamDecodeObject::GetWorkBufferSize(
total_stream_count, stereo_stream_count);
Send(Direction::Host, Message::GetWorkBufferSizeForMultiStreamOK);
} break;
case InitializeMultiStreamDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
auto buffer_size = shared_memory->host_send_data[1];
auto sample_rate = static_cast<s32>(shared_memory->host_send_data[2]);
auto channel_count = static_cast<s32>(shared_memory->host_send_data[3]);
auto total_stream_count = static_cast<s32>(shared_memory->host_send_data[4]);
auto stereo_stream_count = static_cast<s32>(shared_memory->host_send_data[5]);
// Nintendo seem to have a bug here, they try to use &host_send_data[6] for the channel
// mappings, but [6] is never set, and there is not enough room in the argument data for
// more than 40 channels, when 255 are possible.
// It also means the mapping values are undefined, though likely always 0,
// and the mappings given by the game are ignored. The mappings are copied to this
// dedicated buffer host side, so let's do as intended.
auto mappings = shared_memory->channel_mapping.data();
ASSERT(IsValidMultiStreamStreamCounts(total_stream_count, stereo_stream_count));
ASSERT(sample_rate >= 0);
ASSERT(buffer_size >= OpusMultiStreamDecodeObject::GetWorkBufferSize(
total_stream_count, stereo_stream_count));
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
shared_memory->dsp_return_data[0] = decoder_object.InitializeDecoder(
sample_rate, total_stream_count, channel_count, stereo_stream_count, mappings);
Send(Direction::Host, Message::InitializeMultiStreamDecodeObjectOK);
} break;
case ShutdownMultiStreamDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
shared_memory->dsp_return_data[0] = decoder_object.Shutdown();
Send(Direction::Host, Message::ShutdownMultiStreamDecodeObjectOK);
} break;
case DecodeInterleavedForMultiStream: {
auto start_time = system.CoreTiming().GetGlobalTimeUs();
auto buffer = shared_memory->host_send_data[0];
auto input_data = shared_memory->host_send_data[1];
auto input_data_size = shared_memory->host_send_data[2];
auto output_data = shared_memory->host_send_data[3];
auto output_data_size = shared_memory->host_send_data[4];
auto final_range = static_cast<u32>(shared_memory->host_send_data[5]);
auto reset_requested = shared_memory->host_send_data[6];
u32 decoded_samples{0};
auto& decoder_object = OpusMultiStreamDecodeObject::Initialize(buffer, buffer);
s32 error_code{OPUS_OK};
if (reset_requested) {
error_code = decoder_object.ResetDecoder();
}
if (error_code == OPUS_OK) {
error_code = decoder_object.Decode(decoded_samples, output_data, output_data_size,
input_data, input_data_size);
}
if (error_code == OPUS_OK) {
if (final_range && decoder_object.GetFinalRange() != final_range) {
error_code = OPUS_INVALID_PACKET;
}
}
auto end_time = system.CoreTiming().GetGlobalTimeUs();
shared_memory->dsp_return_data[0] = error_code;
shared_memory->dsp_return_data[1] = decoded_samples;
shared_memory->dsp_return_data[2] = (end_time - start_time).count();
Send(Direction::Host, Message::DecodeInterleavedForMultiStreamOK);
} break;
default:
LOG_ERROR(Service_Audio, "Invalid OpusDecoder command {}", msg);
continue;
}
}
}
} // namespace AudioCore::ADSP::OpusDecoder
+22 -5
View File
@@ -6,13 +6,12 @@
#pragma once
#include <memory>
#include <thread>
#include "common/container/unordered_map.h"
#include "audio_core/adsp/apps/opus/shared_memory.h"
#include "audio_core/adsp/mailbox.h"
#include "common/common_types.h"
#include "core/hle/result.h"
namespace Core {
class System;
@@ -49,14 +48,16 @@ enum Message : u32 {
DecodeInterleavedForMultiStreamOK = 50,
};
/// @brief The AudioRenderer application running on the ADSP.
/**
* The AudioRenderer application running on the ADSP.
*/
class OpusDecoder {
public:
explicit OpusDecoder(Core::System& system);
~OpusDecoder();
bool IsRunning() const noexcept {
return dsp_thread.joinable();
return running;
}
void Send(Direction dir, u32 message);
@@ -67,12 +68,28 @@ public:
}
private:
/**
* Initializing thread, launched at audio_core boot to avoid blocking the main emu boot thread.
*/
void Init(std::stop_token stop_token);
/**
* Main OpusDecoder thread, responsible for processing the incoming Opus packets.
*/
void Main(std::stop_token stop_token);
/// Core system
Core::System& system;
/// Mailbox to communicate messages with the host, drives the main thread
Mailbox mailbox;
/// Init thread
std::jthread init_thread{};
/// Main thread
std::jthread main_thread{};
/// The current state
bool running{};
/// Structure shared with the host, input data set by the host before sending a mailbox message,
/// and the responses are written back by the OpusDecoder.
SharedMemory* shared_memory{};
std::jthread dsp_thread{};
};
} // namespace AudioCore::ADSP::OpusDecoder
@@ -0,0 +1,113 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "audio_core/adsp/apps/opus/opus_multistream_decode_object.h"
#include "common/assert.h"
namespace AudioCore::ADSP::OpusDecoder {
namespace {
constexpr u32 OpusStreamCountMax = 255;
bool IsValidStreamCounts(u32 total_stream_count, u32 stereo_stream_count) {
return total_stream_count > 0 && total_stream_count <= OpusStreamCountMax &&
static_cast<s32>(stereo_stream_count) >= 0 &&
stereo_stream_count <= total_stream_count;
}
} // namespace
u32 OpusMultiStreamDecodeObject::GetWorkBufferSize(u32 total_stream_count,
u32 stereo_stream_count) {
if (IsValidStreamCounts(total_stream_count, stereo_stream_count)) {
return static_cast<u32>(sizeof(OpusMultiStreamDecodeObject)) +
opus_multistream_decoder_get_size(total_stream_count, stereo_stream_count);
}
return 0;
}
OpusMultiStreamDecodeObject& OpusMultiStreamDecodeObject::Initialize(u64 buffer, u64 buffer2) {
auto* new_decoder = reinterpret_cast<OpusMultiStreamDecodeObject*>(buffer);
auto* comparison = reinterpret_cast<OpusMultiStreamDecodeObject*>(buffer2);
if (new_decoder->magic == DecodeMultiStreamObjectMagic) {
if (!new_decoder->initialized ||
(new_decoder->initialized && new_decoder->self == comparison)) {
new_decoder->state_valid = true;
}
} else {
new_decoder->initialized = false;
new_decoder->state_valid = true;
}
return *new_decoder;
}
s32 OpusMultiStreamDecodeObject::InitializeDecoder(u32 sample_rate, u32 total_stream_count,
u32 channel_count, u32 stereo_stream_count,
u8* mappings) {
if (!state_valid) {
return OPUS_INVALID_STATE;
}
if (initialized) {
return OPUS_OK;
}
// See OpusDecodeObject::InitializeDecoder for an explanation of this
decoder = (LibOpusMSDecoder*)(this + 1);
s32 ret = opus_multistream_decoder_init(decoder, sample_rate, channel_count, total_stream_count,
stereo_stream_count, mappings);
if (ret == OPUS_OK) {
magic = DecodeMultiStreamObjectMagic;
initialized = true;
state_valid = true;
self = this;
final_range = 0;
}
return ret;
}
s32 OpusMultiStreamDecodeObject::Shutdown() {
if (!state_valid) {
return OPUS_INVALID_STATE;
}
if (initialized) {
magic = 0x0;
initialized = false;
state_valid = false;
self = nullptr;
final_range = 0;
decoder = nullptr;
}
return OPUS_OK;
}
s32 OpusMultiStreamDecodeObject::ResetDecoder() {
return opus_multistream_decoder_ctl(decoder, OPUS_RESET_STATE);
}
s32 OpusMultiStreamDecodeObject::Decode(u32& out_sample_count, u64 output_data,
u64 output_data_size, u64 input_data, u64 input_data_size) {
ASSERT(initialized);
out_sample_count = 0;
if (!state_valid) {
return OPUS_INVALID_STATE;
}
auto ret_code_or_samples = opus_multistream_decode(
decoder, reinterpret_cast<const u8*>(input_data), static_cast<opus_int32>(input_data_size),
reinterpret_cast<opus_int16*>(output_data), static_cast<opus_int32>(output_data_size), 0);
if (ret_code_or_samples < OPUS_OK) {
return ret_code_or_samples;
}
out_sample_count = ret_code_or_samples;
return opus_multistream_decoder_ctl(decoder, OPUS_GET_FINAL_RANGE_REQUEST, &final_range);
}
} // namespace AudioCore::ADSP::OpusDecoder
@@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <opus_multistream.h>
#include "common/common_types.h"
namespace AudioCore::ADSP::OpusDecoder {
using LibOpusMSDecoder = ::OpusMSDecoder;
static constexpr u32 DecodeMultiStreamObjectMagic = 0xDEADBEEF;
class OpusMultiStreamDecodeObject {
public:
static u32 GetWorkBufferSize(u32 total_stream_count, u32 stereo_stream_count);
static OpusMultiStreamDecodeObject& Initialize(u64 buffer, u64 buffer2);
s32 InitializeDecoder(u32 sample_rate, u32 total_stream_count, u32 channel_count,
u32 stereo_stream_count, u8* mappings);
s32 Shutdown();
s32 ResetDecoder();
s32 Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, u64 input_data,
u64 input_data_size);
u32 GetFinalRange() const noexcept {
return final_range;
}
private:
u32 magic;
bool initialized;
bool state_valid;
OpusMultiStreamDecodeObject* self;
u32 final_range;
LibOpusMSDecoder* decoder;
};
static_assert(std::is_trivially_constructible_v<OpusMultiStreamDecodeObject>);
} // namespace AudioCore::ADSP::OpusDecoder
@@ -1,32 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "common/common_types.h"
namespace AudioCore::ADSP {
static constexpr u32 DECODE_OBJECT_MAGIC = 0xDEADBEEF;
struct LibOpusDecoder {
u32 magic;
bool initialized;
bool state_valid;
LibOpusDecoder* self;
u32 final_range;
void* decoder;
};
static_assert(sizeof(LibOpusDecoder) == 32);
static constexpr u32 DECODE_MULTISTREAM_OBJECT_MAGIC = 0xDEADBEEF;
struct LibOpusMultistreamDecoder {
u32 magic;
bool initialized;
bool state_valid;
LibOpusMultistreamDecoder* self;
u32 final_range;
void* decoder;
};
static_assert(sizeof(LibOpusMultistreamDecoder) == 32);
}
@@ -1,11 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/common_funcs.h"
#include "common/common_types.h"
namespace AudioCore::ADSP::OpusDecoder {
+11 -8
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -9,7 +12,9 @@
namespace AudioCore::Renderer {
Manager::Manager(Core::System& system_)
: system{system_}, system_manager{std::make_unique<SystemManager>(system)} {
: system{system_}
, system_manager{std::make_unique<SystemManager>(system)}
{
std::iota(session_ids.begin(), session_ids.end(), 0);
}
@@ -38,14 +43,12 @@ Result Manager::GetWorkBufferSize(const AudioRendererParameterInternal& params,
s32 Manager::GetSessionId() {
std::scoped_lock l{session_lock};
auto session_id{session_ids[session_count]};
if (session_id == -1) {
return -1;
ASSERT(session_count <= session_ids.size());
auto const session_id = session_ids[session_count];
if (session_id >= 0) {
session_ids[session_count] = -1;
session_count++;
}
session_ids[session_count] = -1;
session_count++;
return session_id;
}
+48 -23
View File
@@ -10,18 +10,39 @@
#include "audio_core/audio_core.h"
#include "audio_core/opus/hardware_opus.h"
#include "core/core.h"
#include "core/hle/result.h"
namespace AudioCore::OpusDecoder {
namespace {
using namespace Service::Audio;
static constexpr Result ResultCodeFromLibOpusErrorCode(u64 error_code) {
s32 error{static_cast<s32>(error_code)};
ASSERT(error <= OPUS_OK);
switch (error) {
case OPUS_ALLOC_FAIL:
R_THROW(ResultLibOpusAllocFail);
case OPUS_INVALID_STATE:
R_THROW(ResultLibOpusInvalidState);
case OPUS_UNIMPLEMENTED:
R_THROW(ResultLibOpusUnimplemented);
case OPUS_INVALID_PACKET:
R_THROW(ResultLibOpusInvalidPacket);
case OPUS_INTERNAL_ERROR:
R_THROW(ResultLibOpusInternalError);
case OPUS_BUFFER_TOO_SMALL:
R_THROW(ResultBufferTooSmall);
case OPUS_BAD_ARG:
R_THROW(ResultLibOpusBadArg);
case OPUS_OK:
R_RETURN(ResultSuccess);
}
UNREACHABLE();
}
} // namespace
HardwareOpus::HardwareOpus(Core::System& system_)
: system{system_}
, opus_decoder{system.AudioCore().ADSP().OpusDecoder()}
{
: system{system_}, opus_decoder{system.AudioCore().ADSP().OpusDecoder()} {
opus_decoder.SetSharedMemory(shared_memory);
}
@@ -91,7 +112,7 @@ Result HardwareOpus::InitializeDecodeObject(u32 sample_rate, u32 channel_count,
R_THROW(ResultInvalidOpusDSPReturnCode);
}
R_RETURN(Result(u32(shared_memory.dsp_return_data[0])));
R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
}
Result HardwareOpus::InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count,
@@ -119,7 +140,7 @@ Result HardwareOpus::InitializeMultiStreamDecodeObject(u32 sample_rate, u32 chan
R_THROW(ResultInvalidOpusDSPReturnCode);
}
R_RETURN(Result(u32(shared_memory.dsp_return_data[0])));
R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
}
Result HardwareOpus::ShutdownDecodeObject(void* buffer, u64 buffer_size) {
@@ -133,7 +154,7 @@ Result HardwareOpus::ShutdownDecodeObject(void* buffer, u64 buffer_size) {
"Expected Opus shutdown code {}, got {}",
ADSP::OpusDecoder::Message::ShutdownDecodeObjectOK, msg);
R_RETURN(Result(u32(shared_memory.dsp_return_data[0])));
R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
}
Result HardwareOpus::ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size) {
@@ -148,7 +169,7 @@ Result HardwareOpus::ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_si
"Expected Opus shutdown code {}, got {}",
ADSP::OpusDecoder::Message::ShutdownMultiStreamDecodeObjectOK, msg);
R_RETURN(Result(u32(shared_memory.dsp_return_data[0])));
R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
}
Result HardwareOpus::DecodeInterleaved(u32& out_sample_count, void* output_data,
@@ -172,12 +193,12 @@ Result HardwareOpus::DecodeInterleaved(u32& out_sample_count, void* output_data,
R_THROW(ResultInvalidOpusDSPReturnCode);
}
auto error_code = s32(shared_memory.dsp_return_data[0]);
if (error_code == ResultSuccess.raw) {
out_sample_count = u32(shared_memory.dsp_return_data[1]);
auto error_code{static_cast<s32>(shared_memory.dsp_return_data[0])};
if (error_code == OPUS_OK) {
out_sample_count = static_cast<u32>(shared_memory.dsp_return_data[1]);
out_time_taken = 1000 * shared_memory.dsp_return_data[2];
}
R_RETURN(Result(u32(error_code)));
R_RETURN(ResultCodeFromLibOpusErrorCode(error_code));
}
Result HardwareOpus::DecodeInterleavedForMultiStream(u32& out_sample_count, void* output_data,
@@ -186,27 +207,29 @@ Result HardwareOpus::DecodeInterleavedForMultiStream(u32& out_sample_count, void
void* buffer, u64& out_time_taken,
bool reset) {
std::scoped_lock l{mutex};
shared_memory.host_send_data[0] = u64(buffer);
shared_memory.host_send_data[1] = u64(input_data);
shared_memory.host_send_data[0] = (u64)buffer;
shared_memory.host_send_data[1] = (u64)input_data;
shared_memory.host_send_data[2] = input_data_size;
shared_memory.host_send_data[3] = u64(output_data);
shared_memory.host_send_data[3] = (u64)output_data;
shared_memory.host_send_data[4] = output_data_size;
shared_memory.host_send_data[5] = 0;
shared_memory.host_send_data[6] = reset;
opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStream);
opus_decoder.Send(ADSP::Direction::DSP,
ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStream);
auto msg = opus_decoder.Receive(ADSP::Direction::Host);
if (msg != ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStreamOK) {
LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}", ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStreamOK, msg);
LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStreamOK, msg);
R_THROW(ResultInvalidOpusDSPReturnCode);
}
auto const error_code = shared_memory.dsp_return_data[0];
if (error_code == ResultSuccess.raw) {
auto error_code{static_cast<s32>(shared_memory.dsp_return_data[0])};
if (error_code == OPUS_OK) {
out_sample_count = static_cast<u32>(shared_memory.dsp_return_data[1]);
out_time_taken = 1000 * shared_memory.dsp_return_data[2];
}
R_RETURN(Result(u32(shared_memory.dsp_return_data[0])));
R_RETURN(ResultCodeFromLibOpusErrorCode(error_code));
}
Result HardwareOpus::MapMemory(void* buffer, u64 buffer_size) {
@@ -217,7 +240,8 @@ Result HardwareOpus::MapMemory(void* buffer, u64 buffer_size) {
opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::MapMemory);
auto msg = opus_decoder.Receive(ADSP::Direction::Host);
if (msg != ADSP::OpusDecoder::Message::MapMemoryOK) {
LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}", ADSP::OpusDecoder::Message::MapMemoryOK, msg);
LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
ADSP::OpusDecoder::Message::MapMemoryOK, msg);
R_THROW(ResultInvalidOpusDSPReturnCode);
}
R_SUCCEED();
@@ -231,7 +255,8 @@ Result HardwareOpus::UnmapMemory(void* buffer, u64 buffer_size) {
opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::UnmapMemory);
auto msg = opus_decoder.Receive(ADSP::Direction::Host);
if (msg != ADSP::OpusDecoder::Message::UnmapMemoryOK) {
LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}", ADSP::OpusDecoder::Message::UnmapMemoryOK, msg);
LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
ADSP::OpusDecoder::Message::UnmapMemoryOK, msg);
R_THROW(ResultInvalidOpusDSPReturnCode);
}
R_SUCCEED();
+2
View File
@@ -8,6 +8,8 @@
#include <array>
#include <mutex>
#include <opus.h>
#include "audio_core/adsp/apps/opus/opus_decoder.h"
#include "audio_core/adsp/apps/opus/shared_memory.h"
#include "audio_core/adsp/mailbox.h"
+8
View File
@@ -28,10 +28,18 @@ namespace {
//
// Keep in sync with cubeb_sink.cpp name.
SDL_SetHint("SDL_AUDIO_DEVICE_APP_NAME", "yuzu Latency Getter");
#ifdef __ANDROID__
SDL_SetHintWithPriority(SDL_HINT_AUDIO_DRIVER, "openslES", SDL_HINT_OVERRIDE);
if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) {
LOG_WARNING(Audio_Sink, "OpenSL ES audio initialization failed: {}; retrying default drivers", SDL_GetError());
SDL_ResetHint(SDL_HINT_AUDIO_DRIVER);
}
#endif
if (!SDL_WasInit(SDL_INIT_AUDIO) && !SDL_InitSubSystem(SDL_INIT_AUDIO)) {
LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError());
return false;
}
LOG_INFO(Audio_Sink, "SDL audio driver: {}", SDL_GetCurrentAudioDriver());
}
return true;
}
+1
View File
@@ -1199,6 +1199,7 @@ else()
endif()
endif()
target_include_directories(core PRIVATE ${OPUS_INCLUDE_DIRS})
target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb tz)
if (BOOST_NO_HEADERS)
+17 -17
View File
@@ -185,26 +185,26 @@ public:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("aud:a", std::make_shared<IAudioSystemManagerForApplet>(system));
server_manager->RegisterNamedService("aud:d", std::make_shared<IAudioSystemManagerForDebugger>(system));
server_manager->RegisterNamedService("aud:a", std::make_shared<IAudioSystemManagerForApplet>(system), 30);
server_manager->RegisterNamedService("aud:d", std::make_shared<IAudioSystemManagerForDebugger>(system), 30);
server_manager->RegisterNamedService("audout:d", std::make_shared<IAudioOutManagerForDebugger>(system));
server_manager->RegisterNamedService("audin:d", std::make_shared<IAudioInManagerForDebugger>(system));
server_manager->RegisterNamedService("audrec:d", std::make_shared<IFinalOutputRecorderManagerForDebugger>(system));
server_manager->RegisterNamedService("audren:d", std::make_shared<IAudioInManager>(system));
server_manager->RegisterNamedService("audout:d", std::make_shared<IAudioOutManagerForDebugger>(system), 30);
server_manager->RegisterNamedService("audin:d", std::make_shared<IAudioInManagerForDebugger>(system), 30);
server_manager->RegisterNamedService("audrec:d", std::make_shared<IFinalOutputRecorderManagerForDebugger>(system), 30);
server_manager->RegisterNamedService("audren:d", std::make_shared<IAudioInManager>(system), 30);
server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system));
server_manager->RegisterNamedService("audin:a", std::make_shared<IAudioInManagerForApplet>(system));
server_manager->RegisterNamedService("audout:u", std::make_shared<IAudioOutManager>(system));
server_manager->RegisterNamedService("audout:a", std::make_shared<IAudioOutManagerForApplet>(system));
server_manager->RegisterNamedService("auddev", std::make_shared<IAudioSnoopManager>(system));
server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system), 30);
server_manager->RegisterNamedService("audin:a", std::make_shared<IAudioInManagerForApplet>(system), 30);
server_manager->RegisterNamedService("audout:u", std::make_shared<IAudioOutManager>(system), 30);
server_manager->RegisterNamedService("audout:a", std::make_shared<IAudioOutManagerForApplet>(system), 30);
server_manager->RegisterNamedService("auddev", std::make_shared<IAudioSnoopManager>(system), 30);
// Depends on audout:u and audin:u on ctor!
server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system));
server_manager->RegisterNamedService("audrec:a", std::make_shared<IFinalOutputRecorderManagerForApplet>(system));
server_manager->RegisterNamedService("audrec:u", std::make_shared<IFinalOutputRecorderManager>(system));
server_manager->RegisterNamedService("audren:u", std::make_shared<IAudioRendererManager>(system));
server_manager->RegisterNamedService("audren:a", std::make_shared<IAudioRendererManagerForApplet>(system));
server_manager->RegisterNamedService("hwopus", std::make_shared<IHardwareOpusDecoderManager>(system));
server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system), 30);
server_manager->RegisterNamedService("audrec:a", std::make_shared<IFinalOutputRecorderManagerForApplet>(system), 30);
server_manager->RegisterNamedService("audrec:u", std::make_shared<IFinalOutputRecorderManager>(system), 30);
server_manager->RegisterNamedService("audren:u", std::make_shared<IAudioRendererManager>(system), 30);
server_manager->RegisterNamedService("audren:a", std::make_shared<IAudioRendererManagerForApplet>(system), 30);
server_manager->RegisterNamedService("hwopus", std::make_shared<IHardwareOpusDecoderManager>(system), 25);
ServerManager::RunServer(std::move(server_manager));
}
+12 -18
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -12,25 +15,16 @@ namespace Service::BCAT {
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("bcat:a",
std::make_shared<IServiceCreator>(system, "bcat:a"));
server_manager->RegisterNamedService("bcat:m",
std::make_shared<IServiceCreator>(system, "bcat:m"));
server_manager->RegisterNamedService("bcat:u",
std::make_shared<IServiceCreator>(system, "bcat:u"));
server_manager->RegisterNamedService("bcat:s",
std::make_shared<IServiceCreator>(system, "bcat:s"));
server_manager->RegisterNamedService("bcat:a", std::make_shared<IServiceCreator>(system, "bcat:a"), 32);
server_manager->RegisterNamedService("bcat:m", std::make_shared<IServiceCreator>(system, "bcat:m"), 32);
server_manager->RegisterNamedService("bcat:u", std::make_shared<IServiceCreator>(system, "bcat:u"), 32);
server_manager->RegisterNamedService("bcat:s", std::make_shared<IServiceCreator>(system, "bcat:s"), 32);
server_manager->RegisterNamedService(
"news:a", std::make_shared<News::IServiceCreator>(system, 0xffffffff, "news:a"));
server_manager->RegisterNamedService(
"news:p", std::make_shared<News::IServiceCreator>(system, 0x1, "news:p"));
server_manager->RegisterNamedService(
"news:c", std::make_shared<News::IServiceCreator>(system, 0x2, "news:c"));
server_manager->RegisterNamedService(
"news:v", std::make_shared<News::IServiceCreator>(system, 0x4, "news:v"));
server_manager->RegisterNamedService(
"news:m", std::make_shared<News::IServiceCreator>(system, 0xd, "news:m"));
server_manager->RegisterNamedService("news:a", std::make_shared<News::IServiceCreator>(system, 0xffffffff, "news:a"), 32);
server_manager->RegisterNamedService("news:p", std::make_shared<News::IServiceCreator>(system, 0x1, "news:p"), 32);
server_manager->RegisterNamedService("news:c", std::make_shared<News::IServiceCreator>(system, 0x2, "news:c"), 32);
server_manager->RegisterNamedService("news:v", std::make_shared<News::IServiceCreator>(system, 0x4, "news:v"), 32);
server_manager->RegisterNamedService("news:m", std::make_shared<News::IServiceCreator>(system, 0xd, "news:m"), 32);
ServerManager::RunServer(std::move(server_manager));
}
+19 -5
View File
@@ -101,14 +101,28 @@ public:
}
};
class BPC_AMS final : public ServiceFramework<BPC_AMS> {
public:
explicit BPC_AMS(Core::System& system_) : ServiceFramework{system_, "bpc:ams"} {
// clang-format off
static const FunctionInfo functions[] = {
{65000, nullptr, "RebootToFatalError"},
{65001, nullptr, "SetRebootPayload"},
};
// clang-format on
RegisterHandlers(functions);
}
};
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("bpc", std::make_shared<BPC>(system));
server_manager->RegisterNamedService("bpc:r", std::make_shared<BPC_R>(system));
server_manager->RegisterNamedService("bpc:c", std::make_shared<BPC_C>(system));
server_manager->RegisterNamedService("bpc:b", std::make_shared<BPC_B>(system));
server_manager->RegisterNamedService("bpc:w", std::make_shared<BPC_W>(system));
server_manager->RegisterNamedService("bpc", std::make_shared<BPC>(system), 13);
server_manager->RegisterNamedService("bpc:r", std::make_shared<BPC_R>(system), 13);
server_manager->RegisterNamedService("bpc:c", std::make_shared<BPC_C>(system), 13);
server_manager->RegisterNamedService("bpc:b", std::make_shared<BPC_B>(system), 13);
server_manager->RegisterNamedService("bpc:w", std::make_shared<BPC_W>(system), 13);
server_manager->RegisterNamedService("bpc:ams", std::make_shared<BPC_AMS>(system), 4);
ServerManager::RunServer(std::move(server_manager));
}
@@ -804,9 +804,9 @@ void LoopProcess(Core::System& system) {
const auto FileSystemProxyFactory = [&] { return std::make_shared<FSP_SRV>(system); };
server_manager->RegisterNamedService("fsp-ldr", std::make_shared<FSP_LDR>(system));
server_manager->RegisterNamedService("fsp-pr", std::make_shared<FSP_PR>(system));
server_manager->RegisterNamedService("fsp-srv", std::move(FileSystemProxyFactory));
server_manager->RegisterNamedService("fsp-ldr", std::make_shared<FSP_LDR>(system), 61);
server_manager->RegisterNamedService("fsp-pr", std::make_shared<FSP_PR>(system), 61);
server_manager->RegisterNamedService("fsp-srv", std::move(FileSystemProxyFactory), 61);
ServerManager::RunServer(std::move(server_manager));
}
+15 -20
View File
@@ -36,18 +36,18 @@ std::optional<u64> GetTitleIDForProcessID(Core::System& system, u64 process_id)
ARP_R::ARP_R(Core::System& system_, const ARPManager& manager_)
: ServiceFramework{system_, "arp:r"}, manager{manager_} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ARP_R::GetApplicationLaunchProperty, "GetApplicationLaunchProperty"},
{1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"},
{2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"},
{3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"},
{4, nullptr, "GetApplicationInstanceUnregistrationNotifier"},
{5, nullptr, "ListApplicationInstanceId"},
{6, nullptr, "GetMicroApplicationInstanceId"},
{7, nullptr, "GetApplicationCertificate"},
{9998, nullptr, "GetPreomiaApplicationLaunchProperty"},
{9999, nullptr, "GetPreomiaApplicationControlProperty"},
};
static const FunctionInfo functions[] = {
{0, &ARP_R::GetApplicationLaunchProperty, "GetApplicationLaunchProperty"},
{1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"},
{2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"},
{3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"},
{4, nullptr, "GetApplicationInstanceUnregistrationNotifier"},
{5, nullptr, "ListApplicationInstanceId"},
{6, nullptr, "GetMicroApplicationInstanceId"},
{7, nullptr, "GetApplicationCertificate"},
{9998, nullptr, "GetPreomiaApplicationLaunchProperty"},
{9999, nullptr, "GetPreomiaApplicationControlProperty"},
};
// clang-format on
RegisterHandlers(functions);
@@ -191,8 +191,7 @@ private:
}
if (issued) {
LOG_ERROR(Service_ARP,
"Attempted to issue registrar, but registrar is already issued!");
LOG_ERROR(Service_ARP, "Attempted to issue registrar, but registrar is already issued!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(Glue::ResultAlreadyBound);
return;
@@ -209,9 +208,7 @@ private:
LOG_DEBUG(Service_ARP, "called");
if (issued) {
LOG_ERROR(
Service_ARP,
"Attempted to set application launch property, but registrar is already issued!");
LOG_ERROR(Service_ARP, "Attempted to set application launch property, but registrar is already issued!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(Glue::ResultAlreadyBound);
return;
@@ -228,9 +225,7 @@ private:
LOG_DEBUG(Service_ARP, "called");
if (issued) {
LOG_ERROR(
Service_ARP,
"Attempted to set application control property, but registrar is already issued!");
LOG_ERROR(Service_ARP, "Attempted to set application control property, but registrar is already issued!");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(Glue::ResultAlreadyBound);
return;
+2 -2
View File
@@ -22,8 +22,8 @@ void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
// ARP
server_manager->RegisterNamedService("arp:r", std::make_shared<ARP_R>(system, system.GetARPManager()));
server_manager->RegisterNamedService("arp:w", std::make_shared<ARP_W>(system, system.GetARPManager()));
server_manager->RegisterNamedService("arp:r", std::make_shared<ARP_R>(system, system.GetARPManager()), 16);
server_manager->RegisterNamedService("arp:w", std::make_shared<ARP_W>(system, system.GetARPManager()), 8);
// BackGround Task Controller
server_manager->RegisterNamedService("bgtc:t", std::make_shared<BGTC_T>(system));
+2 -2
View File
@@ -46,8 +46,8 @@ public:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("grc:c", std::make_shared<GRC>(system));
server_manager->RegisterNamedService("grc:d", std::make_shared<GRC_D>(system));
server_manager->RegisterNamedService("grc:c", std::make_shared<GRC>(system), 4);
server_manager->RegisterNamedService("grc:d", std::make_shared<GRC_D>(system), 4);
ServerManager::RunServer(std::move(server_manager));
}
+6 -3
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -56,9 +59,9 @@ public:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("ldr:dmnt", std::make_shared<DebugMonitor>(system));
server_manager->RegisterNamedService("ldr:pm", std::make_shared<ProcessManager>(system));
server_manager->RegisterNamedService("ldr:shel", std::make_shared<Shell>(system));
server_manager->RegisterNamedService("ldr:dmnt", std::make_shared<DebugMonitor>(system), 3);
server_manager->RegisterNamedService("ldr:pm", std::make_shared<ProcessManager>(system), 1);
server_manager->RegisterNamedService("ldr:shel", std::make_shared<Shell>(system), 3);
ServerManager::RunServer(std::move(server_manager));
}
+3 -3
View File
@@ -169,9 +169,9 @@ public:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("ngct:u", std::make_shared<IService>(system));
server_manager->RegisterNamedService("ngct:s", std::make_shared<IServiceWithManagementApi>(system));
server_manager->RegisterNamedService("ngc:u", std::make_shared<NgcServiceImpl>(system));
server_manager->RegisterNamedService("ngct:u", std::make_shared<IService>(system), 4);
server_manager->RegisterNamedService("ngct:s", std::make_shared<IServiceWithManagementApi>(system), 4);
server_manager->RegisterNamedService("ngc:u", std::make_shared<NgcServiceImpl>(system), 4);
ServerManager::RunServer(std::move(server_manager));
}
+3 -6
View File
@@ -1144,12 +1144,9 @@ private:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("nifm:a",
std::make_shared<NetworkInterface>("nifm:a", system));
server_manager->RegisterNamedService("nifm:s",
std::make_shared<NetworkInterface>("nifm:s", system));
server_manager->RegisterNamedService("nifm:u",
std::make_shared<NetworkInterface>("nifm:u", system));
server_manager->RegisterNamedService("nifm:a", std::make_shared<NetworkInterface>("nifm:a", system), 2);
server_manager->RegisterNamedService("nifm:s", std::make_shared<NetworkInterface>("nifm:s", system), 16);
server_manager->RegisterNamedService("nifm:u", std::make_shared<NetworkInterface>("nifm:u", system), 5);
ServerManager::RunServer(std::move(server_manager));
}
+9 -9
View File
@@ -81,16 +81,16 @@ public:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("ns:am2", std::make_shared<IServiceGetterInterface>(system, "ns:am2"));
server_manager->RegisterNamedService("ns:ec", std::make_shared<IServiceGetterInterface>(system, "ns:ec"));
server_manager->RegisterNamedService("ns:rid", std::make_shared<IServiceGetterInterface>(system, "ns:rid"));
server_manager->RegisterNamedService("ns:rt", std::make_shared<IServiceGetterInterface>(system, "ns:rt"));
server_manager->RegisterNamedService("ns:web", std::make_shared<IServiceGetterInterface>(system, "ns:web"));
server_manager->RegisterNamedService("ns:ro", std::make_shared<IServiceGetterInterface>(system, "ns:ro"));
server_manager->RegisterNamedService("ns:am2", std::make_shared<IServiceGetterInterface>(system, "ns:am2"), 5);
server_manager->RegisterNamedService("ns:ec", std::make_shared<IServiceGetterInterface>(system, "ns:ec"), 5);
server_manager->RegisterNamedService("ns:rid", std::make_shared<IServiceGetterInterface>(system, "ns:rid"), 5);
server_manager->RegisterNamedService("ns:rt", std::make_shared<IServiceGetterInterface>(system, "ns:rt"), 5);
server_manager->RegisterNamedService("ns:web", std::make_shared<IServiceGetterInterface>(system, "ns:web"), 5);
server_manager->RegisterNamedService("ns:ro", std::make_shared<IServiceGetterInterface>(system, "ns:ro"), 5);
server_manager->RegisterNamedService("ns:dev", std::make_shared<IDevelopInterface>(system));
server_manager->RegisterNamedService("ns:su", std::make_shared<ISystemUpdateInterface>(system));
server_manager->RegisterNamedService("ns:vm", std::make_shared<IVulnerabilityManagerInterface>(system));
server_manager->RegisterNamedService("ns:dev", std::make_shared<IDevelopInterface>(system), 5);
server_manager->RegisterNamedService("ns:su", std::make_shared<ISystemUpdateInterface>(system), 5);
server_manager->RegisterNamedService("ns:vm", std::make_shared<IVulnerabilityManagerInterface>(system), 5);
server_manager->RegisterNamedService("pdm:ntfy", std::make_shared<INotifyService>(system));
server_manager->RegisterNamedService("pdm:qry", std::make_shared<IQueryService>(system));
+4 -4
View File
@@ -252,10 +252,10 @@ private:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("pm:bm", std::make_shared<BootMode>(system));
server_manager->RegisterNamedService("pm:dmnt", std::make_shared<DebugMonitor>(system));
server_manager->RegisterNamedService("pm:info", std::make_shared<Info>(system));
server_manager->RegisterNamedService("pm:shell", std::make_shared<Shell>(system));
server_manager->RegisterNamedService("pm:bm", std::make_shared<BootMode>(system), 4); // Nx = 4, Ams = 8
server_manager->RegisterNamedService("pm:dmnt", std::make_shared<DebugMonitor>(system), 16);
server_manager->RegisterNamedService("pm:shell", std::make_shared<Shell>(system), 3); //Nx = 3, AMS = 8
server_manager->RegisterNamedService("pm:info", std::make_shared<Info>(system), 25); //48-(4+16+3)
ServerManager::RunServer(std::move(server_manager));
}
+3 -3
View File
@@ -593,9 +593,9 @@ void LoopProcess(Core::System& system) {
return std::make_shared<RoInterface>(system, "ldr:ro", ro, NrrKind::User);
};
server_manager->RegisterNamedService("ldr:ro", std::move(RoInterfaceFactoryForUser));
server_manager->RegisterNamedService("ro:1", std::make_shared<RoInterface>(system, "ro:1", ro, NrrKind::JitPlugin));
server_manager->RegisterNamedService("ro:dmnt", std::make_shared<IDebugMonitorInterface>(system));
server_manager->RegisterNamedService("ldr:ro", std::move(RoInterfaceFactoryForUser), 2);
server_manager->RegisterNamedService("ro:1", std::make_shared<RoInterface>(system, "ro:1", ro, NrrKind::JitPlugin), 2);
server_manager->RegisterNamedService("ro:dmnt", std::make_shared<IDebugMonitorInterface>(system), 2);
ServerManager::RunServer(std::move(server_manager));
}
+7 -7
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -13,13 +16,10 @@ namespace Service::Set {
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("set", std::make_shared<ISettingsServer>(system));
server_manager->RegisterNamedService("set:cal",
std::make_shared<IFactorySettingsServer>(system));
server_manager->RegisterNamedService("set:fd",
std::make_shared<IFirmwareDebugSettingsServer>(system));
server_manager->RegisterNamedService("set:sys",
std::make_shared<ISystemSettingsServer>(system));
server_manager->RegisterNamedService("set", std::make_shared<ISettingsServer>(system), 60);
server_manager->RegisterNamedService("set:cal", std::make_shared<IFactorySettingsServer>(system), 60);
server_manager->RegisterNamedService("set:fd", std::make_shared<IFirmwareDebugSettingsServer>(system), 60);
server_manager->RegisterNamedService("set:sys", std::make_shared<ISystemSettingsServer>(system), 60);
ServerManager::RunServer(std::move(server_manager));
}
+3 -4
View File
@@ -53,8 +53,7 @@ static Result ValidateServiceName(const std::string& name) {
return ResultSuccess;
}
Result ServiceManager::RegisterService(Kernel::KServerPort** out_server_port, std::string name,
u32 max_sessions, SessionRequestHandlerFactory handler) {
Result ServiceManager::RegisterService(Kernel::KServerPort** out_server_port, std::string name, u32 max_sessions, SessionRequestHandlerFactory handler) {
R_TRY(ValidateServiceName(name));
std::scoped_lock lk{lock};
@@ -64,7 +63,7 @@ Result ServiceManager::RegisterService(Kernel::KServerPort** out_server_port, st
}
auto* port = Kernel::KPort::Create(kernel);
port->Initialize(kernel, ServerSessionCountMax, false, 0);
port->Initialize(kernel, max_sessions, false, 0);
// Register the port.
Kernel::KPort::Register(kernel, port);
@@ -264,7 +263,7 @@ void SM::AtmosphereHasService(HLERequestContext& ctx) {
}
SM::SM(ServiceManager& service_manager_, Core::System& system_)
: ServiceFramework{system_, "sm:", 4}
: ServiceFramework{system_, "sm:", 64}
, service_manager{service_manager_}
, kernel{system_.Kernel()}
{
+7 -7
View File
@@ -64,17 +64,17 @@ public:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("ethc:c", std::make_shared<ETHC_C>(system));
server_manager->RegisterNamedService("ethc:i", std::make_shared<ETHC_I>(system));
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD_USA>(system, "bsd:s", false));
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD_USA>(system, "bsd:u", true));
server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD_USA>(system, "bsd:a", true));
server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system));
server_manager->RegisterNamedService("ethc:c", std::make_shared<ETHC_C>(system), 5);
server_manager->RegisterNamedService("ethc:i", std::make_shared<ETHC_I>(system), 5);
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD_USA>(system, "bsd:s", false), 0x7E);
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD_USA>(system, "bsd:u", true), 0x0f);
server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD_USA>(system, "bsd:a", true), 0x17);
server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system), 4);
server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system, "bsdcfg"));
server_manager->RegisterNamedService("ifcfg", std::make_shared<BSDCFG>(system, "ifcfg"));
server_manager->RegisterNamedService("nsd:a", std::make_shared<NSD>(system, "nsd:a"));
server_manager->RegisterNamedService("nsd:u", std::make_shared<NSD>(system, "nsd:u"));
server_manager->RegisterNamedService("sfdnsres", std::make_shared<SFDNSRES>(system));
server_manager->RegisterNamedService("sfdnsres", std::make_shared<SFDNSRES>(system), 30);
server_manager->RegisterNamedService("dns:priv", std::make_shared<DNS_PRIV>(system));
server_manager->RegisterNamedService("eth:nd", std::make_shared<ISfDriverServiceCreator>(system));
+4 -4
View File
@@ -265,17 +265,17 @@ void LoopProcess(Core::System& system) {
server_manager->RegisterNamedService("usb:ds", std::make_shared<IDsRootSession>(system));
server_manager->RegisterNamedService("usb:hs", std::make_shared<IClientRootSession>(system));
server_manager->RegisterNamedService("usb:pd", std::make_shared<IPdManager>(system));
server_manager->RegisterNamedService("usb:pd:c", std::make_shared<IPdCradleManager>(system));
server_manager->RegisterNamedService("usb:pd", std::make_shared<IPdManager>(system), 6);
server_manager->RegisterNamedService("usb:pd:c", std::make_shared<IPdCradleManager>(system), 4);
server_manager->RegisterNamedService("usb:pd:m", std::make_shared<IPdManufactureManager>(system));
server_manager->RegisterNamedService("usb:pm", std::make_shared<IPmMainService>(system));
server_manager->RegisterNamedService("usb:pm", std::make_shared<IPmMainService>(system), 5);
// +7.0.0
if (FirmwareManager::GetFirmwareVersion(system).first.major >= 7) {
server_manager->RegisterNamedService("usb:qdb", std::make_shared<IQdbManager>(system));
}
// +8.0.0
if (FirmwareManager::GetFirmwareVersion(system).first.major >= 8) {
server_manager->RegisterNamedService("usb:obsv", std::make_shared<IPmObserverService>(system));
server_manager->RegisterNamedService("usb:obsv", std::make_shared<IPmObserverService>(system), 2);
}
ServerManager::RunServer(std::move(server_manager));
}
+8 -8
View File
@@ -246,14 +246,14 @@ public:
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("wlan:lcl", std::make_shared<ILocalManager>(system));
server_manager->RegisterNamedService("wlan:lg", std::make_shared<ILocalGetFrame>(system));
server_manager->RegisterNamedService("wlan:lga", std::make_shared<ILocalGetActionFrame>(system));
server_manager->RegisterNamedService("wlan:sg", std::make_shared<ISocketGetFrame>(system));
server_manager->RegisterNamedService("wlan:soc", std::make_shared<ISocketManager>(system));
server_manager->RegisterNamedService("wlan:dtc", std::make_shared<IDetectManager>(system));
server_manager->RegisterNamedService("wlan:p", std::make_shared<IPrivateServiceCreator>(system));
server_manager->RegisterNamedService("wlan:nd", std::make_shared<ISfDriverServiceCreator>(system));
server_manager->RegisterNamedService("wlan:lcl", std::make_shared<ILocalManager>(system), 10);
server_manager->RegisterNamedService("wlan:lg", std::make_shared<ILocalGetFrame>(system), 10);
server_manager->RegisterNamedService("wlan:lga", std::make_shared<ILocalGetActionFrame>(system), 10);
server_manager->RegisterNamedService("wlan:sg", std::make_shared<ISocketGetFrame>(system), 10);
server_manager->RegisterNamedService("wlan:soc", std::make_shared<ISocketManager>(system), 10);
server_manager->RegisterNamedService("wlan:dtc", std::make_shared<IDetectManager>(system), 4);
server_manager->RegisterNamedService("wlan:p", std::make_shared<IPrivateServiceCreator>(system), 30);
server_manager->RegisterNamedService("wlan:nd", std::make_shared<ISfDriverServiceCreator>(system), 5);
ServerManager::RunServer(std::move(server_manager));
}
@@ -31,7 +31,7 @@ struct Jit::Impl final {
, core(conf) {}
HaltReason Run() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
jit_interface->is_executing = true;
@@ -42,7 +42,7 @@ struct Jit::Impl final {
}
HaltReason Step() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
jit_interface->is_executing = true;
@@ -31,7 +31,7 @@ struct Jit::Impl final {
, core(conf) {}
HaltReason Run() {
ASSERT(!is_executing);
DEBUG_ASSERT(!is_executing);
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
is_executing = true;
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
@@ -41,7 +41,7 @@ struct Jit::Impl final {
}
HaltReason Step() {
ASSERT(!is_executing);
DEBUG_ASSERT(!is_executing);
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
is_executing = true;
HaltReason hr = core.Step(current_address_space, current_state, &halt_reason);
@@ -57,7 +57,7 @@ constexpr RegisterList ToRegList(oaknut::Reg reg) {
if (reg.is_vector()) {
return RegisterList{1} << (reg.index() + 32);
}
ASSERT(reg.index() != 31 && "ZR not allowed in reg list");
DEBUG_ASSERT(reg.index() != 31 && "ZR not allowed in reg list");
if (reg.index() == -1) {
return RegisterList{1} << 31;
}
@@ -31,7 +31,7 @@ AddressSpace::AddressSpace(std::size_t code_cache_size)
, code(mem.ptr(), mem.ptr())
, fastmem_manager(exception_handler)
{
ASSERT(code_cache_size <= 128 * 1024 * 1024 && "code_cache_size > 128 MiB not currently supported");
DEBUG_ASSERT(code_cache_size <= 128 * 1024 * 1024 && "code_cache_size > 128 MiB not currently supported");
exception_handler.Register(mem, code_cache_size);
exception_handler.SetFastmemCallback([this](u64 host_pc) {
@@ -115,9 +115,13 @@ EmittedBlockInfo AddressSpace::Emit(IR::Block block) {
EmittedBlockInfo block_info = EmitArm64(code, std::move(block), GetEmitConfig(), fastmem_manager);
ASSERT(block_entries.insert({block.Location(), block_info.entry_point}).second);
ASSERT(reverse_block_entries.insert({block_info.entry_point, block.Location()}).second);
ASSERT(block_infos.insert({block_info.entry_point, block_info}).second);
[[maybe_unused]] bool r = true;
r &= block_entries.insert({block.Location(), block_info.entry_point}).second;
DEBUG_ASSERT(r);
r &= reverse_block_entries.insert({block_info.entry_point, block.Location()}).second;
DEBUG_ASSERT(r);
r &= block_infos.insert({block_info.entry_point, block_info}).second;
DEBUG_ASSERT(r);
Link(block_info);
RelinkForDescriptor(block.Location(), block_info.entry_point);
@@ -54,7 +54,7 @@ void EmitIR<IR::Opcode::PushRSB>(oaknut::CodeGenerator& code, EmitContext& ctx,
}
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[0].IsImmediate());
DEBUG_ASSERT(args[0].IsImmediate());
const IR::LocationDescriptor target{args[0].GetImmediateU64()};
code.LDR(Wscratch2, SP, offsetof(StackLayout, rsb_ptr));
@@ -71,19 +71,19 @@ void EmitIR<IR::Opcode::PushRSB>(oaknut::CodeGenerator& code, EmitContext& ctx,
template<>
void EmitIR<IR::Opcode::GetCarryFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
DEBUG_ASSERT(ctx.reg_alloc.WasValueDefined(inst));
}
template<>
void EmitIR<IR::Opcode::GetOverflowFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
DEBUG_ASSERT(ctx.reg_alloc.WasValueDefined(inst));
}
template<>
void EmitIR<IR::Opcode::GetGEFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
DEBUG_ASSERT(ctx.reg_alloc.WasValueDefined(inst));
}
template<>
@@ -149,13 +149,13 @@ void EmitIR<IR::Opcode::GetNZFromOp>(oaknut::CodeGenerator& code, EmitContext& c
template<>
void EmitIR<IR::Opcode::GetUpperFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
DEBUG_ASSERT(ctx.reg_alloc.WasValueDefined(inst));
}
template<>
void EmitIR<IR::Opcode::GetLowerFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
DEBUG_ASSERT(ctx.reg_alloc.WasValueDefined(inst));
}
template<>
@@ -206,9 +206,9 @@ EmittedBlockInfo EmitArm64(oaknut::CodeGenerator& code, IR::Block block, const E
ebi.entry_point = code.xptr<CodePtr>();
if (ctx.block.GetCondition() == IR::Cond::AL) {
ASSERT(!ctx.block.HasConditionFailedLocation());
DEBUG_ASSERT(!ctx.block.HasConditionFailedLocation());
} else {
ASSERT(ctx.block.HasConditionFailedLocation());
DEBUG_ASSERT(ctx.block.HasConditionFailedLocation());
oaknut::Label pass;
pass = conf.emit_cond(code, ctx, ctx.block.GetCondition());
@@ -234,7 +234,7 @@ void EmitIR<IR::Opcode::A32GetRegister>(oaknut::CodeGenerator& code, EmitContext
template<>
void EmitIR<IR::Opcode::A32GetExtendedRegister32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsSingleExtReg(reg));
DEBUG_ASSERT(A32::IsSingleExtReg(reg));
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::S0);
auto Sresult = ctx.reg_alloc.WriteS(inst);
@@ -248,7 +248,7 @@ void EmitIR<IR::Opcode::A32GetExtendedRegister32>(oaknut::CodeGenerator& code, E
template<>
void EmitIR<IR::Opcode::A32GetVector>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
if (A32::IsDoubleExtReg(reg)) {
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
@@ -266,7 +266,7 @@ void EmitIR<IR::Opcode::A32GetVector>(oaknut::CodeGenerator& code, EmitContext&
template<>
void EmitIR<IR::Opcode::A32GetExtendedRegister64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg));
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
auto Dresult = ctx.reg_alloc.WriteD(inst);
@@ -294,7 +294,7 @@ void EmitIR<IR::Opcode::A32SetRegister>(oaknut::CodeGenerator& code, EmitContext
template<>
void EmitIR<IR::Opcode::A32SetExtendedRegister32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsSingleExtReg(reg));
DEBUG_ASSERT(A32::IsSingleExtReg(reg));
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::S0);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@@ -309,7 +309,7 @@ void EmitIR<IR::Opcode::A32SetExtendedRegister32>(oaknut::CodeGenerator& code, E
template<>
void EmitIR<IR::Opcode::A32SetExtendedRegister64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg));
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@@ -324,7 +324,7 @@ void EmitIR<IR::Opcode::A32SetExtendedRegister64>(oaknut::CodeGenerator& code, E
template<>
void EmitIR<IR::Opcode::A32SetVector>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
if (A32::IsDoubleExtReg(reg)) {
@@ -194,8 +194,8 @@ void EmitIR<IR::Opcode::TestBit>(oaknut::CodeGenerator& code, EmitContext& ctx,
auto Xresult = ctx.reg_alloc.WriteX(inst);
auto Xoperand = ctx.reg_alloc.ReadX(args[0]);
RegAlloc::Realize(Xresult, Xoperand);
ASSERT(args[1].IsImmediate());
ASSERT(args[1].GetImmediateU8() < 64);
DEBUG_ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].GetImmediateU8() < 64);
code.UBFX(Xresult, Xoperand, args[1].GetImmediateU8(), 1);
}
@@ -893,9 +893,9 @@ static void EmitAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
if (overflow_inst) {
// There is a limited set of circumstances where this is required, so assert for this.
ASSERT(!sub);
ASSERT(!nzcv_inst);
ASSERT(args[2].IsImmediate() && args[2].GetImmediateU1() == false);
DEBUG_ASSERT(!sub);
DEBUG_ASSERT(!nzcv_inst);
DEBUG_ASSERT(args[2].IsImmediate() && args[2].GetImmediateU1() == false);
auto Rb = ctx.reg_alloc.ReadReg<bitsize>(args[1]);
auto Woverflow = ctx.reg_alloc.WriteW(overflow_inst);
@@ -1134,7 +1134,7 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
if constexpr (!std::is_same_v<EmitFn2, std::nullptr_t>) {
const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp);
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
ASSERT(!(nz_inst && nzcv_inst));
DEBUG_ASSERT(!(nz_inst && nzcv_inst));
const auto flag_inst = nz_inst ? nz_inst : nzcv_inst;
if (flag_inst) {
@@ -1171,7 +1171,7 @@ template<std::size_t bitsize>
static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp);
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
ASSERT(!(nz_inst && nzcv_inst));
DEBUG_ASSERT(!(nz_inst && nzcv_inst));
const auto flag_inst = nz_inst ? nz_inst : nzcv_inst;
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@@ -1402,7 +1402,7 @@ void EmitIR<IR::Opcode::CountLeadingZeros64>(oaknut::CodeGenerator& code, EmitCo
template<>
void EmitIR<IR::Opcode::ExtractRegister32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[2].IsImmediate());
DEBUG_ASSERT(args[2].IsImmediate());
auto Wresult = ctx.reg_alloc.WriteW(inst);
auto Wop1 = ctx.reg_alloc.ReadW(args[0]);
@@ -1416,7 +1416,7 @@ void EmitIR<IR::Opcode::ExtractRegister32>(oaknut::CodeGenerator& code, EmitCont
template<>
void EmitIR<IR::Opcode::ExtractRegister64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[2].IsImmediate());
DEBUG_ASSERT(args[2].IsImmediate());
auto Xresult = ctx.reg_alloc.WriteX(inst);
auto Xop1 = ctx.reg_alloc.ReadX(args[0]);
@@ -1430,7 +1430,7 @@ void EmitIR<IR::Opcode::ExtractRegister64>(oaknut::CodeGenerator& code, EmitCont
template<>
void EmitIR<IR::Opcode::ReplicateBit32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
auto Wresult = ctx.reg_alloc.WriteW(inst);
auto Wvalue = ctx.reg_alloc.ReadW(args[0]);
@@ -1444,7 +1444,7 @@ void EmitIR<IR::Opcode::ReplicateBit32>(oaknut::CodeGenerator& code, EmitContext
template<>
void EmitIR<IR::Opcode::ReplicateBit64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
auto Xresult = ctx.reg_alloc.WriteX(inst);
auto Xvalue = ctx.reg_alloc.ReadX(args[0]);
@@ -68,7 +68,7 @@ static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
RegAlloc::Realize(Vto, Vfrom);
ctx.fpsr.Load();
ASSERT(rounding_mode == ctx.FPCR().RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR().RMode());
emit(Vto, Vfrom);
}
@@ -106,8 +106,8 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
}
}
} else {
ASSERT(fbits == 0);
ASSERT(bitsize_to != 16);
DEBUG_ASSERT(fbits == 0);
DEBUG_ASSERT(bitsize_to != 16);
if constexpr (is_signed) {
switch (rounding_mode) {
case FP::RoundingMode::ToNearest_TieEven:
@@ -449,7 +449,7 @@ void EmitIR<IR::Opcode::FPRoundInt32>(oaknut::CodeGenerator& code, EmitContext&
ctx.fpsr.Load();
if (exact) {
ASSERT(ctx.FPCR().RMode() == rounding_mode);
DEBUG_ASSERT(ctx.FPCR().RMode() == rounding_mode);
code.FRINTX(Sresult, Soperand);
} else {
switch (rounding_mode) {
@@ -486,7 +486,7 @@ void EmitIR<IR::Opcode::FPRoundInt64>(oaknut::CodeGenerator& code, EmitContext&
ctx.fpsr.Load();
if (exact) {
ASSERT(ctx.FPCR().RMode() == rounding_mode);
DEBUG_ASSERT(ctx.FPCR().RMode() == rounding_mode);
code.FRINTX(Dresult, Doperand);
} else {
switch (rounding_mode) {
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@@ -244,7 +247,7 @@ static void EmitPackedAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::
}
if (ge_inst) {
ASSERT(!is_halving);
DEBUG_ASSERT(!is_halving);
auto Vge = ctx.reg_alloc.WriteD(ge_inst);
RegAlloc::Realize(Vge);
@@ -24,7 +24,7 @@ using namespace oaknut::util;
template<>
void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
ASSERT(overflow_inst);
DEBUG_ASSERT(overflow_inst);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Wresult = ctx.reg_alloc.WriteW(inst);
@@ -44,7 +44,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(oaknut::CodeGenerator& cod
template<>
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
ASSERT(overflow_inst);
DEBUG_ASSERT(overflow_inst);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Wresult = ctx.reg_alloc.WriteW(inst);
@@ -67,7 +67,7 @@ void EmitIR<IR::Opcode::SignedSaturation>(oaknut::CodeGenerator& code, EmitConte
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const std::size_t N = args[1].GetImmediateU8();
ASSERT(N >= 1 && N <= 32);
DEBUG_ASSERT(N >= 1 && N <= 32);
if (N == 32) {
ctx.reg_alloc.DefineAsExisting(inst, args[0]);
@@ -113,7 +113,7 @@ void EmitIR<IR::Opcode::UnsignedSaturation>(oaknut::CodeGenerator& code, EmitCon
ctx.reg_alloc.SpillFlags();
const std::size_t N = args[1].GetImmediateU8();
ASSERT(N <= 31);
DEBUG_ASSERT(N <= 31);
const u32 saturated_value = (1u << N) - 1;
code.MOV(Wscratch0, saturated_value);
@@ -275,7 +275,7 @@ static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
template<std::size_t size, typename EmitFn>
static void EmitGetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
auto Rresult = ctx.reg_alloc.WriteReg<std::max<std::size_t>(32, size)>(inst);
@@ -310,7 +310,7 @@ void EmitIR<IR::Opcode::VectorGetElement64>(oaknut::CodeGenerator& code, EmitCon
template<std::size_t size, typename EmitFn>
static void EmitSetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
auto Qvector = ctx.reg_alloc.ReadWriteQ(args[0], inst);
@@ -650,7 +650,7 @@ void EmitIR<IR::Opcode::VectorExtract>(oaknut::CodeGenerator& code, EmitContext&
auto Qa = ctx.reg_alloc.ReadQ(args[0]);
auto Qb = ctx.reg_alloc.ReadQ(args[1]);
const u8 position = args[2].GetImmediateU8();
ASSERT(position % 8 == 0);
DEBUG_ASSERT(position % 8 == 0);
RegAlloc::Realize(Qresult, Qa, Qb);
code.EXT(Qresult->B16(), Qa->B16(), Qb->B16(), position / 8);
@@ -663,7 +663,7 @@ void EmitIR<IR::Opcode::VectorExtractLower>(oaknut::CodeGenerator& code, EmitCon
auto Da = ctx.reg_alloc.ReadD(args[0]);
auto Db = ctx.reg_alloc.ReadD(args[1]);
const u8 position = args[2].GetImmediateU8();
ASSERT(position % 8 == 0);
DEBUG_ASSERT(position % 8 == 0);
RegAlloc::Realize(Dresult, Da, Db);
code.EXT(Dresult->B8(), Da->B8(), Db->B8(), position / 8);
@@ -958,7 +958,7 @@ void EmitIR<IR::Opcode::VectorMultiply32>(oaknut::CodeGenerator& code, EmitConte
template<>
void EmitIR<IR::Opcode::VectorMultiply64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
ASSERT(ctx.conf.very_verbose_debugging_output && "VectorMultiply64 is for debugging only");
DEBUG_ASSERT(ctx.conf.very_verbose_debugging_output && "VectorMultiply64 is for debugging only");
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
code.FMOV(Xscratch0, Qa->toD());
code.FMOV(Xscratch1, Qb->toD());
@@ -1289,7 +1289,7 @@ void EmitIR<IR::Opcode::VectorReduceAdd64>(oaknut::CodeGenerator& code, EmitCont
template<>
void EmitIR<IR::Opcode::VectorRotateWholeVectorRight>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
EmitImmShift<8>(code, ctx, inst, [&](auto Vresult, auto Voperand, u8 shift_amount) {
ASSERT(shift_amount % 8 == 0);
DEBUG_ASSERT(shift_amount % 8 == 0);
const u8 ext_imm = (shift_amount % 128) / 8;
code.EXT(Vresult, Voperand, Voperand, ext_imm);
});
@@ -1602,12 +1602,12 @@ void EmitIR<IR::Opcode::VectorSub64>(oaknut::CodeGenerator& code, EmitContext& c
template<>
void EmitIR<IR::Opcode::VectorTable>(oaknut::CodeGenerator&, EmitContext&, IR::Inst* inst) {
// Do nothing. We *want* to hold on to the refcount for our arguments, so VectorTableLookup can use our arguments.
ASSERT(inst->UseCount() == 1 && "Table cannot be used multiple times");
DEBUG_ASSERT(inst->UseCount() == 1 && "Table cannot be used multiple times");
}
template<>
void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
DEBUG_ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
@@ -1674,7 +1674,7 @@ void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitCo
template<>
void EmitIR<IR::Opcode::VectorTableLookup128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
DEBUG_ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
@@ -139,7 +139,7 @@ static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Ins
const u8 fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
const bool fpcr_controlled = args[3].GetImmediateU1();
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
RegAlloc::Realize(Qto, Qfrom);
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
@@ -199,7 +199,7 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
}
}
} else {
ASSERT(fbits == 0);
DEBUG_ASSERT(fbits == 0);
if constexpr (is_signed) {
switch (rounding_mode) {
case FP::RoundingMode::ToNearest_TieEven:
@@ -346,7 +346,7 @@ template<>
void EmitIR<IR::Opcode::FPVectorFromHalf32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const auto rounding_mode = static_cast<FP::RoundingMode>(args[1].GetImmediateU8());
ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
DEBUG_ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
const bool fpcr_controlled = args[2].GetImmediateU1();
auto Qresult = ctx.reg_alloc.WriteQ(inst);
@@ -617,7 +617,7 @@ void EmitIR<IR::Opcode::FPVectorRoundInt32>(oaknut::CodeGenerator& code, EmitCon
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
if (exact) {
ASSERT(ctx.FPCR(fpcr_controlled).RMode() == rounding_mode);
DEBUG_ASSERT(ctx.FPCR(fpcr_controlled).RMode() == rounding_mode);
code.FRINTX(Qresult->S4(), Qoperand->S4());
} else {
switch (rounding_mode) {
@@ -657,7 +657,7 @@ void EmitIR<IR::Opcode::FPVectorRoundInt64>(oaknut::CodeGenerator& code, EmitCon
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
if (exact) {
ASSERT(ctx.FPCR(fpcr_controlled).RMode() == rounding_mode);
DEBUG_ASSERT(ctx.FPCR(fpcr_controlled).RMode() == rounding_mode);
code.FRINTX(Qresult->D2(), Qoperand->D2());
} else {
switch (rounding_mode) {
@@ -743,7 +743,7 @@ template<>
void EmitIR<IR::Opcode::FPVectorToHalf32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const auto rounding_mode = static_cast<FP::RoundingMode>(args[1].GetImmediateU8());
ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
DEBUG_ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
const bool fpcr_controlled = args[2].GetImmediateU1();
auto Dresult = ctx.reg_alloc.WriteD(inst);
@@ -53,19 +53,19 @@ bool Argument::GetImmediateU1() const {
u8 Argument::GetImmediateU8() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x100);
DEBUG_ASSERT(imm < 0x100);
return u8(imm);
}
u16 Argument::GetImmediateU16() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x10000);
DEBUG_ASSERT(imm < 0x10000);
return u16(imm);
}
u32 Argument::GetImmediateU32() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x100000000);
DEBUG_ASSERT(imm < 0x100000000);
return u32(imm);
}
@@ -74,12 +74,12 @@ u64 Argument::GetImmediateU64() const {
}
IR::Cond Argument::GetImmediateCond() const {
ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
DEBUG_ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
return value.GetCond();
}
IR::AccType Argument::GetImmediateAccType() const {
ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
DEBUG_ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
return value.GetAccType();
}
@@ -92,12 +92,12 @@ bool HostLocInfo::Contains(const IR::Inst* value) const {
}
void HostLocInfo::SetupScratchLocation() {
ASSERT(IsCompletelyEmpty());
DEBUG_ASSERT(IsCompletelyEmpty());
realized = true;
}
void HostLocInfo::SetupLocation(const IR::Inst* value) {
ASSERT(IsCompletelyEmpty());
DEBUG_ASSERT(IsCompletelyEmpty());
values.clear();
values.push_back(value);
realized = true;
@@ -135,7 +135,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
const IR::Value arg = inst->GetArg(i);
ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
DEBUG_ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
ValueInfo(arg.GetInst()).uses_this_inst++;
}
}
@@ -174,11 +174,11 @@ void RegAlloc::PrepareForCall(std::optional<Argument::copyable_reference> arg0,
for (int i = 0; i < 4; i++) {
if (args[i]) {
if (args[i]->get().GetType() == IR::Type::U128) {
ASSERT(fprs[nsrn].IsCompletelyEmpty());
DEBUG_ASSERT(fprs[nsrn].IsCompletelyEmpty());
LoadCopyInto(args[i]->get().value, oaknut::QReg{nsrn});
nsrn++;
} else {
ASSERT(gprs[ngrn].IsCompletelyEmpty());
DEBUG_ASSERT(gprs[ngrn].IsCompletelyEmpty());
LoadCopyInto(args[i]->get().value, oaknut::XReg{ngrn});
ngrn++;
}
@@ -192,7 +192,7 @@ void RegAlloc::PrepareForCall(std::optional<Argument::copyable_reference> arg0,
void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
defined_insts.insert(inst);
ASSERT(!ValueLocation(inst));
DEBUG_ASSERT(!ValueLocation(inst));
if (arg.value.IsImmediate()) {
inst->ReplaceUsesWith(arg.value);
@@ -206,9 +206,9 @@ void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
void RegAlloc::DefineAsRegister(IR::Inst* inst, oaknut::Reg reg) {
defined_insts.insert(inst);
ASSERT(!ValueLocation(inst));
DEBUG_ASSERT(!ValueLocation(inst));
auto& info = reg.is_vector() ? fprs[reg.index()] : gprs[reg.index()];
ASSERT(info.IsCompletelyEmpty());
DEBUG_ASSERT(info.IsCompletelyEmpty());
info.values.push_back(inst);
info.expected_uses += inst->UseCount();
}
@@ -228,18 +228,18 @@ void RegAlloc::UpdateAllUses() {
void RegAlloc::AssertAllUnlocked() const {
const auto is_unlocked = [](const auto& i) { return !i.locked && !i.realized; };
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_unlocked));
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_unlocked));
ASSERT(is_unlocked(flags));
ASSERT(std::all_of(spills.begin(), spills.end(), is_unlocked));
DEBUG_ASSERT(std::all_of(gprs.begin(), gprs.end(), is_unlocked));
DEBUG_ASSERT(std::all_of(fprs.begin(), fprs.end(), is_unlocked));
DEBUG_ASSERT(is_unlocked(flags));
DEBUG_ASSERT(std::all_of(spills.begin(), spills.end(), is_unlocked));
}
void RegAlloc::AssertNoMoreUses() const {
const auto is_empty = [](const auto& i) { return i.IsCompletelyEmpty(); };
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
ASSERT(is_empty(flags));
ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
DEBUG_ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
DEBUG_ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
DEBUG_ASSERT(is_empty(flags));
DEBUG_ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
}
void RegAlloc::EmitVerboseDebuggingOutput() {
@@ -271,7 +271,7 @@ void RegAlloc::EmitVerboseDebuggingOutput() {
template<HostLoc::Kind kind>
int RegAlloc::GenerateImmediate(const IR::Value& value) {
ASSERT(value.GetType() != IR::Type::U1);
DEBUG_ASSERT(value.GetType() != IR::Type::U1);
if constexpr (kind == HostLoc::Kind::Gpr) {
const int new_location_index = AllocateRegister(gprs, gpr_order);
SpillGpr(new_location_index);
@@ -309,15 +309,15 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
}
const auto current_location = ValueLocation(value.GetInst());
ASSERT(current_location);
DEBUG_ASSERT(current_location);
if (current_location->kind == required_kind) {
ValueInfo(*current_location).realized = true;
return current_location->index;
}
ASSERT(!bool(ValueInfo(*current_location).realized));
ASSERT(bool(ValueInfo(*current_location).locked));
DEBUG_ASSERT(!bool(ValueInfo(*current_location).realized));
DEBUG_ASSERT(bool(ValueInfo(*current_location).locked));
if constexpr (required_kind == HostLoc::Kind::Gpr) {
const int new_location_index = AllocateRegister(gprs, gpr_order);
@@ -328,7 +328,7 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
UNREACHABLE(); //logic error
case HostLoc::Kind::Fpr:
code.FMOV(oaknut::XReg{new_location_index}, oaknut::DReg{current_location->index});
// ASSERT size fits
// DEBUG_ASSERT size fits
break;
case HostLoc::Kind::Spill:
code.LDR(oaknut::XReg{new_location_index}, SP, spill_offset + current_location->index * spill_slot_size);
@@ -355,7 +355,7 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
code.LDR(oaknut::QReg{new_location_index}, SP, spill_offset + current_location->index * spill_slot_size);
break;
case HostLoc::Kind::Flags:
ASSERT(false && "Moving from flags into fprs is not currently supported");
DEBUG_ASSERT(false && "Moving from flags into fprs is not currently supported");
break;
}
@@ -372,7 +372,7 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
template<HostLoc::Kind kind>
int RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
defined_insts.insert(value);
ASSERT(!ValueLocation(value));
DEBUG_ASSERT(!ValueLocation(value));
if constexpr (kind == HostLoc::Kind::Gpr) {
const int new_location_index = AllocateRegister(gprs, gpr_order);
@@ -407,7 +407,7 @@ int RegAlloc::RealizeReadWriteImpl(const IR::Value& read_value, const IR::Inst*
LoadCopyInto(read_value, oaknut::QReg{write_loc});
return write_loc;
} else if constexpr (kind == HostLoc::Kind::Flags) {
ASSERT(false && "Incorrect function for ReadWrite of flags");
DEBUG_ASSERT(false && "Incorrect function for ReadWrite of flags");
} else {
UNREACHABLE();
}
@@ -439,7 +439,7 @@ int RegAlloc::AllocateRegister(const std::array<HostLocInfo, 32>& regs, const st
}
void RegAlloc::SpillGpr(int index) {
ASSERT(!gprs[index].locked && !gprs[index].realized);
DEBUG_ASSERT(!gprs[index].locked && !gprs[index].realized);
if (gprs[index].values.empty()) {
return;
}
@@ -449,7 +449,7 @@ void RegAlloc::SpillGpr(int index) {
}
void RegAlloc::SpillFpr(int index) {
ASSERT(!fprs[index].locked && !fprs[index].realized);
DEBUG_ASSERT(!fprs[index].locked && !fprs[index].realized);
if (fprs[index].values.empty()) {
return;
}
@@ -461,7 +461,7 @@ void RegAlloc::SpillFpr(int index) {
void RegAlloc::ReadWriteFlags(Argument& read, IR::Inst* write) {
defined_insts.insert(write);
const auto current_location = ValueLocation(read.value.GetInst());
ASSERT(current_location);
DEBUG_ASSERT(current_location);
if (current_location->kind == HostLoc::Kind::Flags) {
if (!flags.IsOneRemainingUse()) {
@@ -489,7 +489,7 @@ void RegAlloc::ReadWriteFlags(Argument& read, IR::Inst* write) {
}
void RegAlloc::SpillFlags() {
ASSERT(!flags.locked && !flags.realized);
DEBUG_ASSERT(!flags.locked && !flags.realized);
if (flags.values.empty()) {
return;
}
@@ -501,7 +501,7 @@ void RegAlloc::SpillFlags() {
int RegAlloc::FindFreeSpill() const {
const auto iter = std::find_if(spills.begin(), spills.end(), [](const HostLocInfo& info) { return info.values.empty(); });
ASSERT(iter != spills.end() && "All spill locations are full");
DEBUG_ASSERT(iter != spills.end() && "All spill locations are full");
return static_cast<int>(iter - spills.begin());
}
@@ -512,14 +512,14 @@ void RegAlloc::LoadCopyInto(const IR::Value& value, oaknut::XReg reg) {
}
const auto current_location = ValueLocation(value.GetInst());
ASSERT(current_location);
DEBUG_ASSERT(current_location);
switch (current_location->kind) {
case HostLoc::Kind::Gpr:
code.MOV(reg, oaknut::XReg{current_location->index});
break;
case HostLoc::Kind::Fpr:
code.FMOV(reg, oaknut::DReg{current_location->index});
// ASSERT size fits
// DEBUG_ASSERT size fits
break;
case HostLoc::Kind::Spill:
code.LDR(reg, SP, spill_offset + current_location->index * spill_slot_size);
@@ -538,7 +538,7 @@ void RegAlloc::LoadCopyInto(const IR::Value& value, oaknut::QReg reg) {
}
const auto current_location = ValueLocation(value.GetInst());
ASSERT(current_location);
DEBUG_ASSERT(current_location);
switch (current_location->kind) {
case HostLoc::Kind::Gpr:
code.FMOV(reg.toD(), oaknut::XReg{current_location->index});
@@ -87,7 +87,11 @@ private:
};
MachHandler::MachHandler() {
#define KCHECK(x) ASSERT((x) == KERN_SUCCESS && "init failure at " #x)
#define KCHECK(x) do { \
[[maybe_unused]] auto r = (x); \
DEBUG_ASSERT(r == KERN_SUCCESS && "init failure at " #x); \
} while (0);
KCHECK(mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server_port));
KCHECK(mach_port_insert_right(mach_task_self(), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND));
KCHECK(task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, server_port, EXCEPTION_STATE | MACH_EXCEPTION_CODES, THREAD_STATE));
@@ -138,7 +138,7 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
#elif defined(ARCHITECTURE_loongarch64)
CTX_PC = fc.call_pc;
#else
ASSERT(false);
DEBUG_ASSERT(false);
#endif
return;
}
@@ -115,7 +115,7 @@ void A32AddressSpace::Link(EmittedBlockInfo& block_info) {
break;
}
default:
ASSERT(false && "Invalid relocation target");
DEBUG_ASSERT(false && "Invalid relocation target");
}
}
}
@@ -25,7 +25,7 @@ struct Jit::Impl final {
, current_address_space(conf) {}
HaltReason Run() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
jit_interface->is_executing = true;
const auto location_descriptor = current_state.GetLocationDescriptor();
@@ -38,7 +38,7 @@ struct Jit::Impl final {
}
HaltReason Step() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
jit_interface->is_executing = true;
const auto location_descriptor = A32::LocationDescriptor{current_state.GetLocationDescriptor()}.SetSingleStepping(true);
@@ -20,7 +20,7 @@ public:
explicit CodeBlock(std::size_t size) noexcept
: memsize(size) {
mem = static_cast<u8*>(mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0));
ASSERT(mem != MAP_FAILED);
DEBUG_ASSERT(mem != MAP_FAILED);
la_init_assembler(&as, mem, size);
}
@@ -16,7 +16,7 @@ namespace Dynarmic::Backend::LoongArch64 {
template<IR::Opcode op>
void EmitIR(lagoon_assembler_t&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented opcode");
DEBUG_ASSERT(false && "Unimplemented opcode");
}
template<>
@@ -36,7 +36,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(lagoon_assembler_t&, EmitContext& ct
template<>
void EmitIR<IR::Opcode::GetCarryFromOp>(lagoon_assembler_t&, EmitContext& ctx, IR::Inst* inst) {
ASSERT(ctx.reg_alloc.IsValueLive(inst));
DEBUG_ASSERT(ctx.reg_alloc.IsValueLive(inst));
}
template<>
@@ -98,7 +98,7 @@ EmittedBlockInfo EmitLoongArch64(lagoon_assembler_t& as, IR::Block block, const
const auto term = block.GetTerminal();
const IR::Term::LeafTerminal* leaft_term = std::get_if<IR::Term::LeafTerminal>(&term);
const IR::Term::LinkBlock* link_block_term = std::get_if<IR::Term::LinkBlock>(leaft_term);
ASSERT(link_block_term);
DEBUG_ASSERT(link_block_term);
la_load_immediate64(&as, Xscratch0, link_block_term->next.Value());
la_st_w(&as, Xscratch0, Xstate, static_cast<int32_t>(offsetof(A32JitState, regs) + sizeof(u32) * 15));
@@ -41,7 +41,7 @@ template<>
void EmitIR<IR::Opcode::A32SetCpsrNZC>(lagoon_assembler_t& as, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(!args[0].IsImmediate() && !args[1].IsImmediate());
DEBUG_ASSERT(!args[0].IsImmediate() && !args[1].IsImmediate());
auto Xnz = ctx.reg_alloc.ReadX(args[0]);
auto Xc = ctx.reg_alloc.ReadX(args[1]);
@@ -22,8 +22,8 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(lagoon_assembler_t& as, EmitContext&
auto& shift_arg = args[1];
auto& carry_arg = args[2];
ASSERT(carry_inst != nullptr);
ASSERT(shift_arg.IsImmediate());
DEBUG_ASSERT(carry_inst != nullptr);
DEBUG_ASSERT(shift_arg.IsImmediate());
auto Xresult = ctx.reg_alloc.WriteX(inst);
auto Xcarry_out = ctx.reg_alloc.WriteX(carry_inst);
@@ -42,19 +42,19 @@ bool Argument::GetImmediateU1() const {
u8 Argument::GetImmediateU8() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x100);
DEBUG_ASSERT(imm < 0x100);
return u8(imm);
}
u16 Argument::GetImmediateU16() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x10000);
DEBUG_ASSERT(imm < 0x10000);
return u16(imm);
}
u32 Argument::GetImmediateU32() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x100000000);
DEBUG_ASSERT(imm < 0x100000000);
return u32(imm);
}
@@ -63,12 +63,12 @@ u64 Argument::GetImmediateU64() const {
}
IR::Cond Argument::GetImmediateCond() const {
ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
DEBUG_ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
return value.GetCond();
}
IR::AccType Argument::GetImmediateAccType() const {
ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
DEBUG_ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
return value.GetAccType();
}
@@ -77,7 +77,7 @@ bool HostLocInfo::Contains(const IR::Inst* value) const {
}
void HostLocInfo::SetupScratchLocation() {
ASSERT(IsCompletelyEmpty());
DEBUG_ASSERT(IsCompletelyEmpty());
locked = 1;
realized = true;
}
@@ -103,7 +103,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
const IR::Value arg = inst->GetArg(i);
ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
DEBUG_ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
ValueInfo(arg.GetInst()).uses_this_inst++;
}
}
@@ -121,7 +121,7 @@ void RegAlloc::UpdateAllUses() {
}
void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
ASSERT(!ValueLocation(inst));
DEBUG_ASSERT(!ValueLocation(inst));
if (arg.value.IsImmediate()) {
inst->ReplaceUsesWith(arg.value);
@@ -136,7 +136,7 @@ void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
void RegAlloc::AssertNoMoreUses() const {
// TODO: Re-enable this assert once all register allocation issues are fixed
// const auto is_empty = [](const auto& i) { return i.IsCompletelyEmpty(); };
// ASSERT(std::all_of(hostloc_info.begin(), hostloc_info.end(), is_empty));
// DEBUG_ASSERT(std::all_of(hostloc_info.begin(), hostloc_info.end(), is_empty));
}
template<HostLoc::Kind kind>
@@ -151,7 +151,7 @@ u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
return new_location_index;
} else if constexpr (kind == HostLoc::Kind::Fpr) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
} else {
UNREACHABLE();
}
@@ -165,15 +165,15 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
}
const auto current_location = ValueLocation(value.GetInst());
ASSERT(current_location);
DEBUG_ASSERT(current_location);
if (current_location->kind == required_kind) {
ValueInfo(*current_location).realized = true;
return current_location->index;
}
ASSERT(!ValueInfo(*current_location).realized);
ASSERT(!ValueInfo(*current_location).locked);
DEBUG_ASSERT(!ValueInfo(*current_location).realized);
DEBUG_ASSERT(!ValueInfo(*current_location).locked);
if constexpr (required_kind == HostLoc::Kind::Gpr) {
const u32 new_location_index = AllocateRegister(gpr_order, GprOffset);
@@ -236,7 +236,7 @@ u32 RegAlloc::RealizeWriteImpl(const IR::Inst* value, HostLoc::Kind required_kin
}
}
ASSERT(!ValueLocation(value));
DEBUG_ASSERT(!ValueLocation(value));
const auto setup_location = [&](HostLocInfo& info) {
info = {};
@@ -277,7 +277,7 @@ u32 RegAlloc::AllocateRegister(const std::vector<u32>& order, size_t base_offset
std::copy_if(order.begin(), order.end(), std::back_inserter(candidates), [&](u32 i) {
return !hostloc_info[base_offset + i].locked;
});
ASSERT(!candidates.empty());
DEBUG_ASSERT(!candidates.empty());
u32 best = candidates[0];
size_t min_lru = hostloc_info[base_offset + best].lru_counter;
@@ -294,7 +294,7 @@ u32 RegAlloc::AllocateRegister(const std::vector<u32>& order, size_t base_offset
void RegAlloc::SpillGpr(u32 index) {
auto& gpr_info = hostloc_info[GprOffset + index];
ASSERT(!gpr_info.locked && !gpr_info.realized);
DEBUG_ASSERT(!gpr_info.locked && !gpr_info.realized);
if (gpr_info.values.empty()) {
return;
}
@@ -306,7 +306,7 @@ void RegAlloc::SpillGpr(u32 index) {
void RegAlloc::SpillFpr(u32 index) {
auto& fpr_info = hostloc_info[FprOffset + index];
ASSERT(!fpr_info.locked && !fpr_info.realized);
DEBUG_ASSERT(!fpr_info.locked && !fpr_info.realized);
if (fpr_info.values.empty()) {
return;
}
@@ -94,7 +94,7 @@ void A32AddressSpace::EmitPrelude() {
void A32AddressSpace::SetCursorPtr(CodePtr ptr) {
ptrdiff_t offset = ptr - GetMemPtr<CodePtr>();
ASSERT(offset >= 0);
DEBUG_ASSERT(offset >= 0);
as.RewindBuffer(offset);
}
@@ -31,7 +31,7 @@ struct Jit::Impl final {
, core(conf) {}
HaltReason Run() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
jit_interface->is_executing = true;
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
RequestCacheInvalidation();
@@ -40,9 +40,9 @@ struct Jit::Impl final {
}
HaltReason Step() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
jit_interface->is_executing = true;
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
RequestCacheInvalidation();
jit_interface->is_executing = false;
return HaltReason{};
@@ -28,12 +28,12 @@ struct Jit::Impl final {
, jit_interface(jit_interface) {}
HaltReason Run() {
ASSERT(false);
DEBUG_ASSERT(false);
return HaltReason{};
}
HaltReason Step() {
ASSERT(false);
DEBUG_ASSERT(false);
return HaltReason{};
}
@@ -51,7 +51,7 @@ struct Jit::Impl final {
}
void Reset() {
ASSERT(!is_executing);
DEBUG_ASSERT(!is_executing);
//jit_state = {};
}
@@ -22,7 +22,7 @@ class CodeBlock {
public:
explicit CodeBlock(std::size_t size) noexcept : memsize(size) {
mem = (u8*)mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
ASSERT(mem != nullptr);
DEBUG_ASSERT(mem != nullptr);
}
~CodeBlock() noexcept {
@@ -35,39 +35,39 @@ void EmitIR<IR::Opcode::Identity>(biscuit::Assembler&, EmitContext& ctx, IR::Ins
template<>
void EmitIR<IR::Opcode::Breakpoint>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CallHostFunction>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PushRSB>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::GetCarryFromOp>(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) {
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(ctx.reg_alloc.IsValueLive(inst));
DEBUG_ASSERT(ctx.reg_alloc.IsValueLive(inst));
}
template<>
void EmitIR<IR::Opcode::GetOverflowFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::GetGEFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::GetNZCVFromOp>(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) {
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(ctx.reg_alloc.IsValueLive(inst));
DEBUG_ASSERT(ctx.reg_alloc.IsValueLive(inst));
}
template<>
@@ -87,12 +87,12 @@ void EmitIR<IR::Opcode::GetNZFromOp>(biscuit::Assembler& as, EmitContext& ctx, I
template<>
void EmitIR<IR::Opcode::GetUpperFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::GetLowerFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
@@ -109,7 +109,7 @@ void EmitIR<IR::Opcode::GetCFlagFromNZCV>(biscuit::Assembler& as, EmitContext& c
template<>
void EmitIR<IR::Opcode::NZCVFromPackedFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitConfig& emit_conf) {
@@ -228,7 +228,7 @@ void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx) {
template<>
void EmitIR<IR::Opcode::A32SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
@@ -243,17 +243,17 @@ void EmitIR<IR::Opcode::A32GetRegister>(biscuit::Assembler& as, EmitContext& ctx
template<>
void EmitIR<IR::Opcode::A32GetExtendedRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32GetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32GetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
@@ -272,27 +272,27 @@ void EmitIR<IR::Opcode::A32SetRegister>(biscuit::Assembler& as, EmitContext& ctx
template<>
void EmitIR<IR::Opcode::A32SetExtendedRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32GetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
@@ -307,17 +307,17 @@ void EmitIR<IR::Opcode::A32SetCpsrNZCV>(biscuit::Assembler& as, EmitContext& ctx
template<>
void EmitIR<IR::Opcode::A32SetCpsrNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetCpsrNZCVQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetCpsrNZ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
@@ -325,7 +325,7 @@ void EmitIR<IR::Opcode::A32SetCpsrNZC>(biscuit::Assembler& as, EmitContext& ctx,
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
// TODO: Add full implementation
ASSERT(!args[0].IsImmediate() && !args[1].IsImmediate());
DEBUG_ASSERT(!args[0].IsImmediate() && !args[1].IsImmediate());
auto Xnz = ctx.reg_alloc.ReadX(args[0]);
auto Xc = ctx.reg_alloc.ReadX(args[1]);
@@ -341,82 +341,82 @@ void EmitIR<IR::Opcode::A32SetCpsrNZC>(biscuit::Assembler& as, EmitContext& ctx,
template<>
void EmitIR<IR::Opcode::A32GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32OrQFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32GetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetGEFlagsCompressed>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32BXWritePC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32UpdateUpperLocationDescriptor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32GetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32GetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32SetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,37 +22,37 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::A32CoprocInternalOperation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32CoprocLoadWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32CoprocStoreWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,87 +22,87 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::A32ClearExclusive>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,182 +22,182 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::A64SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetPC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64DataCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64InstructionCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetCNTFRQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetCNTPCT>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetCTR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetDCZID>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64GetTPIDRRO>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64SetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,107 +22,107 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::A64ClearExclusive>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64WriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,82 +22,82 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::CRC32Castagnoli8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CRC32Castagnoli16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CRC32Castagnoli32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CRC32Castagnoli64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CRC32ISO8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CRC32ISO16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CRC32ISO32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CRC32ISO64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::AESDecryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::AESEncryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::AESInverseMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::AESMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SM4AccessSubstitutionBox>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SHA256Hash>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SHA256MessageSchedule0>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SHA256MessageSchedule1>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,67 +22,67 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::Pack2x32To1x64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Pack2x64To1x128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::LeastSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::LeastSignificantHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::LeastSignificantByte>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MostSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MostSignificantBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::IsZero32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::IsZero64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::TestBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ConditionalSelect32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ConditionalSelect64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ConditionalSelectNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
@@ -95,8 +95,8 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext&
auto& carry_arg = args[2];
// TODO: Add full implementation
ASSERT(carry_inst != nullptr);
ASSERT(shift_arg.IsImmediate());
DEBUG_ASSERT(carry_inst != nullptr);
DEBUG_ASSERT(shift_arg.IsImmediate());
auto Xresult = ctx.reg_alloc.WriteX(inst);
auto Xcarry_out = ctx.reg_alloc.WriteX(carry_inst);
@@ -124,7 +124,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext&
template<>
void EmitIR<IR::Opcode::LogicalShiftLeft64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
@@ -136,8 +136,8 @@ void EmitIR<IR::Opcode::LogicalShiftRight32>(biscuit::Assembler& as, EmitContext
auto& shift_arg = args[1];
// TODO: Add full implementation
ASSERT(carry_inst == nullptr);
ASSERT(shift_arg.IsImmediate());
DEBUG_ASSERT(carry_inst == nullptr);
DEBUG_ASSERT(shift_arg.IsImmediate());
const u8 shift = shift_arg.GetImmediateU8();
auto Xresult = ctx.reg_alloc.WriteX(inst);
@@ -153,72 +153,72 @@ void EmitIR<IR::Opcode::LogicalShiftRight32>(biscuit::Assembler& as, EmitContext
template<>
void EmitIR<IR::Opcode::LogicalShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ArithmeticShiftRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ArithmeticShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::BitRotateRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::BitRotateRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::RotateRightExtended>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::LogicalShiftLeftMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::LogicalShiftLeftMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::LogicalShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::LogicalShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::RotateRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::RotateRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<size_t bitsize>
@@ -264,7 +264,7 @@ static void AddImmWithFlags(biscuit::Assembler& as, biscuit::GPR rd, biscuit::GP
as.SLLI(Xscratch1, Xscratch1, 28);
as.OR(flags, flags, Xscratch1);
} else {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
}
@@ -279,7 +279,7 @@ static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst)
auto Xa = ctx.reg_alloc.ReadX(args[0]);
if (overflow_inst) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
} else if (nzcv_inst) {
if (args[1].IsImmediate()) {
const u64 imm = args[1].GetImmediateU64();
@@ -294,17 +294,17 @@ static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst)
AddImmWithFlags<bitsize>(as, *Xresult, *Xa, sub ? -imm : imm, *Xflags);
}
} else {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} else {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} else {
if (args[1].IsImmediate()) {
const u64 imm = args[1].GetImmediateU64();
if (args[2].IsImmediate()) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
} else {
auto Xnzcv = ctx.reg_alloc.ReadX(args[2]);
RegAlloc::Realize(Xresult, Xa, Xnzcv);
@@ -317,7 +317,7 @@ static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst)
as.ADDW(Xresult, Xa, Xscratch0);
}
} else {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
}
}
@@ -329,7 +329,7 @@ void EmitIR<IR::Opcode::Add32>(biscuit::Assembler& as, EmitContext& ctx, IR::Ins
template<>
void EmitIR<IR::Opcode::Add64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
@@ -339,237 +339,237 @@ void EmitIR<IR::Opcode::Sub32>(biscuit::Assembler& as, EmitContext& ctx, IR::Ins
template<>
void EmitIR<IR::Opcode::Sub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Mul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Mul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::And32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::And64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::AndNot32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::AndNot64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Eor32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Eor64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Or32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Or64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Not32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::Not64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ZeroExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ZeroExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ZeroExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ZeroExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ZeroExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ZeroExtendLongToQuad>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ByteReverseWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ByteReverseHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ByteReverseDual>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CountLeadingZeros32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::CountLeadingZeros64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ExtractRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ExtractRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ReplicateBit32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::ReplicateBit64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MaxSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MaxSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MaxUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MaxUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MinSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MinSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MinUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::MinUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,442 +22,442 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::FPAbs16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPCompare32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPCompare64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMulSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMulSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMulSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipExponent16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipExponent32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipExponent64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPHalfToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPHalfToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSingleToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSingleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDoubleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDoubleToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDoubleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDoubleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDoubleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDoubleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDoubleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPDoubleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPHalfToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPHalfToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPHalfToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPHalfToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPHalfToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPHalfToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSingleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSingleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSingleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSingleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSingleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPSingleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedU16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedS16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedU16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedS16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedU32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedS32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedU32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedS32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedU64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedU64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedS64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPFixedS64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,172 +22,172 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::PackedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedHalvingSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSaturatedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSaturatedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSaturatedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSaturatedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSaturatedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSaturatedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSaturatedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSaturatedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedAbsDiffSumU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::PackedSelect>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,112 +22,112 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::SignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::UnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
File diff suppressed because it is too large Load Diff
@@ -22,337 +22,337 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::FPVectorAbs16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorEqual16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorFromHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorFromSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorFromSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorGreater32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorGreater64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorGreaterEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorGreaterEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorPairedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorPairedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorPairedAddLower32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorPairedAddLower64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorToHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorToSignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorToSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorToSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -22,82 +22,82 @@ namespace Dynarmic::Backend::RV64 {
template<>
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorSignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorSignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorSignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorSignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
template<>
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
}
} // namespace Dynarmic::Backend::RV64
@@ -44,19 +44,19 @@ bool Argument::GetImmediateU1() const {
u8 Argument::GetImmediateU8() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x100);
DEBUG_ASSERT(imm < 0x100);
return u8(imm);
}
u16 Argument::GetImmediateU16() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x10000);
DEBUG_ASSERT(imm < 0x10000);
return u16(imm);
}
u32 Argument::GetImmediateU32() const {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm < 0x100000000);
DEBUG_ASSERT(imm < 0x100000000);
return u32(imm);
}
@@ -65,12 +65,12 @@ u64 Argument::GetImmediateU64() const {
}
IR::Cond Argument::GetImmediateCond() const {
ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
DEBUG_ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
return value.GetCond();
}
IR::AccType Argument::GetImmediateAccType() const {
ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
DEBUG_ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
return value.GetAccType();
}
@@ -79,7 +79,7 @@ bool HostLocInfo::Contains(const IR::Inst* value) const {
}
void HostLocInfo::SetupScratchLocation() {
ASSERT(IsCompletelyEmpty());
DEBUG_ASSERT(IsCompletelyEmpty());
realized = true;
}
@@ -104,7 +104,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
const IR::Value arg = inst->GetArg(i);
ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
DEBUG_ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
ValueInfo(arg.GetInst()).uses_this_inst++;
}
}
@@ -128,7 +128,7 @@ void RegAlloc::UpdateAllUses() {
}
void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
ASSERT(!ValueLocation(inst));
DEBUG_ASSERT(!ValueLocation(inst));
if (arg.value.IsImmediate()) {
inst->ReplaceUsesWith(arg.value);
@@ -142,15 +142,15 @@ void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
void RegAlloc::AssertNoMoreUses() const {
const auto is_empty = [](const auto& i) { return i.IsCompletelyEmpty(); };
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
DEBUG_ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
DEBUG_ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
DEBUG_ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
}
template<HostLoc::Kind kind>
u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
// TODO
// ASSERT(value.GetType() != IR::Type::U1);
// DEBUG_ASSERT(value.GetType() != IR::Type::U1);
if constexpr (kind == HostLoc::Kind::Gpr) {
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
@@ -161,7 +161,7 @@ u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
return new_location_index;
} else if constexpr (kind == HostLoc::Kind::Fpr) {
ASSERT(false && "Unimplemented instruction");
DEBUG_ASSERT(false && "Unimplemented instruction");
} else {
UNREACHABLE();
}
@@ -175,15 +175,15 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
}
const auto current_location = ValueLocation(value.GetInst());
ASSERT(current_location);
DEBUG_ASSERT(current_location);
if (current_location->kind == required_kind) {
ValueInfo(*current_location).realized = true;
return current_location->index;
}
ASSERT(!ValueInfo(*current_location).realized);
ASSERT(!ValueInfo(*current_location).locked);
DEBUG_ASSERT(!ValueInfo(*current_location).realized);
DEBUG_ASSERT(!ValueInfo(*current_location).locked);
if constexpr (required_kind == HostLoc::Kind::Gpr) {
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
@@ -194,7 +194,7 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
UNREACHABLE(); //logic error
case HostLoc::Kind::Fpr:
as.FMV_X_D(biscuit::GPR(new_location_index), biscuit::FPR{current_location->index});
// ASSERT size fits
// DEBUG_ASSERT size fits
break;
case HostLoc::Kind::Spill:
as.LD(biscuit::GPR{new_location_index}, spill_offset + current_location->index * spill_slot_size, biscuit::sp);
@@ -229,7 +229,7 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
template<HostLoc::Kind required_kind>
u32 RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
ASSERT(!ValueLocation(value));
DEBUG_ASSERT(!ValueLocation(value));
const auto setup_location = [&](HostLocInfo& info) {
info = {};
@@ -274,7 +274,7 @@ u32 RegAlloc::AllocateRegister(const std::array<HostLocInfo, 32>& regs, const st
}
void RegAlloc::SpillGpr(u32 index) {
ASSERT(!gprs[index].locked && !gprs[index].realized);
DEBUG_ASSERT(!gprs[index].locked && !gprs[index].realized);
if (gprs[index].values.empty()) {
return;
}
@@ -284,7 +284,7 @@ void RegAlloc::SpillGpr(u32 index) {
}
void RegAlloc::SpillFpr(u32 index) {
ASSERT(!fprs[index].locked && !fprs[index].realized);
DEBUG_ASSERT(!fprs[index].locked && !fprs[index].realized);
if (fprs[index].values.empty()) {
return;
}
@@ -295,7 +295,7 @@ void RegAlloc::SpillFpr(u32 index) {
u32 RegAlloc::FindFreeSpill() const {
const auto iter = std::find_if(spills.begin(), spills.end(), [](const HostLocInfo& info) { return info.values.empty(); });
ASSERT(iter != spills.end() && "All spill locations are full");
DEBUG_ASSERT(iter != spills.end() && "All spill locations are full");
return static_cast<u32>(iter - spills.begin());
}
@@ -209,11 +209,11 @@ void A32EmitX64::InvalidateCacheRanges(const boost::icl::interval_set<u32>& rang
void A32EmitX64::EmitCondPrelude(const A32EmitContext& ctx) {
if (ctx.block.GetCondition() == IR::Cond::AL) {
ASSERT(!ctx.block.HasConditionFailedLocation());
DEBUG_ASSERT(!ctx.block.HasConditionFailedLocation());
return;
}
ASSERT(ctx.block.HasConditionFailedLocation());
DEBUG_ASSERT(ctx.block.HasConditionFailedLocation());
Xbyak::Label pass = EmitCond(ctx.block.GetCondition());
if (conf.enable_cycle_counting) {
@@ -311,7 +311,7 @@ void A32EmitX64::EmitA32GetRegister(A32EmitContext& ctx, IR::Inst* inst) {
void A32EmitX64::EmitA32GetExtendedRegister32(A32EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsSingleExtReg(reg));
DEBUG_ASSERT(A32::IsSingleExtReg(reg));
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
code.movss(result, MJitStateExtReg(reg));
@@ -320,7 +320,7 @@ void A32EmitX64::EmitA32GetExtendedRegister32(A32EmitContext& ctx, IR::Inst* ins
void A32EmitX64::EmitA32GetExtendedRegister64(A32EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg));
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
code.movsd(result, MJitStateExtReg(reg));
@@ -329,7 +329,7 @@ void A32EmitX64::EmitA32GetExtendedRegister64(A32EmitContext& ctx, IR::Inst* ins
void A32EmitX64::EmitA32GetVector(A32EmitContext& ctx, IR::Inst* inst) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
if (A32::IsDoubleExtReg(reg)) {
@@ -358,7 +358,7 @@ void A32EmitX64::EmitA32SetRegister(A32EmitContext& ctx, IR::Inst* inst) {
void A32EmitX64::EmitA32SetExtendedRegister32(A32EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsSingleExtReg(reg));
DEBUG_ASSERT(A32::IsSingleExtReg(reg));
if (args[1].IsInXmm(ctx.reg_alloc)) {
Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(code, args[1]);
@@ -372,7 +372,7 @@ void A32EmitX64::EmitA32SetExtendedRegister32(A32EmitContext& ctx, IR::Inst* ins
void A32EmitX64::EmitA32SetExtendedRegister64(A32EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg));
if (args[1].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(code, args[1]);
@@ -386,7 +386,7 @@ void A32EmitX64::EmitA32SetExtendedRegister64(A32EmitContext& ctx, IR::Inst* ins
void A32EmitX64::EmitA32SetVector(A32EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(code, args[1]);
if (A32::IsDoubleExtReg(reg)) {
@@ -647,7 +647,7 @@ void A32EmitX64::EmitA32GetGEFlags(A32EmitContext& ctx, IR::Inst* inst) {
void A32EmitX64::EmitA32SetGEFlags(A32EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(!args[0].IsImmediate());
DEBUG_ASSERT(!args[0].IsImmediate());
if (args[0].IsInXmm(ctx.reg_alloc)) {
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(code, args[0]);
@@ -788,7 +788,7 @@ void A32EmitX64::EmitA32ExceptionRaised(A32EmitContext& ctx, IR::Inst* inst) {
ctx.reg_alloc.EndOfAllocScope();
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[0].IsImmediate() && args[1].IsImmediate());
DEBUG_ASSERT(args[0].IsImmediate() && args[1].IsImmediate());
const u32 pc = args[0].GetImmediateU32();
const u64 exception = args[1].GetImmediateU64();
Devirtualize<&A32::UserCallbacks::ExceptionRaised>(conf.callbacks).EmitCall(code, [&](RegList param) {
@@ -74,7 +74,7 @@ struct Jit::Impl {
~Impl() = default;
HaltReason Run() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason)));
jit_interface->is_executing = true;
const CodePtr current_codeptr = [this] {
@@ -94,7 +94,7 @@ struct Jit::Impl {
}
HaltReason Step() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason)));
jit_interface->is_executing = true;
const HaltReason hr = block_of_code.StepCode(&jit_state, GetCurrentSingleStep());
@@ -116,7 +116,7 @@ struct Jit::Impl {
}
void Reset() {
ASSERT(!jit_interface->is_executing);
DEBUG_ASSERT(!jit_interface->is_executing);
jit_state = {};
}
@@ -501,7 +501,7 @@ void A64EmitX64::EmitA64SetPC(A64EmitContext& ctx, IR::Inst* inst) {
void A64EmitX64::EmitA64CallSupervisor(A64EmitContext& ctx, IR::Inst* inst) {
ctx.reg_alloc.HostCall(code, nullptr);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[0].IsImmediate());
DEBUG_ASSERT(args[0].IsImmediate());
const u32 imm = args[0].GetImmediateU32();
Devirtualize<&A64::UserCallbacks::CallSVC>(conf.callbacks).EmitCall(code, [&](RegList param) {
code.mov(param[0], imm);
@@ -513,7 +513,7 @@ void A64EmitX64::EmitA64CallSupervisor(A64EmitContext& ctx, IR::Inst* inst) {
void A64EmitX64::EmitA64ExceptionRaised(A64EmitContext& ctx, IR::Inst* inst) {
ctx.reg_alloc.HostCall(code, nullptr);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[0].IsImmediate() && args[1].IsImmediate());
DEBUG_ASSERT(args[0].IsImmediate() && args[1].IsImmediate());
const u64 pc = args[0].GetImmediateU64();
const u64 exception = args[1].GetImmediateU64();
Devirtualize<&A64::UserCallbacks::ExceptionRaised>(conf.callbacks).EmitCall(code, [&](RegList param) {
@@ -66,13 +66,13 @@ public:
, emitter(block_of_code, conf, jit)
, polyfill_options(GenPolyfillOptions(block_of_code))
{
ASSERT(conf.page_table_address_space_bits >= 12 && conf.page_table_address_space_bits <= 64);
DEBUG_ASSERT(conf.page_table_address_space_bits >= 12 && conf.page_table_address_space_bits <= 64);
}
~Impl() = default;
HaltReason Run() {
ASSERT(!is_executing);
DEBUG_ASSERT(!is_executing);
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason)));
is_executing = true;
// TODO: Check code alignment
@@ -92,7 +92,7 @@ public:
}
HaltReason Step() {
ASSERT(!is_executing);
DEBUG_ASSERT(!is_executing);
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason)));
is_executing = true;
const HaltReason hr = block_of_code.StepCode(&jit_state, GetCurrentSingleStep());
@@ -116,7 +116,7 @@ public:
}
void Reset() {
ASSERT(!is_executing);
DEBUG_ASSERT(!is_executing);
jit_state = {};
}
@@ -191,12 +191,12 @@ void BlockOfCode::DisableWriting() {
}
void BlockOfCode::ClearCache() {
ASSERT(prelude_complete);
DEBUG_ASSERT(prelude_complete);
SetCodePtr(code_begin);
}
size_t BlockOfCode::SpaceRemaining() const {
ASSERT(prelude_complete);
DEBUG_ASSERT(prelude_complete);
const u8* current_ptr = getCurr<const u8*>();
if (current_ptr >= &top_[maxSize_])
return 0;
@@ -466,7 +466,7 @@ void BlockOfCode::SetCodePtr(CodePtr code_ptr) {
void BlockOfCode::EnsurePatchLocationSize(CodePtr begin, size_t size) {
size_t current_size = getCurr<const u8*>() - reinterpret_cast<const u8*>(begin);
ASSERT(current_size <= size);
DEBUG_ASSERT(current_size <= size);
nop(size - current_size);
}
@@ -28,7 +28,7 @@ Xbyak::Address ConstantPool::GetConstant(BlockOfCode& code, const Xbyak::Address
const auto constant = ConstantT(lower, upper);
auto it = constant_info.find(constant);
if (it == constant_info.end()) {
ASSERT(insertion_point < pool.size());
DEBUG_ASSERT(insertion_point < pool.size());
ConstantT& target_constant = pool[insertion_point];
target_constant = constant;
it = constant_info.insert({constant, &target_constant}).first;
@@ -148,7 +148,7 @@ void EmitX64::EmitVerboseDebuggingOutput(RegAlloc& reg_alloc) {
void EmitX64::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[0].IsImmediate());
DEBUG_ASSERT(args[0].IsImmediate());
const u64 unique_hash_of_target = args[0].GetImmediateU64();
ctx.reg_alloc.ScratchGpr(code, HostLoc::RCX);
@@ -288,7 +288,7 @@ void EmitX64::EmitNZCVFromPackedFlags(EmitContext& ctx, IR::Inst* inst) {
}
void EmitX64::EmitAddCycles(size_t cycles) {
ASSERT(cycles < (std::numeric_limits<s32>::max)());
DEBUG_ASSERT(cycles < (std::numeric_limits<s32>::max)());
code.sub(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], static_cast<u32>(cycles));
}
@@ -129,7 +129,7 @@ void EmitX64::EmitIsZero64(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitTestBit(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const Xbyak::Reg64 result = ctx.reg_alloc.UseScratchGpr(code, args[0]);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
// TODO: Flag optimization
code.bt(result, args[1].GetImmediateU8());
code.setc(result.cvt8());
@@ -1842,7 +1842,7 @@ void EmitX64::EmitFPFixedS32ToSingle(EmitContext& ctx, IR::Inst* inst) {
if (rounding_mode == ctx.FPCR().RMode() || ctx.HasOptimization(OptimizationFlag::Unsafe_IgnoreStandardFPCRValue)) {
code.cvtsi2ss(result, from);
} else {
ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
DEBUG_ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
code.EnterStandardASIMD();
code.cvtsi2ss(result, from);
code.LeaveStandardASIMD();
@@ -1878,7 +1878,7 @@ void EmitX64::EmitFPFixedU32ToSingle(EmitContext& ctx, IR::Inst* inst) {
if (rounding_mode == ctx.FPCR().RMode() || ctx.HasOptimization(OptimizationFlag::Unsafe_IgnoreStandardFPCRValue)) {
op();
} else {
ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
DEBUG_ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
code.EnterStandardASIMD();
op();
code.LeaveStandardASIMD();
@@ -1984,7 +1984,7 @@ void EmitX64::EmitFPFixedS64ToDouble(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
const size_t fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
ASSERT(rounding_mode == ctx.FPCR().RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR().RMode());
code.cvtsi2sd(result, from);
@@ -2003,7 +2003,7 @@ void EmitX64::EmitFPFixedS64ToSingle(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
const size_t fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
ASSERT(rounding_mode == ctx.FPCR().RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR().RMode());
code.cvtsi2ss(result, from);
@@ -2022,7 +2022,7 @@ void EmitX64::EmitFPFixedU64ToDouble(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
const size_t fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
ASSERT(rounding_mode == ctx.FPCR().RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR().RMode());
if (code.HasHostFeature(HostFeature::AVX512F)) {
code.vcvtusi2sd(result, result, from);
@@ -2053,7 +2053,7 @@ void EmitX64::EmitFPFixedU64ToSingle(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
const size_t fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
ASSERT(rounding_mode == ctx.FPCR().RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR().RMode());
if (code.HasHostFeature(HostFeature::AVX512F)) {
const Xbyak::Reg64 from = ctx.reg_alloc.UseGpr(code, args[0]);
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@@ -113,7 +116,7 @@ void AxxEmitX64::EmitMemoryRead(AxxEmitContext& ctx, IR::Inst* inst) {
});
} else {
// Use page table
ASSERT(conf.page_table);
DEBUG_ASSERT(conf.page_table);
const auto src_ptr = EmitVAddrLookup(code, ctx, bitsize, *abort, vaddr);
EmitReadMemoryMov<bitsize>(code, value_idx, src_ptr, ordered);
@@ -200,7 +203,7 @@ void AxxEmitX64::EmitMemoryWrite(AxxEmitContext& ctx, IR::Inst* inst) {
});
} else {
// Use page table
ASSERT(conf.page_table);
DEBUG_ASSERT(conf.page_table);
const auto dest_ptr = EmitVAddrLookup(code, ctx, bitsize, *abort, vaddr);
EmitWriteMemoryMov<bitsize>(code, dest_ptr, value_idx, ordered);
@@ -216,7 +219,7 @@ void AxxEmitX64::EmitMemoryWrite(AxxEmitContext& ctx, IR::Inst* inst) {
template<std::size_t bitsize, auto callback>
void AxxEmitX64::EmitExclusiveReadMemory(AxxEmitContext& ctx, IR::Inst* inst) {
ASSERT(conf.global_monitor != nullptr);
DEBUG_ASSERT(conf.global_monitor != nullptr);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
@@ -267,7 +270,7 @@ void AxxEmitX64::EmitExclusiveReadMemory(AxxEmitContext& ctx, IR::Inst* inst) {
template<std::size_t bitsize, auto callback>
void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) {
ASSERT(conf.global_monitor != nullptr);
DEBUG_ASSERT(conf.global_monitor != nullptr);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool ordered = IsOrdered(args[3].GetImmediateAccType());
@@ -320,7 +323,7 @@ void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) {
template<std::size_t bitsize, auto callback>
void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* inst) {
ASSERT(conf.global_monitor && conf.fastmem_pointer);
DEBUG_ASSERT(conf.global_monitor && conf.fastmem_pointer);
if (!exception_handler.SupportsFastmem()) {
EmitExclusiveReadMemory<bitsize, callback>(ctx, inst);
return;
@@ -397,7 +400,7 @@ void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* in
template<std::size_t bitsize, auto callback>
void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* inst) {
ASSERT(conf.global_monitor && conf.fastmem_pointer);
DEBUG_ASSERT(conf.global_monitor && conf.fastmem_pointer);
if (!exception_handler.SupportsFastmem()) {
EmitExclusiveWriteMemory<bitsize, callback>(ctx, inst);
return;
@@ -148,7 +148,7 @@ template<>
code.and_(tmp, u32((1 << valid_page_index_bits) - 1));
}
} else {
ASSERT(valid_page_index_bits < 32);
DEBUG_ASSERT(valid_page_index_bits < 32);
code.mov(tmp, vaddr);
code.shr(tmp, int(page_table_const_bits));
code.test(tmp, u32(-(1 << valid_page_index_bits)));
@@ -118,7 +118,7 @@ void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const size_t N = args[1].GetImmediateU8();
ASSERT(N >= 1 && N <= 32);
DEBUG_ASSERT(N >= 1 && N <= 32);
if (N == 32) {
if (overflow_inst) {
@@ -167,7 +167,7 @@ void EmitX64::EmitUnsignedSaturation(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const size_t N = args[1].GetImmediateU8();
ASSERT(N <= 31);
DEBUG_ASSERT(N <= 31);
const u32 saturated_value = (1u << N) - 1;
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
@@ -18,7 +18,7 @@ void EmitX64::EmitSHA256Hash(EmitContext& ctx, IR::Inst* inst) {
const bool part1 = args[3].GetImmediateU1();
ASSERT(code.HasHostFeature(HostFeature::SHA));
DEBUG_ASSERT(code.HasHostFeature(HostFeature::SHA));
// 3 2 1 0
// x = d c b a
@@ -54,7 +54,7 @@ void EmitX64::EmitSHA256Hash(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitSHA256MessageSchedule0(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(code.HasHostFeature(HostFeature::SHA));
DEBUG_ASSERT(code.HasHostFeature(HostFeature::SHA));
const Xbyak::Xmm x = ctx.reg_alloc.UseScratchXmm(code, args[0]);
const Xbyak::Xmm y = ctx.reg_alloc.UseXmm(code, args[1]);
@@ -67,7 +67,7 @@ void EmitX64::EmitSHA256MessageSchedule0(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitSHA256MessageSchedule1(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(code.HasHostFeature(HostFeature::SHA));
DEBUG_ASSERT(code.HasHostFeature(HostFeature::SHA));
const Xbyak::Xmm x = ctx.reg_alloc.UseScratchXmm(code, args[0]);
const Xbyak::Xmm y = ctx.reg_alloc.UseXmm(code, args[1]);
@@ -177,7 +177,7 @@ static void EmitTwoArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Ins
void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
// TODO: DefineValue directly on Argument for index == 0
@@ -201,7 +201,7 @@ void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorGetElement16(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
// TODO: DefineValue directly on Argument for index == 0
@@ -214,7 +214,7 @@ void EmitX64::EmitVectorGetElement16(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorGetElement32(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
// TODO: DefineValue directly on Argument for index == 0
@@ -235,7 +235,7 @@ void EmitX64::EmitVectorGetElement32(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorGetElement64(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
if (index == 0) {
@@ -263,7 +263,7 @@ void EmitX64::EmitVectorGetElement64(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorSetElement8(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
auto const source_vector = ctx.reg_alloc.UseScratchXmm(code, args[0]);
@@ -295,7 +295,7 @@ void EmitX64::EmitVectorSetElement8(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorSetElement16(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
auto const source_vector = ctx.reg_alloc.UseScratchXmm(code, args[0]);
@@ -308,7 +308,7 @@ void EmitX64::EmitVectorSetElement16(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorSetElement32(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
auto const source_vector = ctx.reg_alloc.UseScratchXmm(code, args[0]);
@@ -331,7 +331,7 @@ void EmitX64::EmitVectorSetElement32(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorSetElement64(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
auto const source_vector = ctx.reg_alloc.UseScratchXmm(code, args[0]);
@@ -717,9 +717,9 @@ void EmitX64::EmitVectorBroadcast64(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorBroadcastElementLower8(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
ASSERT(index < 16);
DEBUG_ASSERT(index < 16);
if (index > 0) {
code.psrldq(a, index);
}
@@ -741,9 +741,9 @@ void EmitX64::EmitVectorBroadcastElementLower8(EmitContext& ctx, IR::Inst* inst)
void EmitX64::EmitVectorBroadcastElementLower16(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
ASSERT(index < 8);
DEBUG_ASSERT(index < 8);
if (index > 0) {
code.psrldq(a, u8(index * 2));
}
@@ -754,9 +754,9 @@ void EmitX64::EmitVectorBroadcastElementLower16(EmitContext& ctx, IR::Inst* inst
void EmitX64::EmitVectorBroadcastElementLower32(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
ASSERT(index < 4);
DEBUG_ASSERT(index < 4);
if (index > 0) {
code.psrldq(a, u8(index * 4));
@@ -770,9 +770,9 @@ void EmitX64::EmitVectorBroadcastElementLower32(EmitContext& ctx, IR::Inst* inst
void EmitX64::EmitVectorBroadcastElement8(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
ASSERT(index < 16);
DEBUG_ASSERT(index < 16);
if (index > 0) {
code.psrldq(a, index);
}
@@ -794,9 +794,9 @@ void EmitX64::EmitVectorBroadcastElement8(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorBroadcastElement16(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
ASSERT(index < 8);
DEBUG_ASSERT(index < 8);
if (index == 0 && code.HasHostFeature(HostFeature::AVX2)) {
code.vpbroadcastw(a, a);
} else {
@@ -814,9 +814,9 @@ void EmitX64::EmitVectorBroadcastElement16(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorBroadcastElement32(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
ASSERT(index < 4);
DEBUG_ASSERT(index < 4);
code.pshufd(a, a, mcl::bit::replicate_element<2, u8>(index));
@@ -826,9 +826,9 @@ void EmitX64::EmitVectorBroadcastElement32(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorBroadcastElement64(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
ASSERT(args[1].IsImmediate());
DEBUG_ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8();
ASSERT(index < 2);
DEBUG_ASSERT(index < 2);
if (code.HasHostFeature(HostFeature::AVX)) {
code.vpermilpd(a, a, mcl::bit::replicate_element<1, u8>(index));
@@ -1314,7 +1314,7 @@ void EmitX64::EmitVectorExtract(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const u8 position = args[2].GetImmediateU8();
ASSERT(position % 8 == 0);
DEBUG_ASSERT(position % 8 == 0);
if (position == 0) {
ctx.reg_alloc.DefineValue(code, inst, args[0]);
@@ -1346,7 +1346,7 @@ void EmitX64::EmitVectorExtractLower(EmitContext& ctx, IR::Inst* inst) {
auto const xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
const u8 position = args[2].GetImmediateU8();
ASSERT(position % 8 == 0);
DEBUG_ASSERT(position % 8 == 0);
if (position != 0) {
auto const xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
@@ -3821,7 +3821,7 @@ void EmitX64::EmitVectorRotateWholeVectorRight(EmitContext& ctx, IR::Inst* inst)
auto const operand = ctx.reg_alloc.UseXmm(code, args[0]);
auto const result = ctx.reg_alloc.ScratchXmm(code);
const u8 shift_amount = args[1].GetImmediateU8();
ASSERT(shift_amount % 32 == 0);
DEBUG_ASSERT(shift_amount % 32 == 0);
const u8 shuffle_imm = std::rotr<u8>(0b11100100, shift_amount / 32 * 2);
code.pshufd(result, operand, shuffle_imm);
@@ -4914,7 +4914,7 @@ static void EmitVectorSignedSaturatedNarrowToUnsigned(size_t original_esize, Blo
code.punpcklbw(reconstructed, xmm0);
break;
case 32:
ASSERT(code.HasHostFeature(HostFeature::SSE41));
DEBUG_ASSERT(code.HasHostFeature(HostFeature::SSE41));
code.packusdw(dest, xmm0); // SSE4.1
code.movdqa(reconstructed, dest);
code.punpcklwd(reconstructed, xmm0);
@@ -5276,11 +5276,11 @@ void EmitX64::EmitVectorSub64(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorTable(EmitContext&, IR::Inst* inst) {
// Do nothing. We *want* to hold on to the refcount for our arguments, so VectorTableLookup can use our arguments.
ASSERT(inst->UseCount() == 1 && "Table cannot be used multiple times");
DEBUG_ASSERT(inst->UseCount() == 1 && "Table cannot be used multiple times");
}
void EmitX64::EmitVectorTableLookup64(EmitContext& ctx, IR::Inst* inst) {
ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
DEBUG_ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
@@ -5438,7 +5438,7 @@ void EmitX64::EmitVectorTableLookup64(EmitContext& ctx, IR::Inst* inst) {
code.pxor(xmm0, xmm0);
code.punpcklqdq(xmm_table1, xmm0);
} else {
ASSERT(table_size == 4);
DEBUG_ASSERT(table_size == 4);
auto const xmm_table1_upper = ctx.reg_alloc.UseXmm(code, table[3]);
code.punpcklqdq(xmm_table1, xmm_table1_upper);
ctx.reg_alloc.Release(xmm_table1_upper);
@@ -5529,7 +5529,7 @@ void EmitX64::EmitVectorTableLookup64(EmitContext& ctx, IR::Inst* inst) {
}
void EmitX64::EmitVectorTableLookup128(EmitContext& ctx, IR::Inst* inst) {
ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
DEBUG_ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
@@ -676,7 +676,7 @@ void EmitX64::EmitFPVectorFromSignedFixed32(EmitContext& ctx, IR::Inst* inst) {
const int fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
const bool fpcr_controlled = args[3].GetImmediateU1();
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
code.cvtdq2ps(xmm, xmm);
@@ -694,7 +694,7 @@ void EmitX64::EmitFPVectorFromSignedFixed64(EmitContext& ctx, IR::Inst* inst) {
const int fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
const bool fpcr_controlled = args[3].GetImmediateU1();
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) {
@@ -745,7 +745,7 @@ void EmitX64::EmitFPVectorFromUnsignedFixed32(EmitContext& ctx, IR::Inst* inst)
const int fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
const bool fpcr_controlled = args[3].GetImmediateU1();
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
if (code.HasHostFeature(HostFeature::AVX512_Ortho)) {
@@ -795,7 +795,7 @@ void EmitX64::EmitFPVectorFromUnsignedFixed64(EmitContext& ctx, IR::Inst* inst)
const int fbits = args[1].GetImmediateU8();
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
const bool fpcr_controlled = args[3].GetImmediateU1();
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
DEBUG_ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) {
@@ -104,7 +104,7 @@ static PrologueInformation GetPrologueInformation() {
entry.code.OpInfo = reg;
};
const auto alloc_large = [&](u8 offset, size_t size) {
ASSERT(size % 8 == 0);
DEBUG_ASSERT(size % 8 == 0);
size /= 8;
auto& entry = next_entry();
@@ -123,7 +123,7 @@ static PrologueInformation GetPrologueInformation() {
}
};
const auto save_xmm128 = [&](u8 offset, u8 reg, size_t frame_offset) {
ASSERT(frame_offset % 16 == 0);
DEBUG_ASSERT(frame_offset % 16 == 0);
auto& entry = next_entry();
entry.code.CodeOffset = offset;
@@ -165,7 +165,7 @@ static PrologueInformation GetPrologueInformation() {
auto& last_entry = next_entry();
last_entry.FrameOffset = 0;
}
ASSERT(ret.unwind_code.size() % 2 == 0);
DEBUG_ASSERT(ret.unwind_code.size() % 2 == 0);
return ret;
}
@@ -78,12 +78,12 @@ constexpr bool HostLocIsFlag(HostLoc reg) {
}
constexpr HostLoc HostLocRegIdx(int idx) {
ASSERT(idx >= 0 && idx <= 15);
DEBUG_ASSERT(idx >= 0 && idx <= 15);
return HostLoc(idx);
}
constexpr HostLoc HostLocXmmIdx(int idx) {
ASSERT(idx >= 0 && idx <= 15);
DEBUG_ASSERT(idx >= 0 && idx <= 15);
return HostLoc(size_t(HostLoc::XMM0) + idx);
}
@@ -159,12 +159,12 @@ const std::bitset<32> any_xmm = BuildRegSet({
});
inline Xbyak::Reg64 HostLocToReg64(HostLoc loc) noexcept {
ASSERT(HostLocIsGPR(loc));
DEBUG_ASSERT(HostLocIsGPR(loc));
return Xbyak::Reg64(int(loc));
}
inline Xbyak::Xmm HostLocToXmm(HostLoc loc) noexcept {
ASSERT(HostLocIsXMM(loc));
DEBUG_ASSERT(HostLocIsXMM(loc));
return Xbyak::Xmm(int(loc) - int(HostLoc::XMM0));
}
@@ -56,11 +56,11 @@ static inline bool IsValuelessType(const IR::Type type) noexcept {
}
void HostLocInfo::ReleaseOne() noexcept {
ASSERT(is_being_used_count > 0);
DEBUG_ASSERT(is_being_used_count > 0);
--is_being_used_count;
is_scratch = false;
if (current_references > 0) {
ASSERT(size_t(accumulated_uses) + 1 < (std::numeric_limits<decltype(accumulated_uses)>::max)());
DEBUG_ASSERT(size_t(accumulated_uses) + 1 < (std::numeric_limits<decltype(accumulated_uses)>::max)());
++accumulated_uses;
--current_references;
if (current_references == 0)
@@ -69,7 +69,7 @@ void HostLocInfo::ReleaseOne() noexcept {
}
void HostLocInfo::ReleaseAll() noexcept {
ASSERT(size_t(accumulated_uses) + current_references < (std::numeric_limits<decltype(accumulated_uses)>::max)());
DEBUG_ASSERT(size_t(accumulated_uses) + current_references < (std::numeric_limits<decltype(accumulated_uses)>::max)());
accumulated_uses += current_references;
current_references = 0;
is_set_last_use = false;
@@ -91,7 +91,7 @@ void HostLocInfo::AddValue(HostLoc loc, IR::Inst* inst) noexcept {
}
values.push_back(inst);
ASSERT(size_t(total_uses) + inst->UseCount() < (std::numeric_limits<decltype(total_uses)>::max)());
DEBUG_ASSERT(size_t(total_uses) + inst->UseCount() < (std::numeric_limits<decltype(total_uses)>::max)());
total_uses += inst->UseCount();
max_bit_width = std::max<uint8_t>(max_bit_width, std::countr_zero(GetBitWidth(inst->GetType())));
}
@@ -129,24 +129,24 @@ bool Argument::GetImmediateU1() const noexcept {
u8 Argument::GetImmediateU8() const noexcept {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm <= u64(std::numeric_limits<u8>::max()));
DEBUG_ASSERT(imm <= u64(std::numeric_limits<u8>::max()));
return u8(imm);
}
u16 Argument::GetImmediateU16() const noexcept {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm <= u64(std::numeric_limits<u16>::max()));
DEBUG_ASSERT(imm <= u64(std::numeric_limits<u16>::max()));
return u16(imm);
}
u32 Argument::GetImmediateU32() const noexcept {
const u64 imm = value.GetImmediateAsU64();
ASSERT(imm <= u64(std::numeric_limits<u32>::max()));
DEBUG_ASSERT(imm <= u64(std::numeric_limits<u32>::max()));
return u32(imm);
}
u64 Argument::GetImmediateS32() const noexcept {
ASSERT(FitsInImmediateS32());
DEBUG_ASSERT(FitsInImmediateS32());
return value.GetImmediateAsU64();
}
@@ -155,12 +155,12 @@ u64 Argument::GetImmediateU64() const noexcept {
}
IR::Cond Argument::GetImmediateCond() const noexcept {
ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
DEBUG_ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
return value.GetCond();
}
IR::AccType Argument::GetImmediateAccType() const noexcept {
ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
DEBUG_ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
return value.GetAccType();
}
@@ -201,7 +201,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(const IR::Inst* inst) noexcept
ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
auto const loc = ValueLocation(arg.GetInst());
ASSERT(loc && "argument must already been defined");
DEBUG_ASSERT(loc && "argument must already been defined");
LocInfo(*loc).AddArgReference();
}
}
@@ -209,7 +209,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(const IR::Inst* inst) noexcept
}
void RegAlloc::RegisterPseudoOperation(const IR::Inst* inst) noexcept {
ASSERT(IsValueLive(inst) || !inst->HasUses());
DEBUG_ASSERT(IsValueLive(inst) || !inst->HasUses());
for (size_t i = 0; i < inst->NumArgs(); i++) {
auto const arg = inst->GetArg(i);
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
@@ -222,37 +222,37 @@ void RegAlloc::RegisterPseudoOperation(const IR::Inst* inst) noexcept {
}
Xbyak::Reg64 RegAlloc::UseScratchGpr(BlockOfCode& code, Argument& arg) noexcept {
ASSERT(!arg.allocated);
DEBUG_ASSERT(!arg.allocated);
arg.allocated = true;
return HostLocToReg64(UseScratchImpl(code, arg.value, gpr_order));
}
Xbyak::Xmm RegAlloc::UseScratchXmm(BlockOfCode& code, Argument& arg) noexcept {
ASSERT(!arg.allocated);
DEBUG_ASSERT(!arg.allocated);
arg.allocated = true;
return HostLocToXmm(UseScratchImpl(code, arg.value, xmm_order));
}
void RegAlloc::UseScratch(BlockOfCode& code, Argument& arg, HostLoc host_loc) noexcept {
ASSERT(!arg.allocated);
DEBUG_ASSERT(!arg.allocated);
arg.allocated = true;
UseScratchImpl(code, arg.value, BuildRegSet({host_loc}));
}
void RegAlloc::DefineValue(BlockOfCode& code, IR::Inst* inst, const Xbyak::Reg& reg) noexcept {
ASSERT(reg.getKind() == Xbyak::Operand::XMM || reg.getKind() == Xbyak::Operand::REG);
DEBUG_ASSERT(reg.getKind() == Xbyak::Operand::XMM || reg.getKind() == Xbyak::Operand::REG);
const auto hostloc = static_cast<HostLoc>(reg.getIdx() + static_cast<size_t>(reg.getKind() == Xbyak::Operand::XMM ? HostLoc::XMM0 : HostLoc::RAX));
DefineValueImpl(code, inst, hostloc);
}
void RegAlloc::DefineValue(BlockOfCode& code, IR::Inst* inst, Argument& arg) noexcept {
ASSERT(!arg.allocated);
DEBUG_ASSERT(!arg.allocated);
arg.allocated = true;
DefineValueImpl(code, inst, arg.value);
}
void RegAlloc::Release(const Xbyak::Reg& reg) noexcept {
ASSERT(reg.getKind() == Xbyak::Operand::XMM || reg.getKind() == Xbyak::Operand::REG);
DEBUG_ASSERT(reg.getKind() == Xbyak::Operand::XMM || reg.getKind() == Xbyak::Operand::REG);
const auto hostloc = static_cast<HostLoc>(reg.getIdx() + static_cast<size_t>(reg.getKind() == Xbyak::Operand::XMM ? HostLoc::XMM0 : HostLoc::RAX));
LocInfo(hostloc).ReleaseOne();
}
@@ -382,15 +382,15 @@ void RegAlloc::HostCall(
}
void RegAlloc::AllocStackSpace(BlockOfCode& code, const size_t stack_space) noexcept {
ASSERT(stack_space < size_t((std::numeric_limits<s32>::max)()));
ASSERT(reserved_stack_space == 0);
DEBUG_ASSERT(stack_space < size_t((std::numeric_limits<s32>::max)()));
DEBUG_ASSERT(reserved_stack_space == 0);
reserved_stack_space = stack_space;
code.sub(code.rsp, u32(stack_space));
}
void RegAlloc::ReleaseStackSpace(BlockOfCode& code, const size_t stack_space) noexcept {
ASSERT(stack_space < size_t((std::numeric_limits<s32>::max)()));
ASSERT(reserved_stack_space == stack_space);
DEBUG_ASSERT(stack_space < size_t((std::numeric_limits<s32>::max)()));
DEBUG_ASSERT(reserved_stack_space == stack_space);
reserved_stack_space = 0;
code.add(code.rsp, u32(stack_space));
}
@@ -449,7 +449,7 @@ HostLoc RegAlloc::SelectARegister(std::bitset<32> desired_locations) const noexc
auto const it_final = it_empty_candidate != HostLoc::FirstSpill
? it_empty_candidate : it_candidate != HostLoc::FirstSpill
? it_candidate : it_rex_candidate;
ASSERT(it_final != HostLoc::FirstSpill && "All candidate registers have already been allocated");
DEBUG_ASSERT(it_final != HostLoc::FirstSpill && "All candidate registers have already been allocated");
// Evil magic - increment LRU counter (will wrap at 256)
const_cast<RegAlloc*>(this)->LocInfo(HostLoc(it_final)).lru_counter++;
return HostLoc(it_final);
@@ -459,26 +459,26 @@ std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const noex
for (size_t i = 0; i < hostloc_info.size(); i++)
if (hostloc_info[i].ContainsValue(value)) {
//for (size_t j = 0; j < hostloc_info.size(); ++j)
// ASSERT((i == j || !hostloc_info[j].ContainsValue(value)) && "duplicate defs");
// DEBUG_ASSERT((i == j || !hostloc_info[j].ContainsValue(value)) && "duplicate defs");
return HostLoc(i);
}
return std::nullopt;
}
void RegAlloc::DefineValueImpl(BlockOfCode& code, IR::Inst* def_inst, HostLoc host_loc) noexcept {
ASSERT(!ValueLocation(def_inst) && "def_inst has already been defined");
DEBUG_ASSERT(!ValueLocation(def_inst) && "def_inst has already been defined");
LocInfo(host_loc).AddValue(host_loc, def_inst);
ASSERT(*ValueLocation(def_inst) == host_loc);
DEBUG_ASSERT(*ValueLocation(def_inst) == host_loc);
}
void RegAlloc::DefineValueImpl(BlockOfCode& code, IR::Inst* def_inst, const IR::Value& use_inst) noexcept {
ASSERT(!ValueLocation(def_inst) && "def_inst has already been defined");
DEBUG_ASSERT(!ValueLocation(def_inst) && "def_inst has already been defined");
if (use_inst.IsImmediate()) {
const HostLoc location = ScratchImpl(code, gpr_order);
DefineValueImpl(code, def_inst, location);
LoadImmediate(code, use_inst, location);
} else {
ASSERT(ValueLocation(use_inst.GetInst()) && "use_inst must already be defined");
DEBUG_ASSERT(ValueLocation(use_inst.GetInst()) && "use_inst must already be defined");
const HostLoc location = *ValueLocation(use_inst.GetInst());
DefineValueImpl(code, def_inst, location);
}
@@ -486,22 +486,22 @@ void RegAlloc::DefineValueImpl(BlockOfCode& code, IR::Inst* def_inst, const IR::
void RegAlloc::Move(BlockOfCode& code, HostLoc to, HostLoc from) noexcept {
const size_t bit_width = LocInfo(from).GetMaxBitWidth();
ASSERT(LocInfo(to).IsEmpty() && !LocInfo(from).IsLocked());
ASSERT(bit_width <= HostLocBitWidth(to));
ASSERT(!LocInfo(from).IsEmpty() && "Mov eliminated");
DEBUG_ASSERT(LocInfo(to).IsEmpty() && !LocInfo(from).IsLocked());
DEBUG_ASSERT(bit_width <= HostLocBitWidth(to));
DEBUG_ASSERT(!LocInfo(from).IsEmpty() && "Mov eliminated");
EmitMove(code, bit_width, to, from);
LocInfo(to) = std::exchange(LocInfo(from), {});
}
void RegAlloc::CopyToScratch(BlockOfCode& code, size_t bit_width, HostLoc to, HostLoc from) noexcept {
ASSERT(LocInfo(to).IsEmpty() && !LocInfo(from).IsEmpty());
DEBUG_ASSERT(LocInfo(to).IsEmpty() && !LocInfo(from).IsEmpty());
EmitMove(code, bit_width, to, from);
}
void RegAlloc::Exchange(BlockOfCode& code, HostLoc a, HostLoc b) noexcept {
ASSERT(!LocInfo(a).IsLocked() && !LocInfo(b).IsLocked());
ASSERT(LocInfo(a).GetMaxBitWidth() <= HostLocBitWidth(b));
ASSERT(LocInfo(b).GetMaxBitWidth() <= HostLocBitWidth(a));
DEBUG_ASSERT(!LocInfo(a).IsLocked() && !LocInfo(b).IsLocked());
DEBUG_ASSERT(LocInfo(a).GetMaxBitWidth() <= HostLocBitWidth(b));
DEBUG_ASSERT(LocInfo(b).GetMaxBitWidth() <= HostLocBitWidth(a));
if (LocInfo(a).IsEmpty()) {
Move(code, a, b);
@@ -514,16 +514,16 @@ void RegAlloc::Exchange(BlockOfCode& code, HostLoc a, HostLoc b) noexcept {
}
void RegAlloc::MoveOutOfTheWay(BlockOfCode& code, HostLoc reg) noexcept {
ASSERT(!LocInfo(reg).IsLocked());
DEBUG_ASSERT(!LocInfo(reg).IsLocked());
if (!LocInfo(reg).IsEmpty()) {
SpillRegister(code, reg);
}
}
void RegAlloc::SpillRegister(BlockOfCode& code, HostLoc loc) noexcept {
ASSERT(HostLocIsRegister(loc) && "Only registers can be spilled");
ASSERT(!LocInfo(loc).IsEmpty() && "There is no need to spill unoccupied registers");
ASSERT(!LocInfo(loc).IsLocked() && "Registers that have been allocated must not be spilt");
DEBUG_ASSERT(HostLocIsRegister(loc) && "Only registers can be spilled");
DEBUG_ASSERT(!LocInfo(loc).IsEmpty() && "There is no need to spill unoccupied registers");
DEBUG_ASSERT(!LocInfo(loc).IsLocked() && "Registers that have been allocated must not be spilt");
auto const new_loc = FindFreeSpill(HostLocIsXMM(loc));
Move(code, new_loc, loc);
}
@@ -559,7 +559,7 @@ HostLoc RegAlloc::FindFreeSpill(bool is_xmm) const noexcept {
}()
HostLoc RegAlloc::LoadImmediate(BlockOfCode& code, IR::Value imm, HostLoc host_loc) noexcept {
ASSERT(imm.IsImmediate() && "imm is not an immediate");
DEBUG_ASSERT(imm.IsImmediate() && "imm is not an immediate");
if (HostLocIsGPR(host_loc)) {
const Xbyak::Reg64 reg = HostLocToReg64(host_loc);
const u64 imm_value = imm.GetImmediateAsU64();
@@ -584,9 +584,9 @@ HostLoc RegAlloc::LoadImmediate(BlockOfCode& code, IR::Value imm, HostLoc host_l
void RegAlloc::EmitMove(BlockOfCode& code, const size_t bit_width, const HostLoc to, const HostLoc from) noexcept {
auto const spill_to_op_arg_helper = [&](HostLoc loc, size_t reserved_stack_space) {
ASSERT(HostLocIsSpill(loc));
DEBUG_ASSERT(HostLocIsSpill(loc));
size_t i = size_t(loc) - size_t(HostLoc::FirstSpill);
ASSERT(i < SpillCount && "Spill index greater than number of available spill locations");
DEBUG_ASSERT(i < SpillCount && "Spill index greater than number of available spill locations");
return Xbyak::util::rsp + reserved_stack_space + ABI_SHADOW_SPACE + offsetof(StackLayout, spill) + i * sizeof(StackLayout::spill[0]);
};
auto const spill_xmm_to_op = [&](const HostLoc loc) {
@@ -595,21 +595,21 @@ void RegAlloc::EmitMove(BlockOfCode& code, const size_t bit_width, const HostLoc
if (HostLocIsXMM(to) && HostLocIsXMM(from)) {
MAYBE_AVX(movaps, HostLocToXmm(to), HostLocToXmm(from));
} else if (HostLocIsGPR(to) && HostLocIsGPR(from)) {
ASSERT(bit_width != 128);
DEBUG_ASSERT(bit_width != 128);
if (bit_width == 64) {
code.mov(HostLocToReg64(to), HostLocToReg64(from));
} else {
code.mov(HostLocToReg64(to).cvt32(), HostLocToReg64(from).cvt32());
}
} else if (HostLocIsXMM(to) && HostLocIsGPR(from)) {
ASSERT(bit_width != 128);
DEBUG_ASSERT(bit_width != 128);
if (bit_width == 64) {
MAYBE_AVX(movq, HostLocToXmm(to), HostLocToReg64(from));
} else {
MAYBE_AVX(movd, HostLocToXmm(to), HostLocToReg64(from).cvt32());
}
} else if (HostLocIsGPR(to) && HostLocIsXMM(from)) {
ASSERT(bit_width != 128);
DEBUG_ASSERT(bit_width != 128);
if (bit_width == 64) {
MAYBE_AVX(movq, HostLocToReg64(to), HostLocToXmm(from));
} else {
@@ -617,7 +617,7 @@ void RegAlloc::EmitMove(BlockOfCode& code, const size_t bit_width, const HostLoc
}
} else if (HostLocIsXMM(to) && HostLocIsSpill(from)) {
const Xbyak::Address spill_addr = spill_xmm_to_op(from);
ASSERT(spill_addr.getBit() >= bit_width);
DEBUG_ASSERT(spill_addr.getBit() >= bit_width);
switch (bit_width) {
case 128:
MAYBE_AVX(movaps, HostLocToXmm(to), spill_addr);
@@ -635,7 +635,7 @@ void RegAlloc::EmitMove(BlockOfCode& code, const size_t bit_width, const HostLoc
}
} else if (HostLocIsSpill(to) && HostLocIsXMM(from)) {
const Xbyak::Address spill_addr = spill_xmm_to_op(to);
ASSERT(spill_addr.getBit() >= bit_width);
DEBUG_ASSERT(spill_addr.getBit() >= bit_width);
switch (bit_width) {
case 128:
MAYBE_AVX(movaps, spill_addr, HostLocToXmm(from));
@@ -652,14 +652,14 @@ void RegAlloc::EmitMove(BlockOfCode& code, const size_t bit_width, const HostLoc
UNREACHABLE();
}
} else if (HostLocIsGPR(to) && HostLocIsSpill(from)) {
ASSERT(bit_width != 128);
DEBUG_ASSERT(bit_width != 128);
if (bit_width == 64) {
code.mov(HostLocToReg64(to), Xbyak::util::qword[spill_to_op_arg_helper(from, reserved_stack_space)]);
} else {
code.mov(HostLocToReg64(to).cvt32(), Xbyak::util::dword[spill_to_op_arg_helper(from, reserved_stack_space)]);
}
} else if (HostLocIsSpill(to) && HostLocIsGPR(from)) {
ASSERT(bit_width != 128);
DEBUG_ASSERT(bit_width != 128);
if (bit_width == 64) {
code.mov(Xbyak::util::qword[spill_to_op_arg_helper(to, reserved_stack_space)], HostLocToReg64(from));
} else {
@@ -672,7 +672,7 @@ void RegAlloc::EmitMove(BlockOfCode& code, const size_t bit_width, const HostLoc
#undef MAYBE_AVX
void RegAlloc::EmitExchange(BlockOfCode& code, const HostLoc a, const HostLoc b) noexcept {
ASSERT(HostLocIsGPR(a) && HostLocIsGPR(b) && "Exchanging XMM registers is uneeded OR invalid emit");
DEBUG_ASSERT(HostLocIsGPR(a) && HostLocIsGPR(b) && "Exchanging XMM registers is uneeded OR invalid emit");
code.xchg(HostLocToReg64(a), HostLocToReg64(b));
}

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