Compare commits

..

3 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
121 changed files with 2147 additions and 1664 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 {
+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"
+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)
@@ -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));
}
@@ -49,19 +49,19 @@ public:
return is_being_used_count == 0 && current_references == 1 && size_t(accumulated_uses) + 1 == size_t(total_uses);
}
inline void ReadLock() noexcept {
ASSERT(size_t(is_being_used_count) + 1 < (std::numeric_limits<decltype(is_being_used_count)>::max)());
ASSERT(!bool(is_scratch));
DEBUG_ASSERT(size_t(is_being_used_count) + 1 < (std::numeric_limits<decltype(is_being_used_count)>::max)());
DEBUG_ASSERT(!bool(is_scratch));
is_being_used_count++;
}
inline void WriteLock() noexcept {
ASSERT(is_being_used_count == 0);
DEBUG_ASSERT(is_being_used_count == 0);
is_being_used_count++;
is_scratch = true;
}
inline void AddArgReference() noexcept {
ASSERT(size_t(current_references) + 1 < (std::numeric_limits<decltype(current_references)>::max)());
DEBUG_ASSERT(size_t(current_references) + 1 < (std::numeric_limits<decltype(current_references)>::max)());
++current_references;
ASSERT(size_t(accumulated_uses) + current_references <= size_t(total_uses));
DEBUG_ASSERT(size_t(accumulated_uses) + current_references <= size_t(total_uses));
}
void ReleaseOne() noexcept;
void ReleaseAll() noexcept;
@@ -147,12 +147,12 @@ public:
return !!ValueLocation(inst);
}
inline Xbyak::Reg64 UseGpr(BlockOfCode& code, Argument& arg) noexcept {
ASSERT(!arg.allocated);
DEBUG_ASSERT(!arg.allocated);
arg.allocated = true;
return HostLocToReg64(UseImpl(code, arg.value, gpr_order));
}
inline Xbyak::Xmm UseXmm(BlockOfCode& code, Argument& arg) noexcept {
ASSERT(!arg.allocated);
DEBUG_ASSERT(!arg.allocated);
arg.allocated = true;
return HostLocToXmm(UseImpl(code, arg.value, xmm_order));
}
@@ -160,7 +160,7 @@ public:
return UseGpr(code, arg);
}
inline void Use(BlockOfCode& code, Argument& arg, const HostLoc host_loc) noexcept {
ASSERT(!arg.allocated);
DEBUG_ASSERT(!arg.allocated);
arg.allocated = true;
UseImpl(code, arg.value, BuildRegSet({host_loc}));
}
@@ -205,7 +205,7 @@ public:
iter.ReleaseAll();
}
inline void AssertNoMoreUses() noexcept {
ASSERT(std::all_of(hostloc_info.begin(), hostloc_info.end(), [](const auto& i) noexcept { return i.IsEmpty(); }));
DEBUG_ASSERT(std::all_of(hostloc_info.begin(), hostloc_info.end(), [](const auto& i) noexcept { return i.IsEmpty(); }));
}
#ifndef NDEBUG
inline void EmitVerboseDebuggingOutput(BlockOfCode& code) noexcept {
+3 -3
View File
@@ -73,7 +73,7 @@ public:
/// Set rounding mode control field.
void RMode(FP::RoundingMode rounding_mode) {
ASSERT(static_cast<u32>(rounding_mode) <= 0b11 && "FPCR: Invalid rounding mode");
DEBUG_ASSERT(static_cast<u32>(rounding_mode) <= 0b11 && "FPCR: Invalid rounding mode");
value = mcl::bit::set_bits<22, 23>(value, static_cast<u32>(rounding_mode));
}
@@ -93,7 +93,7 @@ public:
/// Set the stride of a vector when executing AArch32 VFP instructions.
/// This field has no function in AArch64 state.
void Stride(size_t stride) {
ASSERT(stride >= 1 && stride <= 2 && "FPCR: Invalid stride");
DEBUG_ASSERT(stride >= 1 && stride <= 2 && "FPCR: Invalid stride");
value = mcl::bit::set_bits<20, 21>(value, stride == 1 ? 0b00u : 0b11u);
}
@@ -116,7 +116,7 @@ public:
/// Sets the length of a vector when executing AArch32 VFP instructions.
/// This field has no function in AArch64 state.
void Len(size_t len) {
ASSERT(len >= 1 && len <= 8 && "FPCR: Invalid len");
DEBUG_ASSERT(len >= 1 && len <= 8 && "FPCR: Invalid len");
value = mcl::bit::set_bits<16, 18>(value, static_cast<u32>(len - 1));
}
@@ -26,7 +26,7 @@ namespace Dynarmic::FP {
template<typename FPT>
u64 FPRoundInt(FPT op, FPCR fpcr, RoundingMode rounding, bool exact, FPSR& fpsr) {
ASSERT(rounding != RoundingMode::ToOdd);
DEBUG_ASSERT(rounding != RoundingMode::ToOdd);
auto [type, sign, value] = FPUnpack<FPT>(op, fpcr, fpsr);
@@ -25,9 +25,9 @@ namespace Dynarmic::FP {
template<typename FPT>
u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, RoundingMode rounding, FPSR& fpsr) {
ASSERT(rounding != RoundingMode::ToOdd);
ASSERT(ibits <= 64);
ASSERT(fbits <= ibits);
DEBUG_ASSERT(rounding != RoundingMode::ToOdd);
DEBUG_ASSERT(ibits <= 64);
DEBUG_ASSERT(fbits <= ibits);
auto [type, sign, value] = FPUnpack<FPT>(op, fpcr, fpsr);
@@ -18,27 +18,27 @@ namespace Dynarmic::FP {
void FPProcessException(FPExc exception, FPCR fpcr, FPSR& fpsr) {
switch (exception) {
case FPExc::InvalidOp:
ASSERT(!fpcr.IOE() && "Raising floating point exceptions unimplemented");
DEBUG_ASSERT(!fpcr.IOE() && "Raising floating point exceptions unimplemented");
fpsr.IOC(true);
break;
case FPExc::DivideByZero:
ASSERT(!fpcr.DZE() && "Raising floating point exceptions unimplemented");
DEBUG_ASSERT(!fpcr.DZE() && "Raising floating point exceptions unimplemented");
fpsr.DZC(true);
break;
case FPExc::Overflow:
ASSERT(!fpcr.OFE() && "Raising floating point exceptions unimplemented");
DEBUG_ASSERT(!fpcr.OFE() && "Raising floating point exceptions unimplemented");
fpsr.OFC(true);
break;
case FPExc::Underflow:
ASSERT(!fpcr.UFE() && "Raising floating point exceptions unimplemented");
DEBUG_ASSERT(!fpcr.UFE() && "Raising floating point exceptions unimplemented");
fpsr.UFC(true);
break;
case FPExc::Inexact:
ASSERT(!fpcr.IXE() && "Raising floating point exceptions unimplemented");
DEBUG_ASSERT(!fpcr.IXE() && "Raising floating point exceptions unimplemented");
fpsr.IXC(true);
break;
case FPExc::InputDenorm:
ASSERT(!fpcr.IDE() && "Raising floating point exceptions unimplemented");
DEBUG_ASSERT(!fpcr.IDE() && "Raising floating point exceptions unimplemented");
fpsr.IDC(true);
break;
default:
@@ -23,7 +23,7 @@ namespace Dynarmic::FP {
template<typename FPT>
FPT FPProcessNaN(FPType type, FPT op, FPCR fpcr, FPSR& fpsr) {
ASSERT(type == FPType::QNaN || type == FPType::SNaN);
DEBUG_ASSERT(type == FPType::QNaN || type == FPType::SNaN);
constexpr size_t topfrac = FPInfo<FPT>::explicit_mantissa_width - 1;
@@ -85,8 +85,8 @@ std::tuple<bool, int, u64, ResidualError> Normalize(FPUnpacked op, int extra_rig
template<typename FPT>
FPT FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr) {
ASSERT(op.mantissa != 0);
ASSERT(rounding != RoundingMode::ToNearest_TieAwayFromZero);
DEBUG_ASSERT(op.mantissa != 0);
DEBUG_ASSERT(rounding != RoundingMode::ToNearest_TieAwayFromZero);
constexpr int minimum_exp = FPInfo<FPT>::exponent_min;
constexpr size_t E = FPInfo<FPT>::exponent_width;
@@ -35,7 +35,7 @@ std::string DisassembleX64(const void* begin, const void* end) {
while (pos < end) {
char buffer[80];
size_t inst_size = LLVMDisasmInstruction(llvm_ctx, const_cast<u8*>(pos), remaining, reinterpret_cast<u64>(pos), buffer, sizeof(buffer));
ASSERT(inst_size);
DEBUG_ASSERT(inst_size);
for (const u8* i = pos; i < pos + inst_size; i++)
result += fmt::format("{:02x} ", *i);
for (size_t i = inst_size; i < 10; i++)
@@ -64,12 +64,12 @@ IR::U32U64 IREmitter::GetExtendedRegister(ExtReg reg) {
}
IR::U128 IREmitter::GetVector(ExtReg reg) {
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
return Inst<IR::U128>(Opcode::A32GetVector, IR::Value(reg));
}
void IREmitter::SetRegister(const Reg reg, const IR::U32& value) {
ASSERT(reg != A32::Reg::PC);
DEBUG_ASSERT(reg != A32::Reg::PC);
Inst(Opcode::A32SetRegister, IR::Value(reg), value);
}
@@ -84,7 +84,7 @@ void IREmitter::SetExtendedRegister(const ExtReg reg, const IR::U32U64& value) {
}
void IREmitter::SetVector(ExtReg reg, const IR::U128& value) {
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
DEBUG_ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
Inst(Opcode::A32SetVector, IR::Value(reg), value);
}
@@ -361,7 +361,7 @@ IR::U32 IREmitter::ExclusiveWriteMemory64(const IR::U32& vaddr, const IR::U32& v
}
void IREmitter::CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, CoprocReg CRd, CoprocReg CRn, CoprocReg CRm, size_t opc2) {
ASSERT(coproc_no <= 15);
DEBUG_ASSERT(coproc_no <= 15);
const IR::Value::CoprocessorInfo coproc_info{static_cast<u8>(coproc_no),
static_cast<u8>(two ? 1 : 0),
static_cast<u8>(opc1),
@@ -373,7 +373,7 @@ void IREmitter::CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1,
}
void IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, CoprocReg CRn, CoprocReg CRm, size_t opc2, const IR::U32& word) {
ASSERT(coproc_no <= 15);
DEBUG_ASSERT(coproc_no <= 15);
const IR::Value::CoprocessorInfo coproc_info{static_cast<u8>(coproc_no),
static_cast<u8>(two ? 1 : 0),
static_cast<u8>(opc1),
@@ -384,7 +384,7 @@ void IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, Copro
}
void IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, CoprocReg CRm, const IR::U32& word1, const IR::U32& word2) {
ASSERT(coproc_no <= 15);
DEBUG_ASSERT(coproc_no <= 15);
const IR::Value::CoprocessorInfo coproc_info{static_cast<u8>(coproc_no),
static_cast<u8>(two ? 1 : 0),
static_cast<u8>(opc),
@@ -393,7 +393,7 @@ void IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, Copro
}
IR::U32 IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, CoprocReg CRn, CoprocReg CRm, size_t opc2) {
ASSERT(coproc_no <= 15);
DEBUG_ASSERT(coproc_no <= 15);
const IR::Value::CoprocessorInfo coproc_info{static_cast<u8>(coproc_no),
static_cast<u8>(two ? 1 : 0),
static_cast<u8>(opc1),
@@ -404,7 +404,7 @@ IR::U32 IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, Cop
}
IR::U64 IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, CoprocReg CRm) {
ASSERT(coproc_no <= 15);
DEBUG_ASSERT(coproc_no <= 15);
const IR::Value::CoprocessorInfo coproc_info{static_cast<u8>(coproc_no),
static_cast<u8>(two ? 1 : 0),
static_cast<u8>(opc),
@@ -413,7 +413,7 @@ IR::U64 IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, Cop
}
void IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, CoprocReg CRd, const IR::U32& address, bool has_option, u8 option) {
ASSERT(coproc_no <= 15);
DEBUG_ASSERT(coproc_no <= 15);
const IR::Value::CoprocessorInfo coproc_info{static_cast<u8>(coproc_no),
static_cast<u8>(two ? 1 : 0),
static_cast<u8>(long_transfer ? 1 : 0),
@@ -424,7 +424,7 @@ void IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer,
}
void IREmitter::CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, CoprocReg CRd, const IR::U32& address, bool has_option, u8 option) {
ASSERT(coproc_no <= 15);
DEBUG_ASSERT(coproc_no <= 15);
const IR::Value::CoprocessorInfo coproc_info{static_cast<u8>(coproc_no),
static_cast<u8>(two ? 1 : 0),
static_cast<u8>(long_transfer ? 1 : 0),
@@ -85,7 +85,7 @@ constexpr bool IsQuadExtReg(ExtReg reg) {
}
inline size_t RegNumber(Reg reg) {
ASSERT(reg != Reg::INVALID_REG);
DEBUG_ASSERT(reg != Reg::INVALID_REG);
return size_t(reg);
}
@@ -95,13 +95,13 @@ inline size_t RegNumber(ExtReg reg) {
} else if (IsDoubleExtReg(reg)) {
return size_t(reg) - size_t(ExtReg::D0);
}
ASSERT(IsQuadExtReg(reg));
DEBUG_ASSERT(IsQuadExtReg(reg));
return size_t(reg) - size_t(ExtReg::Q0);
}
inline Reg operator+(Reg reg, size_t number) {
const size_t new_reg = RegNumber(reg) + number;
ASSERT(new_reg <= 15);
DEBUG_ASSERT(new_reg <= 15);
return static_cast<Reg>(new_reg);
}
@@ -109,7 +109,7 @@ inline Reg operator+(Reg reg, size_t number) {
inline ExtReg operator+(ExtReg reg, size_t number) {
const auto new_reg = static_cast<ExtReg>(static_cast<size_t>(reg) + number);
ASSERT((IsSingleExtReg(reg) && IsSingleExtReg(new_reg))
DEBUG_ASSERT((IsSingleExtReg(reg) && IsSingleExtReg(new_reg))
|| (IsDoubleExtReg(reg) && IsDoubleExtReg(new_reg))
|| (IsQuadExtReg(reg) && IsQuadExtReg(new_reg)));
@@ -21,7 +21,7 @@
namespace Dynarmic::A32 {
bool CondCanContinue(const ConditionalState cond_state, const A32::IREmitter& ir) {
ASSERT(cond_state != ConditionalState::Break && "Should never happen.");
DEBUG_ASSERT(cond_state != ConditionalState::Break && "Should never happen.");
if (cond_state == ConditionalState::None)
return true;
@@ -32,7 +32,7 @@ bool CondCanContinue(const ConditionalState cond_state, const A32::IREmitter& ir
}
bool IsConditionPassed(TranslatorVisitor& v, IR::Cond cond) {
ASSERT(v.cond_state != ConditionalState::Break && "This should never happen. We requested a break but that wasn't honored.");
DEBUG_ASSERT(v.cond_state != ConditionalState::Break && "This should never happen. We requested a break but that wasn't honored.");
if (cond == IR::Cond::NV) {
// NV conditional is obsolete
@@ -29,7 +29,7 @@ bool TranslatorVisitor::ThumbConditionPassed() {
bool TranslatorVisitor::VFPConditionPassed(Cond cond) {
if (ir.current_location.TFlag()) {
ASSERT(cond == Cond::AL);
DEBUG_ASSERT(cond == Cond::AL);
return true;
}
return ArmConditionPassed(cond);
@@ -130,7 +130,7 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, bool D, size_t imm6, size_t Vd, b
}
return v.ir.VectorUnsignedSaturatedNarrow(source_esize, wide_result);
case Narrowing::SaturateToSigned:
ASSERT(signedness == Signedness::Signed);
DEBUG_ASSERT(signedness == Signedness::Signed);
return v.ir.VectorSignedSaturatedNarrowToSigned(source_esize, wide_result);
}
UNREACHABLE();
@@ -95,7 +95,7 @@ bool TranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n, Re
return UnpredictableInstruction();
}
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@@ -126,7 +126,7 @@ bool TranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n, Re
// LDR <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDR <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) {
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (m == Reg::PC) {
return UnpredictableInstruction();
}
@@ -184,7 +184,7 @@ bool TranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n, R
return UnpredictableInstruction();
}
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@@ -209,7 +209,7 @@ bool TranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n, R
// LDRB <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRB <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) {
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
@@ -352,7 +352,7 @@ bool TranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n, R
// LDRH <Rt>, [PC, #-/+<imm>]
bool TranslatorVisitor::arm_LDRH_lit(Cond cond, bool P, bool U, bool W, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (P == W) {
return UnpredictableInstruction();
}
@@ -382,7 +382,7 @@ bool TranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, R
return UnpredictableInstruction();
}
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@@ -407,7 +407,7 @@ bool TranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, R
// LDRH <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRH <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
@@ -456,7 +456,7 @@ bool TranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction();
}
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@@ -481,7 +481,7 @@ bool TranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg n,
// LDRSB <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRSB <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
@@ -529,7 +529,7 @@ bool TranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction();
}
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@@ -554,7 +554,7 @@ bool TranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n,
// LDRSH <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRSH <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT(!(!P && W) && "T form of instruction unimplemented");
DEBUG_ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
@@ -34,7 +34,7 @@ bool TranslatorVisitor::arm_MRS(Cond cond, Reg d) {
// MSR<c> <spec_reg>, #<const>
bool TranslatorVisitor::arm_MSR_imm(Cond cond, unsigned mask, int rotate, Imm<8> imm8) {
ASSERT(mask != 0 && "Decode error");
DEBUG_ASSERT(mask != 0 && "Decode error");
if (!ArmConditionPassed(cond)) {
return true;
@@ -687,7 +687,7 @@ bool TranslatorVisitor::thumb16_NOP() {
// IT{<x>{<y>{<z>}}} <cond>
bool TranslatorVisitor::thumb16_IT(Imm<8> imm8) {
ASSERT((imm8.Bits<0, 3>() != 0b0000) && "Decode Error");
DEBUG_ASSERT((imm8.Bits<0, 3>() != 0b0000) && "Decode Error");
if (imm8.Bits<4, 7>() == 0b1111 || (imm8.Bits<4, 7>() == 0b1110 && std::popcount(imm8.Bits<0, 3>()) != 1)) {
return UnpredictableInstruction();
}
@@ -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.
@@ -23,7 +23,7 @@ bool TranslatorVisitor::thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
}
bool TranslatorVisitor::thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT(!(d == Reg::PC && S) && "Decode error");
DEBUG_ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction();
}
@@ -69,7 +69,7 @@ bool TranslatorVisitor::thumb32_MOV_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Im
}
bool TranslatorVisitor::thumb32_ORR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT(n != Reg::PC && "Decode error");
DEBUG_ASSERT(n != Reg::PC && "Decode error");
if (d == Reg::PC) {
return UnpredictableInstruction();
}
@@ -100,7 +100,7 @@ bool TranslatorVisitor::thumb32_MVN_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Im
}
bool TranslatorVisitor::thumb32_ORN_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT(n != Reg::PC && "Decode error");
DEBUG_ASSERT(n != Reg::PC && "Decode error");
if (d == Reg::PC) {
return UnpredictableInstruction();
}
@@ -128,7 +128,7 @@ bool TranslatorVisitor::thumb32_TEQ_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
}
bool TranslatorVisitor::thumb32_EOR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT(!(d == Reg::PC && S) && "Decode error");
DEBUG_ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction();
}
@@ -156,7 +156,7 @@ bool TranslatorVisitor::thumb32_CMN_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
}
bool TranslatorVisitor::thumb32_ADD_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT(!(d == Reg::PC && S) && "Decode error");
DEBUG_ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction();
}
@@ -214,7 +214,7 @@ bool TranslatorVisitor::thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
}
bool TranslatorVisitor::thumb32_SUB_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT(!(d == Reg::PC && S) && "Decode error");
DEBUG_ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction();
}
@@ -17,7 +17,7 @@ namespace Dynarmic::A32 {
using SaturationFunction = IR::ResultAndOverflow<IR::U32> (IREmitter::*)(const IR::U32&, size_t);
static bool Saturation(TranslatorVisitor& v, bool sh, Reg n, Reg d, Imm<5> shift_amount, size_t saturate_to, SaturationFunction sat_fn) {
ASSERT(!(sh && shift_amount == 0) && "Invalid decode");
DEBUG_ASSERT(!(sh && shift_amount == 0) && "Invalid decode");
if (d == Reg::PC || n == Reg::PC) {
return v.UnpredictableInstruction();
@@ -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.
@@ -23,7 +23,7 @@ bool TranslatorVisitor::thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
}
bool TranslatorVisitor::thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT(!(d == Reg::PC && S) && "Decode error");
DEBUG_ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@@ -67,7 +67,7 @@ bool TranslatorVisitor::thumb32_MOV_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2,
}
bool TranslatorVisitor::thumb32_ORR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT(n != Reg::PC && "Decode error");
DEBUG_ASSERT(n != Reg::PC && "Decode error");
if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@@ -97,7 +97,7 @@ bool TranslatorVisitor::thumb32_MVN_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2,
}
bool TranslatorVisitor::thumb32_ORN_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT(n != Reg::PC && "Decode error");
DEBUG_ASSERT(n != Reg::PC && "Decode error");
if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@@ -125,7 +125,7 @@ bool TranslatorVisitor::thumb32_TEQ_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
}
bool TranslatorVisitor::thumb32_EOR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT(!(d == Reg::PC && S) && "Decode error");
DEBUG_ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@@ -168,7 +168,7 @@ bool TranslatorVisitor::thumb32_CMN_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
}
bool TranslatorVisitor::thumb32_ADD_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT(!(d == Reg::PC && S) && "Decode error");
DEBUG_ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@@ -224,7 +224,7 @@ bool TranslatorVisitor::thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
}
bool TranslatorVisitor::thumb32_SUB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT(!(d == Reg::PC && S) && "Decode error");
DEBUG_ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@@ -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.
@@ -1304,11 +1304,11 @@ bool TranslatorVisitor::vfp_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd, bo
// VSTM{mode}<c> <Rn>{!}, <list of double registers>
bool TranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) {
ASSERT(false && "Decode error");
DEBUG_ASSERT(false && "Decode error");
}
if (p && !w) {
ASSERT(false && "Decode error");
DEBUG_ASSERT(false && "Decode error");
}
if (p == u && w) {
@@ -1356,11 +1356,11 @@ bool TranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w, R
// VSTM{mode}<c> <Rn>{!}, <list of single registers>
bool TranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) {
ASSERT(false && "Decode error");
DEBUG_ASSERT(false && "Decode error");
}
if (p && !w) {
ASSERT(false && "Decode error");
DEBUG_ASSERT(false && "Decode error");
}
if (p == u && w) {
@@ -1399,11 +1399,11 @@ bool TranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w, R
// VLDM{mode}<c> <Rn>{!}, <list of double registers>
bool TranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) {
ASSERT(false && "Decode error");
DEBUG_ASSERT(false && "Decode error");
}
if (p && !w) {
ASSERT(false && "Decode error");
DEBUG_ASSERT(false && "Decode error");
}
if (p == u && w) {
@@ -1449,11 +1449,11 @@ bool TranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w, R
// VLDM{mode}<c> <Rn>{!}, <list of single registers>
bool TranslatorVisitor::vfp_VLDM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) {
ASSERT(false && "Decode error");
DEBUG_ASSERT(false && "Decode error");
}
if (p && !w) {
ASSERT(false && "Decode error");
DEBUG_ASSERT(false && "Decode error");
}
if (p == u && w) {

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