mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 01:08:56 +02:00
Compare commits
14 commits
d42e79244b
...
a675e17c77
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a675e17c77 | ||
|
|
f39c94f2f5 | ||
|
|
343a129c5b | ||
|
|
f52dcffb57 | ||
|
|
0a56a75fbc | ||
|
|
17db5b0b8d | ||
|
|
6c7949ce4f | ||
|
|
876884e783 | ||
|
|
028050cf04 | ||
|
|
1f787ffc39 | ||
|
|
148dc7b480 | ||
|
|
612a203ab2 | ||
|
|
5e927199c5 | ||
|
|
ac99ea96da |
225 changed files with 1912 additions and 1515 deletions
|
|
@ -16,6 +16,7 @@ This contains documentation created by developers. This contains build instructi
|
|||
- **[Dynarmic](./dynarmic)**
|
||||
- **[Cross compilation](./CrossCompile.md)**
|
||||
- **[Driver Bugs](./DriverBugs.md)**
|
||||
- **[Building Older Commits](./build/OlderCommits.md)**
|
||||
|
||||
## Policies
|
||||
|
||||
|
|
|
|||
40
docs/build/OlderCommits.md
vendored
Normal file
40
docs/build/OlderCommits.md
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Building Older Commits
|
||||
|
||||
Bisecting and debugging older versions of Eden can be difficult, as many of our submodules have been deleted or removed. However, work has been done to make this process as simple as possible for users.
|
||||
|
||||
## Script
|
||||
|
||||
Copy the following script and store it in `fix.sh`:
|
||||
|
||||
```sh
|
||||
#!/bin/sh -e
|
||||
|
||||
git -C externals/discord-rpc checkout 0d8b2d6a37c6e47d62b37caa14708bf747c883bb
|
||||
git add externals/discord-rpc
|
||||
|
||||
git -C externals/dynarmic checkout 05b7ba50588d1004e23ef91f1bda8be234be68f4
|
||||
git add externals/dynarmic
|
||||
|
||||
git -C externals/mbedtls checkout ce4f81f4a926a0e0dcadd0128e016baba416e8ea
|
||||
git add externals/mbedtls
|
||||
|
||||
git -C externals/oboe checkout e4f06f2143eb0173bf4a2bd15aae5e8cc3179405
|
||||
git add externals/oboe
|
||||
|
||||
git -C externals/sirit checkout b870b062998244231a4f08004d3b25151732c5c5
|
||||
git add externals/sirit
|
||||
```
|
||||
|
||||
Then, run `chmod +x fix.sh`
|
||||
|
||||
## Submodules
|
||||
|
||||
To check out submodules successfully, use this order of operations:
|
||||
|
||||
```sh
|
||||
git submodule update --init --recursive --depth 1 --jobs 8 --progress
|
||||
./fix.sh
|
||||
git submodule update --init --recursive --depth 1 --jobs 8 --progress
|
||||
```
|
||||
|
||||
And you should be good to go! If you check out a different commit that changes submodule commits, run the above command list again.
|
||||
9
externals/CMakeLists.txt
vendored
9
externals/CMakeLists.txt
vendored
|
|
@ -62,6 +62,12 @@ endif()
|
|||
# unordered_dense
|
||||
AddJsonPackage(unordered-dense)
|
||||
|
||||
# httplib
|
||||
if (IOS)
|
||||
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
|
||||
endif()
|
||||
AddJsonPackage(httplib)
|
||||
|
||||
if (YUZU_STATIC_ROOM)
|
||||
return()
|
||||
endif()
|
||||
|
|
@ -227,9 +233,6 @@ if (VulkanMemoryAllocator_ADDED)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
# httplib
|
||||
AddJsonPackage(httplib)
|
||||
|
||||
# cpp-jwt
|
||||
if (ENABLE_WEB_SERVICE OR ENABLE_UPDATE_CHECKER)
|
||||
AddJsonPackage(cpp-jwt)
|
||||
|
|
|
|||
3
externals/cpmfile.json
vendored
3
externals/cpmfile.json
vendored
|
|
@ -36,7 +36,8 @@
|
|||
"0002-fix-zstd.patch"
|
||||
],
|
||||
"options": [
|
||||
"HTTPLIB_REQUIRE_OPENSSL ON"
|
||||
"HTTPLIB_REQUIRE_OPENSSL ON",
|
||||
"HTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES ON"
|
||||
]
|
||||
},
|
||||
"cpp-jwt": {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
include_directories(.)
|
||||
|
||||
# Dynarmic
|
||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 AND NOT YUZU_STATIC_ROOM)
|
||||
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64) AND NOT YUZU_STATIC_ROOM)
|
||||
add_subdirectory(dynarmic)
|
||||
add_library(dynarmic::dynarmic ALIAS dynarmic)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -146,7 +146,8 @@ add_library(
|
|||
zstd_compression.cpp
|
||||
zstd_compression.h
|
||||
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
|
||||
fs/symlink.h fs/symlink.cpp)
|
||||
fs/symlink.h fs/symlink.cpp
|
||||
httplib.h)
|
||||
|
||||
if(WIN32)
|
||||
target_sources(common PRIVATE windows/timer_resolution.cpp
|
||||
|
|
@ -244,7 +245,7 @@ else()
|
|||
target_link_libraries(common PUBLIC Boost::headers)
|
||||
endif()
|
||||
|
||||
target_link_libraries(common PUBLIC Boost::filesystem Boost::context)
|
||||
target_link_libraries(common PUBLIC Boost::filesystem Boost::context httplib::httplib)
|
||||
|
||||
if (lz4_ADDED)
|
||||
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
|
||||
|
|
|
|||
18
src/common/httplib.h
Normal file
18
src/common/httplib.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES 1
|
||||
#define CPPHTTPLIB_OPENSSL_SUPPORT 1
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
#endif
|
||||
#include <httplib.h>
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
|
@ -287,8 +287,6 @@ struct Values {
|
|||
true,
|
||||
&use_custom_cpu_ticks};
|
||||
|
||||
SwitchableSetting<bool> vtable_bouncing{linkage, true, "vtable_bouncing", Category::Cpu};
|
||||
|
||||
Setting<bool> cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug};
|
||||
Setting<bool> cpuopt_block_linking{linkage, true, "cpuopt_block_linking", Category::CpuDebug};
|
||||
Setting<bool> cpuopt_return_stack_buffer{linkage, true, "cpuopt_return_stack_buffer",
|
||||
|
|
|
|||
|
|
@ -1246,7 +1246,7 @@ if (HAS_NCE)
|
|||
target_link_libraries(core PRIVATE merry::oaknut)
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
|
||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64)
|
||||
target_sources(core PRIVATE
|
||||
arm/dynarmic/arm_dynarmic.h
|
||||
arm/dynarmic/arm_dynarmic_64.cpp
|
||||
|
|
@ -1269,7 +1269,6 @@ endif()
|
|||
target_sources(core PRIVATE hle/service/ssl/ssl_backend_openssl.cpp)
|
||||
|
||||
target_link_libraries(core PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||
target_compile_definitions(core PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
|
||||
# TODO
|
||||
|
||||
|
|
|
|||
|
|
@ -59,14 +59,10 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
|
|||
#if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
|
||||
_mm_mfence();
|
||||
_mm_lfence();
|
||||
#elif defined(ARCHITECTURE_x86_64)
|
||||
asm volatile("mfence\n\tlfence\n\t" : : : "memory");
|
||||
#elif defined(_MSC_VER) && defined(ARCHITECTURE_arm64)
|
||||
_Memory_barrier();
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
asm volatile("dsb sy\n\t" : : : "memory");
|
||||
#else
|
||||
#error Unsupported architecture
|
||||
__sync_synchronize();
|
||||
#endif
|
||||
return 0;
|
||||
},
|
||||
|
|
@ -78,14 +74,10 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
|
|||
[](void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
|
||||
#if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
|
||||
_mm_mfence();
|
||||
#elif defined(ARCHITECTURE_x86_64)
|
||||
asm volatile("mfence\n\t" : : : "memory");
|
||||
#elif defined(_MSC_VER) && defined(ARCHITECTURE_arm64)
|
||||
_Memory_barrier();
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
asm volatile("dmb sy\n\t" : : : "memory");
|
||||
#else
|
||||
#error Unsupported architecture
|
||||
__sync_synchronize();
|
||||
#endif
|
||||
return 0;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
|
|
@ -103,26 +103,12 @@ void PhysicalCore::RunThread(Kernel::KThread* thread) {
|
|||
const bool data_abort = True(hr & Core::HaltReason::DataAbort);
|
||||
const bool interrupt = True(hr & Core::HaltReason::BreakLoop);
|
||||
|
||||
bool may_abort = true; // Ignore aborting virtual functions (for debugging)
|
||||
if (prefetch_abort && ::Settings::values.vtable_bouncing) {
|
||||
auto& lock = m_kernel.GlobalSchedulerContext().SchedulerLock();
|
||||
lock.Lock();
|
||||
Kernel::Svc::ThreadContext ctx;
|
||||
interface->GetContext(ctx);
|
||||
LOG_WARNING(Core_ARM, "vtable bouncing {:016X}", ctx.lr);
|
||||
ctx.pc = ctx.lr;
|
||||
ctx.r[0] = 0;
|
||||
interface->SetContext(ctx);
|
||||
lock.Unlock();
|
||||
may_abort = false;
|
||||
}
|
||||
|
||||
// Since scheduling may occur here, we cannot use any cached
|
||||
// state after returning from calls we make.
|
||||
|
||||
// Notify the debugger and go to sleep if a breakpoint was hit,
|
||||
// or if the thread is unable to continue for any reason.
|
||||
if (breakpoint || (prefetch_abort && may_abort)) {
|
||||
if (breakpoint || prefetch_abort) {
|
||||
if (breakpoint) {
|
||||
interface->RewindBreakpointInstruction();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@
|
|||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
#include <httplib.h>
|
||||
#endif
|
||||
#include "common/httplib.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
|
|
@ -103,8 +101,6 @@ std::vector<u8> TryLoadFromDisk(const std::filesystem::path& path) {
|
|||
|
||||
std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem::path& cache_path) {
|
||||
LOG_INFO(Service_BCAT, "Downloading image: https://eden-emu.dev{}", url_path);
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
try {
|
||||
httplib::Client cli("https://eden-emu.dev");
|
||||
cli.set_follow_location(true);
|
||||
|
|
@ -128,8 +124,6 @@ std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem
|
|||
} catch (...) {
|
||||
LOG_WARNING(Service_BCAT, "Failed to download: {}", url_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
@ -232,8 +226,6 @@ void WriteCachedJson(std::string_view json) {
|
|||
}
|
||||
|
||||
std::optional<std::string> DownloadReleasesJson() {
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
try {
|
||||
httplib::SSLClient cli{"api.github.com", 443};
|
||||
cli.set_connection_timeout(10);
|
||||
|
|
@ -255,7 +247,6 @@ std::optional<std::string> DownloadReleasesJson() {
|
|||
} catch (...) {
|
||||
LOG_WARNING(Service_BCAT, " failed to download releases");
|
||||
}
|
||||
#endif
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
|
|||
find_package(oaknut 2.0.1 CONFIG)
|
||||
endif()
|
||||
|
||||
if ("riscv" IN_LIST ARCHITECTURE)
|
||||
if ("riscv64" IN_LIST ARCHITECTURE)
|
||||
find_package(biscuit 0.9.1 REQUIRED)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,7 @@ add_library(dynarmic STATIC
|
|||
backend/block_range_information.h
|
||||
backend/exception_handler.h
|
||||
common/always_false.h
|
||||
common/assert.cpp
|
||||
common/assert.h
|
||||
common/cast_util.h
|
||||
common/common_types.h
|
||||
common/crypto/aes.cpp
|
||||
common/crypto/aes.h
|
||||
common/crypto/crc32.cpp
|
||||
|
|
@ -258,7 +255,7 @@ if ("arm64" IN_LIST ARCHITECTURE)
|
|||
)
|
||||
endif()
|
||||
|
||||
if ("riscv" IN_LIST ARCHITECTURE)
|
||||
if ("riscv64" IN_LIST ARCHITECTURE)
|
||||
target_link_libraries(dynarmic PRIVATE biscuit::biscuit)
|
||||
|
||||
target_sources(dynarmic PRIVATE
|
||||
|
|
@ -281,6 +278,7 @@ if ("riscv" IN_LIST ARCHITECTURE)
|
|||
backend/riscv64/emit_riscv64_vector.cpp
|
||||
backend/riscv64/emit_riscv64.cpp
|
||||
backend/riscv64/emit_riscv64.h
|
||||
backend/riscv64/exclusive_monitor.cpp
|
||||
backend/riscv64/reg_alloc.cpp
|
||||
backend/riscv64/reg_alloc.h
|
||||
backend/riscv64/stack_layout.h
|
||||
|
|
@ -289,9 +287,12 @@ if ("riscv" IN_LIST ARCHITECTURE)
|
|||
backend/riscv64/a32_address_space.h
|
||||
backend/riscv64/a32_core.h
|
||||
backend/riscv64/a32_interface.cpp
|
||||
backend/riscv64/a64_interface.cpp
|
||||
backend/riscv64/code_block.h
|
||||
|
||||
common/spin_lock_riscv64.cpp
|
||||
)
|
||||
message(FATAL_ERROR "TODO: Unimplemented frontend for this host architecture")
|
||||
message(WARNING "TODO: Incomplete frontend for this host architecture")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
|
|
@ -359,7 +360,7 @@ set_target_properties(dynarmic PROPERTIES
|
|||
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
||||
|
||||
target_link_libraries(dynarmic PRIVATE unordered_dense::unordered_dense)
|
||||
target_link_libraries(dynarmic PUBLIC fmt::fmt)
|
||||
target_link_libraries(dynarmic PUBLIC fmt::fmt common)
|
||||
|
||||
if (BOOST_NO_HEADERS)
|
||||
target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ void A32AddressSpace::EmitPrelude() {
|
|||
|
||||
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||
code.LDR(Xscratch0, l_return_to_dispatcher);
|
||||
for (size_t i = 0; i < RSBCount; i++) {
|
||||
for (std::size_t i = 0; i < RSBCount; i++) {
|
||||
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
||||
}
|
||||
}
|
||||
|
|
@ -266,7 +266,7 @@ void A32AddressSpace::EmitPrelude() {
|
|||
|
||||
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||
code.LDR(Xscratch0, l_return_to_dispatcher);
|
||||
for (size_t i = 0; i < RSBCount; i++) {
|
||||
for (std::size_t i = 0; i < RSBCount; i++) {
|
||||
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/arm64/a32_address_space.h"
|
||||
#include "dynarmic/backend/arm64/a32_core.h"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
||||
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||
#include "dynarmic/ir/location_descriptor.h"
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ void A64AddressSpace::EmitPrelude() {
|
|||
|
||||
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||
code.LDR(Xscratch0, l_return_to_dispatcher);
|
||||
for (size_t i = 0; i < RSBCount; i++) {
|
||||
for (std::size_t i = 0; i < RSBCount; i++) {
|
||||
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
||||
}
|
||||
}
|
||||
|
|
@ -441,7 +441,7 @@ void A64AddressSpace::EmitPrelude() {
|
|||
|
||||
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||
code.LDR(Xscratch0, l_return_to_dispatcher);
|
||||
for (size_t i = 0; i < RSBCount; i++) {
|
||||
for (std::size_t i = 0; i < RSBCount; i++) {
|
||||
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/arm64/a64_address_space.h"
|
||||
#include "dynarmic/backend/arm64/a64_core.h"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -11,22 +11,22 @@
|
|||
#include <vector>
|
||||
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include <oaknut/oaknut.hpp>
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
using namespace oaknut::util;
|
||||
|
||||
static constexpr size_t gpr_size = 8;
|
||||
static constexpr size_t fpr_size = 16;
|
||||
static constexpr std::size_t gpr_size = 8;
|
||||
static constexpr std::size_t fpr_size = 16;
|
||||
|
||||
struct FrameInfo {
|
||||
std::vector<int> gprs;
|
||||
std::vector<int> fprs;
|
||||
size_t frame_size;
|
||||
size_t gprs_size;
|
||||
size_t fprs_size;
|
||||
std::size_t frame_size;
|
||||
std::size_t gprs_size;
|
||||
std::size_t fprs_size;
|
||||
};
|
||||
|
||||
static std::vector<int> ListToIndexes(u32 list) {
|
||||
|
|
@ -39,15 +39,15 @@ static std::vector<int> ListToIndexes(u32 list) {
|
|||
return indexes;
|
||||
}
|
||||
|
||||
static FrameInfo CalculateFrameInfo(RegisterList rl, size_t frame_size) {
|
||||
static FrameInfo CalculateFrameInfo(RegisterList rl, std::size_t frame_size) {
|
||||
const auto gprs = ListToIndexes(static_cast<u32>(rl));
|
||||
const auto fprs = ListToIndexes(static_cast<u32>(rl >> 32));
|
||||
|
||||
const size_t num_gprs = gprs.size();
|
||||
const size_t num_fprs = fprs.size();
|
||||
const std::size_t num_gprs = gprs.size();
|
||||
const std::size_t num_fprs = fprs.size();
|
||||
|
||||
const size_t gprs_size = (num_gprs + 1) / 2 * 16;
|
||||
const size_t fprs_size = num_fprs * 16;
|
||||
const std::size_t gprs_size = (num_gprs + 1) / 2 * 16;
|
||||
const std::size_t fprs_size = num_fprs * 16;
|
||||
|
||||
return {
|
||||
gprs,
|
||||
|
|
@ -60,16 +60,16 @@ static FrameInfo CalculateFrameInfo(RegisterList rl, size_t frame_size) {
|
|||
|
||||
#define DO_IT(TYPE, REG_TYPE, PAIR_OP, SINGLE_OP, OFFSET) \
|
||||
if (frame_info.TYPE##s.size() > 0) { \
|
||||
for (size_t i = 0; i < frame_info.TYPE##s.size() - 1; i += 2) { \
|
||||
for (std::size_t i = 0; i < frame_info.TYPE##s.size() - 1; i += 2) { \
|
||||
code.PAIR_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, oaknut::REG_TYPE{frame_info.TYPE##s[i + 1]}, SP, (OFFSET) + i * TYPE##_size); \
|
||||
} \
|
||||
if (frame_info.TYPE##s.size() % 2 == 1) { \
|
||||
const size_t i = frame_info.TYPE##s.size() - 1; \
|
||||
const std::size_t i = frame_info.TYPE##s.size() - 1; \
|
||||
code.SINGLE_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, SP, (OFFSET) + i * TYPE##_size); \
|
||||
} \
|
||||
}
|
||||
|
||||
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame_size) {
|
||||
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t frame_size) {
|
||||
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
|
||||
|
||||
code.SUB(SP, SP, frame_info.gprs_size + frame_info.fprs_size);
|
||||
|
|
@ -80,7 +80,7 @@ void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t fram
|
|||
code.SUB(SP, SP, frame_info.frame_size);
|
||||
}
|
||||
|
||||
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame_size) {
|
||||
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t frame_size) {
|
||||
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
|
||||
|
||||
code.ADD(SP, SP, frame_info.frame_size);
|
||||
|
|
|
|||
|
|
@ -9,14 +9,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include <oaknut/oaknut.hpp>
|
||||
|
||||
#include "dynarmic/common/always_false.h"
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
|
|
@ -29,7 +26,7 @@ constexpr oaknut::XReg Xpagetable{24};
|
|||
constexpr oaknut::XReg Xscratch0{16}, Xscratch1{17}, Xscratch2{30};
|
||||
constexpr oaknut::WReg Wscratch0{16}, Wscratch1{17}, Wscratch2{30};
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
constexpr auto Rscratch0() {
|
||||
if constexpr (bitsize == 32) {
|
||||
return Wscratch0;
|
||||
|
|
@ -40,7 +37,7 @@ constexpr auto Rscratch0() {
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
constexpr auto Rscratch1() {
|
||||
if constexpr (bitsize == 32) {
|
||||
return Wscratch1;
|
||||
|
|
@ -70,7 +67,7 @@ constexpr RegisterList ToRegList(oaknut::Reg reg) {
|
|||
constexpr RegisterList ABI_CALLEE_SAVE = 0x0000ff00'7ff80000;
|
||||
constexpr RegisterList ABI_CALLER_SAVE = 0xffffffff'4000ffff;
|
||||
|
||||
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t stack_space);
|
||||
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t stack_space);
|
||||
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t stack_space);
|
||||
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t stack_space);
|
||||
|
||||
} // namespace Dynarmic::Backend::Arm64
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
AddressSpace::AddressSpace(size_t code_cache_size)
|
||||
AddressSpace::AddressSpace(std::size_t code_cache_size)
|
||||
: ir_block{IR::LocationDescriptor{0}}
|
||||
, code_cache_size(code_cache_size)
|
||||
, mem(code_cache_size)
|
||||
|
|
@ -102,8 +102,8 @@ void AddressSpace::ClearCache() {
|
|||
code.set_offset(prelude_info.end_of_prelude);
|
||||
}
|
||||
|
||||
size_t AddressSpace::GetRemainingSize() {
|
||||
return code_cache_size - static_cast<size_t>(code.offset());
|
||||
std::size_t AddressSpace::GetRemainingSize() {
|
||||
return code_cache_size - static_cast<std::size_t>(code.offset());
|
||||
}
|
||||
|
||||
EmittedBlockInfo AddressSpace::Emit(IR::Block block) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <map>
|
||||
#include <optional>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include <oaknut/code_block.hpp>
|
||||
#include <oaknut/oaknut.hpp>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
|
@ -26,7 +26,7 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
class AddressSpace {
|
||||
public:
|
||||
explicit AddressSpace(size_t code_cache_size);
|
||||
explicit AddressSpace(std::size_t code_cache_size);
|
||||
virtual ~AddressSpace();
|
||||
|
||||
virtual void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const = 0;
|
||||
|
|
@ -60,7 +60,7 @@ protected:
|
|||
#endif
|
||||
}
|
||||
|
||||
size_t GetRemainingSize();
|
||||
std::size_t GetRemainingSize();
|
||||
EmittedBlockInfo Emit(IR::Block ir_block);
|
||||
void Link(EmittedBlockInfo& block);
|
||||
void LinkBlockLinks(const CodePtr entry_point, const CodePtr target_ptr, const std::vector<BlockRelocation>& block_relocations_list);
|
||||
|
|
@ -69,7 +69,7 @@ protected:
|
|||
FakeCall FastmemCallback(u64 host_pc);
|
||||
|
||||
IR::Block ir_block;
|
||||
const size_t code_cache_size;
|
||||
const std::size_t code_cache_size;
|
||||
oaknut::CodeBlock mem;
|
||||
oaknut::CodeGenerator code;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <bit>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/function_info.hpp"
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ void EmitIR<IR::Opcode::NZCVFromPackedFlags>(oaknut::CodeGenerator&, EmitContext
|
|||
ctx.reg_alloc.DefineAsExisting(inst, args[0]);
|
||||
}
|
||||
|
||||
static void EmitAddCycles(oaknut::CodeGenerator& code, EmitContext& ctx, size_t cycles_to_add) {
|
||||
static void EmitAddCycles(oaknut::CodeGenerator& code, EmitContext& ctx, std::size_t cycles_to_add) {
|
||||
if (!ctx.conf.enable_cycle_counting) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
#include "dynarmic/backend/arm64/fastmem.h"
|
||||
|
|
@ -103,7 +103,7 @@ struct BlockRelocation {
|
|||
|
||||
struct EmittedBlockInfo {
|
||||
CodePtr entry_point;
|
||||
size_t size;
|
||||
std::size_t size;
|
||||
std::vector<Relocation> relocations;
|
||||
ankerl::unordered_dense::map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations;
|
||||
ankerl::unordered_dense::map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info;
|
||||
|
|
@ -127,9 +127,9 @@ struct EmitConfig {
|
|||
|
||||
// Page table
|
||||
u64 page_table_pointer;
|
||||
size_t page_table_address_space_bits;
|
||||
std::size_t page_table_address_space_bits;
|
||||
int page_table_pointer_mask_bits;
|
||||
size_t page_table_log2_stride;
|
||||
std::size_t page_table_log2_stride;
|
||||
bool silently_mirror_page_table;
|
||||
bool absolute_offset_page_table;
|
||||
u8 detect_misaligned_access_via_page_table;
|
||||
|
|
@ -138,7 +138,7 @@ struct EmitConfig {
|
|||
// Fastmem
|
||||
std::optional<u64> fastmem_pointer;
|
||||
bool recompile_on_fastmem_failure;
|
||||
size_t fastmem_address_space_bits;
|
||||
std::size_t fastmem_address_space_bits;
|
||||
bool silently_mirror_fastmem;
|
||||
|
||||
// Timing
|
||||
|
|
@ -156,9 +156,9 @@ struct EmitConfig {
|
|||
void (*emit_check_memory_abort)(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, oaknut::Label& end);
|
||||
|
||||
// State offsets
|
||||
size_t state_nzcv_offset;
|
||||
size_t state_fpsr_offset;
|
||||
size_t state_exclusive_state_offset;
|
||||
std::size_t state_nzcv_offset;
|
||||
std::size_t state_fpsr_offset;
|
||||
std::size_t state_exclusive_state_offset;
|
||||
|
||||
// A32 specific
|
||||
std::array<std::shared_ptr<A32::Coprocessor>, 16> coprocessors{};
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -45,7 +45,7 @@ static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A3
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocInternalOperation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||
const size_t coproc_num = coproc_info[0];
|
||||
const std::size_t coproc_num = coproc_info[0];
|
||||
const bool two = coproc_info[1] != 0;
|
||||
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
||||
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||
|
|
@ -72,7 +72,7 @@ template<>
|
|||
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||
const size_t coproc_num = coproc_info[0];
|
||||
const std::size_t coproc_num = coproc_info[0];
|
||||
const bool two = coproc_info[1] != 0;
|
||||
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
||||
const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||
|
|
@ -115,7 +115,7 @@ void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(oaknut::CodeGenerator& code, Emit
|
|||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||
const size_t coproc_num = coproc_info[0];
|
||||
const std::size_t coproc_num = coproc_info[0];
|
||||
const bool two = coproc_info[1] != 0;
|
||||
const auto opc = static_cast<unsigned>(coproc_info[2]);
|
||||
const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||
|
|
@ -158,7 +158,7 @@ template<>
|
|||
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||
|
||||
const size_t coproc_num = coproc_info[0];
|
||||
const std::size_t coproc_num = coproc_info[0];
|
||||
const bool two = coproc_info[1] != 0;
|
||||
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
||||
const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||
|
|
@ -199,7 +199,7 @@ void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitCo
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||
const size_t coproc_num = coproc_info[0];
|
||||
const std::size_t coproc_num = coproc_info[0];
|
||||
const bool two = coproc_info[1] != 0;
|
||||
const unsigned opc = coproc_info[2];
|
||||
const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||
|
|
@ -243,7 +243,7 @@ void EmitIR<IR::Opcode::A32CoprocLoadWords>(oaknut::CodeGenerator& code, EmitCon
|
|||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||
const size_t coproc_num = coproc_info[0];
|
||||
const std::size_t coproc_num = coproc_info[0];
|
||||
const bool two = coproc_info[1] != 0;
|
||||
const bool long_transfer = coproc_info[2] != 0;
|
||||
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||
|
|
@ -274,7 +274,7 @@ void EmitIR<IR::Opcode::A32CoprocStoreWords>(oaknut::CodeGenerator& code, EmitCo
|
|||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||
const size_t coproc_num = coproc_info[0];
|
||||
const std::size_t coproc_num = coproc_info[0];
|
||||
const bool two = coproc_info[1] != 0;
|
||||
const bool long_transfer = coproc_info[2] != 0;
|
||||
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -21,7 +21,7 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
using namespace oaknut::util;
|
||||
|
||||
template<size_t bitsize, typename EmitFn>
|
||||
template<std::size_t bitsize, typename EmitFn>
|
||||
static void EmitCRC(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit_fn) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include <fmt/ostream.h>
|
||||
#include <oaknut/oaknut.hpp>
|
||||
|
||||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
||||
#include "dynarmic/backend/arm64/abi.h"
|
||||
#include "dynarmic/backend/arm64/emit_arm64.h"
|
||||
#include "dynarmic/backend/arm64/emit_context.h"
|
||||
|
|
@ -24,7 +23,7 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
using namespace oaknut::util;
|
||||
|
||||
template<size_t bitsize, typename EmitFn>
|
||||
template<std::size_t bitsize, typename EmitFn>
|
||||
static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
@ -35,7 +34,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
|||
emit(Rresult, Roperand);
|
||||
}
|
||||
|
||||
template<size_t bitsize, typename EmitFn>
|
||||
template<std::size_t bitsize, typename EmitFn>
|
||||
static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
@ -868,7 +867,7 @@ void EmitIR<IR::Opcode::RotateRightMasked64>(oaknut::CodeGenerator& code, EmitCo
|
|||
[&](auto& Xresult, auto& Xoperand, auto& Xshift) { code.ROR(Xresult, Xoperand, Xshift); });
|
||||
}
|
||||
|
||||
template<size_t bitsize, typename EmitFn>
|
||||
template<std::size_t bitsize, typename EmitFn>
|
||||
static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
|
||||
static_assert(bitsize == 32 || bitsize == 64);
|
||||
if constexpr (bitsize == 32) {
|
||||
|
|
@ -882,7 +881,7 @@ static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn)
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize, bool sub>
|
||||
template<std::size_t bitsize, bool sub>
|
||||
static void EmitAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
||||
|
|
@ -1102,7 +1101,7 @@ void EmitIR<IR::Opcode::SignedDiv64>(oaknut::CodeGenerator& code, EmitContext& c
|
|||
[&](auto& Xresult, auto& Xa, auto& Xb) { code.SDIV(Xresult, Xa, Xb); });
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
static bool IsValidBitImm(u64 imm) {
|
||||
static_assert(bitsize == 32 || bitsize == 64);
|
||||
if constexpr (bitsize == 32) {
|
||||
|
|
@ -1112,7 +1111,7 @@ static bool IsValidBitImm(u64 imm) {
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize, typename EmitFn>
|
||||
template<std::size_t bitsize, typename EmitFn>
|
||||
static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
|
||||
static_assert(bitsize == 32 || bitsize == 64);
|
||||
if constexpr (bitsize == 32) {
|
||||
|
|
@ -1126,7 +1125,7 @@ static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize, typename EmitFn1, typename EmitFn2 = std::nullptr_t>
|
||||
template<std::size_t bitsize, typename EmitFn1, typename EmitFn2 = std::nullptr_t>
|
||||
static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn1 emit_without_flags, EmitFn2 emit_with_flags = nullptr) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Rresult = ctx.reg_alloc.WriteReg<bitsize>(inst);
|
||||
|
|
@ -1168,7 +1167,7 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
using namespace oaknut::util;
|
||||
|
||||
template<size_t bitsize, typename EmitFn>
|
||||
template<std::size_t bitsize, typename EmitFn>
|
||||
static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
||||
|
|
@ -34,7 +34,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
|||
emit(Vresult, Voperand);
|
||||
}
|
||||
|
||||
template<size_t bitsize, typename EmitFn>
|
||||
template<std::size_t bitsize, typename EmitFn>
|
||||
static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
||||
|
|
@ -46,7 +46,7 @@ static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
|
|||
emit(Vresult, Va, Vb);
|
||||
}
|
||||
|
||||
template<size_t bitsize, typename EmitFn>
|
||||
template<std::size_t bitsize, typename EmitFn>
|
||||
static void EmitFourOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
||||
|
|
@ -59,7 +59,7 @@ static void EmitFourOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
|||
emit(Vresult, Va, Vb, Vc);
|
||||
}
|
||||
|
||||
template<size_t bitsize_from, size_t bitsize_to, typename EmitFn>
|
||||
template<std::size_t bitsize_from, std::size_t bitsize_to, typename EmitFn>
|
||||
static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Vto = ctx.reg_alloc.WriteVec<bitsize_to>(inst);
|
||||
|
|
@ -73,12 +73,12 @@ static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
|
|||
emit(Vto, Vfrom);
|
||||
}
|
||||
|
||||
template<size_t bitsize_from, size_t bitsize_to, bool is_signed>
|
||||
template<std::size_t bitsize_from, std::size_t bitsize_to, bool is_signed>
|
||||
static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Rto = ctx.reg_alloc.WriteReg<std::max<size_t>(bitsize_to, 32)>(inst);
|
||||
auto Rto = ctx.reg_alloc.WriteReg<std::max<std::size_t>(bitsize_to, 32)>(inst);
|
||||
auto Vfrom = ctx.reg_alloc.ReadVec<bitsize_from>(args[0]);
|
||||
const size_t fbits = args[1].GetImmediateU8();
|
||||
const std::size_t fbits = args[1].GetImmediateU8();
|
||||
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
RegAlloc::Realize(Rto, Vfrom);
|
||||
ctx.fpsr.Load();
|
||||
|
|
@ -158,12 +158,12 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize_from, size_t bitsize_to, typename EmitFn>
|
||||
template<std::size_t bitsize_from, std::size_t bitsize_to, typename EmitFn>
|
||||
static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Vto = ctx.reg_alloc.WriteVec<bitsize_to>(inst);
|
||||
auto Rfrom = ctx.reg_alloc.ReadReg<std::max<size_t>(bitsize_from, 32)>(args[0]);
|
||||
const size_t fbits = args[1].GetImmediateU8();
|
||||
auto Rfrom = ctx.reg_alloc.ReadReg<std::max<std::size_t>(bitsize_from, 32)>(args[0]);
|
||||
const std::size_t fbits = args[1].GetImmediateU8();
|
||||
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
RegAlloc::Realize(Vto, Rfrom);
|
||||
ctx.fpsr.Load();
|
||||
|
|
@ -212,7 +212,7 @@ void EmitIR<IR::Opcode::FPAdd64>(oaknut::CodeGenerator& code, EmitContext& ctx,
|
|||
EmitThreeOp<64>(code, ctx, inst, [&](auto& Dresult, auto& Da, auto& Db) { code.FADD(Dresult, Da, Db); });
|
||||
}
|
||||
|
||||
template<size_t size>
|
||||
template<std::size_t size>
|
||||
void EmitCompare(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto flags = ctx.reg_alloc.WriteFlags(inst);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
|
||||
#include <bit>
|
||||
#include <oaknut/oaknut.hpp>
|
||||
|
|
@ -23,7 +24,6 @@
|
|||
#include "dynarmic/ir/acc_type.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
#include "dynarmic/ir/microinstruction.h"
|
||||
#include "dynarmic/ir/opcodes.h"
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ bool IsOrdered(IR::AccType acctype) {
|
|||
return acctype == IR::AccType::ORDERED || acctype == IR::AccType::ORDEREDRW || acctype == IR::AccType::LIMITEDORDERED;
|
||||
}
|
||||
|
||||
LinkTarget ReadMemoryLinkTarget(size_t bitsize) {
|
||||
LinkTarget ReadMemoryLinkTarget(std::size_t bitsize) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
return LinkTarget::ReadMemory8;
|
||||
|
|
@ -51,7 +51,7 @@ LinkTarget ReadMemoryLinkTarget(size_t bitsize) {
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
LinkTarget WriteMemoryLinkTarget(size_t bitsize) {
|
||||
LinkTarget WriteMemoryLinkTarget(std::size_t bitsize) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
return LinkTarget::WriteMemory8;
|
||||
|
|
@ -67,7 +67,7 @@ LinkTarget WriteMemoryLinkTarget(size_t bitsize) {
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
LinkTarget WrappedReadMemoryLinkTarget(size_t bitsize) {
|
||||
LinkTarget WrappedReadMemoryLinkTarget(std::size_t bitsize) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
return LinkTarget::WrappedReadMemory8;
|
||||
|
|
@ -83,7 +83,7 @@ LinkTarget WrappedReadMemoryLinkTarget(size_t bitsize) {
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
LinkTarget WrappedWriteMemoryLinkTarget(size_t bitsize) {
|
||||
LinkTarget WrappedWriteMemoryLinkTarget(std::size_t bitsize) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
return LinkTarget::WrappedWriteMemory8;
|
||||
|
|
@ -99,7 +99,7 @@ LinkTarget WrappedWriteMemoryLinkTarget(size_t bitsize) {
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) {
|
||||
LinkTarget ExclusiveReadMemoryLinkTarget(std::size_t bitsize) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
return LinkTarget::ExclusiveReadMemory8;
|
||||
|
|
@ -115,7 +115,7 @@ LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) {
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
LinkTarget ExclusiveWriteMemoryLinkTarget(size_t bitsize) {
|
||||
LinkTarget ExclusiveWriteMemoryLinkTarget(std::size_t bitsize) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
return LinkTarget::ExclusiveWriteMemory8;
|
||||
|
|
@ -131,7 +131,7 @@ LinkTarget ExclusiveWriteMemoryLinkTarget(size_t bitsize) {
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void CallbackOnlyEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||
|
|
@ -150,7 +150,7 @@ void CallbackOnlyEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void CallbackOnlyEmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||
|
|
@ -171,7 +171,7 @@ void CallbackOnlyEmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContex
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void CallbackOnlyEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
||||
|
|
@ -186,7 +186,7 @@ void CallbackOnlyEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx,
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void CallbackOnlyEmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
||||
|
|
@ -209,13 +209,13 @@ void CallbackOnlyEmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitConte
|
|||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||
}
|
||||
|
||||
constexpr size_t page_table_const_bits = 12;
|
||||
constexpr size_t page_table_const_size = 1 << page_table_const_bits;
|
||||
constexpr size_t page_table_const_mask = (1 << page_table_const_bits) - 1;
|
||||
constexpr std::size_t page_table_const_bits = 12;
|
||||
constexpr std::size_t page_table_const_size = 1 << page_table_const_bits;
|
||||
constexpr std::size_t page_table_const_mask = (1 << page_table_const_bits) - 1;
|
||||
|
||||
// This function may use Xscratch0 as a scratch register
|
||||
// Trashes NZCV
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitDetectMisalignedVAddr(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
||||
static_assert(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64 || bitsize == 128);
|
||||
|
||||
|
|
@ -253,10 +253,10 @@ void EmitDetectMisalignedVAddr(oaknut::CodeGenerator& code, EmitContext& ctx, oa
|
|||
// May use Xscratch1 as scratch register
|
||||
// Address to read/write = [ret0 + ret1], ret0 is always Xscratch0 and ret1 is either Xaddr or Xscratch1
|
||||
// Trashes NZCV
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
||||
const size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_table_const_bits;
|
||||
const size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
|
||||
const std::size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_table_const_bits;
|
||||
const std::size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
|
||||
|
||||
EmitDetectMisalignedVAddr<bitsize>(code, ctx, Xaddr, fallback);
|
||||
|
||||
|
|
@ -408,7 +408,7 @@ CodePtr EmitMemoryStr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
|
|||
return fastmem_location;
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void InlinePageTableEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
||||
|
|
@ -448,7 +448,7 @@ void InlinePageTableEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx
|
|||
code.l(*end);
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void InlinePageTableEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
||||
|
|
@ -511,7 +511,7 @@ inline bool ShouldExt32(EmitContext& ctx) {
|
|||
// May use Xscratch0 as scratch register
|
||||
// Address to read/write = [ret0 + ret1], ret0 is always Xfastmem and ret1 is either Xaddr or Xscratch0
|
||||
// Trashes NZCV
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
std::pair<oaknut::XReg, oaknut::XReg> FastmemEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
||||
if (ctx.conf.fastmem_address_space_bits == 64 || ShouldExt32(ctx)) {
|
||||
return std::make_pair(Xfastmem, Xaddr);
|
||||
|
|
@ -527,7 +527,7 @@ std::pair<oaknut::XReg, oaknut::XReg> FastmemEmitVAddrLookup(oaknut::CodeGenerat
|
|||
return std::make_pair(Xfastmem, Xaddr);
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void FastmemEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, DoNotFastmemMarker marker) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
||||
|
|
@ -577,7 +577,7 @@ void FastmemEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::In
|
|||
code.l(*end);
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void FastmemEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, DoNotFastmemMarker marker) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
||||
|
|
@ -633,7 +633,7 @@ void FastmemEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::I
|
|||
|
||||
} // namespace
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
||||
FastmemEmitReadMemory<bitsize>(code, ctx, inst, *marker);
|
||||
|
|
@ -644,12 +644,12 @@ void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* ins
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
CallbackOnlyEmitExclusiveReadMemory<bitsize>(code, ctx, inst);
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
||||
FastmemEmitWriteMemory<bitsize>(code, ctx, inst, *marker);
|
||||
|
|
@ -660,7 +660,7 @@ void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* in
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
CallbackOnlyEmitExclusiveWriteMemory<bitsize>(code, ctx, inst);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cstddef>
|
||||
|
||||
namespace oaknut {
|
||||
struct CodeGenerator;
|
||||
|
|
@ -23,13 +23,13 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
struct EmitContext;
|
||||
enum class LinkTarget;
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||
|
||||
} // namespace Dynarmic::Backend::Arm64
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -66,7 +66,7 @@ void EmitIR<IR::Opcode::SignedSaturation>(oaknut::CodeGenerator& code, EmitConte
|
|||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const size_t N = args[1].GetImmediateU8();
|
||||
const std::size_t N = args[1].GetImmediateU8();
|
||||
ASSERT(N >= 1 && N <= 32);
|
||||
|
||||
if (N == 32) {
|
||||
|
|
@ -112,7 +112,7 @@ void EmitIR<IR::Opcode::UnsignedSaturation>(oaknut::CodeGenerator& code, EmitCon
|
|||
RegAlloc::Realize(Wresult, Woperand);
|
||||
ctx.reg_alloc.SpillFlags();
|
||||
|
||||
const size_t N = args[1].GetImmediateU8();
|
||||
const std::size_t N = args[1].GetImmediateU8();
|
||||
ASSERT(N <= 31);
|
||||
const u32 saturated_value = (1u << N) - 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
|||
emit(Qresult, Qoperand);
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||
if constexpr (size == 8) {
|
||||
|
|
@ -50,7 +50,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitTwoOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitTwoOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) {
|
||||
ctx.fpsr.Load();
|
||||
|
|
@ -58,7 +58,7 @@ static void EmitTwoOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext&
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||
if constexpr (size == 8) {
|
||||
|
|
@ -73,7 +73,7 @@ static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||
if constexpr (size == 16) {
|
||||
|
|
@ -88,7 +88,7 @@ static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ct
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitTwoOpArrangedSaturatedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitTwoOpArrangedNarrow<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) {
|
||||
ctx.fpsr.Load();
|
||||
|
|
@ -96,7 +96,7 @@ static void EmitTwoOpArrangedSaturatedNarrow(oaknut::CodeGenerator& code, EmitCo
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||
if constexpr (size == 8) {
|
||||
|
|
@ -111,7 +111,7 @@ static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext&
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitTwoOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||
if constexpr (size == 8) {
|
||||
|
|
@ -137,7 +137,7 @@ static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
|
|||
emit(Qresult, Qa, Qb);
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||
if constexpr (size == 8) {
|
||||
|
|
@ -154,7 +154,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitThreeOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitThreeOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) {
|
||||
ctx.fpsr.Load();
|
||||
|
|
@ -162,7 +162,7 @@ static void EmitThreeOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContex
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||
if constexpr (size == 8) {
|
||||
|
|
@ -179,7 +179,7 @@ static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& c
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitThreeOpArrangedSaturatedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitThreeOpArrangedWiden<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) {
|
||||
ctx.fpsr.Load();
|
||||
|
|
@ -187,7 +187,7 @@ static void EmitThreeOpArrangedSaturatedWiden(oaknut::CodeGenerator& code, EmitC
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||
if constexpr (size == 8) {
|
||||
|
|
@ -202,7 +202,7 @@ static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& c
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qaccumulator = ctx.reg_alloc.ReadWriteQ(args[1], inst); // NB: Swapped
|
||||
|
|
@ -223,7 +223,7 @@ static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qresult = ctx.reg_alloc.WriteQ(inst);
|
||||
|
|
@ -244,7 +244,7 @@ static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* ins
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitImmShiftSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitImmShift<size>(code, ctx, inst, [&](auto Vresult, auto Voperand, u8 shift_amount) {
|
||||
ctx.fpsr.Load();
|
||||
|
|
@ -252,7 +252,7 @@ static void EmitImmShiftSaturated(oaknut::CodeGenerator& code, EmitContext& ctx,
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Vresult = ctx.reg_alloc.WriteVec<size>(inst);
|
||||
|
|
@ -272,13 +272,13 @@ static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
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());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
auto Rresult = ctx.reg_alloc.WriteReg<std::max<size_t>(32, size)>(inst);
|
||||
auto Rresult = ctx.reg_alloc.WriteReg<std::max<std::size_t>(32, size)>(inst);
|
||||
auto Qvalue = ctx.reg_alloc.ReadQ(args[0]);
|
||||
RegAlloc::Realize(Rresult, Qvalue);
|
||||
|
||||
|
|
@ -307,14 +307,14 @@ void EmitIR<IR::Opcode::VectorGetElement64>(oaknut::CodeGenerator& code, EmitCon
|
|||
EmitGetElement<64>(code, ctx, inst, [&](auto& Xresult, auto& Qvalue, u8 index) { code.UMOV(Xresult, Qvalue->Delem()[index]); });
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
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());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
auto Qvector = ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
||||
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<size_t>(32, size)>(args[2]);
|
||||
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<std::size_t>(32, size)>(args[2]);
|
||||
RegAlloc::Realize(Qvector, Rvalue);
|
||||
|
||||
// TODO: fpr source
|
||||
|
|
@ -432,11 +432,11 @@ void EmitIR<IR::Opcode::VectorArithmeticVShift64>(oaknut::CodeGenerator& code, E
|
|||
EmitThreeOpArranged<64>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) { code.SSHL(Vresult, Va, Vb); });
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitBroadcast(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qvector = ctx.reg_alloc.WriteQ(inst);
|
||||
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<size_t>(32, size)>(args[0]);
|
||||
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<std::size_t>(32, size)>(args[0]);
|
||||
RegAlloc::Realize(Qvector, Rvalue);
|
||||
|
||||
// TODO: fpr source
|
||||
|
|
@ -479,7 +479,7 @@ void EmitIR<IR::Opcode::VectorBroadcast64>(oaknut::CodeGenerator& code, EmitCont
|
|||
EmitBroadcast<64>(code, ctx, inst, [&](auto& Qvector, auto& Xvalue) { code.DUP(Qvector->D2(), Xvalue); });
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitBroadcastElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qvector = ctx.reg_alloc.WriteQ(inst);
|
||||
|
|
@ -1612,17 +1612,17 @@ void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitCo
|
|||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
||||
|
||||
const size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
|
||||
const std::size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
|
||||
const bool is_defaults_zero = inst->GetArg(0).IsZero();
|
||||
|
||||
auto Dresult = is_defaults_zero ? ctx.reg_alloc.WriteD(inst) : ctx.reg_alloc.ReadWriteD(args[0], inst);
|
||||
auto Dindices = ctx.reg_alloc.ReadD(args[2]);
|
||||
std::vector<RAReg<oaknut::DReg>> Dtable;
|
||||
for (size_t i = 0; i < table_size; i++) {
|
||||
for (std::size_t i = 0; i < table_size; i++) {
|
||||
Dtable.emplace_back(ctx.reg_alloc.ReadD(table[i]));
|
||||
}
|
||||
RegAlloc::Realize(Dresult, Dindices);
|
||||
for (size_t i = 0; i < table_size; i++) {
|
||||
for (std::size_t i = 0; i < table_size; i++) {
|
||||
RegAlloc::Realize(Dtable[i]);
|
||||
}
|
||||
|
||||
|
|
@ -1679,17 +1679,17 @@ void EmitIR<IR::Opcode::VectorTableLookup128>(oaknut::CodeGenerator& code, EmitC
|
|||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
||||
|
||||
const size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
|
||||
const std::size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
|
||||
const bool is_defaults_zero = inst->GetArg(0).IsZero();
|
||||
|
||||
auto Qresult = is_defaults_zero ? ctx.reg_alloc.WriteQ(inst) : ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
||||
auto Qindices = ctx.reg_alloc.ReadQ(args[2]);
|
||||
std::vector<RAReg<oaknut::QReg>> Qtable;
|
||||
for (size_t i = 0; i < table_size; i++) {
|
||||
for (std::size_t i = 0; i < table_size; i++) {
|
||||
Qtable.emplace_back(ctx.reg_alloc.ReadQ(table[i]));
|
||||
}
|
||||
RegAlloc::Realize(Qresult, Qindices);
|
||||
for (size_t i = 0; i < table_size; i++) {
|
||||
for (std::size_t i = 0; i < table_size; i++) {
|
||||
RegAlloc::Realize(Qtable[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
using namespace oaknut::util;
|
||||
using A64FullVectorWidth = std::integral_constant<size_t, 128>;
|
||||
using A64FullVectorWidth = std::integral_constant<std::size_t, 128>;
|
||||
|
||||
// Array alias that always sizes itself according to the given type T
|
||||
// relative to the size of a vector register. e.g. T = u32 would result
|
||||
|
|
@ -65,7 +65,7 @@ static void EmitTwoOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
|
|||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa); });
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qa) {
|
||||
if constexpr (size == 16) {
|
||||
|
|
@ -93,7 +93,7 @@ static void EmitThreeOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
|
|||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa, Qb); });
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||
if constexpr (size == 16) {
|
||||
|
|
@ -108,7 +108,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qresult = ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
||||
|
|
@ -131,7 +131,7 @@ static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* ins
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qto = ctx.reg_alloc.WriteQ(inst);
|
||||
|
|
@ -153,12 +153,12 @@ static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Ins
|
|||
});
|
||||
}
|
||||
|
||||
template<size_t fsize, bool is_signed>
|
||||
template<std::size_t fsize, bool is_signed>
|
||||
void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qto = ctx.reg_alloc.WriteQ(inst);
|
||||
auto Qfrom = ctx.reg_alloc.ReadQ(args[0]);
|
||||
const size_t fbits = args[1].GetImmediateU8();
|
||||
const std::size_t fbits = args[1].GetImmediateU8();
|
||||
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
const bool fpcr_controlled = inst->GetArg(3).GetU1();
|
||||
RegAlloc::Realize(Qto, Qfrom);
|
||||
|
|
@ -272,7 +272,7 @@ static void EmitTwoOpFallbackWithoutRegAlloc(oaknut::CodeGenerator& code, EmitCo
|
|||
ABI_PopRegisters(code, ABI_CALLER_SAVE & ~(1ull << Qresult.index()), stack_size);
|
||||
}
|
||||
|
||||
template<size_t fpcr_controlled_arg_index = 1, typename Lambda>
|
||||
template<std::size_t fpcr_controlled_arg_index = 1, typename Lambda>
|
||||
static void EmitTwoOpFallback(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qarg1 = ctx.reg_alloc.ReadQ(args[0]);
|
||||
|
|
@ -562,7 +562,7 @@ void EmitIR<IR::Opcode::FPVectorRecipStepFused64>(oaknut::CodeGenerator& code, E
|
|||
/// TODO: we have space for a 5th parameter? :)
|
||||
template<typename FPT, FP::RoundingMode rounding_mode, bool exact>
|
||||
static void EmitIRVectorRoundInt16Thunk(VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < output.size(); ++i)
|
||||
for (std::size_t i = 0; i < output.size(); ++i)
|
||||
output[i] = FPT(FP::FPRoundInt<FPT>(input[i], fpcr, rounding_mode, exact, fpsr));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
using namespace oaknut::util;
|
||||
|
||||
template<size_t size, typename EmitFn>
|
||||
template<std::size_t size, typename EmitFn>
|
||||
static void Emit(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Qresult = ctx.reg_alloc.WriteQ(inst);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ void ExclusiveMonitor::Unlock() {
|
|||
lock.Unlock();
|
||||
}
|
||||
|
||||
bool ExclusiveMonitor::CheckAndClear(size_t processor_id, VAddr address) {
|
||||
bool ExclusiveMonitor::CheckAndClear(std::size_t processor_id, VAddr address) {
|
||||
const VAddr masked_address = address & RESERVATION_GRANULE_MASK;
|
||||
|
||||
Lock();
|
||||
|
|
@ -52,7 +52,7 @@ void ExclusiveMonitor::Clear() {
|
|||
Unlock();
|
||||
}
|
||||
|
||||
void ExclusiveMonitor::ClearProcessor(size_t processor_id) {
|
||||
void ExclusiveMonitor::ClearProcessor(std::size_t processor_id) {
|
||||
Lock();
|
||||
exclusive_addresses[processor_id] = INVALID_EXCLUSIVE_ADDRESS;
|
||||
Unlock();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/backend/exception_handler.h"
|
||||
#include "dynarmic/ir/location_descriptor.h"
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
||||
|
||||
constexpr size_t xmrx(size_t x) noexcept {
|
||||
constexpr std::size_t xmrx(std::size_t x) noexcept {
|
||||
x ^= x >> 32;
|
||||
x *= 0xff51afd7ed558ccd;
|
||||
x ^= mcl::bit::rotate_right(x, 47) ^ mcl::bit::rotate_right(x, 23);
|
||||
|
|
@ -29,7 +29,7 @@ constexpr size_t xmrx(size_t x) noexcept {
|
|||
}
|
||||
|
||||
struct DoNotFastmemMarkerHash {
|
||||
[[nodiscard]] size_t operator()(const DoNotFastmemMarker& value) const noexcept {
|
||||
[[nodiscard]] std::size_t operator()(const DoNotFastmemMarker& value) const noexcept {
|
||||
return xmrx(std::get<0>(value).Value() ^ u64(std::get<1>(value)));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -13,7 +16,7 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
using namespace oaknut::util;
|
||||
|
||||
FpsrManager::FpsrManager(oaknut::CodeGenerator& code, size_t state_fpsr_offset)
|
||||
FpsrManager::FpsrManager(oaknut::CodeGenerator& code, std::size_t state_fpsr_offset)
|
||||
: code{code}, state_fpsr_offset{state_fpsr_offset} {}
|
||||
|
||||
void FpsrManager::Spill() {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cstddef>
|
||||
|
||||
namespace oaknut {
|
||||
struct CodeGenerator;
|
||||
|
|
@ -19,7 +19,7 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
class FpsrManager {
|
||||
public:
|
||||
explicit FpsrManager(oaknut::CodeGenerator& code, size_t state_fpsr_offset);
|
||||
explicit FpsrManager(oaknut::CodeGenerator& code, std::size_t state_fpsr_offset);
|
||||
|
||||
void Spill();
|
||||
void Load();
|
||||
|
|
@ -29,7 +29,7 @@ public:
|
|||
|
||||
private:
|
||||
oaknut::CodeGenerator& code;
|
||||
size_t state_fpsr_offset;
|
||||
std::size_t state_fpsr_offset;
|
||||
bool fpsr_loaded = false;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
#include <array>
|
||||
#include <iterator>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include <bit>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/arm64/abi.h"
|
||||
#include "dynarmic/backend/arm64/emit_context.h"
|
||||
|
|
@ -27,8 +27,8 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
using namespace oaknut::util;
|
||||
|
||||
constexpr size_t spill_offset = offsetof(StackLayout, spill);
|
||||
constexpr size_t spill_slot_size = sizeof(decltype(StackLayout::spill)::value_type);
|
||||
constexpr std::size_t spill_offset = offsetof(StackLayout, spill);
|
||||
constexpr std::size_t spill_slot_size = sizeof(decltype(StackLayout::spill)::value_type);
|
||||
|
||||
static bool IsValuelessType(IR::Type type) {
|
||||
switch (type) {
|
||||
|
|
@ -131,7 +131,7 @@ void HostLocInfo::UpdateUses() {
|
|||
|
||||
RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
||||
ArgumentInfo ret = {Argument{}, Argument{}, Argument{}, Argument{}};
|
||||
for (size_t i = 0; i < inst->NumArgs(); i++) {
|
||||
for (std::size_t i = 0; i < inst->NumArgs(); i++) {
|
||||
const IR::Value arg = inst->GetArg(i);
|
||||
ret[i].value = arg;
|
||||
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
|
||||
|
|
@ -245,7 +245,7 @@ void RegAlloc::AssertNoMoreUses() const {
|
|||
void RegAlloc::EmitVerboseDebuggingOutput() {
|
||||
code.MOV(X19, std::bit_cast<u64>(&PrintVerboseDebuggingOutputLine)); // Non-volatile register
|
||||
|
||||
const auto do_location = [&](HostLocInfo& info, HostLocType type, size_t index) {
|
||||
const auto do_location = [&](HostLocInfo& info, HostLocType type, std::size_t index) {
|
||||
using namespace oaknut::util;
|
||||
for (const IR::Inst* value : info.values) {
|
||||
code.MOV(X0, SP);
|
||||
|
|
@ -257,14 +257,14 @@ void RegAlloc::EmitVerboseDebuggingOutput() {
|
|||
}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < gprs.size(); i++) {
|
||||
for (std::size_t i = 0; i < gprs.size(); i++) {
|
||||
do_location(gprs[i], HostLocType::X, i);
|
||||
}
|
||||
for (size_t i = 0; i < fprs.size(); i++) {
|
||||
for (std::size_t i = 0; i < fprs.size(); i++) {
|
||||
do_location(fprs[i], HostLocType::Q, i);
|
||||
}
|
||||
do_location(flags, HostLocType::Nzcv, 0);
|
||||
for (size_t i = 0; i < spills.size(); i++) {
|
||||
for (std::size_t i = 0; i < spills.size(); i++) {
|
||||
do_location(spills[i], HostLocType::Spill, i);
|
||||
}
|
||||
}
|
||||
|
|
@ -576,13 +576,13 @@ std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
|
|||
HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) {
|
||||
switch (host_loc.kind) {
|
||||
case HostLoc::Kind::Gpr:
|
||||
return gprs[static_cast<size_t>(host_loc.index)];
|
||||
return gprs[static_cast<std::size_t>(host_loc.index)];
|
||||
case HostLoc::Kind::Fpr:
|
||||
return fprs[static_cast<size_t>(host_loc.index)];
|
||||
return fprs[static_cast<std::size_t>(host_loc.index)];
|
||||
case HostLoc::Kind::Flags:
|
||||
return flags;
|
||||
case HostLoc::Kind::Spill:
|
||||
return spills[static_cast<size_t>(host_loc.index)];
|
||||
return spills[static_cast<std::size_t>(host_loc.index)];
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
||||
#include <oaknut/oaknut.hpp>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
|
@ -141,11 +141,11 @@ private:
|
|||
|
||||
struct HostLocInfo final {
|
||||
std::vector<const IR::Inst*> values;
|
||||
size_t locked = 0;
|
||||
std::size_t locked = 0;
|
||||
bool realized = false;
|
||||
size_t uses_this_inst = 0;
|
||||
size_t accumulated_uses = 0;
|
||||
size_t expected_uses = 0;
|
||||
std::size_t uses_this_inst = 0;
|
||||
std::size_t accumulated_uses = 0;
|
||||
std::size_t expected_uses = 0;
|
||||
|
||||
bool Contains(const IR::Inst*) const;
|
||||
void SetupScratchLocation();
|
||||
|
|
@ -179,7 +179,7 @@ public:
|
|||
auto ReadH(Argument& arg) { return RAReg<oaknut::HReg>{*this, RWType::Read, arg.value, nullptr}; }
|
||||
auto ReadB(Argument& arg) { return RAReg<oaknut::BReg>{*this, RWType::Read, arg.value, nullptr}; }
|
||||
|
||||
template<size_t size>
|
||||
template<std::size_t size>
|
||||
auto ReadReg(Argument& arg) {
|
||||
if constexpr (size == 64) {
|
||||
return ReadX(arg);
|
||||
|
|
@ -190,7 +190,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t size>
|
||||
template<std::size_t size>
|
||||
auto ReadVec(Argument& arg) {
|
||||
if constexpr (size == 128) {
|
||||
return ReadQ(arg);
|
||||
|
|
@ -218,7 +218,7 @@ public:
|
|||
|
||||
auto WriteFlags(IR::Inst* inst) { return RAReg<FlagsTag>{*this, RWType::Write, {}, inst}; }
|
||||
|
||||
template<size_t size>
|
||||
template<std::size_t size>
|
||||
auto WriteReg(IR::Inst* inst) {
|
||||
if constexpr (size == 64) {
|
||||
return WriteX(inst);
|
||||
|
|
@ -229,7 +229,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t size>
|
||||
template<std::size_t size>
|
||||
auto WriteVec(IR::Inst* inst) {
|
||||
if constexpr (size == 128) {
|
||||
return WriteQ(inst);
|
||||
|
|
@ -255,7 +255,7 @@ public:
|
|||
auto ReadWriteH(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::HReg>{*this, RWType::ReadWrite, arg.value, inst}; }
|
||||
auto ReadWriteB(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::BReg>{*this, RWType::ReadWrite, arg.value, inst}; }
|
||||
|
||||
template<size_t size>
|
||||
template<std::size_t size>
|
||||
auto ReadWriteReg(Argument& arg, const IR::Inst* inst) {
|
||||
if constexpr (size == 64) {
|
||||
return ReadWriteX(arg, inst);
|
||||
|
|
@ -266,7 +266,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<size_t size>
|
||||
template<std::size_t size>
|
||||
auto ReadWriteVec(Argument& arg, const IR::Inst* inst) {
|
||||
if constexpr (size == 128) {
|
||||
return ReadWriteQ(arg, inst);
|
||||
|
|
@ -335,7 +335,7 @@ private:
|
|||
HostLocInfo flags;
|
||||
std::array<HostLocInfo, SpillCount> spills;
|
||||
|
||||
mutable size_t alloc_candidate_index = 0;
|
||||
mutable std::size_t alloc_candidate_index = 0;
|
||||
ankerl::unordered_dense::set<const IR::Inst*> defined_insts;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
|
|
@ -19,14 +19,14 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
# pragma warning(disable : 4324) // Structure was padded due to alignment specifier
|
||||
#endif
|
||||
|
||||
constexpr size_t SpillCount = 64;
|
||||
constexpr std::size_t SpillCount = 64;
|
||||
|
||||
struct alignas(16) RSBEntry {
|
||||
u64 target;
|
||||
u64 code_ptr;
|
||||
};
|
||||
|
||||
constexpr size_t RSBCount = 8;
|
||||
constexpr std::size_t RSBCount = 8;
|
||||
constexpr u64 RSBIndexMask = (RSBCount - 1) * sizeof(RSBEntry);
|
||||
|
||||
struct alignas(16) StackLayout {
|
||||
|
|
|
|||
|
|
@ -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) 2023 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -51,7 +54,7 @@ void EmitVerboseDebuggingOutput(oaknut::CodeGenerator& code, EmitContext& ctx) {
|
|||
code.ADD(SP, SP, sizeof(RegisterData));
|
||||
}
|
||||
|
||||
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, size_t reg_index, size_t inst_index, IR::Type inst_type) {
|
||||
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, std::size_t reg_index, std::size_t inst_index, IR::Type inst_type) {
|
||||
fmt::print("dynarmic debug: %{:05} = ", inst_index);
|
||||
|
||||
Vector value = [&]() -> Vector {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/arm64/stack_layout.h"
|
||||
|
||||
|
|
@ -54,6 +54,6 @@ struct alignas(16) RegisterData {
|
|||
#endif
|
||||
|
||||
void EmitVerboseDebuggingOutput(oaknut::CodeGenerator& code, EmitContext& ctx);
|
||||
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, size_t reg_index, size_t inst_index, IR::Type inst_type);
|
||||
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, std::size_t reg_index, std::size_t inst_index, IR::Type inst_type);
|
||||
|
||||
} // namespace Dynarmic::Backend::Arm64
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <boost/icl/interval_map.hpp>
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
namespace Dynarmic::Backend {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
|
@ -43,6 +43,7 @@ struct FakeCall {
|
|||
};
|
||||
#elif defined(ARCHITECTURE_riscv64)
|
||||
struct FakeCall {
|
||||
u64 call_sepc;
|
||||
};
|
||||
#else
|
||||
# error "Invalid architecture"
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
#include <bit>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/exception_handler.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
|
@ -16,9 +17,9 @@
|
|||
#include <fmt/format.h>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include "dynarmic/backend/exception_handler.h"
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/common/context.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
# include "dynarmic/backend/x64/block_of_code.h"
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
|
|
@ -140,7 +141,15 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
|
|||
}
|
||||
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
|
||||
#elif defined(ARCHITECTURE_riscv64)
|
||||
UNREACHABLE();
|
||||
{
|
||||
std::shared_lock guard(sig_handler->code_block_infos_mutex);
|
||||
if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_SEPC); iter != sig_handler->code_block_infos.end()) {
|
||||
FakeCall fc = iter->second.cb(CTX_SEPC);
|
||||
CTX_SEPC = fc.call_sepc;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_SEPC);
|
||||
#else
|
||||
# error "Invalid architecture"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
|
||||
#include "dynarmic/backend/riscv64/abi.h"
|
||||
#include "dynarmic/backend/riscv64/emit_riscv64.h"
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
||||
#include "dynarmic/backend/riscv64/a32_core.h"
|
||||
|
|
@ -42,7 +42,7 @@ struct Jit::Impl final {
|
|||
HaltReason Step() {
|
||||
ASSERT(!jit_interface->is_executing);
|
||||
jit_interface->is_executing = true;
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
RequestCacheInvalidation();
|
||||
jit_interface->is_executing = false;
|
||||
return HaltReason{};
|
||||
|
|
@ -108,6 +108,10 @@ struct Jit::Impl final {
|
|||
current_state.exclusive_state = false;
|
||||
}
|
||||
|
||||
std::string Disassemble() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
void RequestCacheInvalidation() {
|
||||
// UNREACHABLE();
|
||||
|
|
@ -198,4 +202,8 @@ void Jit::ClearExclusiveState() {
|
|||
impl->ClearExclusiveState();
|
||||
}
|
||||
|
||||
std::string Jit::Disassemble() const {
|
||||
return impl->Disassemble();
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include "dynarmic/backend/riscv64/a32_jitstate.h"
|
||||
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::Backend::RV64 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||
#include "dynarmic/ir/location_descriptor.h"
|
||||
|
|
|
|||
295
src/dynarmic/src/dynarmic/backend/riscv64/a64_interface.cpp
Normal file
295
src/dynarmic/src/dynarmic/backend/riscv64/a64_interface.cpp
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
#include "dynarmic/backend/riscv64/a32_core.h"
|
||||
#include "dynarmic/common/atomic.h"
|
||||
#include "dynarmic/ir/opt_passes.h"
|
||||
#include "dynarmic/interface/A64/a64.h"
|
||||
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
using namespace Dynarmic::Backend::RV64;
|
||||
using CodePtr = std::uint32_t*;
|
||||
|
||||
struct Jit::Impl final {
|
||||
Impl(Jit* jit_interface, A64::UserConfig conf)
|
||||
: conf(conf)
|
||||
//, current_address_space(conf)
|
||||
, jit_interface(jit_interface) {}
|
||||
|
||||
HaltReason Run() {
|
||||
ASSERT(false);
|
||||
return HaltReason{};
|
||||
}
|
||||
|
||||
HaltReason Step() {
|
||||
ASSERT(false);
|
||||
return HaltReason{};
|
||||
}
|
||||
|
||||
void ClearCache() {
|
||||
std::unique_lock lock{invalidation_mutex};
|
||||
invalidate_entire_cache = true;
|
||||
HaltExecution(HaltReason::CacheInvalidation);
|
||||
}
|
||||
|
||||
void InvalidateCacheRange(u64 start_address, size_t length) {
|
||||
std::unique_lock lock{invalidation_mutex};
|
||||
const auto end_address = u64(start_address + length - 1);
|
||||
invalid_cache_ranges.add(boost::icl::discrete_interval<u64>::closed(start_address, end_address));
|
||||
HaltExecution(HaltReason::CacheInvalidation);
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
ASSERT(!is_executing);
|
||||
//jit_state = {};
|
||||
}
|
||||
|
||||
void HaltExecution(HaltReason hr) {
|
||||
//Atomic::Or(&jit_state.halt_reason, u32(hr));
|
||||
}
|
||||
|
||||
void ClearHalt(HaltReason hr) {
|
||||
//Atomic::And(&jit_state.halt_reason, ~u32(hr));
|
||||
}
|
||||
|
||||
u64 GetSP() const {
|
||||
return 0;//jit_state.sp;
|
||||
}
|
||||
|
||||
void SetSP(u64 value) {
|
||||
//jit_state.sp = value;
|
||||
}
|
||||
|
||||
u64 GetPC() const {
|
||||
return 0;//jit_state.pc;
|
||||
}
|
||||
|
||||
void SetPC(u64 value) {
|
||||
//jit_state.pc = value;
|
||||
}
|
||||
|
||||
u64 GetRegister(size_t index) const {
|
||||
return 0;//index == 31 ? GetSP() : jit_state.regs.at(index);
|
||||
}
|
||||
|
||||
void SetRegister(size_t index, u64 value) {
|
||||
if (index == 31)
|
||||
return SetSP(value);
|
||||
//jit_state.regs.at(index) = value;
|
||||
}
|
||||
|
||||
std::array<u64, 31> GetRegisters() const {
|
||||
return {};//jit_state.regs;
|
||||
}
|
||||
|
||||
void SetRegisters(const std::array<u64, 31>& value) {
|
||||
//jit_state.regs = value;
|
||||
}
|
||||
|
||||
Vector GetVector(size_t index) const {
|
||||
//return {jit_state.vec.at(index * 2), jit_state.vec.at(index * 2 + 1)};
|
||||
return Vector{};
|
||||
}
|
||||
|
||||
void SetVector(size_t index, Vector value) {
|
||||
//jit_state.vec.at(index * 2) = value[0];
|
||||
//jit_state.vec.at(index * 2 + 1) = value[1];
|
||||
}
|
||||
|
||||
std::array<Vector, 32> GetVectors() const {
|
||||
std::array<Vector, 32> ret;
|
||||
//static_assert(sizeof(ret) == sizeof(jit_state.vec));
|
||||
//std::memcpy(ret.data(), jit_state.vec.data(), sizeof(jit_state.vec));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SetVectors(const std::array<Vector, 32>& value) {
|
||||
//static_assert(sizeof(value) == sizeof(jit_state.vec));
|
||||
//std::memcpy(jit_state.vec.data(), value.data(), sizeof(jit_state.vec));
|
||||
}
|
||||
|
||||
u32 GetFpcr() const {
|
||||
return 0;//jit_state.fpcr;
|
||||
}
|
||||
|
||||
void SetFpcr(u32 value) {
|
||||
//jit_state.fpcr = value;
|
||||
}
|
||||
|
||||
u32 GetFpsr() const {
|
||||
return 0;//jit_state.fpsr;
|
||||
}
|
||||
|
||||
void SetFpsr(u32 value) {
|
||||
//jit_state.fpsr = value;
|
||||
}
|
||||
|
||||
u32 GetPstate() const {
|
||||
return 0;//jit_state.pstate;
|
||||
}
|
||||
|
||||
void SetPstate(u32 value) {
|
||||
//jit_state.pstate = value;
|
||||
}
|
||||
|
||||
void ClearExclusiveState() {
|
||||
//jit_state.exclusive_state = 0;
|
||||
}
|
||||
|
||||
bool IsExecuting() const {
|
||||
return is_executing;
|
||||
}
|
||||
|
||||
std::string Disassemble() const {
|
||||
// const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||
// auto const* p = reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||
// return Common::DisassemblePPC64(p, p + size);
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
void RequestCacheInvalidation() {
|
||||
// UNREACHABLE();
|
||||
invalidate_entire_cache = false;
|
||||
invalid_cache_ranges.clear();
|
||||
}
|
||||
|
||||
A64::UserConfig conf;
|
||||
//A64JitState jit_state{};
|
||||
//A64AddressSpace current_address_space;
|
||||
Jit* jit_interface;
|
||||
volatile u32 halt_reason = 0;
|
||||
bool is_executing = false;
|
||||
|
||||
boost::icl::interval_set<u64> invalid_cache_ranges;
|
||||
bool invalidate_entire_cache = false;
|
||||
std::mutex invalidation_mutex;
|
||||
};
|
||||
|
||||
Jit::Jit(UserConfig conf) : impl(std::make_unique<Jit::Impl>(this, conf)) {}
|
||||
Jit::~Jit() = default;
|
||||
|
||||
HaltReason Jit::Run() {
|
||||
return impl->Run();
|
||||
}
|
||||
|
||||
HaltReason Jit::Step() {
|
||||
return impl->Step();
|
||||
}
|
||||
|
||||
void Jit::ClearCache() {
|
||||
impl->ClearCache();
|
||||
}
|
||||
|
||||
void Jit::InvalidateCacheRange(u64 start_address, size_t length) {
|
||||
impl->InvalidateCacheRange(start_address, length);
|
||||
}
|
||||
|
||||
void Jit::Reset() {
|
||||
impl->Reset();
|
||||
}
|
||||
|
||||
void Jit::HaltExecution(HaltReason hr) {
|
||||
impl->HaltExecution(hr);
|
||||
}
|
||||
|
||||
void Jit::ClearHalt(HaltReason hr) {
|
||||
impl->ClearHalt(hr);
|
||||
}
|
||||
|
||||
u64 Jit::GetSP() const {
|
||||
return impl->GetSP();
|
||||
}
|
||||
|
||||
void Jit::SetSP(u64 value) {
|
||||
impl->SetSP(value);
|
||||
}
|
||||
|
||||
u64 Jit::GetPC() const {
|
||||
return impl->GetPC();
|
||||
}
|
||||
|
||||
void Jit::SetPC(u64 value) {
|
||||
impl->SetPC(value);
|
||||
}
|
||||
|
||||
u64 Jit::GetRegister(size_t index) const {
|
||||
return impl->GetRegister(index);
|
||||
}
|
||||
|
||||
void Jit::SetRegister(size_t index, u64 value) {
|
||||
impl->SetRegister(index, value);
|
||||
}
|
||||
|
||||
std::array<u64, 31> Jit::GetRegisters() const {
|
||||
return impl->GetRegisters();
|
||||
}
|
||||
|
||||
void Jit::SetRegisters(const std::array<u64, 31>& value) {
|
||||
impl->SetRegisters(value);
|
||||
}
|
||||
|
||||
Vector Jit::GetVector(size_t index) const {
|
||||
return impl->GetVector(index);
|
||||
}
|
||||
|
||||
void Jit::SetVector(size_t index, Vector value) {
|
||||
impl->SetVector(index, value);
|
||||
}
|
||||
|
||||
std::array<Vector, 32> Jit::GetVectors() const {
|
||||
return impl->GetVectors();
|
||||
}
|
||||
|
||||
void Jit::SetVectors(const std::array<Vector, 32>& value) {
|
||||
impl->SetVectors(value);
|
||||
}
|
||||
|
||||
u32 Jit::GetFpcr() const {
|
||||
return impl->GetFpcr();
|
||||
}
|
||||
|
||||
void Jit::SetFpcr(u32 value) {
|
||||
impl->SetFpcr(value);
|
||||
}
|
||||
|
||||
u32 Jit::GetFpsr() const {
|
||||
return impl->GetFpsr();
|
||||
}
|
||||
|
||||
void Jit::SetFpsr(u32 value) {
|
||||
impl->SetFpsr(value);
|
||||
}
|
||||
|
||||
u32 Jit::GetPstate() const {
|
||||
return impl->GetPstate();
|
||||
}
|
||||
|
||||
void Jit::SetPstate(u32 value) {
|
||||
impl->SetPstate(value);
|
||||
}
|
||||
|
||||
void Jit::ClearExclusiveState() {
|
||||
impl->ClearExclusiveState();
|
||||
}
|
||||
|
||||
bool Jit::IsExecuting() const {
|
||||
return impl->IsExecuting();
|
||||
}
|
||||
|
||||
std::string Jit::Disassemble() const {
|
||||
return impl->Disassemble();
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::Backend::RV64 {
|
||||
|
||||
class CodeBlock {
|
||||
|
|
|
|||
|
|
@ -35,17 +35,17 @@ void EmitIR<IR::Opcode::Identity>(biscuit::Assembler&, EmitContext& ctx, IR::Ins
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Breakpoint>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CallHostFunction>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PushRSB>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -56,12 +56,12 @@ void EmitIR<IR::Opcode::GetCarryFromOp>(biscuit::Assembler&, EmitContext& ctx, I
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetOverflowFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetGEFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
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*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetLowerFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
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*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitConfig& emit_conf) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <biscuit/label.hpp>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace biscuit {
|
||||
class Assembler;
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx) {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -220,17 +220,17 @@ void EmitIR<IR::Opcode::A32GetRegister>(biscuit::Assembler& as, EmitContext& ctx
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetExtendedRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -249,27 +249,27 @@ void EmitIR<IR::Opcode::A32SetRegister>(biscuit::Assembler& as, EmitContext& ctx
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetExtendedRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -284,17 +284,17 @@ void EmitIR<IR::Opcode::A32SetCpsrNZCV>(biscuit::Assembler& as, EmitContext& ctx
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCpsrNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCpsrNZCVQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCpsrNZ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -318,82 +318,82 @@ void EmitIR<IR::Opcode::A32SetCpsrNZC>(biscuit::Assembler& as, EmitContext& ctx,
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32OrQFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetGEFlagsCompressed>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32BXWritePC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32UpdateUpperLocationDescriptor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,37 +22,37 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocInternalOperation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocLoadWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocStoreWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,87 +22,87 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ClearExclusive>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,182 +22,182 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetPC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64DataCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64InstructionCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetCNTFRQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetCNTPCT>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetCTR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetDCZID>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetTPIDRRO>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,107 +22,107 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ClearExclusive>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,82 +22,82 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32Castagnoli8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32Castagnoli16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32Castagnoli32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32Castagnoli64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32ISO8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32ISO16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32ISO32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32ISO64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AESDecryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AESEncryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AESInverseMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AESMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SM4AccessSubstitutionBox>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SHA256Hash>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SHA256MessageSchedule0>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SHA256MessageSchedule1>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
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*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Pack2x64To1x128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LeastSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LeastSignificantHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LeastSignificantByte>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MostSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MostSignificantBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::IsZero32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::IsZero64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::TestBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ConditionalSelect32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ConditionalSelect64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ConditionalSelectNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -124,7 +124,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext&
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeft64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -153,72 +153,72 @@ void EmitIR<IR::Opcode::LogicalShiftRight32>(biscuit::Assembler& as, EmitContext
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::BitRotateRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::BitRotateRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightExtended>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeftMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeftMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
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 {
|
||||
UNIMPLEMENTED();
|
||||
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) {
|
||||
UNIMPLEMENTED();
|
||||
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 {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
} else {
|
||||
if (args[1].IsImmediate()) {
|
||||
const u64 imm = args[1].GetImmediateU64();
|
||||
|
||||
if (args[2].IsImmediate()) {
|
||||
UNIMPLEMENTED();
|
||||
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 {
|
||||
UNIMPLEMENTED();
|
||||
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*) {
|
||||
UNIMPLEMENTED();
|
||||
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*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Mul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Mul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::And32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::And64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AndNot32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AndNot64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Eor32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Eor64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Or32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Or64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Not32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Not64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendLongToQuad>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseDual>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CountLeadingZeros32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CountLeadingZeros64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ExtractRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ExtractRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ReplicateBit32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ReplicateBit64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,442 +22,442 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAbs16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPCompare32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPCompare64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipExponent16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipExponent32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipExponent64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,172 +22,172 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAbsDiffSumU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSelect>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,112 +22,112 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,337 +22,337 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAbs16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorEqual16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorGreater32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorGreater64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorGreaterEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorGreaterEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorPairedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorPairedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorPairedAddLower32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorPairedAddLower64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -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) 2024 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -19,82 +22,82 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "dynarmic/interface/exclusive_monitor.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Dynarmic {
|
||||
|
||||
ExclusiveMonitor::ExclusiveMonitor(std::size_t processor_count)
|
||||
: exclusive_addresses(processor_count, INVALID_EXCLUSIVE_ADDRESS), exclusive_values(processor_count) {}
|
||||
|
||||
size_t ExclusiveMonitor::GetProcessorCount() const {
|
||||
return exclusive_addresses.size();
|
||||
}
|
||||
|
||||
void ExclusiveMonitor::Lock() {
|
||||
lock.Lock();
|
||||
}
|
||||
|
||||
void ExclusiveMonitor::Unlock() {
|
||||
lock.Unlock();
|
||||
}
|
||||
|
||||
bool ExclusiveMonitor::CheckAndClear(size_t processor_id, VAddr address) {
|
||||
const VAddr masked_address = address & RESERVATION_GRANULE_MASK;
|
||||
|
||||
Lock();
|
||||
if (exclusive_addresses[processor_id] != masked_address) {
|
||||
Unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (VAddr& other_address : exclusive_addresses) {
|
||||
if (other_address == masked_address) {
|
||||
other_address = INVALID_EXCLUSIVE_ADDRESS;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExclusiveMonitor::Clear() {
|
||||
Lock();
|
||||
std::fill(exclusive_addresses.begin(), exclusive_addresses.end(), INVALID_EXCLUSIVE_ADDRESS);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void ExclusiveMonitor::ClearProcessor(size_t processor_id) {
|
||||
Lock();
|
||||
exclusive_addresses[processor_id] = INVALID_EXCLUSIVE_ADDRESS;
|
||||
Unlock();
|
||||
}
|
||||
|
||||
} // namespace Dynarmic
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/common/always_false.h"
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
|
|||
|
||||
return new_location_index;
|
||||
} else if constexpr (kind == HostLoc::Kind::Fpr) {
|
||||
UNIMPLEMENTED();
|
||||
ASSERT(false && "Unimplemented instruction");
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#include <biscuit/assembler.hpp>
|
||||
#include <biscuit/registers.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::Backend::RV64 {
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ostream.h>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include <boost/container/static_vector.hpp>
|
||||
|
||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include <bit>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/common/llvm_disassemble.h"
|
||||
|
||||
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -9,8 +9,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
|
|
@ -48,8 +49,8 @@ struct A32JitState {
|
|||
// Exclusive state
|
||||
u32 exclusive_state = 0;
|
||||
|
||||
static constexpr size_t RSBSize = 8; // MUST be a power of 2.
|
||||
static constexpr size_t RSBPtrMask = RSBSize - 1;
|
||||
static constexpr std::size_t RSBSize = 8; // MUST be a power of 2.
|
||||
static constexpr std::size_t RSBPtrMask = RSBSize - 1;
|
||||
u32 rsb_ptr = 0;
|
||||
std::array<u64, RSBSize> rsb_location_descriptors;
|
||||
std::array<u64, RSBSize> rsb_codeptrs;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ostream.h>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
||||
#include <boost/container/static_vector.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/common/fp/fpcr.h"
|
||||
#include "dynarmic/common/llvm_disassemble.h"
|
||||
#include <bit>
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include <array>
|
||||
#include <bitset>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/backend/x64/hostloc.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include <type_traits>
|
||||
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
#include "dynarmic/backend/x64/abi.h"
|
||||
#include "dynarmic/backend/x64/callback.h"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <cstring>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include <span>
|
||||
#include <utility>
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <optional>
|
||||
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/common/fp/rounding_mode.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <utility>
|
||||
|
||||
#include <bit>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/function_info.hpp"
|
||||
|
||||
#include "dynarmic/backend/x64/callback.h"
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@
|
|||
|
||||
#include <iterator>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include <boost/variant/detail/apply_visitor_binary.hpp>
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/x64/abi.h"
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
#include "dynarmic/backend/x64/emit_x64.h"
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include <limits>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
#include <cstdlib>
|
||||
#include <type_traits>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/function_info.hpp"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "common/assert.h"
|
||||
#include "dynarmic/mcl/function_info.hpp"
|
||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
|
@ -1985,6 +1985,13 @@ void EmitX64::EmitFPVectorToHalf32(EmitContext& ctx, IR::Inst* inst) {
|
|||
// output[i] = FPT(FP::FPToFixed<FPT>(fsize, input[i], fbits, unsigned_, fpcr, rounding_mode, fpsr));
|
||||
// }
|
||||
|
||||
template<size_t fsize, bool unsigned_, FP::RoundingMode rounding_mode, size_t fbits>
|
||||
static void EmitFPVectorToFixedThunk(VectorArray<mcl::unsigned_integer_of_size<fsize>>& output, const VectorArray<mcl::unsigned_integer_of_size<fsize>>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||
for (size_t i = 0; i < output.size(); ++i)
|
||||
output[i] = FPT(FP::FPToFixed<FPT>(fsize, input[i], fbits, unsigned_, fpcr, rounding_mode, fpsr));
|
||||
}
|
||||
|
||||
template<size_t fsize, bool unsigned_>
|
||||
void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const size_t fbits = inst->GetArg(1).GetU8();
|
||||
|
|
@ -2106,43 +2113,88 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
ctx.reg_alloc.DefineValue(code, inst, src);
|
||||
return;
|
||||
}
|
||||
auto const fpt_fn = [fbits, rounding]() -> void (*)(VectorArray<mcl::unsigned_integer_of_size<fsize>>& output, const VectorArray<mcl::unsigned_integer_of_size<fsize>>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
#define ROUNDING_MODE_CASE(CASE, N) \
|
||||
if (rounding == FP::RoundingMode::CASE && fsize >= (N) && fbits == (N)) return &EmitFPVectorToFixedThunk<fsize, unsigned_, FP::RoundingMode::CASE, N>;
|
||||
#define ROUNDING_MODE_SWITCH(CASE) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x00) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x01) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x02) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x03) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x04) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x05) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x06) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x07) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x08) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x09) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x0a) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x0b) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x0c) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x0d) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x0e) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x0f) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x10) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x11) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x12) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x13) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x14) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x15) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x16) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x17) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x18) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x19) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x1a) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x1b) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x1c) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x1d) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x1e) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x1f) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x20) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x21) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x22) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x23) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x24) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x25) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x26) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x27) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x28) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x29) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x2a) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x2b) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x2c) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x2d) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x2e) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x2f) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x30) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x31) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x32) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x33) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x34) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x35) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x36) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x37) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x38) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x39) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x3a) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x3b) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x3c) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x3d) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x3e) \
|
||||
ROUNDING_MODE_CASE(CASE, 0x3f)
|
||||
|
||||
using FPT = mcl::unsigned_integer_of_size<fsize>; // WORKAROUND: For issue 678 on MSVC
|
||||
auto const func = [rounding]() -> void(*)(VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
switch (rounding) {
|
||||
case FP::RoundingMode::ToNearest_TieEven:
|
||||
return [](VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < output.size(); ++i)
|
||||
output[i] = FPT(FP::FPToFixed<FPT>(fsize, input[i], fsize, unsigned_, fpcr, FP::RoundingMode::ToNearest_TieEven, fpsr));
|
||||
};
|
||||
case FP::RoundingMode::TowardsPlusInfinity:
|
||||
return [](VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < output.size(); ++i)
|
||||
output[i] = FPT(FP::FPToFixed<FPT>(fsize, input[i], fsize, unsigned_, fpcr, FP::RoundingMode::TowardsPlusInfinity, fpsr));
|
||||
};
|
||||
case FP::RoundingMode::TowardsMinusInfinity:
|
||||
return [](VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < output.size(); ++i)
|
||||
output[i] = FPT(FP::FPToFixed<FPT>(fsize, input[i], fsize, unsigned_, fpcr, FP::RoundingMode::TowardsMinusInfinity, fpsr));
|
||||
};
|
||||
case FP::RoundingMode::TowardsZero:
|
||||
return [](VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < output.size(); ++i)
|
||||
output[i] = FPT(FP::FPToFixed<FPT>(fsize, input[i], fsize, unsigned_, fpcr, FP::RoundingMode::TowardsZero, fpsr));
|
||||
};
|
||||
case FP::RoundingMode::ToNearest_TieAwayFromZero:
|
||||
return [](VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < output.size(); ++i)
|
||||
output[i] = FPT(FP::FPToFixed<FPT>(fsize, input[i], fsize, unsigned_, fpcr, FP::RoundingMode::ToNearest_TieAwayFromZero, fpsr));
|
||||
};
|
||||
case FP::RoundingMode::ToOdd:
|
||||
return [](VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||
for (size_t i = 0; i < output.size(); ++i)
|
||||
output[i] = FPT(FP::FPToFixed<FPT>(fsize, input[i], fsize, unsigned_, fpcr, FP::RoundingMode::ToOdd, fpsr));
|
||||
};
|
||||
}
|
||||
// FUCK YOU MSVC, FUCKING DEPTH CANT EVEN HANDLE 8+16+32+64 DEPTH OF A ELSE STATMENT YOU FUCKING STUPID
|
||||
// BURN MSVC BURN IT STUPID COMPILER CAN'T EVEN COMPILE THE MOST BASIC C++
|
||||
ROUNDING_MODE_SWITCH(ToNearest_TieEven)
|
||||
ROUNDING_MODE_SWITCH(TowardsPlusInfinity)
|
||||
ROUNDING_MODE_SWITCH(TowardsMinusInfinity)
|
||||
ROUNDING_MODE_SWITCH(TowardsZero)
|
||||
ROUNDING_MODE_SWITCH(ToNearest_TieAwayFromZero)
|
||||
#undef ROUNDING_MODE_SWITCH
|
||||
#undef ROUNDING_MODE_CASE
|
||||
return nullptr;
|
||||
}();
|
||||
EmitTwoOpFallback<3>(code, ctx, inst, func);
|
||||
|
||||
EmitTwoOpFallback<3>(code, ctx, inst, fpt_fn);
|
||||
}
|
||||
|
||||
void EmitX64::EmitFPVectorToSignedFixed16(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
#include "dynarmic/backend/x64/constants.h"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue