mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 05:28:56 +02:00
Compare commits
22 commits
a3cdea9446
...
88d0ea45e8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88d0ea45e8 | ||
|
|
696c6d903c | ||
|
|
0c1fdd8be0 | ||
|
|
b4516101ad | ||
|
|
c4bc5b8ca3 | ||
|
|
02eeace2b2 | ||
|
|
e18cd4a87d | ||
|
|
21a3d5b975 | ||
|
|
4ce80ad503 | ||
|
|
ebe1e4d43b | ||
|
|
8a5acdbc1f | ||
|
|
70e53f86c4 | ||
|
|
cb0c5aa196 | ||
|
|
9f4f807f58 | ||
|
|
6fb304e11e | ||
|
|
7fe1639fa9 | ||
|
|
db34c0ef0b | ||
|
|
7a87b88650 | ||
|
|
13ee8bedc8 | ||
|
|
5322bce4b8 | ||
|
|
276dcdd8ea | ||
|
|
59254cd1e7 |
241 changed files with 2661 additions and 2204 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -773,7 +773,11 @@ std::optional<u64> MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, m
|
|||
bool was_executed = false;
|
||||
|
||||
auto decoder = Dynarmic::A64::Decode<VisitorBase>(instruction);
|
||||
was_executed = decoder.get().call(visitor, instruction);
|
||||
if (decoder) {
|
||||
was_executed = decoder->get().call(visitor, instruction);
|
||||
} else {
|
||||
was_executed = false;
|
||||
}
|
||||
return was_executed ? std::optional<u64>(pc + 4) : std::nullopt;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ else()
|
|||
endif()
|
||||
option(DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT "Enables support for systems that require W^X" ${REQUIRE_WX})
|
||||
|
||||
option(DYNARMIC_IGNORE_ASSERTS "Ignore asserts" ON)
|
||||
option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF "NOT YUZU_DISABLE_LLVM" OFF)
|
||||
|
||||
|
|
@ -126,7 +125,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)
|
||||
|
|
@ -378,9 +379,6 @@ endif()
|
|||
if (DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT)
|
||||
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
|
||||
endif()
|
||||
if (DYNARMIC_IGNORE_ASSERTS)
|
||||
target_compile_definitions(dynarmic PRIVATE MCL_IGNORE_ASSERTS=1)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cassert>
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/arm64/a32_address_space.h"
|
||||
#include "dynarmic/backend/arm64/a32_core.h"
|
||||
|
|
@ -31,7 +31,7 @@ struct Jit::Impl final {
|
|||
, core(conf) {}
|
||||
|
||||
HaltReason Run() {
|
||||
ASSERT(!jit_interface->is_executing);
|
||||
assert(!jit_interface->is_executing);
|
||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
||||
|
||||
jit_interface->is_executing = true;
|
||||
|
|
@ -42,7 +42,7 @@ struct Jit::Impl final {
|
|||
}
|
||||
|
||||
HaltReason Step() {
|
||||
ASSERT(!jit_interface->is_executing);
|
||||
assert(!jit_interface->is_executing);
|
||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
||||
|
||||
jit_interface->is_executing = true;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cassert>
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/arm64/a64_address_space.h"
|
||||
#include "dynarmic/backend/arm64/a64_core.h"
|
||||
|
|
@ -31,7 +31,7 @@ struct Jit::Impl final {
|
|||
, core(conf) {}
|
||||
|
||||
HaltReason Run() {
|
||||
ASSERT(!is_executing);
|
||||
assert(!is_executing);
|
||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
||||
is_executing = true;
|
||||
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
|
||||
|
|
@ -41,7 +41,7 @@ struct Jit::Impl final {
|
|||
}
|
||||
|
||||
HaltReason Step() {
|
||||
ASSERT(!is_executing);
|
||||
assert(!is_executing);
|
||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&halt_reason)));
|
||||
is_executing = true;
|
||||
HaltReason hr = core.Step(current_address_space, current_state, &halt_reason);
|
||||
|
|
|
|||
|
|
@ -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,7 +11,7 @@
|
|||
#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 {
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#include <oaknut/oaknut.hpp>
|
||||
|
||||
#include "dynarmic/common/always_false.h"
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
|
|
@ -29,25 +26,25 @@ 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;
|
||||
} else if constexpr (bitsize == 64) {
|
||||
return Xscratch0;
|
||||
} else {
|
||||
return Xscratch0; //UNREACHABLE();
|
||||
return Xscratch0; //std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
template<std::size_t bitsize>
|
||||
constexpr auto Rscratch1() {
|
||||
if constexpr (bitsize == 32) {
|
||||
return Wscratch1;
|
||||
} else if constexpr (bitsize == 64) {
|
||||
return Xscratch1;
|
||||
} else {
|
||||
return Xscratch1; //UNREACHABLE();
|
||||
return Xscratch1; //std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +57,7 @@ constexpr RegisterList ToRegList(oaknut::Reg reg) {
|
|||
if (reg.is_vector()) {
|
||||
return RegisterList{1} << (reg.index() + 32);
|
||||
}
|
||||
ASSERT(reg.index() != 31 && "ZR not allowed in reg list");
|
||||
assert(reg.index() != 31 && "ZR not allowed in reg list");
|
||||
if (reg.index() == -1) {
|
||||
return RegisterList{1} << 31;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ AddressSpace::AddressSpace(size_t code_cache_size)
|
|||
, code(mem.ptr(), mem.ptr())
|
||||
, fastmem_manager(exception_handler)
|
||||
{
|
||||
ASSERT(code_cache_size <= 128 * 1024 * 1024 && "code_cache_size > 128 MiB not currently supported");
|
||||
assert(code_cache_size <= 128 * 1024 * 1024 && "code_cache_size > 128 MiB not currently supported");
|
||||
|
||||
exception_handler.Register(mem, code_cache_size);
|
||||
exception_handler.SetFastmemCallback([this](u64 host_pc) {
|
||||
|
|
@ -115,9 +115,9 @@ EmittedBlockInfo AddressSpace::Emit(IR::Block block) {
|
|||
|
||||
EmittedBlockInfo block_info = EmitArm64(code, std::move(block), GetEmitConfig(), fastmem_manager);
|
||||
|
||||
ASSERT(block_entries.insert({block.Location(), block_info.entry_point}).second);
|
||||
ASSERT(reverse_block_entries.insert({block_info.entry_point, block.Location()}).second);
|
||||
ASSERT(block_infos.insert({block_info.entry_point, block_info}).second);
|
||||
assert(block_entries.insert({block.Location(), block_info.entry_point}).second);
|
||||
assert(reverse_block_entries.insert({block_info.entry_point, block.Location()}).second);
|
||||
assert(block_infos.insert({block_info.entry_point, block_info}).second);
|
||||
|
||||
Link(block_info);
|
||||
RelinkForDescriptor(block.Location(), block_info.entry_point);
|
||||
|
|
@ -260,7 +260,7 @@ void AddressSpace::Link(EmittedBlockInfo& block_info) {
|
|||
c.BL(prelude_info.get_ticks_remaining);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -294,7 +294,7 @@ void AddressSpace::LinkBlockLinks(const CodePtr entry_point, const CodePtr targe
|
|||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -346,7 +346,7 @@ FakeCall AddressSpace::FastmemCallback(u64 host_pc) {
|
|||
fail:
|
||||
fmt::print("dynarmic: Segfault happened within JITted code at host_pc = {:016x}\n"
|
||||
"Segfault wasn't at a fastmem patch location!\n", host_pc);
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::Arm64
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ void EmitIR<IR::Opcode::PushRSB>(oaknut::CodeGenerator& code, EmitContext& ctx,
|
|||
}
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[0].IsImmediate());
|
||||
assert(args[0].IsImmediate());
|
||||
const IR::LocationDescriptor target{args[0].GetImmediateU64()};
|
||||
|
||||
code.LDR(Wscratch2, SP, offsetof(StackLayout, rsb_ptr));
|
||||
|
|
@ -71,19 +71,19 @@ void EmitIR<IR::Opcode::PushRSB>(oaknut::CodeGenerator& code, EmitContext& ctx,
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::GetCarryFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
|
||||
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
|
||||
assert(ctx.reg_alloc.WasValueDefined(inst));
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetOverflowFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
|
||||
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
|
||||
assert(ctx.reg_alloc.WasValueDefined(inst));
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetGEFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
|
||||
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
|
||||
assert(ctx.reg_alloc.WasValueDefined(inst));
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -112,7 +112,7 @@ void EmitIR<IR::Opcode::GetNZCVFromOp>(oaknut::CodeGenerator& code, EmitContext&
|
|||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,20 +142,20 @@ void EmitIR<IR::Opcode::GetNZFromOp>(oaknut::CodeGenerator& code, EmitContext& c
|
|||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetUpperFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
|
||||
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
|
||||
assert(ctx.reg_alloc.WasValueDefined(inst));
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetLowerFromOp>(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) {
|
||||
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(ctx.reg_alloc.WasValueDefined(inst));
|
||||
assert(ctx.reg_alloc.WasValueDefined(inst));
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -206,9 +206,9 @@ EmittedBlockInfo EmitArm64(oaknut::CodeGenerator& code, IR::Block block, const E
|
|||
ebi.entry_point = code.xptr<CodePtr>();
|
||||
|
||||
if (ctx.block.GetCondition() == IR::Cond::AL) {
|
||||
ASSERT(!ctx.block.HasConditionFailedLocation());
|
||||
assert(!ctx.block.HasConditionFailedLocation());
|
||||
} else {
|
||||
ASSERT(ctx.block.HasConditionFailedLocation());
|
||||
assert(ctx.block.HasConditionFailedLocation());
|
||||
oaknut::Label pass;
|
||||
|
||||
pass = conf.emit_cond(code, ctx, ctx.block.GetCondition());
|
||||
|
|
@ -239,7 +239,7 @@ EmittedBlockInfo EmitArm64(oaknut::CodeGenerator& code, IR::Block block, const E
|
|||
#undef A32OPC
|
||||
#undef A64OPC
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
reg_alloc.UpdateAllUses();
|
||||
|
|
@ -283,7 +283,7 @@ void EmitBlockLinkRelocation(oaknut::CodeGenerator& code, EmitContext& ctx, cons
|
|||
code.NOP();
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ void EmitIR<IR::Opcode::A32GetRegister>(oaknut::CodeGenerator& code, EmitContext
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetExtendedRegister32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsSingleExtReg(reg));
|
||||
assert(A32::IsSingleExtReg(reg));
|
||||
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::S0);
|
||||
|
||||
auto Sresult = ctx.reg_alloc.WriteS(inst);
|
||||
|
|
@ -225,7 +225,7 @@ void EmitIR<IR::Opcode::A32GetExtendedRegister32>(oaknut::CodeGenerator& code, E
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetVector>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||
assert(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||
|
||||
if (A32::IsDoubleExtReg(reg)) {
|
||||
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
|
||||
|
|
@ -243,7 +243,7 @@ void EmitIR<IR::Opcode::A32GetVector>(oaknut::CodeGenerator& code, EmitContext&
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetExtendedRegister64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsDoubleExtReg(reg));
|
||||
assert(A32::IsDoubleExtReg(reg));
|
||||
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
|
||||
|
||||
auto Dresult = ctx.reg_alloc.WriteD(inst);
|
||||
|
|
@ -271,7 +271,7 @@ void EmitIR<IR::Opcode::A32SetRegister>(oaknut::CodeGenerator& code, EmitContext
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetExtendedRegister32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsSingleExtReg(reg));
|
||||
assert(A32::IsSingleExtReg(reg));
|
||||
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::S0);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -286,7 +286,7 @@ void EmitIR<IR::Opcode::A32SetExtendedRegister32>(oaknut::CodeGenerator& code, E
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetExtendedRegister64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsDoubleExtReg(reg));
|
||||
assert(A32::IsDoubleExtReg(reg));
|
||||
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -301,7 +301,7 @@ void EmitIR<IR::Opcode::A32SetExtendedRegister64>(oaknut::CodeGenerator& code, E
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetVector>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||
assert(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
if (A32::IsDoubleExtReg(reg)) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -24,7 +24,7 @@ using namespace oaknut::util;
|
|||
|
||||
static void EmitCoprocessorException() {
|
||||
// TODO: Raise coproc except
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr, std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}) {
|
||||
|
|
@ -107,7 +107,7 @@ void EmitIR<IR::Opcode::A32CoprocSendOneWord>(oaknut::CodeGenerator& code, EmitC
|
|||
return;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -151,7 +151,7 @@ void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(oaknut::CodeGenerator& code, Emit
|
|||
return;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -193,7 +193,7 @@ void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitCo
|
|||
return;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -235,7 +235,7 @@ void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(oaknut::CodeGenerator& code, EmitC
|
|||
return;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -120,7 +120,7 @@ void EmitIR<IR::Opcode::SM4AccessSubstitutionBox>(oaknut::CodeGenerator& code, E
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -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,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"
|
||||
|
|
@ -195,8 +194,8 @@ void EmitIR<IR::Opcode::TestBit>(oaknut::CodeGenerator& code, EmitContext& ctx,
|
|||
auto Xresult = ctx.reg_alloc.WriteX(inst);
|
||||
auto Xoperand = ctx.reg_alloc.ReadX(args[0]);
|
||||
RegAlloc::Realize(Xresult, Xoperand);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
ASSERT(args[1].GetImmediateU8() < 64);
|
||||
assert(args[1].IsImmediate());
|
||||
assert(args[1].GetImmediateU8() < 64);
|
||||
|
||||
code.UBFX(Xresult, Xoperand, args[1].GetImmediateU8(), 1);
|
||||
}
|
||||
|
|
@ -642,7 +641,7 @@ void EmitIR<IR::Opcode::ArithmeticShiftRight64>(oaknut::CodeGenerator& code, Emi
|
|||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitIR<IR::Opcode::BitRotateRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -708,7 +707,7 @@ void EmitIR<IR::Opcode::RotateRight32>(oaknut::CodeGenerator& code, EmitContext&
|
|||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRight64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitIR<IR::Opcode::BitRotateRight64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto& operand_arg = args[0];
|
||||
auto& shift_arg = args[1];
|
||||
|
|
@ -894,9 +893,9 @@ static void EmitAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
|
|||
|
||||
if (overflow_inst) {
|
||||
// There is a limited set of circumstances where this is required, so assert for this.
|
||||
ASSERT(!sub);
|
||||
ASSERT(!nzcv_inst);
|
||||
ASSERT(args[2].IsImmediate() && args[2].GetImmediateU1() == false);
|
||||
assert(!sub);
|
||||
assert(!nzcv_inst);
|
||||
assert(args[2].IsImmediate() && args[2].GetImmediateU1() == false);
|
||||
|
||||
auto Rb = ctx.reg_alloc.ReadReg<bitsize>(args[1]);
|
||||
auto Woverflow = ctx.reg_alloc.WriteW(overflow_inst);
|
||||
|
|
@ -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) {
|
||||
|
|
@ -1135,7 +1134,7 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
|
|||
if constexpr (!std::is_same_v<EmitFn2, std::nullptr_t>) {
|
||||
const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp);
|
||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
||||
ASSERT(!(nz_inst && nzcv_inst));
|
||||
assert(!(nz_inst && nzcv_inst));
|
||||
const auto flag_inst = nz_inst ? nz_inst : nzcv_inst;
|
||||
|
||||
if (flag_inst) {
|
||||
|
|
@ -1172,7 +1171,7 @@ template<size_t bitsize>
|
|||
static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp);
|
||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
||||
ASSERT(!(nz_inst && nzcv_inst));
|
||||
assert(!(nz_inst && nzcv_inst));
|
||||
const auto flag_inst = nz_inst ? nz_inst : nzcv_inst;
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -1403,7 +1402,7 @@ void EmitIR<IR::Opcode::CountLeadingZeros64>(oaknut::CodeGenerator& code, EmitCo
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::ExtractRegister32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[2].IsImmediate());
|
||||
assert(args[2].IsImmediate());
|
||||
|
||||
auto Wresult = ctx.reg_alloc.WriteW(inst);
|
||||
auto Wop1 = ctx.reg_alloc.ReadW(args[0]);
|
||||
|
|
@ -1417,7 +1416,7 @@ void EmitIR<IR::Opcode::ExtractRegister32>(oaknut::CodeGenerator& code, EmitCont
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::ExtractRegister64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[2].IsImmediate());
|
||||
assert(args[2].IsImmediate());
|
||||
|
||||
auto Xresult = ctx.reg_alloc.WriteX(inst);
|
||||
auto Xop1 = ctx.reg_alloc.ReadX(args[0]);
|
||||
|
|
@ -1431,7 +1430,7 @@ void EmitIR<IR::Opcode::ExtractRegister64>(oaknut::CodeGenerator& code, EmitCont
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::ReplicateBit32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
|
||||
auto Wresult = ctx.reg_alloc.WriteW(inst);
|
||||
auto Wvalue = ctx.reg_alloc.ReadW(args[0]);
|
||||
|
|
@ -1445,7 +1444,7 @@ void EmitIR<IR::Opcode::ReplicateBit32>(oaknut::CodeGenerator& code, EmitContext
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::ReplicateBit64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
|
||||
auto Xresult = ctx.reg_alloc.WriteX(inst);
|
||||
auto Xvalue = ctx.reg_alloc.ReadX(args[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
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
|
|
@ -68,7 +68,7 @@ static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
|
|||
RegAlloc::Realize(Vto, Vfrom);
|
||||
ctx.fpsr.Load();
|
||||
|
||||
ASSERT(rounding_mode == ctx.FPCR().RMode());
|
||||
assert(rounding_mode == ctx.FPCR().RMode());
|
||||
|
||||
emit(Vto, Vfrom);
|
||||
}
|
||||
|
|
@ -106,8 +106,8 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
|
|||
}
|
||||
}
|
||||
} else {
|
||||
ASSERT(fbits == 0);
|
||||
ASSERT(bitsize_to != 16);
|
||||
assert(fbits == 0);
|
||||
assert(bitsize_to != 16);
|
||||
if constexpr (is_signed) {
|
||||
switch (rounding_mode) {
|
||||
case FP::RoundingMode::ToNearest_TieEven:
|
||||
|
|
@ -126,10 +126,10 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
|
|||
code.FCVTAS(Rto, Vfrom);
|
||||
break;
|
||||
case FP::RoundingMode::ToOdd:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
} else {
|
||||
switch (rounding_mode) {
|
||||
|
|
@ -149,10 +149,10 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
|
|||
code.FCVTAU(Rto, Vfrom);
|
||||
break;
|
||||
case FP::RoundingMode::ToOdd:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -189,7 +189,7 @@ void EmitIR<IR::Opcode::FPAbs16>(oaknut::CodeGenerator& code, EmitContext& ctx,
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -316,7 +316,7 @@ void EmitIR<IR::Opcode::FPMulAdd16>(oaknut::CodeGenerator& code, EmitContext& ct
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -334,7 +334,7 @@ void EmitIR<IR::Opcode::FPMulSub16>(oaknut::CodeGenerator& code, EmitContext& ct
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -362,7 +362,7 @@ void EmitIR<IR::Opcode::FPNeg16>(oaknut::CodeGenerator& code, EmitContext& ctx,
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -380,7 +380,7 @@ void EmitIR<IR::Opcode::FPRecipEstimate16>(oaknut::CodeGenerator& code, EmitCont
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -398,7 +398,7 @@ void EmitIR<IR::Opcode::FPRecipExponent16>(oaknut::CodeGenerator& code, EmitCont
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -416,7 +416,7 @@ void EmitIR<IR::Opcode::FPRecipStepFused16>(oaknut::CodeGenerator& code, EmitCon
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -434,7 +434,7 @@ void EmitIR<IR::Opcode::FPRoundInt16>(oaknut::CodeGenerator& code, EmitContext&
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -449,7 +449,7 @@ void EmitIR<IR::Opcode::FPRoundInt32>(oaknut::CodeGenerator& code, EmitContext&
|
|||
ctx.fpsr.Load();
|
||||
|
||||
if (exact) {
|
||||
ASSERT(ctx.FPCR().RMode() == rounding_mode);
|
||||
assert(ctx.FPCR().RMode() == rounding_mode);
|
||||
code.FRINTX(Sresult, Soperand);
|
||||
} else {
|
||||
switch (rounding_mode) {
|
||||
|
|
@ -469,7 +469,7 @@ void EmitIR<IR::Opcode::FPRoundInt32>(oaknut::CodeGenerator& code, EmitContext&
|
|||
code.FRINTA(Sresult, Soperand);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -486,7 +486,7 @@ void EmitIR<IR::Opcode::FPRoundInt64>(oaknut::CodeGenerator& code, EmitContext&
|
|||
ctx.fpsr.Load();
|
||||
|
||||
if (exact) {
|
||||
ASSERT(ctx.FPCR().RMode() == rounding_mode);
|
||||
assert(ctx.FPCR().RMode() == rounding_mode);
|
||||
code.FRINTX(Dresult, Doperand);
|
||||
} else {
|
||||
switch (rounding_mode) {
|
||||
|
|
@ -506,7 +506,7 @@ void EmitIR<IR::Opcode::FPRoundInt64>(oaknut::CodeGenerator& code, EmitContext&
|
|||
code.FRINTA(Dresult, Doperand);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -516,7 +516,7 @@ void EmitIR<IR::Opcode::FPRSqrtEstimate16>(oaknut::CodeGenerator& code, EmitCont
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -534,7 +534,7 @@ void EmitIR<IR::Opcode::FPRSqrtStepFused16>(oaknut::CodeGenerator& code, EmitCon
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -648,7 +648,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedS16>(oaknut::CodeGenerator& code, EmitConte
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -656,7 +656,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedS32>(oaknut::CodeGenerator& code, EmitConte
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -664,7 +664,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedS64>(oaknut::CodeGenerator& code, EmitConte
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -672,7 +672,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedU16>(oaknut::CodeGenerator& code, EmitConte
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -680,7 +680,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedU32>(oaknut::CodeGenerator& code, EmitConte
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -688,7 +688,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedU64>(oaknut::CodeGenerator& code, EmitConte
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ LinkTarget ReadMemoryLinkTarget(size_t bitsize) {
|
|||
case 128:
|
||||
return LinkTarget::ReadMemory128;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
LinkTarget WriteMemoryLinkTarget(size_t bitsize) {
|
||||
|
|
@ -64,7 +64,7 @@ LinkTarget WriteMemoryLinkTarget(size_t bitsize) {
|
|||
case 128:
|
||||
return LinkTarget::WriteMemory128;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
LinkTarget WrappedReadMemoryLinkTarget(size_t bitsize) {
|
||||
|
|
@ -80,7 +80,7 @@ LinkTarget WrappedReadMemoryLinkTarget(size_t bitsize) {
|
|||
case 128:
|
||||
return LinkTarget::WrappedReadMemory128;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
LinkTarget WrappedWriteMemoryLinkTarget(size_t bitsize) {
|
||||
|
|
@ -96,7 +96,7 @@ LinkTarget WrappedWriteMemoryLinkTarget(size_t bitsize) {
|
|||
case 128:
|
||||
return LinkTarget::WrappedWriteMemory128;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) {
|
||||
|
|
@ -112,7 +112,7 @@ LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) {
|
|||
case 128:
|
||||
return LinkTarget::ExclusiveReadMemory128;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
LinkTarget ExclusiveWriteMemoryLinkTarget(size_t bitsize) {
|
||||
|
|
@ -128,10 +128,10 @@ LinkTarget ExclusiveWriteMemoryLinkTarget(size_t bitsize) {
|
|||
case 128:
|
||||
return LinkTarget::ExclusiveWriteMemory128;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //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_bits = 12;
|
||||
constexpr size_t page_size = 1 << page_bits;
|
||||
constexpr size_t page_mask = (1 << page_bits) - 1;
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
|
|
@ -235,35 +235,35 @@ void EmitDetectMisalignedVAddr(oaknut::CodeGenerator& code, EmitContext& ctx, oa
|
|||
case 128:
|
||||
return 0b1111;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}();
|
||||
|
||||
code.TST(Xaddr, align_mask);
|
||||
code.B(NE, *fallback);
|
||||
} else {
|
||||
// If (addr & page_mask) > page_size - byte_size, use fallback.
|
||||
code.AND(Xscratch0, Xaddr, page_mask);
|
||||
code.CMP(Xscratch0, page_size - bitsize / 8);
|
||||
// If (addr & page_table_const_mask) > page_table_const_size - byte_size, use fallback.
|
||||
code.AND(Xscratch0, Xaddr, page_table_const_mask);
|
||||
code.CMP(Xscratch0, page_table_const_size - bitsize / 8);
|
||||
code.B(HI, *fallback);
|
||||
}
|
||||
}
|
||||
|
||||
// Outputs Xscratch0 = page_table[addr >> page_bits]
|
||||
// Outputs Xscratch0 = page_table[addr >> page_table_const_bits]
|
||||
// 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_bits;
|
||||
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;
|
||||
|
||||
EmitDetectMisalignedVAddr<bitsize>(code, ctx, Xaddr, fallback);
|
||||
|
||||
if (ctx.conf.silently_mirror_page_table || unused_top_bits == 0) {
|
||||
code.UBFX(Xscratch0, Xaddr, page_bits, valid_page_index_bits);
|
||||
code.UBFX(Xscratch0, Xaddr, page_table_const_bits, valid_page_index_bits);
|
||||
} else {
|
||||
code.LSR(Xscratch0, Xaddr, page_bits);
|
||||
code.LSR(Xscratch0, Xaddr, page_table_const_bits);
|
||||
code.TST(Xscratch0, u64(~u64(0)) << valid_page_index_bits);
|
||||
code.B(NE, *fallback);
|
||||
}
|
||||
|
|
@ -283,7 +283,7 @@ std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::Cod
|
|||
if (ctx.conf.absolute_offset_page_table) {
|
||||
return std::make_pair(Xscratch0, Xaddr);
|
||||
}
|
||||
code.AND(Xscratch1, Xaddr, page_mask);
|
||||
code.AND(Xscratch1, Xaddr, page_table_const_mask);
|
||||
return std::make_pair(Xscratch0, Xscratch1);
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +318,7 @@ CodePtr EmitMemoryLdr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
|
|||
code.DMB(oaknut::BarrierOp::ISH);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
} else {
|
||||
fastmem_location = code.xptr<CodePtr>();
|
||||
|
|
@ -340,7 +340,7 @@ CodePtr EmitMemoryLdr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
|
|||
code.LDR(oaknut::QReg{value_idx}, Xbase, Roffset, index_ext);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ CodePtr EmitMemoryStr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
|
|||
code.DMB(oaknut::BarrierOp::ISH);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
} else {
|
||||
fastmem_location = code.xptr<CodePtr>();
|
||||
|
|
@ -401,14 +401,14 @@ CodePtr EmitMemoryStr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
|
|||
code.STR(oaknut::QReg{value_idx}, Xbase, Roffset, index_ext);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
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,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2022 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -244,7 +247,7 @@ static void EmitPackedAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::
|
|||
}
|
||||
|
||||
if (ge_inst) {
|
||||
ASSERT(!is_halving);
|
||||
assert(!is_halving);
|
||||
|
||||
auto Vge = ctx.reg_alloc.WriteD(ge_inst);
|
||||
RegAlloc::Realize(Vge);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -24,7 +24,7 @@ using namespace oaknut::util;
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
||||
ASSERT(overflow_inst);
|
||||
assert(overflow_inst);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Wresult = ctx.reg_alloc.WriteW(inst);
|
||||
|
|
@ -44,7 +44,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(oaknut::CodeGenerator& cod
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
||||
ASSERT(overflow_inst);
|
||||
assert(overflow_inst);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto Wresult = ctx.reg_alloc.WriteW(inst);
|
||||
|
|
@ -67,7 +67,7 @@ void EmitIR<IR::Opcode::SignedSaturation>(oaknut::CodeGenerator& code, EmitConte
|
|||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const size_t N = args[1].GetImmediateU8();
|
||||
ASSERT(N >= 1 && N <= 32);
|
||||
assert(N >= 1 && N <= 32);
|
||||
|
||||
if (N == 32) {
|
||||
ctx.reg_alloc.DefineAsExisting(inst, args[0]);
|
||||
|
|
@ -113,7 +113,7 @@ void EmitIR<IR::Opcode::UnsignedSaturation>(oaknut::CodeGenerator& code, EmitCon
|
|||
ctx.reg_alloc.SpillFlags();
|
||||
|
||||
const size_t N = args[1].GetImmediateU8();
|
||||
ASSERT(N <= 31);
|
||||
assert(N <= 31);
|
||||
const u32 saturated_value = (1u << N) - 1;
|
||||
|
||||
code.MOV(Wscratch0, saturated_value);
|
||||
|
|
@ -134,7 +134,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAdd8>(oaknut::CodeGenerator& code, EmitCo
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -142,7 +142,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAdd16>(oaknut::CodeGenerator& code, EmitC
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -150,7 +150,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAdd32>(oaknut::CodeGenerator& code, EmitC
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -158,7 +158,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAdd64>(oaknut::CodeGenerator& code, EmitC
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -166,7 +166,7 @@ void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh16>(oaknut::Cod
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -174,7 +174,7 @@ void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh32>(oaknut::Cod
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -182,7 +182,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSub8>(oaknut::CodeGenerator& code, EmitCo
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -190,7 +190,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSub16>(oaknut::CodeGenerator& code, EmitC
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -198,7 +198,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSub32>(oaknut::CodeGenerator& code, EmitC
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -206,7 +206,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSub64>(oaknut::CodeGenerator& code, EmitC
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -214,7 +214,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedAdd8>(oaknut::CodeGenerator& code, Emit
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -222,7 +222,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedAdd16>(oaknut::CodeGenerator& code, Emi
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -230,7 +230,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedAdd32>(oaknut::CodeGenerator& code, Emi
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -238,7 +238,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedAdd64>(oaknut::CodeGenerator& code, Emi
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -246,7 +246,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedSub8>(oaknut::CodeGenerator& code, Emit
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -254,7 +254,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedSub16>(oaknut::CodeGenerator& code, Emi
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -262,7 +262,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedSub32>(oaknut::CodeGenerator& code, Emi
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -270,7 +270,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedSub64>(oaknut::CodeGenerator& code, Emi
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::Arm64
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->D2(), Qoperand->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx
|
|||
} else if constexpr (size == 32) {
|
||||
emit(Qresult->D2(), Qoperand->toD().S2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ct
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->toD().S2(), Qoperand->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -106,7 +106,7 @@ static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext&
|
|||
} else if constexpr (size == 32) {
|
||||
emit(Qresult->D2(), Qoperand->S4());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ static void EmitTwoOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx
|
|||
} else if constexpr (size == 32) {
|
||||
emit(Qresult->toD().S2(), Qoperand->toD().S2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -174,7 +174,7 @@ static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& c
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->Q1(), Qa->toD().D1(), Qb->toD().D1());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -197,7 +197,7 @@ static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& c
|
|||
} else if constexpr (size == 32) {
|
||||
emit(Qresult->toD().S2(), Qa->toD().S2(), Qb->toD().S2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -219,7 +219,7 @@ static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qaccumulator->D2(), Qoperand->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +240,7 @@ static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* ins
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->D2(), Qoperand->D2(), shift_amount);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -268,14 +268,14 @@ static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Vresult, Qoperand->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
template<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());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
auto Rresult = ctx.reg_alloc.WriteReg<std::max<size_t>(32, size)>(inst);
|
||||
|
|
@ -310,7 +310,7 @@ void EmitIR<IR::Opcode::VectorGetElement64>(oaknut::CodeGenerator& code, EmitCon
|
|||
template<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());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
auto Qvector = ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
||||
|
|
@ -640,7 +640,7 @@ void EmitIR<IR::Opcode::VectorEqual128>(oaknut::CodeGenerator& code, EmitContext
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -650,7 +650,7 @@ void EmitIR<IR::Opcode::VectorExtract>(oaknut::CodeGenerator& code, EmitContext&
|
|||
auto Qa = ctx.reg_alloc.ReadQ(args[0]);
|
||||
auto Qb = ctx.reg_alloc.ReadQ(args[1]);
|
||||
const u8 position = args[2].GetImmediateU8();
|
||||
ASSERT(position % 8 == 0);
|
||||
assert(position % 8 == 0);
|
||||
RegAlloc::Realize(Qresult, Qa, Qb);
|
||||
|
||||
code.EXT(Qresult->B16(), Qa->B16(), Qb->B16(), position / 8);
|
||||
|
|
@ -663,7 +663,7 @@ void EmitIR<IR::Opcode::VectorExtractLower>(oaknut::CodeGenerator& code, EmitCon
|
|||
auto Da = ctx.reg_alloc.ReadD(args[0]);
|
||||
auto Db = ctx.reg_alloc.ReadD(args[1]);
|
||||
const u8 position = args[2].GetImmediateU8();
|
||||
ASSERT(position % 8 == 0);
|
||||
assert(position % 8 == 0);
|
||||
RegAlloc::Realize(Dresult, Da, Db);
|
||||
|
||||
code.EXT(Dresult->B8(), Da->B8(), Db->B8(), position / 8);
|
||||
|
|
@ -869,7 +869,7 @@ void EmitIR<IR::Opcode::VectorMaxS64>(oaknut::CodeGenerator& code, EmitContext&
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -892,7 +892,7 @@ void EmitIR<IR::Opcode::VectorMaxU64>(oaknut::CodeGenerator& code, EmitContext&
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -915,7 +915,7 @@ void EmitIR<IR::Opcode::VectorMinS64>(oaknut::CodeGenerator& code, EmitContext&
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -938,7 +938,7 @@ void EmitIR<IR::Opcode::VectorMinU64>(oaknut::CodeGenerator& code, EmitContext&
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -958,7 +958,7 @@ void EmitIR<IR::Opcode::VectorMultiply32>(oaknut::CodeGenerator& code, EmitConte
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorMultiply64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(ctx.conf.very_verbose_debugging_output && "VectorMultiply64 is for debugging only");
|
||||
assert(ctx.conf.very_verbose_debugging_output && "VectorMultiply64 is for debugging only");
|
||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||
code.FMOV(Xscratch0, Qa->toD());
|
||||
code.FMOV(Xscratch1, Qb->toD());
|
||||
|
|
@ -1289,7 +1289,7 @@ void EmitIR<IR::Opcode::VectorReduceAdd64>(oaknut::CodeGenerator& code, EmitCont
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::VectorRotateWholeVectorRight>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitImmShift<8>(code, ctx, inst, [&](auto Vresult, auto Voperand, u8 shift_amount) {
|
||||
ASSERT(shift_amount % 8 == 0);
|
||||
assert(shift_amount % 8 == 0);
|
||||
const u8 ext_imm = (shift_amount % 128) / 8;
|
||||
code.EXT(Vresult, Voperand, Voperand, ext_imm);
|
||||
});
|
||||
|
|
@ -1385,7 +1385,7 @@ void EmitIR<IR::Opcode::VectorSignExtend64>(oaknut::CodeGenerator& code, EmitCon
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -1408,7 +1408,7 @@ void EmitIR<IR::Opcode::VectorSignedMultiply16>(oaknut::CodeGenerator& code, Emi
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -1416,7 +1416,7 @@ void EmitIR<IR::Opcode::VectorSignedMultiply32>(oaknut::CodeGenerator& code, Emi
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -1602,12 +1602,12 @@ void EmitIR<IR::Opcode::VectorSub64>(oaknut::CodeGenerator& code, EmitContext& c
|
|||
template<>
|
||||
void EmitIR<IR::Opcode::VectorTable>(oaknut::CodeGenerator&, EmitContext&, IR::Inst* inst) {
|
||||
// Do nothing. We *want* to hold on to the refcount for our arguments, so VectorTableLookup can use our arguments.
|
||||
ASSERT(inst->UseCount() == 1 && "Table cannot be used multiple times");
|
||||
assert(inst->UseCount() == 1 && "Table cannot be used multiple times");
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
|
||||
assert(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
||||
|
|
@ -1668,13 +1668,13 @@ void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitCo
|
|||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorTableLookup128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
|
||||
assert(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
||||
|
|
@ -1732,7 +1732,7 @@ void EmitIR<IR::Opcode::VectorTableLookup128>(oaknut::CodeGenerator& code, EmitC
|
|||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1780,7 +1780,7 @@ void EmitIR<IR::Opcode::VectorUnsignedMultiply16>(oaknut::CodeGenerator& code, E
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -1788,7 +1788,7 @@ void EmitIR<IR::Opcode::VectorUnsignedMultiply32>(oaknut::CodeGenerator& code, E
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->D2(), Qa->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* ins
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->D2(), Qm->D2(), Qn->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -139,7 +139,7 @@ static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Ins
|
|||
const u8 fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
const bool fpcr_controlled = args[3].GetImmediateU1();
|
||||
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
assert(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
RegAlloc::Realize(Qto, Qfrom);
|
||||
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
|
|
@ -148,7 +148,7 @@ static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Ins
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qto->D2(), Qfrom->D2(), fbits);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
|
|||
} else if constexpr (fsize == 64) {
|
||||
return Qto->D2();
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}();
|
||||
auto Vfrom = [&] {
|
||||
|
|
@ -179,7 +179,7 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
|
|||
} else if constexpr (fsize == 64) {
|
||||
return Qfrom->D2();
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}();
|
||||
|
||||
|
|
@ -199,7 +199,7 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
ASSERT(fbits == 0);
|
||||
assert(fbits == 0);
|
||||
if constexpr (is_signed) {
|
||||
switch (rounding_mode) {
|
||||
case FP::RoundingMode::ToNearest_TieEven:
|
||||
|
|
@ -218,10 +218,10 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
|
|||
code.FCVTAS(Vto, Vfrom);
|
||||
break;
|
||||
case FP::RoundingMode::ToOdd:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
} else {
|
||||
switch (rounding_mode) {
|
||||
|
|
@ -241,10 +241,10 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
|
|||
code.FCVTAU(Vto, Vfrom);
|
||||
break;
|
||||
case FP::RoundingMode::ToOdd:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -329,7 +329,7 @@ void EmitIR<IR::Opcode::FPVectorEqual16>(oaknut::CodeGenerator& code, EmitContex
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -346,7 +346,7 @@ template<>
|
|||
void EmitIR<IR::Opcode::FPVectorFromHalf32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const auto rounding_mode = static_cast<FP::RoundingMode>(args[1].GetImmediateU8());
|
||||
ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
|
||||
assert(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
|
||||
const bool fpcr_controlled = args[2].GetImmediateU1();
|
||||
|
||||
auto Qresult = ctx.reg_alloc.WriteQ(inst);
|
||||
|
|
@ -454,7 +454,7 @@ void EmitIR<IR::Opcode::FPVectorMulAdd16>(oaknut::CodeGenerator& code, EmitConte
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -482,7 +482,7 @@ void EmitIR<IR::Opcode::FPVectorNeg16>(oaknut::CodeGenerator& code, EmitContext&
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -527,7 +527,7 @@ void EmitIR<IR::Opcode::FPVectorRecipEstimate16>(oaknut::CodeGenerator& code, Em
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -545,7 +545,7 @@ void EmitIR<IR::Opcode::FPVectorRecipStepFused16>(oaknut::CodeGenerator& code, E
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -599,7 +599,7 @@ void EmitIR<IR::Opcode::FPVectorRoundInt16>(oaknut::CodeGenerator& code, EmitCon
|
|||
: EmitTwoOpFallback<3>(code, ctx, inst, EmitIRVectorRoundInt16Thunk<FPT, FP::RoundingMode::ToNearest_TieAwayFromZero, false>);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -617,7 +617,7 @@ void EmitIR<IR::Opcode::FPVectorRoundInt32>(oaknut::CodeGenerator& code, EmitCon
|
|||
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
if (exact) {
|
||||
ASSERT(ctx.FPCR(fpcr_controlled).RMode() == rounding_mode);
|
||||
assert(ctx.FPCR(fpcr_controlled).RMode() == rounding_mode);
|
||||
code.FRINTX(Qresult->S4(), Qoperand->S4());
|
||||
} else {
|
||||
switch (rounding_mode) {
|
||||
|
|
@ -637,7 +637,7 @@ void EmitIR<IR::Opcode::FPVectorRoundInt32>(oaknut::CodeGenerator& code, EmitCon
|
|||
code.FRINTA(Qresult->S4(), Qoperand->S4());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -657,7 +657,7 @@ void EmitIR<IR::Opcode::FPVectorRoundInt64>(oaknut::CodeGenerator& code, EmitCon
|
|||
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
if (exact) {
|
||||
ASSERT(ctx.FPCR(fpcr_controlled).RMode() == rounding_mode);
|
||||
assert(ctx.FPCR(fpcr_controlled).RMode() == rounding_mode);
|
||||
code.FRINTX(Qresult->D2(), Qoperand->D2());
|
||||
} else {
|
||||
switch (rounding_mode) {
|
||||
|
|
@ -677,7 +677,7 @@ void EmitIR<IR::Opcode::FPVectorRoundInt64>(oaknut::CodeGenerator& code, EmitCon
|
|||
code.FRINTA(Qresult->D2(), Qoperand->D2());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -688,7 +688,7 @@ void EmitIR<IR::Opcode::FPVectorRSqrtEstimate16>(oaknut::CodeGenerator& code, Em
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -706,7 +706,7 @@ void EmitIR<IR::Opcode::FPVectorRSqrtStepFused16>(oaknut::CodeGenerator& code, E
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -743,7 +743,7 @@ template<>
|
|||
void EmitIR<IR::Opcode::FPVectorToHalf32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const auto rounding_mode = static_cast<FP::RoundingMode>(args[1].GetImmediateU8());
|
||||
ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
|
||||
assert(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
|
||||
const bool fpcr_controlled = args[2].GetImmediateU1();
|
||||
|
||||
auto Dresult = ctx.reg_alloc.WriteD(inst);
|
||||
|
|
@ -761,7 +761,7 @@ void EmitIR<IR::Opcode::FPVectorToSignedFixed16>(oaknut::CodeGenerator& code, Em
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -779,7 +779,7 @@ void EmitIR<IR::Opcode::FPVectorToUnsignedFixed16>(oaknut::CodeGenerator& code,
|
|||
(void)code;
|
||||
(void)ctx;
|
||||
(void)inst;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ static void Emit(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitF
|
|||
} else if constexpr (size == 64) {
|
||||
emit(Qresult->D2(), Qa->D2(), Qb->D2());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
|
||||
namespace Dynarmic {
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ constexpr size_t xmrx(size_t x) noexcept {
|
|||
}
|
||||
|
||||
struct DoNotFastmemMarkerHash {
|
||||
[[nodiscard]] constexpr size_t operator()(const DoNotFastmemMarker& value) const noexcept {
|
||||
[[nodiscard]] size_t operator()(const DoNotFastmemMarker& value) const noexcept {
|
||||
return xmrx(std::get<0>(value).Value() ^ u64(std::get<1>(value)));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#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"
|
||||
|
|
@ -53,19 +53,19 @@ bool Argument::GetImmediateU1() const {
|
|||
|
||||
u8 Argument::GetImmediateU8() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x100);
|
||||
assert(imm < 0x100);
|
||||
return u8(imm);
|
||||
}
|
||||
|
||||
u16 Argument::GetImmediateU16() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x10000);
|
||||
assert(imm < 0x10000);
|
||||
return u16(imm);
|
||||
}
|
||||
|
||||
u32 Argument::GetImmediateU32() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x100000000);
|
||||
assert(imm < 0x100000000);
|
||||
return u32(imm);
|
||||
}
|
||||
|
||||
|
|
@ -74,12 +74,12 @@ u64 Argument::GetImmediateU64() const {
|
|||
}
|
||||
|
||||
IR::Cond Argument::GetImmediateCond() const {
|
||||
ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
|
||||
assert(IsImmediate() && GetType() == IR::Type::Cond);
|
||||
return value.GetCond();
|
||||
}
|
||||
|
||||
IR::AccType Argument::GetImmediateAccType() const {
|
||||
ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
|
||||
assert(IsImmediate() && GetType() == IR::Type::AccType);
|
||||
return value.GetAccType();
|
||||
}
|
||||
|
||||
|
|
@ -92,12 +92,12 @@ bool HostLocInfo::Contains(const IR::Inst* value) const {
|
|||
}
|
||||
|
||||
void HostLocInfo::SetupScratchLocation() {
|
||||
ASSERT(IsCompletelyEmpty());
|
||||
assert(IsCompletelyEmpty());
|
||||
realized = true;
|
||||
}
|
||||
|
||||
void HostLocInfo::SetupLocation(const IR::Inst* value) {
|
||||
ASSERT(IsCompletelyEmpty());
|
||||
assert(IsCompletelyEmpty());
|
||||
values.clear();
|
||||
values.push_back(value);
|
||||
realized = true;
|
||||
|
|
@ -135,7 +135,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
|||
const IR::Value arg = inst->GetArg(i);
|
||||
ret[i].value = arg;
|
||||
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
|
||||
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
|
||||
assert(ValueLocation(arg.GetInst()) && "argument must already been defined");
|
||||
ValueInfo(arg.GetInst()).uses_this_inst++;
|
||||
}
|
||||
}
|
||||
|
|
@ -174,11 +174,11 @@ void RegAlloc::PrepareForCall(std::optional<Argument::copyable_reference> arg0,
|
|||
for (int i = 0; i < 4; i++) {
|
||||
if (args[i]) {
|
||||
if (args[i]->get().GetType() == IR::Type::U128) {
|
||||
ASSERT(fprs[nsrn].IsCompletelyEmpty());
|
||||
assert(fprs[nsrn].IsCompletelyEmpty());
|
||||
LoadCopyInto(args[i]->get().value, oaknut::QReg{nsrn});
|
||||
nsrn++;
|
||||
} else {
|
||||
ASSERT(gprs[ngrn].IsCompletelyEmpty());
|
||||
assert(gprs[ngrn].IsCompletelyEmpty());
|
||||
LoadCopyInto(args[i]->get().value, oaknut::XReg{ngrn});
|
||||
ngrn++;
|
||||
}
|
||||
|
|
@ -192,7 +192,7 @@ void RegAlloc::PrepareForCall(std::optional<Argument::copyable_reference> arg0,
|
|||
|
||||
void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
|
||||
defined_insts.insert(inst);
|
||||
ASSERT(!ValueLocation(inst));
|
||||
assert(!ValueLocation(inst));
|
||||
|
||||
if (arg.value.IsImmediate()) {
|
||||
inst->ReplaceUsesWith(arg.value);
|
||||
|
|
@ -206,9 +206,9 @@ void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
|
|||
|
||||
void RegAlloc::DefineAsRegister(IR::Inst* inst, oaknut::Reg reg) {
|
||||
defined_insts.insert(inst);
|
||||
ASSERT(!ValueLocation(inst));
|
||||
assert(!ValueLocation(inst));
|
||||
auto& info = reg.is_vector() ? fprs[reg.index()] : gprs[reg.index()];
|
||||
ASSERT(info.IsCompletelyEmpty());
|
||||
assert(info.IsCompletelyEmpty());
|
||||
info.values.push_back(inst);
|
||||
info.expected_uses += inst->UseCount();
|
||||
}
|
||||
|
|
@ -228,18 +228,18 @@ void RegAlloc::UpdateAllUses() {
|
|||
|
||||
void RegAlloc::AssertAllUnlocked() const {
|
||||
const auto is_unlocked = [](const auto& i) { return !i.locked && !i.realized; };
|
||||
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_unlocked));
|
||||
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_unlocked));
|
||||
ASSERT(is_unlocked(flags));
|
||||
ASSERT(std::all_of(spills.begin(), spills.end(), is_unlocked));
|
||||
assert(std::all_of(gprs.begin(), gprs.end(), is_unlocked));
|
||||
assert(std::all_of(fprs.begin(), fprs.end(), is_unlocked));
|
||||
assert(is_unlocked(flags));
|
||||
assert(std::all_of(spills.begin(), spills.end(), is_unlocked));
|
||||
}
|
||||
|
||||
void RegAlloc::AssertNoMoreUses() const {
|
||||
const auto is_empty = [](const auto& i) { return i.IsCompletelyEmpty(); };
|
||||
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
|
||||
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
|
||||
ASSERT(is_empty(flags));
|
||||
ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
|
||||
assert(std::all_of(gprs.begin(), gprs.end(), is_empty));
|
||||
assert(std::all_of(fprs.begin(), fprs.end(), is_empty));
|
||||
assert(is_empty(flags));
|
||||
assert(std::all_of(spills.begin(), spills.end(), is_empty));
|
||||
}
|
||||
|
||||
void RegAlloc::EmitVerboseDebuggingOutput() {
|
||||
|
|
@ -271,7 +271,7 @@ void RegAlloc::EmitVerboseDebuggingOutput() {
|
|||
|
||||
template<HostLoc::Kind kind>
|
||||
int RegAlloc::GenerateImmediate(const IR::Value& value) {
|
||||
ASSERT(value.GetType() != IR::Type::U1);
|
||||
assert(value.GetType() != IR::Type::U1);
|
||||
if constexpr (kind == HostLoc::Kind::Gpr) {
|
||||
const int new_location_index = AllocateRegister(gprs, gpr_order);
|
||||
SpillGpr(new_location_index);
|
||||
|
|
@ -298,7 +298,7 @@ int RegAlloc::GenerateImmediate(const IR::Value& value) {
|
|||
|
||||
return 0;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -309,15 +309,15 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
}
|
||||
|
||||
const auto current_location = ValueLocation(value.GetInst());
|
||||
ASSERT(current_location);
|
||||
assert(current_location);
|
||||
|
||||
if (current_location->kind == required_kind) {
|
||||
ValueInfo(*current_location).realized = true;
|
||||
return current_location->index;
|
||||
}
|
||||
|
||||
ASSERT(!ValueInfo(*current_location).realized);
|
||||
ASSERT(ValueInfo(*current_location).locked);
|
||||
assert(!ValueInfo(*current_location).realized);
|
||||
assert(ValueInfo(*current_location).locked);
|
||||
|
||||
if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||
const int new_location_index = AllocateRegister(gprs, gpr_order);
|
||||
|
|
@ -325,10 +325,10 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
|
||||
switch (current_location->kind) {
|
||||
case HostLoc::Kind::Gpr:
|
||||
UNREACHABLE(); //logic error
|
||||
std::terminate(); //unreachable //logic error
|
||||
case HostLoc::Kind::Fpr:
|
||||
code.FMOV(oaknut::XReg{new_location_index}, oaknut::DReg{current_location->index});
|
||||
// ASSERT size fits
|
||||
// assert size fits
|
||||
break;
|
||||
case HostLoc::Kind::Spill:
|
||||
code.LDR(oaknut::XReg{new_location_index}, SP, spill_offset + current_location->index * spill_slot_size);
|
||||
|
|
@ -350,12 +350,12 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
code.FMOV(oaknut::DReg{new_location_index}, oaknut::XReg{current_location->index});
|
||||
break;
|
||||
case HostLoc::Kind::Fpr:
|
||||
UNREACHABLE(); //logic error
|
||||
std::terminate(); //unreachable //logic error
|
||||
case HostLoc::Kind::Spill:
|
||||
code.LDR(oaknut::QReg{new_location_index}, SP, spill_offset + current_location->index * spill_slot_size);
|
||||
break;
|
||||
case HostLoc::Kind::Flags:
|
||||
ASSERT(false && "Moving from flags into fprs is not currently supported");
|
||||
assert(false && "Moving from flags into fprs is not currently supported");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -363,16 +363,16 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
fprs[new_location_index].realized = true;
|
||||
return new_location_index;
|
||||
} else if constexpr (required_kind == HostLoc::Kind::Flags) {
|
||||
UNREACHABLE(); //A simple read from flags is likely a logic error
|
||||
std::terminate(); //unreachable //A simple read from flags is likely a logic error
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
template<HostLoc::Kind kind>
|
||||
int RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
||||
defined_insts.insert(value);
|
||||
ASSERT(!ValueLocation(value));
|
||||
assert(!ValueLocation(value));
|
||||
|
||||
if constexpr (kind == HostLoc::Kind::Gpr) {
|
||||
const int new_location_index = AllocateRegister(gprs, gpr_order);
|
||||
|
|
@ -389,7 +389,7 @@ int RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
|||
flags.SetupLocation(value);
|
||||
return 0;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -407,9 +407,9 @@ int RegAlloc::RealizeReadWriteImpl(const IR::Value& read_value, const IR::Inst*
|
|||
LoadCopyInto(read_value, oaknut::QReg{write_loc});
|
||||
return write_loc;
|
||||
} else if constexpr (kind == HostLoc::Kind::Flags) {
|
||||
ASSERT(false && "Incorrect function for ReadWrite of flags");
|
||||
assert(false && "Incorrect function for ReadWrite of flags");
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -439,7 +439,7 @@ int RegAlloc::AllocateRegister(const std::array<HostLocInfo, 32>& regs, const st
|
|||
}
|
||||
|
||||
void RegAlloc::SpillGpr(int index) {
|
||||
ASSERT(!gprs[index].locked && !gprs[index].realized);
|
||||
assert(!gprs[index].locked && !gprs[index].realized);
|
||||
if (gprs[index].values.empty()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -449,7 +449,7 @@ void RegAlloc::SpillGpr(int index) {
|
|||
}
|
||||
|
||||
void RegAlloc::SpillFpr(int index) {
|
||||
ASSERT(!fprs[index].locked && !fprs[index].realized);
|
||||
assert(!fprs[index].locked && !fprs[index].realized);
|
||||
if (fprs[index].values.empty()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -461,7 +461,7 @@ void RegAlloc::SpillFpr(int index) {
|
|||
void RegAlloc::ReadWriteFlags(Argument& read, IR::Inst* write) {
|
||||
defined_insts.insert(write);
|
||||
const auto current_location = ValueLocation(read.value.GetInst());
|
||||
ASSERT(current_location);
|
||||
assert(current_location);
|
||||
|
||||
if (current_location->kind == HostLoc::Kind::Flags) {
|
||||
if (!flags.IsOneRemainingUse()) {
|
||||
|
|
@ -479,7 +479,7 @@ void RegAlloc::ReadWriteFlags(Argument& read, IR::Inst* write) {
|
|||
code.LDR(Wscratch0, SP, spill_offset + current_location->index * spill_slot_size);
|
||||
code.MSR(oaknut::SystemReg::NZCV, Xscratch0);
|
||||
} else {
|
||||
UNREACHABLE(); //ASSERT(false && "Invalid current location for flags");
|
||||
std::terminate(); //unreachable //assert(false && "Invalid current location for flags");
|
||||
}
|
||||
|
||||
if (write) {
|
||||
|
|
@ -489,7 +489,7 @@ void RegAlloc::ReadWriteFlags(Argument& read, IR::Inst* write) {
|
|||
}
|
||||
|
||||
void RegAlloc::SpillFlags() {
|
||||
ASSERT(!flags.locked && !flags.realized);
|
||||
assert(!flags.locked && !flags.realized);
|
||||
if (flags.values.empty()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -501,7 +501,7 @@ void RegAlloc::SpillFlags() {
|
|||
|
||||
int RegAlloc::FindFreeSpill() const {
|
||||
const auto iter = std::find_if(spills.begin(), spills.end(), [](const HostLocInfo& info) { return info.values.empty(); });
|
||||
ASSERT(iter != spills.end() && "All spill locations are full");
|
||||
assert(iter != spills.end() && "All spill locations are full");
|
||||
return static_cast<int>(iter - spills.begin());
|
||||
}
|
||||
|
||||
|
|
@ -512,14 +512,14 @@ void RegAlloc::LoadCopyInto(const IR::Value& value, oaknut::XReg reg) {
|
|||
}
|
||||
|
||||
const auto current_location = ValueLocation(value.GetInst());
|
||||
ASSERT(current_location);
|
||||
assert(current_location);
|
||||
switch (current_location->kind) {
|
||||
case HostLoc::Kind::Gpr:
|
||||
code.MOV(reg, oaknut::XReg{current_location->index});
|
||||
break;
|
||||
case HostLoc::Kind::Fpr:
|
||||
code.FMOV(reg, oaknut::DReg{current_location->index});
|
||||
// ASSERT size fits
|
||||
// assert size fits
|
||||
break;
|
||||
case HostLoc::Kind::Spill:
|
||||
code.LDR(reg, SP, spill_offset + current_location->index * spill_slot_size);
|
||||
|
|
@ -538,7 +538,7 @@ void RegAlloc::LoadCopyInto(const IR::Value& value, oaknut::QReg reg) {
|
|||
}
|
||||
|
||||
const auto current_location = ValueLocation(value.GetInst());
|
||||
ASSERT(current_location);
|
||||
assert(current_location);
|
||||
switch (current_location->kind) {
|
||||
case HostLoc::Kind::Gpr:
|
||||
code.FMOV(reg.toD(), oaknut::XReg{current_location->index});
|
||||
|
|
@ -551,7 +551,7 @@ void RegAlloc::LoadCopyInto(const IR::Value& value, oaknut::QReg reg) {
|
|||
code.LDR(reg, SP, spill_offset + current_location->index * spill_slot_size);
|
||||
break;
|
||||
case HostLoc::Kind::Flags:
|
||||
UNREACHABLE(); //ASSERT(false && "Moving from flags into fprs is not currently supported");
|
||||
std::terminate(); //unreachable //assert(false && "Moving from flags into fprs is not currently supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -584,7 +584,7 @@ HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) {
|
|||
case HostLoc::Kind::Spill:
|
||||
return spills[static_cast<size_t>(host_loc.index)];
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
|
||||
|
|
@ -599,7 +599,7 @@ HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
|
|||
} else if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != spills.end()) {
|
||||
return *iter;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::Arm64
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cassert>
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
||||
#include <oaknut/oaknut.hpp>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
|
@ -186,7 +186,7 @@ public:
|
|||
} else if constexpr (size == 32) {
|
||||
return ReadW(arg);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ public:
|
|||
} else if constexpr (size == 8) {
|
||||
return ReadB(arg);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ public:
|
|||
} else if constexpr (size == 32) {
|
||||
return WriteW(inst);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +242,7 @@ public:
|
|||
} else if constexpr (size == 8) {
|
||||
return WriteB(inst);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ public:
|
|||
} else if constexpr (size == 32) {
|
||||
return ReadWriteW(arg, inst);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ public:
|
|||
} else if constexpr (size == 8) {
|
||||
return ReadWriteB(arg, inst);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -370,7 +370,7 @@ void RAReg<T>::Realize() {
|
|||
reg = T{reg_alloc.RealizeReadWriteImpl<kind>(read_value, write_value)};
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/exception_handler.h"
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ private:
|
|||
};
|
||||
|
||||
MachHandler::MachHandler() {
|
||||
#define KCHECK(x) ASSERT((x) == KERN_SUCCESS && "init failure at " #x)
|
||||
#define KCHECK(x) assert((x) == KERN_SUCCESS && "init failure at " #x)
|
||||
KCHECK(mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server_port));
|
||||
KCHECK(mach_port_insert_right(mach_task_self(), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND));
|
||||
KCHECK(task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, server_port, EXCEPTION_STATE | MACH_EXCEPTION_CODES, THREAD_STATE));
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#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)
|
||||
|
|
@ -115,7 +116,7 @@ void RegisterHandler() {
|
|||
}
|
||||
|
||||
void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
|
||||
DEBUG_ASSERT(sig == SIGSEGV || sig == SIGBUS);
|
||||
assert(sig == SIGSEGV || sig == SIGBUS);
|
||||
CTX_DECLARE(raw_context);
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
{
|
||||
|
|
@ -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 <cassert>
|
||||
|
||||
#include "dynarmic/backend/riscv64/abi.h"
|
||||
#include "dynarmic/backend/riscv64/emit_riscv64.h"
|
||||
|
|
@ -94,7 +94,7 @@ void A32AddressSpace::EmitPrelude() {
|
|||
|
||||
void A32AddressSpace::SetCursorPtr(CodePtr ptr) {
|
||||
ptrdiff_t offset = ptr - GetMemPtr<CodePtr>();
|
||||
ASSERT(offset >= 0);
|
||||
assert(offset >= 0);
|
||||
as.RewindBuffer(offset);
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ void A32AddressSpace::Link(EmittedBlockInfo& block_info) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cassert>
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
||||
#include "dynarmic/backend/riscv64/a32_core.h"
|
||||
|
|
@ -31,7 +31,7 @@ struct Jit::Impl final {
|
|||
, core(conf) {}
|
||||
|
||||
HaltReason Run() {
|
||||
ASSERT(!jit_interface->is_executing);
|
||||
assert(!jit_interface->is_executing);
|
||||
jit_interface->is_executing = true;
|
||||
HaltReason hr = core.Run(current_address_space, current_state, &halt_reason);
|
||||
RequestCacheInvalidation();
|
||||
|
|
@ -40,9 +40,9 @@ struct Jit::Impl final {
|
|||
}
|
||||
|
||||
HaltReason Step() {
|
||||
ASSERT(!jit_interface->is_executing);
|
||||
assert(!jit_interface->is_executing);
|
||||
jit_interface->is_executing = true;
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
RequestCacheInvalidation();
|
||||
jit_interface->is_executing = false;
|
||||
return HaltReason{};
|
||||
|
|
@ -110,7 +110,7 @@ struct Jit::Impl final {
|
|||
|
||||
private:
|
||||
void RequestCacheInvalidation() {
|
||||
// UNREACHABLE();
|
||||
// std::terminate(); //unreachable
|
||||
|
||||
invalidate_entire_cache = false;
|
||||
invalid_cache_ranges.clear();
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#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() {
|
||||
// std::terminate(); //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,13 +13,16 @@
|
|||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <cassert>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::Backend::RV64 {
|
||||
|
||||
class CodeBlock {
|
||||
public:
|
||||
explicit CodeBlock(std::size_t size) noexcept : memsize(size) {
|
||||
mem = (u8*)mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
ASSERT(mem != nullptr);
|
||||
assert(mem != nullptr);
|
||||
}
|
||||
|
||||
~CodeBlock() noexcept {
|
||||
|
|
|
|||
|
|
@ -35,39 +35,39 @@ void EmitIR<IR::Opcode::Identity>(biscuit::Assembler&, EmitContext& ctx, IR::Ins
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Breakpoint>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CallHostFunction>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PushRSB>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetCarryFromOp>(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) {
|
||||
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(ctx.reg_alloc.IsValueLive(inst));
|
||||
assert(ctx.reg_alloc.IsValueLive(inst));
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetOverflowFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetGEFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetNZCVFromOp>(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) {
|
||||
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(ctx.reg_alloc.IsValueLive(inst));
|
||||
assert(ctx.reg_alloc.IsValueLive(inst));
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -87,12 +87,12 @@ void EmitIR<IR::Opcode::GetNZFromOp>(biscuit::Assembler& as, EmitContext& ctx, I
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetUpperFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetLowerFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitConfig& emit_conf) {
|
||||
|
|
@ -143,7 +143,7 @@ EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitCon
|
|||
#undef A32OPC
|
||||
#undef A64OPC
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void EmitA32Cond(biscuit::Assembler& as, EmitContext&, IR::Cond cond, biscuit::L
|
|||
as.BNEZ(Xscratch0, label);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx) {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCpsrNZCVQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetCpsrNZ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -302,7 +302,7 @@ void EmitIR<IR::Opcode::A32SetCpsrNZC>(biscuit::Assembler& as, EmitContext& ctx,
|
|||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
// TODO: Add full implementation
|
||||
ASSERT(!args[0].IsImmediate() && !args[1].IsImmediate());
|
||||
assert(!args[0].IsImmediate() && !args[1].IsImmediate());
|
||||
|
||||
auto Xnz = ctx.reg_alloc.ReadX(args[0]);
|
||||
auto Xc = ctx.reg_alloc.ReadX(args[1]);
|
||||
|
|
@ -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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32OrQFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetGEFlagsCompressed>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32BXWritePC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32UpdateUpperLocationDescriptor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32GetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32SetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocLoadWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32CoprocStoreWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetPC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64DataCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64InstructionCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetCNTFRQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetCNTPCT>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetCTR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetDCZID>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64GetTPIDRRO>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64SetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64WriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32Castagnoli16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32Castagnoli32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32Castagnoli64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32ISO8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32ISO16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32ISO32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CRC32ISO64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AESDecryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AESEncryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AESInverseMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AESMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SM4AccessSubstitutionBox>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SHA256Hash>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SHA256MessageSchedule0>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SHA256MessageSchedule1>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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,67 +22,67 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Pack2x32To1x64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Pack2x64To1x128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LeastSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LeastSignificantHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LeastSignificantByte>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MostSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MostSignificantBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::IsZero32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::IsZero64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::TestBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ConditionalSelect32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ConditionalSelect64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ConditionalSelectNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -92,8 +95,8 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext&
|
|||
auto& carry_arg = args[2];
|
||||
|
||||
// TODO: Add full implementation
|
||||
ASSERT(carry_inst != nullptr);
|
||||
ASSERT(shift_arg.IsImmediate());
|
||||
assert(carry_inst != nullptr);
|
||||
assert(shift_arg.IsImmediate());
|
||||
|
||||
auto Xresult = ctx.reg_alloc.WriteX(inst);
|
||||
auto Xcarry_out = ctx.reg_alloc.WriteX(carry_inst);
|
||||
|
|
@ -121,7 +124,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext&
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeft64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -133,8 +136,8 @@ void EmitIR<IR::Opcode::LogicalShiftRight32>(biscuit::Assembler& as, EmitContext
|
|||
auto& shift_arg = args[1];
|
||||
|
||||
// TODO: Add full implementation
|
||||
ASSERT(carry_inst == nullptr);
|
||||
ASSERT(shift_arg.IsImmediate());
|
||||
assert(carry_inst == nullptr);
|
||||
assert(shift_arg.IsImmediate());
|
||||
|
||||
const u8 shift = shift_arg.GetImmediateU8();
|
||||
auto Xresult = ctx.reg_alloc.WriteX(inst);
|
||||
|
|
@ -150,72 +153,72 @@ void EmitIR<IR::Opcode::LogicalShiftRight32>(biscuit::Assembler& as, EmitContext
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
void EmitIR<IR::Opcode::BitRotateRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
void EmitIR<IR::Opcode::BitRotateRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightExtended>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeftMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftLeftMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::LogicalShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::RotateRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<size_t bitsize>
|
||||
|
|
@ -261,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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -276,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();
|
||||
std::terminate(); //unimplemented
|
||||
} else if (nzcv_inst) {
|
||||
if (args[1].IsImmediate()) {
|
||||
const u64 imm = args[1].GetImmediateU64();
|
||||
|
|
@ -291,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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
} else {
|
||||
if (args[1].IsImmediate()) {
|
||||
const u64 imm = args[1].GetImmediateU64();
|
||||
|
||||
if (args[2].IsImmediate()) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
} else {
|
||||
auto Xnzcv = ctx.reg_alloc.ReadX(args[2]);
|
||||
RegAlloc::Realize(Xresult, Xa, Xnzcv);
|
||||
|
|
@ -314,7 +317,7 @@ static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst)
|
|||
as.ADDW(Xresult, Xa, Xscratch0);
|
||||
}
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -326,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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -336,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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Mul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Mul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::And32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::And64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AndNot32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::AndNot64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Eor32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Eor64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Or32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Or64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Not32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::Not64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ZeroExtendLongToQuad>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ByteReverseDual>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CountLeadingZeros32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::CountLeadingZeros64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ExtractRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ExtractRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ReplicateBit32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::ReplicateBit64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MaxUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::MinUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPCompare32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPCompare64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipExponent16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipExponent32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipExponent64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPDoubleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPHalfToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPSingleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedU64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPFixedS64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedHalvingSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSaturatedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedAbsDiffSumU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::PackedSelect>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::SignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorEqual16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorGreater32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorGreater64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorGreaterEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorGreaterEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorPairedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorPairedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorPairedAddLower32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorPairedAddLower64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
}
|
||||
|
||||
} // 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 <cassert>
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/common/always_false.h"
|
||||
|
||||
|
|
@ -44,19 +44,19 @@ bool Argument::GetImmediateU1() const {
|
|||
|
||||
u8 Argument::GetImmediateU8() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x100);
|
||||
assert(imm < 0x100);
|
||||
return u8(imm);
|
||||
}
|
||||
|
||||
u16 Argument::GetImmediateU16() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x10000);
|
||||
assert(imm < 0x10000);
|
||||
return u16(imm);
|
||||
}
|
||||
|
||||
u32 Argument::GetImmediateU32() const {
|
||||
const u64 imm = value.GetImmediateAsU64();
|
||||
ASSERT(imm < 0x100000000);
|
||||
assert(imm < 0x100000000);
|
||||
return u32(imm);
|
||||
}
|
||||
|
||||
|
|
@ -65,12 +65,12 @@ u64 Argument::GetImmediateU64() const {
|
|||
}
|
||||
|
||||
IR::Cond Argument::GetImmediateCond() const {
|
||||
ASSERT(IsImmediate() && GetType() == IR::Type::Cond);
|
||||
assert(IsImmediate() && GetType() == IR::Type::Cond);
|
||||
return value.GetCond();
|
||||
}
|
||||
|
||||
IR::AccType Argument::GetImmediateAccType() const {
|
||||
ASSERT(IsImmediate() && GetType() == IR::Type::AccType);
|
||||
assert(IsImmediate() && GetType() == IR::Type::AccType);
|
||||
return value.GetAccType();
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ bool HostLocInfo::Contains(const IR::Inst* value) const {
|
|||
}
|
||||
|
||||
void HostLocInfo::SetupScratchLocation() {
|
||||
ASSERT(IsCompletelyEmpty());
|
||||
assert(IsCompletelyEmpty());
|
||||
realized = true;
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
|||
const IR::Value arg = inst->GetArg(i);
|
||||
ret[i].value = arg;
|
||||
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
|
||||
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
|
||||
assert(ValueLocation(arg.GetInst()) && "argument must already been defined");
|
||||
ValueInfo(arg.GetInst()).uses_this_inst++;
|
||||
}
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ void RegAlloc::UpdateAllUses() {
|
|||
}
|
||||
|
||||
void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
|
||||
ASSERT(!ValueLocation(inst));
|
||||
assert(!ValueLocation(inst));
|
||||
|
||||
if (arg.value.IsImmediate()) {
|
||||
inst->ReplaceUsesWith(arg.value);
|
||||
|
|
@ -142,15 +142,15 @@ void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
|
|||
|
||||
void RegAlloc::AssertNoMoreUses() const {
|
||||
const auto is_empty = [](const auto& i) { return i.IsCompletelyEmpty(); };
|
||||
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
|
||||
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
|
||||
ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
|
||||
assert(std::all_of(gprs.begin(), gprs.end(), is_empty));
|
||||
assert(std::all_of(fprs.begin(), fprs.end(), is_empty));
|
||||
assert(std::all_of(spills.begin(), spills.end(), is_empty));
|
||||
}
|
||||
|
||||
template<HostLoc::Kind kind>
|
||||
u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
|
||||
// TODO
|
||||
// ASSERT(value.GetType() != IR::Type::U1);
|
||||
// assert(value.GetType() != IR::Type::U1);
|
||||
|
||||
if constexpr (kind == HostLoc::Kind::Gpr) {
|
||||
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
|
||||
|
|
@ -161,9 +161,9 @@ u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
|
|||
|
||||
return new_location_index;
|
||||
} else if constexpr (kind == HostLoc::Kind::Fpr) {
|
||||
UNIMPLEMENTED();
|
||||
std::terminate(); //unimplemented
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -175,15 +175,15 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
}
|
||||
|
||||
const auto current_location = ValueLocation(value.GetInst());
|
||||
ASSERT(current_location);
|
||||
assert(current_location);
|
||||
|
||||
if (current_location->kind == required_kind) {
|
||||
ValueInfo(*current_location).realized = true;
|
||||
return current_location->index;
|
||||
}
|
||||
|
||||
ASSERT(!ValueInfo(*current_location).realized);
|
||||
ASSERT(!ValueInfo(*current_location).locked);
|
||||
assert(!ValueInfo(*current_location).realized);
|
||||
assert(!ValueInfo(*current_location).locked);
|
||||
|
||||
if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
|
||||
|
|
@ -191,10 +191,10 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
|
||||
switch (current_location->kind) {
|
||||
case HostLoc::Kind::Gpr:
|
||||
UNREACHABLE(); //logic error
|
||||
std::terminate(); //unreachable //logic error
|
||||
case HostLoc::Kind::Fpr:
|
||||
as.FMV_X_D(biscuit::GPR(new_location_index), biscuit::FPR{current_location->index});
|
||||
// ASSERT size fits
|
||||
// assert size fits
|
||||
break;
|
||||
case HostLoc::Kind::Spill:
|
||||
as.LD(biscuit::GPR{new_location_index}, spill_offset + current_location->index * spill_slot_size, biscuit::sp);
|
||||
|
|
@ -213,7 +213,7 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
as.FMV_D_X(biscuit::FPR{new_location_index}, biscuit::GPR(current_location->index));
|
||||
break;
|
||||
case HostLoc::Kind::Fpr:
|
||||
UNREACHABLE(); //logic error
|
||||
std::terminate(); //unreachable //logic error
|
||||
case HostLoc::Kind::Spill:
|
||||
as.FLD(biscuit::FPR{new_location_index}, spill_offset + current_location->index * spill_slot_size, biscuit::sp);
|
||||
break;
|
||||
|
|
@ -223,13 +223,13 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
fprs[new_location_index].realized = true;
|
||||
return new_location_index;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
template<HostLoc::Kind required_kind>
|
||||
u32 RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
||||
ASSERT(!ValueLocation(value));
|
||||
assert(!ValueLocation(value));
|
||||
|
||||
const auto setup_location = [&](HostLocInfo& info) {
|
||||
info = {};
|
||||
|
|
@ -250,7 +250,7 @@ u32 RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
|||
setup_location(fprs[new_location_index]);
|
||||
return new_location_index;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ u32 RegAlloc::AllocateRegister(const std::array<HostLocInfo, 32>& regs, const st
|
|||
}
|
||||
|
||||
void RegAlloc::SpillGpr(u32 index) {
|
||||
ASSERT(!gprs[index].locked && !gprs[index].realized);
|
||||
assert(!gprs[index].locked && !gprs[index].realized);
|
||||
if (gprs[index].values.empty()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ void RegAlloc::SpillGpr(u32 index) {
|
|||
}
|
||||
|
||||
void RegAlloc::SpillFpr(u32 index) {
|
||||
ASSERT(!fprs[index].locked && !fprs[index].realized);
|
||||
assert(!fprs[index].locked && !fprs[index].realized);
|
||||
if (fprs[index].values.empty()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -295,7 +295,7 @@ void RegAlloc::SpillFpr(u32 index) {
|
|||
|
||||
u32 RegAlloc::FindFreeSpill() const {
|
||||
const auto iter = std::find_if(spills.begin(), spills.end(), [](const HostLocInfo& info) { return info.values.empty(); });
|
||||
ASSERT(iter != spills.end() && "All spill locations are full");
|
||||
assert(iter != spills.end() && "All spill locations are full");
|
||||
return static_cast<u32>(iter - spills.begin());
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +322,7 @@ HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) {
|
|||
case HostLoc::Kind::Spill:
|
||||
return spills[size_t(host_loc.index)];
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
|
||||
|
|
@ -336,7 +336,7 @@ HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
|
|||
} else if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != gprs.end()) {
|
||||
return *iter;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#include <biscuit/assembler.hpp>
|
||||
#include <biscuit/registers.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cassert>
|
||||
#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 <cassert>
|
||||
#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"
|
||||
|
|
@ -56,7 +56,7 @@ static Xbyak::Address MJitStateExtReg(A32::ExtReg reg) {
|
|||
const size_t index = size_t(reg) - size_t(A32::ExtReg::Q0);
|
||||
return xword[BlockOfCode::ABI_JIT_PTR + offsetof(A32JitState, ExtReg) + 2 * sizeof(u64) * index];
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
A32EmitContext::A32EmitContext(const A32::UserConfig& conf, RegAlloc& reg_alloc, IR::Block& block)
|
||||
|
|
@ -135,7 +135,7 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
|
|||
#undef A32OPC
|
||||
#undef A64OPC
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
reg_alloc.EndOfAllocScope();
|
||||
#ifndef NDEBUG
|
||||
|
|
@ -183,11 +183,11 @@ void A32EmitX64::InvalidateCacheRanges(const boost::icl::interval_set<u32>& rang
|
|||
|
||||
void A32EmitX64::EmitCondPrelude(const A32EmitContext& ctx) {
|
||||
if (ctx.block.GetCondition() == IR::Cond::AL) {
|
||||
ASSERT(!ctx.block.HasConditionFailedLocation());
|
||||
assert(!ctx.block.HasConditionFailedLocation());
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(ctx.block.HasConditionFailedLocation());
|
||||
assert(ctx.block.HasConditionFailedLocation());
|
||||
|
||||
Xbyak::Label pass = EmitCond(ctx.block.GetCondition());
|
||||
if (conf.enable_cycle_counting) {
|
||||
|
|
@ -285,7 +285,7 @@ void A32EmitX64::EmitA32GetRegister(A32EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void A32EmitX64::EmitA32GetExtendedRegister32(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsSingleExtReg(reg));
|
||||
assert(A32::IsSingleExtReg(reg));
|
||||
|
||||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
code.movss(result, MJitStateExtReg(reg));
|
||||
|
|
@ -294,7 +294,7 @@ void A32EmitX64::EmitA32GetExtendedRegister32(A32EmitContext& ctx, IR::Inst* ins
|
|||
|
||||
void A32EmitX64::EmitA32GetExtendedRegister64(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsDoubleExtReg(reg));
|
||||
assert(A32::IsDoubleExtReg(reg));
|
||||
|
||||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
code.movsd(result, MJitStateExtReg(reg));
|
||||
|
|
@ -303,7 +303,7 @@ void A32EmitX64::EmitA32GetExtendedRegister64(A32EmitContext& ctx, IR::Inst* ins
|
|||
|
||||
void A32EmitX64::EmitA32GetVector(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||
assert(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||
|
||||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
if (A32::IsDoubleExtReg(reg)) {
|
||||
|
|
@ -332,7 +332,7 @@ void A32EmitX64::EmitA32SetRegister(A32EmitContext& ctx, IR::Inst* inst) {
|
|||
void A32EmitX64::EmitA32SetExtendedRegister32(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsSingleExtReg(reg));
|
||||
assert(A32::IsSingleExtReg(reg));
|
||||
|
||||
if (args[1].IsInXmm(ctx.reg_alloc)) {
|
||||
Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||
|
|
@ -346,7 +346,7 @@ void A32EmitX64::EmitA32SetExtendedRegister32(A32EmitContext& ctx, IR::Inst* ins
|
|||
void A32EmitX64::EmitA32SetExtendedRegister64(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsDoubleExtReg(reg));
|
||||
assert(A32::IsDoubleExtReg(reg));
|
||||
|
||||
if (args[1].IsInXmm(ctx.reg_alloc)) {
|
||||
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||
|
|
@ -360,7 +360,7 @@ void A32EmitX64::EmitA32SetExtendedRegister64(A32EmitContext& ctx, IR::Inst* ins
|
|||
void A32EmitX64::EmitA32SetVector(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||
assert(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||
|
||||
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||
if (A32::IsDoubleExtReg(reg)) {
|
||||
|
|
@ -621,7 +621,7 @@ void A32EmitX64::EmitA32GetGEFlags(A32EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void A32EmitX64::EmitA32SetGEFlags(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(!args[0].IsImmediate());
|
||||
assert(!args[0].IsImmediate());
|
||||
|
||||
if (args[0].IsInXmm(ctx.reg_alloc)) {
|
||||
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(code, args[0]);
|
||||
|
|
@ -762,7 +762,7 @@ void A32EmitX64::EmitA32ExceptionRaised(A32EmitContext& ctx, IR::Inst* inst) {
|
|||
ctx.reg_alloc.EndOfAllocScope();
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[0].IsImmediate() && args[1].IsImmediate());
|
||||
assert(args[0].IsImmediate() && args[1].IsImmediate());
|
||||
const u32 pc = args[0].GetImmediateU32();
|
||||
const u64 exception = args[1].GetImmediateU64();
|
||||
Devirtualize<&A32::UserCallbacks::ExceptionRaised>(conf.callbacks).EmitCall(code, [&](RegList param) {
|
||||
|
|
@ -833,7 +833,7 @@ void A32EmitX64::EmitA32SetFpscrNZCV(A32EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
static void EmitCoprocessorException() {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
static void CallCoprocCallback(BlockOfCode& code, RegAlloc& reg_alloc, A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr, std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}) {
|
||||
|
|
@ -909,7 +909,7 @@ void A32EmitX64::EmitA32CoprocSendOneWord(A32EmitContext& ctx, IR::Inst* inst) {
|
|||
return;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void A32EmitX64::EmitA32CoprocSendTwoWords(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -952,7 +952,7 @@ void A32EmitX64::EmitA32CoprocSendTwoWords(A32EmitContext& ctx, IR::Inst* inst)
|
|||
return;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void A32EmitX64::EmitA32CoprocGetOneWord(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -995,7 +995,7 @@ void A32EmitX64::EmitA32CoprocGetOneWord(A32EmitContext& ctx, IR::Inst* inst) {
|
|||
return;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void A32EmitX64::EmitA32CoprocGetTwoWords(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -1040,7 +1040,7 @@ void A32EmitX64::EmitA32CoprocGetTwoWords(A32EmitContext& ctx, IR::Inst* inst) {
|
|||
return;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void A32EmitX64::EmitA32CoprocLoadWords(A32EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -1216,7 +1216,7 @@ void EmitTerminalImpl(A32EmitX64& e, IR::Term::CheckHalt terminal, IR::LocationD
|
|||
}
|
||||
|
||||
void EmitTerminalImpl(A32EmitX64&, IR::Term::Invalid, IR::LocationDescriptor, bool) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <cassert>
|
||||
#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"
|
||||
|
|
@ -74,7 +74,7 @@ struct Jit::Impl {
|
|||
~Impl() = default;
|
||||
|
||||
HaltReason Run() {
|
||||
ASSERT(!jit_interface->is_executing);
|
||||
assert(!jit_interface->is_executing);
|
||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason)));
|
||||
jit_interface->is_executing = true;
|
||||
const CodePtr current_codeptr = [this] {
|
||||
|
|
@ -94,7 +94,7 @@ struct Jit::Impl {
|
|||
}
|
||||
|
||||
HaltReason Step() {
|
||||
ASSERT(!jit_interface->is_executing);
|
||||
assert(!jit_interface->is_executing);
|
||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason)));
|
||||
jit_interface->is_executing = true;
|
||||
const HaltReason hr = block_of_code.StepCode(&jit_state, GetCurrentSingleStep());
|
||||
|
|
@ -116,7 +116,7 @@ struct Jit::Impl {
|
|||
}
|
||||
|
||||
void Reset() {
|
||||
ASSERT(!jit_interface->is_executing);
|
||||
assert(!jit_interface->is_executing);
|
||||
jit_state = {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <cassert>
|
||||
#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"
|
||||
|
|
@ -51,8 +51,8 @@ namespace Dynarmic::Backend::X64 {
|
|||
*/
|
||||
|
||||
u32 A32JitState::Cpsr() const {
|
||||
DEBUG_ASSERT((cpsr_q & ~1) == 0);
|
||||
DEBUG_ASSERT((cpsr_jaifm & ~0x010001DF) == 0);
|
||||
assert((cpsr_q & ~1) == 0);
|
||||
assert((cpsr_jaifm & ~0x010001DF) == 0);
|
||||
|
||||
u32 cpsr = 0;
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ constexpr u32 FPSCR_MODE_MASK = A32::LocationDescriptor::FPSCR_MODE_MASK;
|
|||
constexpr u32 FPSCR_NZCV_MASK = 0xF0000000;
|
||||
|
||||
u32 A32JitState::Fpscr() const {
|
||||
DEBUG_ASSERT((fpsr_nzcv & ~FPSCR_NZCV_MASK) == 0);
|
||||
assert((fpsr_nzcv & ~FPSCR_NZCV_MASK) == 0);
|
||||
|
||||
const u32 fpcr_mode = static_cast<u32>(upper_location_descriptor) & FPSCR_MODE_MASK;
|
||||
const u32 mxcsr = guest_MXCSR | asimd_MXCSR;
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
||||
#include <boost/container/static_vector.hpp>
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) noexcept {
|
|||
code.align();
|
||||
const auto* const entrypoint = code.getCurr();
|
||||
|
||||
DEBUG_ASSERT(block.GetCondition() == IR::Cond::AL);
|
||||
assert(block.GetCondition() == IR::Cond::AL);
|
||||
typedef void (EmitX64::*EmitHandlerFn)(EmitContext& context, IR::Inst* inst);
|
||||
constexpr EmitHandlerFn opcode_handlers[] = {
|
||||
#define OPCODE(name, type, ...) &EmitX64::Emit##name,
|
||||
|
|
@ -123,7 +123,7 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) noexcept {
|
|||
#undef A32OPC
|
||||
#undef A64OPC
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
opcode_branch:
|
||||
(this->*opcode_handlers[size_t(opcode)])(ctx, &inst);
|
||||
|
|
@ -497,7 +497,7 @@ void A64EmitX64::EmitA64SetPC(A64EmitContext& ctx, IR::Inst* inst) {
|
|||
void A64EmitX64::EmitA64CallSupervisor(A64EmitContext& ctx, IR::Inst* inst) {
|
||||
ctx.reg_alloc.HostCall(code, nullptr);
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[0].IsImmediate());
|
||||
assert(args[0].IsImmediate());
|
||||
const u32 imm = args[0].GetImmediateU32();
|
||||
Devirtualize<&A64::UserCallbacks::CallSVC>(conf.callbacks).EmitCall(code, [&](RegList param) {
|
||||
code.mov(param[0], imm);
|
||||
|
|
@ -509,7 +509,7 @@ void A64EmitX64::EmitA64CallSupervisor(A64EmitContext& ctx, IR::Inst* inst) {
|
|||
void A64EmitX64::EmitA64ExceptionRaised(A64EmitContext& ctx, IR::Inst* inst) {
|
||||
ctx.reg_alloc.HostCall(code, nullptr);
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[0].IsImmediate() && args[1].IsImmediate());
|
||||
assert(args[0].IsImmediate() && args[1].IsImmediate());
|
||||
const u64 pc = args[0].GetImmediateU64();
|
||||
const u64 exception = args[1].GetImmediateU64();
|
||||
Devirtualize<&A64::UserCallbacks::ExceptionRaised>(conf.callbacks).EmitCall(code, [&](RegList param) {
|
||||
|
|
@ -710,7 +710,7 @@ void EmitTerminalImpl(A64EmitX64& e, IR::Term::CheckHalt terminal, IR::LocationD
|
|||
}
|
||||
|
||||
void EmitTerminalImpl(A64EmitX64&, IR::Term::Invalid, IR::LocationDescriptor, bool) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <mutex>
|
||||
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <cassert>
|
||||
#include "dynarmic/common/fp/fpcr.h"
|
||||
#include "dynarmic/common/llvm_disassemble.h"
|
||||
#include <bit>
|
||||
|
|
@ -66,13 +66,13 @@ public:
|
|||
, emitter(block_of_code, conf, jit)
|
||||
, polyfill_options(GenPolyfillOptions(block_of_code))
|
||||
{
|
||||
ASSERT(conf.page_table_address_space_bits >= 12 && conf.page_table_address_space_bits <= 64);
|
||||
assert(conf.page_table_address_space_bits >= 12 && conf.page_table_address_space_bits <= 64);
|
||||
}
|
||||
|
||||
~Impl() = default;
|
||||
|
||||
HaltReason Run() {
|
||||
ASSERT(!is_executing);
|
||||
assert(!is_executing);
|
||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason)));
|
||||
is_executing = true;
|
||||
// TODO: Check code alignment
|
||||
|
|
@ -92,7 +92,7 @@ public:
|
|||
}
|
||||
|
||||
HaltReason Step() {
|
||||
ASSERT(!is_executing);
|
||||
assert(!is_executing);
|
||||
PerformRequestedCacheInvalidation(static_cast<HaltReason>(Atomic::Load(&jit_state.halt_reason)));
|
||||
is_executing = true;
|
||||
const HaltReason hr = block_of_code.StepCode(&jit_state, GetCurrentSingleStep());
|
||||
|
|
@ -116,7 +116,7 @@ public:
|
|||
}
|
||||
|
||||
void Reset() {
|
||||
ASSERT(!is_executing);
|
||||
assert(!is_executing);
|
||||
jit_state = {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#include "dynarmic/mcl/bit.hpp"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
|
|
@ -278,12 +278,12 @@ void BlockOfCode::DisableWriting() {
|
|||
}
|
||||
|
||||
void BlockOfCode::ClearCache() {
|
||||
ASSERT(prelude_complete);
|
||||
assert(prelude_complete);
|
||||
SetCodePtr(code_begin);
|
||||
}
|
||||
|
||||
size_t BlockOfCode::SpaceRemaining() const {
|
||||
ASSERT(prelude_complete);
|
||||
assert(prelude_complete);
|
||||
const u8* current_ptr = getCurr<const u8*>();
|
||||
if (current_ptr >= &top_[maxSize_])
|
||||
return 0;
|
||||
|
|
@ -515,7 +515,7 @@ void BlockOfCode::LoadRequiredFlagsForCondFromRax(IR::Cond cond) {
|
|||
case IR::Cond::NV:
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -553,7 +553,7 @@ void BlockOfCode::SetCodePtr(CodePtr code_ptr) {
|
|||
|
||||
void BlockOfCode::EnsurePatchLocationSize(CodePtr begin, size_t size) {
|
||||
size_t current_size = getCurr<const u8*>() - reinterpret_cast<const u8*>(begin);
|
||||
ASSERT(current_size <= size);
|
||||
assert(current_size <= size);
|
||||
nop(size - current_size);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -120,7 +120,7 @@ public:
|
|||
case 64:
|
||||
return;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ Xbyak::Address ConstantPool::GetConstant(const Xbyak::AddressFrame& frame, u64 l
|
|||
const auto constant = ConstantT(lower, upper);
|
||||
auto iter = constant_info.find(constant);
|
||||
if (iter == constant_info.end()) {
|
||||
ASSERT(insertion_point < pool.size());
|
||||
assert(insertion_point < pool.size());
|
||||
ConstantT& target_constant = pool[insertion_point];
|
||||
target_constant = constant;
|
||||
iter = constant_info.insert({constant, &target_constant}).first;
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#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"
|
||||
|
|
@ -53,7 +53,7 @@ std::optional<EmitX64::BlockDescriptor> EmitX64::GetBasicBlock(IR::LocationDescr
|
|||
}
|
||||
|
||||
void EmitX64::EmitInvalid(EmitContext&, IR::Inst* inst) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void EmitX64::EmitVoid(EmitContext&, IR::Inst*) {
|
||||
|
|
@ -103,7 +103,7 @@ void EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, I
|
|||
code.mov(qword[code.ABI_JIT_PTR + index_reg * 8 + code.GetJitStateInfo().offsetof_rsb_location_descriptors], loc_desc_reg);
|
||||
code.mov(qword[code.ABI_JIT_PTR + index_reg * 8 + code.GetJitStateInfo().offsetof_rsb_codeptrs], rcx);
|
||||
// Byte size hack
|
||||
DEBUG_ASSERT(code.GetJitStateInfo().rsb_ptr_mask <= 0xFF);
|
||||
assert(code.GetJitStateInfo().rsb_ptr_mask <= 0xFF);
|
||||
code.add(index_reg.cvt32(), 1); //flags trashed, 1 single byte, haswell doesn't care
|
||||
code.and_(index_reg.cvt32(), u32(code.GetJitStateInfo().rsb_ptr_mask)); //trashes flags
|
||||
// Results ready and sort by least needed: give OOO some break
|
||||
|
|
@ -144,7 +144,7 @@ void EmitX64::EmitVerboseDebuggingOutput(RegAlloc& reg_alloc) {
|
|||
|
||||
void EmitX64::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[0].IsImmediate());
|
||||
assert(args[0].IsImmediate());
|
||||
const u64 unique_hash_of_target = args[0].GetImmediateU64();
|
||||
|
||||
ctx.reg_alloc.ScratchGpr(code, HostLoc::RCX);
|
||||
|
|
@ -193,7 +193,7 @@ void EmitX64::EmitGetNZFromOp(EmitContext& ctx, IR::Inst* inst) {
|
|||
case IR::Type::U64:
|
||||
return 64;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}();
|
||||
|
||||
|
|
@ -224,7 +224,7 @@ void EmitX64::EmitGetNZCVFromOp(EmitContext& ctx, IR::Inst* inst) {
|
|||
case IR::Type::U64:
|
||||
return 64;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}();
|
||||
|
||||
|
|
@ -284,7 +284,7 @@ void EmitX64::EmitNZCVFromPackedFlags(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
void EmitX64::EmitAddCycles(size_t cycles) {
|
||||
ASSERT(cycles < (std::numeric_limits<s32>::max)());
|
||||
assert(cycles < (std::numeric_limits<s32>::max)());
|
||||
code.sub(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], static_cast<u32>(cycles));
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +339,7 @@ Xbyak::Label EmitX64::EmitCond(IR::Cond cond) {
|
|||
code.jle(pass);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
#include "dynarmic/backend/x64/emit_x64.h"
|
||||
|
|
@ -129,7 +129,7 @@ void EmitX64::EmitIsZero64(EmitContext& ctx, IR::Inst* inst) {
|
|||
void EmitX64::EmitTestBit(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Reg64 result = ctx.reg_alloc.UseScratchGpr(code, args[0]);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
// TODO: Flag optimization
|
||||
code.bt(result, args[1].GetImmediateU8());
|
||||
code.setc(result.cvt8());
|
||||
|
|
@ -194,7 +194,7 @@ static void EmitConditionalSelect(BlockOfCode& code, EmitContext& ctx, IR::Inst*
|
|||
code.mov(else_, then_);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
ctx.reg_alloc.DefineValue(code, inst, else_);
|
||||
|
|
@ -663,7 +663,7 @@ void EmitX64::EmitArithmeticShiftRight64(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
}
|
||||
|
||||
void EmitX64::EmitRotateRight32(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64::EmitBitRotateRight32(EmitContext& ctx, IR::Inst* inst) {
|
||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
|
@ -736,7 +736,7 @@ void EmitX64::EmitRotateRight32(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
}
|
||||
|
||||
void EmitX64::EmitRotateRight64(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64::EmitBitRotateRight64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto& operand_arg = args[0];
|
||||
auto& shift_arg = args[1];
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cassert>
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
|
|
@ -659,7 +659,7 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, bo
|
|||
FCODE(ucomis)(result, result);
|
||||
code.jp(*fallback, code.T_NEAR);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
if (ctx.FPCR().DN()) {
|
||||
ForceToDefaultNaN<fsize>(code, result);
|
||||
|
|
@ -1079,7 +1079,7 @@ static void EmitFPRound(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, siz
|
|||
case 64: code.CallFunction(EmitFPRoundThunk<u64>); break;
|
||||
case 32: code.CallFunction(EmitFPRoundThunk<u32>); break;
|
||||
case 16: code.CallFunction(EmitFPRoundThunk<u16>); break;
|
||||
default: UNREACHABLE();
|
||||
default: std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1842,7 +1842,7 @@ void EmitX64::EmitFPFixedS32ToSingle(EmitContext& ctx, IR::Inst* inst) {
|
|||
if (rounding_mode == ctx.FPCR().RMode() || ctx.HasOptimization(OptimizationFlag::Unsafe_IgnoreStandardFPCRValue)) {
|
||||
code.cvtsi2ss(result, from);
|
||||
} else {
|
||||
ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
|
||||
assert(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
|
||||
code.EnterStandardASIMD();
|
||||
code.cvtsi2ss(result, from);
|
||||
code.LeaveStandardASIMD();
|
||||
|
|
@ -1878,7 +1878,7 @@ void EmitX64::EmitFPFixedU32ToSingle(EmitContext& ctx, IR::Inst* inst) {
|
|||
if (rounding_mode == ctx.FPCR().RMode() || ctx.HasOptimization(OptimizationFlag::Unsafe_IgnoreStandardFPCRValue)) {
|
||||
op();
|
||||
} else {
|
||||
ASSERT(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
|
||||
assert(rounding_mode == FP::RoundingMode::ToNearest_TieEven);
|
||||
code.EnterStandardASIMD();
|
||||
op();
|
||||
code.LeaveStandardASIMD();
|
||||
|
|
@ -1984,7 +1984,7 @@ void EmitX64::EmitFPFixedS64ToDouble(EmitContext& ctx, IR::Inst* inst) {
|
|||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
const size_t fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
ASSERT(rounding_mode == ctx.FPCR().RMode());
|
||||
assert(rounding_mode == ctx.FPCR().RMode());
|
||||
|
||||
code.cvtsi2sd(result, from);
|
||||
|
||||
|
|
@ -2003,7 +2003,7 @@ void EmitX64::EmitFPFixedS64ToSingle(EmitContext& ctx, IR::Inst* inst) {
|
|||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
const size_t fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
ASSERT(rounding_mode == ctx.FPCR().RMode());
|
||||
assert(rounding_mode == ctx.FPCR().RMode());
|
||||
|
||||
code.cvtsi2ss(result, from);
|
||||
|
||||
|
|
@ -2022,7 +2022,7 @@ void EmitX64::EmitFPFixedU64ToDouble(EmitContext& ctx, IR::Inst* inst) {
|
|||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
const size_t fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
ASSERT(rounding_mode == ctx.FPCR().RMode());
|
||||
assert(rounding_mode == ctx.FPCR().RMode());
|
||||
|
||||
if (code.HasHostFeature(HostFeature::AVX512F)) {
|
||||
code.vcvtusi2sd(result, result, from);
|
||||
|
|
@ -2053,7 +2053,7 @@ void EmitX64::EmitFPFixedU64ToSingle(EmitContext& ctx, IR::Inst* inst) {
|
|||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
const size_t fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
ASSERT(rounding_mode == ctx.FPCR().RMode());
|
||||
assert(rounding_mode == ctx.FPCR().RMode());
|
||||
|
||||
if (code.HasHostFeature(HostFeature::AVX512F)) {
|
||||
const Xbyak::Reg64 from = ctx.reg_alloc.UseGpr(code, args[0]);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ FakeCall AxxEmitX64::FastmemCallback(u64 rip_) {
|
|||
}
|
||||
fmt::print("dynarmic: Segfault happened within JITted code at rip = {:016x}\n"
|
||||
"Segfault wasn't at a fastmem patch location!\n", rip_);
|
||||
UNREACHABLE(); //("iter != fastmem_patch_info.end()");
|
||||
std::terminate(); //unreachable //("iter != fastmem_patch_info.end()");
|
||||
}
|
||||
|
||||
template<std::size_t bitsize, auto callback>
|
||||
|
|
@ -113,7 +113,7 @@ void AxxEmitX64::EmitMemoryRead(AxxEmitContext& ctx, IR::Inst* inst) {
|
|||
});
|
||||
} else {
|
||||
// Use page table
|
||||
ASSERT(conf.page_table);
|
||||
assert(conf.page_table);
|
||||
const auto src_ptr = EmitVAddrLookup(code, ctx, bitsize, *abort, vaddr);
|
||||
EmitReadMemoryMov<bitsize>(code, value_idx, src_ptr, ordered);
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ void AxxEmitX64::EmitMemoryWrite(AxxEmitContext& ctx, IR::Inst* inst) {
|
|||
});
|
||||
} else {
|
||||
// Use page table
|
||||
ASSERT(conf.page_table);
|
||||
assert(conf.page_table);
|
||||
const auto dest_ptr = EmitVAddrLookup(code, ctx, bitsize, *abort, vaddr);
|
||||
EmitWriteMemoryMov<bitsize>(code, dest_ptr, value_idx, ordered);
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ void AxxEmitX64::EmitMemoryWrite(AxxEmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<std::size_t bitsize, auto callback>
|
||||
void AxxEmitX64::EmitExclusiveReadMemory(AxxEmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(conf.global_monitor != nullptr);
|
||||
assert(conf.global_monitor != nullptr);
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
||||
|
||||
|
|
@ -267,7 +267,7 @@ void AxxEmitX64::EmitExclusiveReadMemory(AxxEmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<std::size_t bitsize, auto callback>
|
||||
void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(conf.global_monitor != nullptr);
|
||||
assert(conf.global_monitor != nullptr);
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const bool ordered = IsOrdered(args[3].GetImmediateAccType());
|
||||
|
||||
|
|
@ -320,7 +320,7 @@ void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
template<std::size_t bitsize, auto callback>
|
||||
void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(conf.global_monitor && conf.fastmem_pointer);
|
||||
assert(conf.global_monitor && conf.fastmem_pointer);
|
||||
if (!exception_handler.SupportsFastmem()) {
|
||||
EmitExclusiveReadMemory<bitsize, callback>(ctx, inst);
|
||||
return;
|
||||
|
|
@ -397,7 +397,7 @@ void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* in
|
|||
|
||||
template<std::size_t bitsize, auto callback>
|
||||
void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(conf.global_monitor && conf.fastmem_pointer);
|
||||
assert(conf.global_monitor && conf.fastmem_pointer);
|
||||
if (!exception_handler.SupportsFastmem()) {
|
||||
EmitExclusiveWriteMemory<bitsize, callback>(ctx, inst);
|
||||
return;
|
||||
|
|
@ -489,7 +489,7 @@ void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* i
|
|||
code.cmpxchg16b(ptr[dest_ptr]);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
code.setnz(status.cvt8());
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bit>
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
|
|
@ -22,9 +24,9 @@ namespace {
|
|||
|
||||
using namespace Xbyak::util;
|
||||
|
||||
constexpr size_t page_bits = 12;
|
||||
constexpr size_t page_size = 1 << page_bits;
|
||||
constexpr size_t page_mask = (1 << page_bits) - 1;
|
||||
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;
|
||||
|
||||
template<typename EmitContext>
|
||||
void EmitDetectMisalignedVAddr(BlockOfCode& code, EmitContext& ctx, size_t bitsize, Xbyak::Label& abort, Xbyak::Reg64 vaddr, Xbyak::Reg64 tmp) {
|
||||
|
|
@ -43,14 +45,14 @@ void EmitDetectMisalignedVAddr(BlockOfCode& code, EmitContext& ctx, size_t bitsi
|
|||
case 128:
|
||||
return 0b1111;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}();
|
||||
|
||||
code.test(vaddr, align_mask);
|
||||
|
||||
if (ctx.conf.only_detect_misalignment_via_page_table_on_page_boundary) {
|
||||
const u32 page_align_mask = static_cast<u32>(page_size - 1) & ~align_mask;
|
||||
const u32 page_align_mask = static_cast<u32>(page_table_const_size - 1) & ~align_mask;
|
||||
|
||||
SharedLabel detect_boundary = GenSharedLabel(), resume = GenSharedLabel();
|
||||
|
||||
|
|
@ -83,7 +85,7 @@ template<>
|
|||
// TODO: This code assumes vaddr has been zext from 32-bits to 64-bits.
|
||||
|
||||
code.mov(tmp, vaddr.cvt32());
|
||||
code.shr(tmp, int(page_bits));
|
||||
code.shr(tmp, int(page_table_const_bits));
|
||||
code.shl(tmp, int(ctx.conf.page_table_log2_stride));
|
||||
code.mov(page, qword[r14 + tmp.cvt64()]);
|
||||
if (ctx.conf.page_table_pointer_mask_bits == 0) {
|
||||
|
|
@ -96,13 +98,13 @@ template<>
|
|||
return page + vaddr;
|
||||
}
|
||||
code.mov(tmp, vaddr.cvt32());
|
||||
code.and_(tmp, static_cast<u32>(page_mask));
|
||||
code.and_(tmp, static_cast<u32>(page_table_const_mask));
|
||||
return page + tmp.cvt64();
|
||||
}
|
||||
|
||||
template<>
|
||||
[[maybe_unused]] Xbyak::RegExp EmitVAddrLookup<A64EmitContext>(BlockOfCode& code, A64EmitContext& ctx, size_t bitsize, Xbyak::Label& abort, Xbyak::Reg64 vaddr) {
|
||||
const size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_bits;
|
||||
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 Xbyak::Reg64 page = ctx.reg_alloc.ScratchGpr(code);
|
||||
|
|
@ -112,29 +114,29 @@ template<>
|
|||
|
||||
if (unused_top_bits == 0) {
|
||||
code.mov(tmp, vaddr);
|
||||
code.shr(tmp, int(page_bits));
|
||||
code.shr(tmp, int(page_table_const_bits));
|
||||
} else if (ctx.conf.silently_mirror_page_table) {
|
||||
if (valid_page_index_bits >= 32) {
|
||||
if (code.HasHostFeature(HostFeature::BMI2)) {
|
||||
const Xbyak::Reg64 bit_count = ctx.reg_alloc.ScratchGpr(code);
|
||||
code.mov(bit_count, unused_top_bits);
|
||||
code.bzhi(tmp, vaddr, bit_count);
|
||||
code.shr(tmp, int(page_bits));
|
||||
code.shr(tmp, int(page_table_const_bits));
|
||||
ctx.reg_alloc.Release(bit_count);
|
||||
} else {
|
||||
code.mov(tmp, vaddr);
|
||||
code.shl(tmp, int(unused_top_bits));
|
||||
code.shr(tmp, int(unused_top_bits + page_bits));
|
||||
code.shr(tmp, int(unused_top_bits + page_table_const_bits));
|
||||
}
|
||||
} else {
|
||||
code.mov(tmp, vaddr);
|
||||
code.shr(tmp, int(page_bits));
|
||||
code.shr(tmp, int(page_table_const_bits));
|
||||
code.and_(tmp, u32((1 << valid_page_index_bits) - 1));
|
||||
}
|
||||
} else {
|
||||
ASSERT(valid_page_index_bits < 32);
|
||||
assert(valid_page_index_bits < 32);
|
||||
code.mov(tmp, vaddr);
|
||||
code.shr(tmp, int(page_bits));
|
||||
code.shr(tmp, int(page_table_const_bits));
|
||||
code.test(tmp, u32(-(1 << valid_page_index_bits)));
|
||||
code.jnz(abort, code.T_NEAR);
|
||||
}
|
||||
|
|
@ -151,7 +153,7 @@ template<>
|
|||
return page + vaddr;
|
||||
}
|
||||
code.mov(tmp, vaddr);
|
||||
code.and_(tmp, static_cast<u32>(page_mask));
|
||||
code.and_(tmp, static_cast<u32>(page_table_const_mask));
|
||||
return page + tmp;
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +247,7 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
|
|||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
return fastmem_location;
|
||||
} else {
|
||||
|
|
@ -267,7 +269,7 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
|
|||
code.movups(Xbyak::Xmm(value_idx), xword[addr]);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
return fastmem_location;
|
||||
}
|
||||
|
|
@ -313,7 +315,7 @@ const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int
|
|||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
return fastmem_location;
|
||||
} else {
|
||||
|
|
@ -335,7 +337,7 @@ const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int
|
|||
code.movups(xword[addr], Xbyak::Xmm(value_idx));
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
return fastmem_location;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include <limits>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <cassert>
|
||||
#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"
|
||||
|
|
@ -25,12 +25,12 @@ using namespace Xbyak::util;
|
|||
|
||||
namespace {
|
||||
|
||||
enum class Op {
|
||||
enum class SaturationOp {
|
||||
Add,
|
||||
Sub,
|
||||
};
|
||||
|
||||
template<Op op, size_t size, bool has_overflow_inst = false>
|
||||
template<SaturationOp op, size_t size, bool has_overflow_inst = false>
|
||||
void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
|
|||
|
||||
// overflow now contains 0x7F... if a was positive, or 0x80... if a was negative
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == SaturationOp::Add) {
|
||||
code.add(result, addend);
|
||||
} else {
|
||||
code.sub(result, addend);
|
||||
|
|
@ -75,16 +75,16 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
|
|||
ctx.reg_alloc.DefineValue(code, inst, result);
|
||||
}
|
||||
|
||||
template<Op op, size_t size>
|
||||
template<SaturationOp op, size_t size>
|
||||
void EmitUnsignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg op_result = ctx.reg_alloc.UseScratchGpr(code, args[0]).changeBit(size);
|
||||
Xbyak::Reg addend = ctx.reg_alloc.UseScratchGpr(code, args[1]).changeBit(size);
|
||||
|
||||
constexpr u64 boundary = op == Op::Add ? (std::numeric_limits<mcl::unsigned_integer_of_size<size>>::max)() : 0;
|
||||
constexpr u64 boundary = op == SaturationOp::Add ? (std::numeric_limits<mcl::unsigned_integer_of_size<size>>::max)() : 0;
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == SaturationOp::Add) {
|
||||
code.add(op_result, addend);
|
||||
} else {
|
||||
code.sub(op_result, addend);
|
||||
|
|
@ -106,11 +106,11 @@ void EmitUnsignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst
|
|||
} // anonymous namespace
|
||||
|
||||
void EmitX64::EmitSignedSaturatedAddWithFlag32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Add, 32, true>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Add, 32, true>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedSubWithFlag32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Sub, 32, true>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Sub, 32, true>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -118,7 +118,7 @@ void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const size_t N = args[1].GetImmediateU8();
|
||||
ASSERT(N >= 1 && N <= 32);
|
||||
assert(N >= 1 && N <= 32);
|
||||
|
||||
if (N == 32) {
|
||||
if (overflow_inst) {
|
||||
|
|
@ -167,7 +167,7 @@ void EmitX64::EmitUnsignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const size_t N = args[1].GetImmediateU8();
|
||||
ASSERT(N <= 31);
|
||||
assert(N <= 31);
|
||||
|
||||
const u32 saturated_value = (1u << N) - 1;
|
||||
|
||||
|
|
@ -192,19 +192,19 @@ void EmitX64::EmitUnsignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedAdd8(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Add, 8>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Add, 8>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedAdd16(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Add, 16>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Add, 16>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedAdd32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Add, 32>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Add, 32>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedAdd64(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Add, 64>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Add, 64>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedDoublingMultiplyReturnHigh16(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -256,51 +256,51 @@ void EmitX64::EmitSignedSaturatedDoublingMultiplyReturnHigh32(EmitContext& ctx,
|
|||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedSub8(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Sub, 8>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Sub, 8>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedSub16(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Sub, 16>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Sub, 16>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedSub32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Sub, 32>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Sub, 32>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitSignedSaturatedSub64(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitSignedSaturatedOp<Op::Sub, 64>(code, ctx, inst);
|
||||
EmitSignedSaturatedOp<SaturationOp::Sub, 64>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitUnsignedSaturatedAdd8(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitUnsignedSaturatedOp<Op::Add, 8>(code, ctx, inst);
|
||||
EmitUnsignedSaturatedOp<SaturationOp::Add, 8>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitUnsignedSaturatedAdd16(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitUnsignedSaturatedOp<Op::Add, 16>(code, ctx, inst);
|
||||
EmitUnsignedSaturatedOp<SaturationOp::Add, 16>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitUnsignedSaturatedAdd32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitUnsignedSaturatedOp<Op::Add, 32>(code, ctx, inst);
|
||||
EmitUnsignedSaturatedOp<SaturationOp::Add, 32>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitUnsignedSaturatedAdd64(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitUnsignedSaturatedOp<Op::Add, 64>(code, ctx, inst);
|
||||
EmitUnsignedSaturatedOp<SaturationOp::Add, 64>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitUnsignedSaturatedSub8(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitUnsignedSaturatedOp<Op::Sub, 8>(code, ctx, inst);
|
||||
EmitUnsignedSaturatedOp<SaturationOp::Sub, 8>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitUnsignedSaturatedSub16(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitUnsignedSaturatedOp<Op::Sub, 16>(code, ctx, inst);
|
||||
EmitUnsignedSaturatedOp<SaturationOp::Sub, 16>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitUnsignedSaturatedSub32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitUnsignedSaturatedOp<Op::Sub, 32>(code, ctx, inst);
|
||||
EmitUnsignedSaturatedOp<SaturationOp::Sub, 32>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitUnsignedSaturatedSub64(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitUnsignedSaturatedOp<Op::Sub, 64>(code, ctx, inst);
|
||||
EmitUnsignedSaturatedOp<SaturationOp::Sub, 64>(code, ctx, inst);
|
||||
}
|
||||
|
||||
} // 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.
|
||||
|
|
@ -18,7 +18,7 @@ void EmitX64::EmitSHA256Hash(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
const bool part1 = args[3].GetImmediateU1();
|
||||
|
||||
ASSERT(code.HasHostFeature(HostFeature::SHA));
|
||||
assert(code.HasHostFeature(HostFeature::SHA));
|
||||
|
||||
// 3 2 1 0
|
||||
// x = d c b a
|
||||
|
|
@ -54,7 +54,7 @@ void EmitX64::EmitSHA256Hash(EmitContext& ctx, IR::Inst* inst) {
|
|||
void EmitX64::EmitSHA256MessageSchedule0(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
ASSERT(code.HasHostFeature(HostFeature::SHA));
|
||||
assert(code.HasHostFeature(HostFeature::SHA));
|
||||
|
||||
const Xbyak::Xmm x = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
const Xbyak::Xmm y = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||
|
|
@ -67,7 +67,7 @@ void EmitX64::EmitSHA256MessageSchedule0(EmitContext& ctx, IR::Inst* inst) {
|
|||
void EmitX64::EmitSHA256MessageSchedule1(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
ASSERT(code.HasHostFeature(HostFeature::SHA));
|
||||
assert(code.HasHostFeature(HostFeature::SHA));
|
||||
|
||||
const Xbyak::Xmm x = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
const Xbyak::Xmm y = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
#include <cstdlib>
|
||||
#include <type_traits>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <cassert>
|
||||
#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"
|
||||
|
||||
|
|
@ -189,7 +189,7 @@ static void EmitTwoArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Ins
|
|||
|
||||
void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
// TODO: DefineValue directly on Argument for index == 0
|
||||
|
|
@ -213,7 +213,7 @@ void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void EmitX64::EmitVectorGetElement16(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
// TODO: DefineValue directly on Argument for index == 0
|
||||
|
|
@ -226,7 +226,7 @@ void EmitX64::EmitVectorGetElement16(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void EmitX64::EmitVectorGetElement32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
// TODO: DefineValue directly on Argument for index == 0
|
||||
|
|
@ -247,7 +247,7 @@ void EmitX64::EmitVectorGetElement32(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void EmitX64::EmitVectorGetElement64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
if (index == 0) {
|
||||
|
|
@ -275,7 +275,7 @@ void EmitX64::EmitVectorGetElement64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void EmitX64::EmitVectorSetElement8(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
const Xbyak::Xmm source_vector = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
|
||||
|
|
@ -307,7 +307,7 @@ void EmitX64::EmitVectorSetElement8(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void EmitX64::EmitVectorSetElement16(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
|
||||
const Xbyak::Xmm source_vector = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
|
|
@ -320,7 +320,7 @@ void EmitX64::EmitVectorSetElement16(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void EmitX64::EmitVectorSetElement32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
const Xbyak::Xmm source_vector = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
|
||||
|
|
@ -343,7 +343,7 @@ void EmitX64::EmitVectorSetElement32(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void EmitX64::EmitVectorSetElement64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
const Xbyak::Xmm source_vector = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
|
||||
|
|
@ -748,9 +748,9 @@ void EmitX64::EmitVectorBroadcast64(EmitContext& ctx, IR::Inst* inst) {
|
|||
void EmitX64::EmitVectorBroadcastElementLower8(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
ASSERT(index < 16);
|
||||
assert(index < 16);
|
||||
if (index > 0) {
|
||||
code.psrldq(a, index);
|
||||
}
|
||||
|
|
@ -772,9 +772,9 @@ void EmitX64::EmitVectorBroadcastElementLower8(EmitContext& ctx, IR::Inst* inst)
|
|||
void EmitX64::EmitVectorBroadcastElementLower16(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
ASSERT(index < 8);
|
||||
assert(index < 8);
|
||||
if (index > 0) {
|
||||
code.psrldq(a, u8(index * 2));
|
||||
}
|
||||
|
|
@ -785,9 +785,9 @@ void EmitX64::EmitVectorBroadcastElementLower16(EmitContext& ctx, IR::Inst* inst
|
|||
void EmitX64::EmitVectorBroadcastElementLower32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
ASSERT(index < 4);
|
||||
assert(index < 4);
|
||||
|
||||
if (index > 0) {
|
||||
code.psrldq(a, u8(index * 4));
|
||||
|
|
@ -801,9 +801,9 @@ void EmitX64::EmitVectorBroadcastElementLower32(EmitContext& ctx, IR::Inst* inst
|
|||
void EmitX64::EmitVectorBroadcastElement8(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
ASSERT(index < 16);
|
||||
assert(index < 16);
|
||||
if (index > 0) {
|
||||
code.psrldq(a, index);
|
||||
}
|
||||
|
|
@ -825,9 +825,9 @@ void EmitX64::EmitVectorBroadcastElement8(EmitContext& ctx, IR::Inst* inst) {
|
|||
void EmitX64::EmitVectorBroadcastElement16(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
ASSERT(index < 8);
|
||||
assert(index < 8);
|
||||
if (index == 0 && code.HasHostFeature(HostFeature::AVX2)) {
|
||||
code.vpbroadcastw(a, a);
|
||||
} else {
|
||||
|
|
@ -845,9 +845,9 @@ void EmitX64::EmitVectorBroadcastElement16(EmitContext& ctx, IR::Inst* inst) {
|
|||
void EmitX64::EmitVectorBroadcastElement32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
ASSERT(index < 4);
|
||||
assert(index < 4);
|
||||
|
||||
code.pshufd(a, a, mcl::bit::replicate_element<2, u8>(index));
|
||||
|
||||
|
|
@ -857,9 +857,9 @@ void EmitX64::EmitVectorBroadcastElement32(EmitContext& ctx, IR::Inst* inst) {
|
|||
void EmitX64::EmitVectorBroadcastElement64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
ASSERT(args[1].IsImmediate());
|
||||
assert(args[1].IsImmediate());
|
||||
const u8 index = args[1].GetImmediateU8();
|
||||
ASSERT(index < 2);
|
||||
assert(index < 2);
|
||||
|
||||
if (code.HasHostFeature(HostFeature::AVX)) {
|
||||
code.vpermilpd(a, a, mcl::bit::replicate_element<1, u8>(index));
|
||||
|
|
@ -1345,7 +1345,7 @@ void EmitX64::EmitVectorExtract(EmitContext& ctx, IR::Inst* inst) {
|
|||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
const u8 position = args[2].GetImmediateU8();
|
||||
ASSERT(position % 8 == 0);
|
||||
assert(position % 8 == 0);
|
||||
|
||||
if (position == 0) {
|
||||
ctx.reg_alloc.DefineValue(code, inst, args[0]);
|
||||
|
|
@ -1377,7 +1377,7 @@ void EmitX64::EmitVectorExtractLower(EmitContext& ctx, IR::Inst* inst) {
|
|||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||
|
||||
const u8 position = args[2].GetImmediateU8();
|
||||
ASSERT(position % 8 == 0);
|
||||
assert(position % 8 == 0);
|
||||
|
||||
if (position != 0) {
|
||||
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||
|
|
@ -2280,27 +2280,27 @@ void EmitX64::EmitVectorMultiply64(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
void EmitX64::EmitVectorMultiplySignedWiden8(EmitContext&, IR::Inst*) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorMultiplySignedWiden16(EmitContext&, IR::Inst*) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorMultiplySignedWiden32(EmitContext&, IR::Inst*) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorMultiplyUnsignedWiden8(EmitContext&, IR::Inst*) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorMultiplyUnsignedWiden16(EmitContext&, IR::Inst*) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorMultiplyUnsignedWiden32(EmitContext&, IR::Inst*) {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorNarrow16(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -3527,7 +3527,7 @@ void EmitX64::EmitVectorRotateWholeVectorRight(EmitContext& ctx, IR::Inst* inst)
|
|||
const Xbyak::Xmm operand = ctx.reg_alloc.UseXmm(code, args[0]);
|
||||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
const u8 shift_amount = args[1].GetImmediateU8();
|
||||
ASSERT(shift_amount % 32 == 0);
|
||||
assert(shift_amount % 32 == 0);
|
||||
const u8 shuffle_imm = std::rotr<u8>(0b11100100, shift_amount / 32 * 2);
|
||||
|
||||
code.pshufd(result, operand, shuffle_imm);
|
||||
|
|
@ -3869,7 +3869,7 @@ static void EmitVectorSignedAbsoluteDifference(size_t esize, EmitContext& ctx, I
|
|||
code.psubd(x, tmp);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
} else {
|
||||
code.movdqa(tmp, y);
|
||||
|
|
@ -3888,7 +3888,7 @@ static void EmitVectorSignedAbsoluteDifference(size_t esize, EmitContext& ctx, I
|
|||
code.psubd(x, tmp);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4092,7 +4092,7 @@ static void EmitVectorSignedSaturatedAbs(size_t esize, BlockOfCode& code, EmitCo
|
|||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
code.or_(code.dword[code.ABI_JIT_PTR + code.GetJitStateInfo().offsetof_fpsr_qc], bit);
|
||||
|
|
@ -4542,7 +4542,7 @@ static void EmitVectorSignedSaturatedNarrowToSigned(size_t original_esize, Block
|
|||
code.punpcklwd(reconstructed, sign);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
const Xbyak::Reg32 bit = ctx.reg_alloc.ScratchGpr(code).cvt32();
|
||||
|
|
@ -4591,13 +4591,13 @@ static void EmitVectorSignedSaturatedNarrowToUnsigned(size_t original_esize, Blo
|
|||
code.punpcklbw(reconstructed, xmm0);
|
||||
break;
|
||||
case 32:
|
||||
ASSERT(code.HasHostFeature(HostFeature::SSE41));
|
||||
assert(code.HasHostFeature(HostFeature::SSE41));
|
||||
code.packusdw(dest, xmm0); // SSE4.1
|
||||
code.movdqa(reconstructed, dest);
|
||||
code.punpcklwd(reconstructed, xmm0);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
const Xbyak::Reg32 bit = ctx.reg_alloc.ScratchGpr(code).cvt32();
|
||||
|
|
@ -4661,7 +4661,7 @@ static void EmitVectorSignedSaturatedNeg(size_t esize, BlockOfCode& code, EmitCo
|
|||
case 64:
|
||||
return code.Const(xword, 0x8000000000000000, 0x8000000000000000);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}();
|
||||
|
||||
|
|
@ -4874,11 +4874,11 @@ void EmitX64::EmitVectorSub64(EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
void EmitX64::EmitVectorTable(EmitContext&, IR::Inst* inst) {
|
||||
// Do nothing. We *want* to hold on to the refcount for our arguments, so VectorTableLookup can use our arguments.
|
||||
ASSERT(inst->UseCount() == 1 && "Table cannot be used multiple times");
|
||||
assert(inst->UseCount() == 1 && "Table cannot be used multiple times");
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorTableLookup64(EmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
|
||||
assert(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
||||
|
|
@ -4957,7 +4957,7 @@ void EmitX64::EmitVectorTableLookup64(EmitContext& ctx, IR::Inst* inst) {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
|
@ -5036,7 +5036,7 @@ void EmitX64::EmitVectorTableLookup64(EmitContext& ctx, IR::Inst* inst) {
|
|||
code.pxor(xmm0, xmm0);
|
||||
code.punpcklqdq(xmm_table1, xmm0);
|
||||
} else {
|
||||
ASSERT(table_size == 4);
|
||||
assert(table_size == 4);
|
||||
const Xbyak::Xmm xmm_table1_upper = ctx.reg_alloc.UseXmm(code, table[3]);
|
||||
code.punpcklqdq(xmm_table1, xmm_table1_upper);
|
||||
ctx.reg_alloc.Release(xmm_table1_upper);
|
||||
|
|
@ -5133,7 +5133,7 @@ void EmitX64::EmitVectorTableLookup64(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
void EmitX64::EmitVectorTableLookup128(EmitContext& ctx, IR::Inst* inst) {
|
||||
ASSERT(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
|
||||
assert(inst->GetArg(1).GetInst()->GetOpcode() == IR::Opcode::VectorTable);
|
||||
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
||||
|
|
@ -5854,3 +5854,5 @@ void EmitX64::EmitZeroVector(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::X64
|
||||
|
||||
#undef ICODE
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <cassert>
|
||||
#include "dynarmic/mcl/function_info.hpp"
|
||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
|
@ -265,7 +265,7 @@ struct PairedIndexer {
|
|||
case 1:
|
||||
return std::make_tuple(b[2 * i], b[2 * i + 1]);
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -288,7 +288,7 @@ struct PairedLowerIndexer {
|
|||
}
|
||||
return std::make_tuple(0, 0);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -681,7 +681,7 @@ void EmitX64::EmitFPVectorFromHalf32(EmitContext& ctx, IR::Inst* inst) {
|
|||
EmitTwoOpFallback<2>(code, ctx, inst, EmitFPVectorFromHalf32Thunk<FP::RoundingMode::ToNearest_TieAwayFromZero>);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -692,7 +692,7 @@ void EmitX64::EmitFPVectorFromSignedFixed32(EmitContext& ctx, IR::Inst* inst) {
|
|||
const int fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
const bool fpcr_controlled = args[3].GetImmediateU1();
|
||||
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
assert(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
code.cvtdq2ps(xmm, xmm);
|
||||
|
|
@ -710,7 +710,7 @@ void EmitX64::EmitFPVectorFromSignedFixed64(EmitContext& ctx, IR::Inst* inst) {
|
|||
const int fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
const bool fpcr_controlled = args[3].GetImmediateU1();
|
||||
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
assert(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) {
|
||||
|
|
@ -761,7 +761,7 @@ void EmitX64::EmitFPVectorFromUnsignedFixed32(EmitContext& ctx, IR::Inst* inst)
|
|||
const int fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
const bool fpcr_controlled = args[3].GetImmediateU1();
|
||||
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
assert(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
if (code.HasHostFeature(HostFeature::AVX512_Ortho)) {
|
||||
|
|
@ -811,7 +811,7 @@ void EmitX64::EmitFPVectorFromUnsignedFixed64(EmitContext& ctx, IR::Inst* inst)
|
|||
const int fbits = args[1].GetImmediateU8();
|
||||
const FP::RoundingMode rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||
const bool fpcr_controlled = args[3].GetImmediateU1();
|
||||
ASSERT(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
assert(rounding_mode == ctx.FPCR(fpcr_controlled).RMode());
|
||||
|
||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] {
|
||||
if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) {
|
||||
|
|
@ -1679,7 +1679,7 @@ void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
case FP::RoundingMode::TowardsPlusInfinity: return 0b10;
|
||||
case FP::RoundingMode::TowardsMinusInfinity: return 0b01;
|
||||
case FP::RoundingMode::TowardsZero: return 0b11;
|
||||
default: UNREACHABLE();
|
||||
default: std::terminate(); //unreachable
|
||||
}
|
||||
}();
|
||||
|
||||
|
|
@ -1720,7 +1720,7 @@ void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
: EmitTwoOpFallback<3>(code, ctx, inst, EmitFPVectorRoundIntThunk<FPT, FP::RoundingMode::ToNearest_TieAwayFromZero, false>);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1988,7 +1988,7 @@ void EmitX64::EmitFPVectorToHalf32(EmitContext& ctx, IR::Inst* inst) {
|
|||
EmitTwoOpFallback<2>(code, ctx, inst, EmitFPVectorToHalf32Thunk<FP::RoundingMode::ToNearest_TieAwayFromZero>);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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/block_of_code.h"
|
||||
#include "dynarmic/backend/x64/constants.h"
|
||||
|
|
@ -52,12 +52,12 @@ void EmitVectorSaturatedNative(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
|
|||
ctx.reg_alloc.DefineValue(code, inst, result);
|
||||
}
|
||||
|
||||
enum class Op {
|
||||
enum class VectorSaturationOp {
|
||||
Add,
|
||||
Sub,
|
||||
};
|
||||
|
||||
template<Op op, size_t esize>
|
||||
template<VectorSaturationOp op, size_t esize>
|
||||
void EmitVectorSignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
static_assert(esize == 32 || esize == 64);
|
||||
constexpr u64 msb_mask = esize == 32 ? 0x8000000080000000 : 0x8000000000000000;
|
||||
|
|
@ -72,7 +72,7 @@ void EmitVectorSignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
|
|||
|
||||
code.movaps(xmm0, operand1);
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == VectorSaturationOp::Add) {
|
||||
ICODE(vpadd)(result, operand1, operand2);
|
||||
code.vpternlogd(xmm0, result, operand2, 0b00100100);
|
||||
} else {
|
||||
|
|
@ -102,7 +102,7 @@ void EmitVectorSignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
|
|||
const Xbyak::Xmm tmp = ctx.reg_alloc.ScratchXmm(code);
|
||||
|
||||
if (code.HasHostFeature(HostFeature::AVX)) {
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == VectorSaturationOp::Add) {
|
||||
ICODE(vpadd)(result, operand1, operand2);
|
||||
} else {
|
||||
ICODE(vpsub)(result, operand1, operand2);
|
||||
|
|
@ -112,7 +112,7 @@ void EmitVectorSignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
|
|||
} else {
|
||||
code.movaps(xmm0, operand1);
|
||||
code.movaps(tmp, operand1);
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == VectorSaturationOp::Add) {
|
||||
ICODE(padd)(result, operand2);
|
||||
} else {
|
||||
ICODE(psub)(result, operand2);
|
||||
|
|
@ -121,7 +121,7 @@ void EmitVectorSignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
|
|||
code.pxor(tmp, result);
|
||||
}
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == VectorSaturationOp::Add) {
|
||||
code.pandn(xmm0, tmp);
|
||||
} else {
|
||||
code.pand(xmm0, tmp);
|
||||
|
|
@ -165,7 +165,7 @@ void EmitVectorSignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
|
|||
}
|
||||
}
|
||||
|
||||
template<Op op, size_t esize>
|
||||
template<VectorSaturationOp op, size_t esize>
|
||||
void EmitVectorUnsignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
static_assert(esize == 32 || esize == 64);
|
||||
|
||||
|
|
@ -177,7 +177,7 @@ void EmitVectorUnsignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst*
|
|||
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(code);
|
||||
const Xbyak::Reg8 overflow = ctx.reg_alloc.ScratchGpr(code).cvt8();
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == VectorSaturationOp::Add) {
|
||||
ICODE(vpadd)(result, operand1, operand2);
|
||||
ICODE(vpcmpu)(k1, result, operand1, CmpInt::LessThan);
|
||||
ICODE(vpternlog)(result | k1, result, result, u8(0xFF));
|
||||
|
|
@ -201,7 +201,7 @@ void EmitVectorUnsignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst*
|
|||
const Xbyak::Reg8 overflow = ctx.reg_alloc.ScratchGpr(code).cvt8();
|
||||
const Xbyak::Xmm tmp = ctx.reg_alloc.ScratchXmm(code);
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == VectorSaturationOp::Add) {
|
||||
if (code.HasHostFeature(HostFeature::AVX)) {
|
||||
code.vpxor(xmm0, operand1, operand2);
|
||||
code.vpand(tmp, operand1, operand2);
|
||||
|
|
@ -250,7 +250,7 @@ void EmitVectorUnsignedSaturated(BlockOfCode& code, EmitContext& ctx, IR::Inst*
|
|||
code.setnz(overflow);
|
||||
code.or_(code.byte[code.ABI_JIT_PTR + code.GetJitStateInfo().offsetof_fpsr_qc], overflow);
|
||||
|
||||
if constexpr (op == Op::Add) {
|
||||
if constexpr (op == VectorSaturationOp::Add) {
|
||||
code.por(result, tmp);
|
||||
ctx.reg_alloc.DefineValue(code, inst, result);
|
||||
} else {
|
||||
|
|
@ -270,11 +270,11 @@ void EmitX64::EmitVectorSignedSaturatedAdd16(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
void EmitX64::EmitVectorSignedSaturatedAdd32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitVectorSignedSaturated<Op::Add, 32>(code, ctx, inst);
|
||||
EmitVectorSignedSaturated<VectorSaturationOp::Add, 32>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorSignedSaturatedAdd64(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitVectorSignedSaturated<Op::Add, 64>(code, ctx, inst);
|
||||
EmitVectorSignedSaturated<VectorSaturationOp::Add, 64>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorSignedSaturatedSub8(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -286,11 +286,11 @@ void EmitX64::EmitVectorSignedSaturatedSub16(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
void EmitX64::EmitVectorSignedSaturatedSub32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitVectorSignedSaturated<Op::Sub, 32>(code, ctx, inst);
|
||||
EmitVectorSignedSaturated<VectorSaturationOp::Sub, 32>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorSignedSaturatedSub64(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitVectorSignedSaturated<Op::Sub, 64>(code, ctx, inst);
|
||||
EmitVectorSignedSaturated<VectorSaturationOp::Sub, 64>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorUnsignedSaturatedAdd8(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -302,11 +302,11 @@ void EmitX64::EmitVectorUnsignedSaturatedAdd16(EmitContext& ctx, IR::Inst* inst)
|
|||
}
|
||||
|
||||
void EmitX64::EmitVectorUnsignedSaturatedAdd32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitVectorUnsignedSaturated<Op::Add, 32>(code, ctx, inst);
|
||||
EmitVectorUnsignedSaturated<VectorSaturationOp::Add, 32>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorUnsignedSaturatedAdd64(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitVectorUnsignedSaturated<Op::Add, 64>(code, ctx, inst);
|
||||
EmitVectorUnsignedSaturated<VectorSaturationOp::Add, 64>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorUnsignedSaturatedSub8(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
@ -318,11 +318,11 @@ void EmitX64::EmitVectorUnsignedSaturatedSub16(EmitContext& ctx, IR::Inst* inst)
|
|||
}
|
||||
|
||||
void EmitX64::EmitVectorUnsignedSaturatedSub32(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitVectorUnsignedSaturated<Op::Sub, 32>(code, ctx, inst);
|
||||
EmitVectorUnsignedSaturated<VectorSaturationOp::Sub, 32>(code, ctx, inst);
|
||||
}
|
||||
|
||||
void EmitX64::EmitVectorUnsignedSaturatedSub64(EmitContext& ctx, IR::Inst* inst) {
|
||||
EmitVectorUnsignedSaturated<Op::Sub, 64>(code, ctx, inst);
|
||||
EmitVectorUnsignedSaturated<VectorSaturationOp::Sub, 64>(code, ctx, inst);
|
||||
}
|
||||
|
||||
} // 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.
|
||||
|
|
@ -12,9 +12,9 @@
|
|||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <cassert>
|
||||
#include <bit>
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "dynarmic/backend/exception_handler.h"
|
||||
#include "dynarmic/backend/x64/block_of_code.h"
|
||||
|
|
@ -104,7 +104,7 @@ static PrologueInformation GetPrologueInformation() {
|
|||
entry.code.OpInfo = reg;
|
||||
};
|
||||
const auto alloc_large = [&](u8 offset, size_t size) {
|
||||
ASSERT(size % 8 == 0);
|
||||
assert(size % 8 == 0);
|
||||
size /= 8;
|
||||
|
||||
auto& entry = next_entry();
|
||||
|
|
@ -123,7 +123,7 @@ static PrologueInformation GetPrologueInformation() {
|
|||
}
|
||||
};
|
||||
const auto save_xmm128 = [&](u8 offset, u8 reg, size_t frame_offset) {
|
||||
ASSERT(frame_offset % 16 == 0);
|
||||
assert(frame_offset % 16 == 0);
|
||||
|
||||
auto& entry = next_entry();
|
||||
entry.code.CodeOffset = offset;
|
||||
|
|
@ -165,7 +165,7 @@ static PrologueInformation GetPrologueInformation() {
|
|||
auto& last_entry = next_entry();
|
||||
last_entry.FrameOffset = 0;
|
||||
}
|
||||
ASSERT(ret.unwind_code.size() % 2 == 0);
|
||||
assert(ret.unwind_code.size() % 2 == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <cassert>
|
||||
|
||||
namespace Dynarmic {
|
||||
|
||||
|
|
|
|||
|
|
@ -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 "common/common_types.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <bitset>
|
||||
#include <xbyak/xbyak.h>
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include <cassert>
|
||||
#include "common/common_types.h"
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
|
@ -80,12 +80,12 @@ constexpr bool HostLocIsFlag(HostLoc reg) {
|
|||
}
|
||||
|
||||
constexpr HostLoc HostLocRegIdx(int idx) {
|
||||
ASSERT(idx >= 0 && idx <= 15);
|
||||
assert(idx >= 0 && idx <= 15);
|
||||
return HostLoc(idx);
|
||||
}
|
||||
|
||||
constexpr HostLoc HostLocXmmIdx(int idx) {
|
||||
ASSERT(idx >= 0 && idx <= 15);
|
||||
assert(idx >= 0 && idx <= 15);
|
||||
return HostLoc(size_t(HostLoc::XMM0) + idx);
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ constexpr size_t HostLocBitWidth(HostLoc loc) {
|
|||
return 128;
|
||||
else if (HostLocIsFlag(loc))
|
||||
return 1;
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
constexpr std::bitset<32> BuildRegSet(std::initializer_list<HostLoc> regs) {
|
||||
|
|
@ -161,12 +161,12 @@ const std::bitset<32> any_xmm = BuildRegSet({
|
|||
});
|
||||
|
||||
inline Xbyak::Reg64 HostLocToReg64(HostLoc loc) noexcept {
|
||||
ASSERT(HostLocIsGPR(loc));
|
||||
assert(HostLocIsGPR(loc));
|
||||
return Xbyak::Reg64(int(loc));
|
||||
}
|
||||
|
||||
inline Xbyak::Xmm HostLocToXmm(HostLoc loc) noexcept {
|
||||
ASSERT(HostLocIsXMM(loc));
|
||||
assert(HostLocIsXMM(loc));
|
||||
return Xbyak::Xmm(int(loc) - int(HostLoc::XMM0));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,17 +8,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include <cstddef>
|
||||
|
||||
namespace Dynarmic::Backend::X64::NZCV {
|
||||
|
||||
constexpr u32 arm_mask = 0xF000'0000;
|
||||
constexpr u32 x64_mask = 0xC101;
|
||||
|
||||
constexpr size_t x64_n_flag_bit = 15;
|
||||
constexpr size_t x64_z_flag_bit = 14;
|
||||
constexpr size_t x64_c_flag_bit = 8;
|
||||
constexpr size_t x64_v_flag_bit = 0;
|
||||
constexpr std::size_t x64_n_flag_bit = 15;
|
||||
constexpr std::size_t x64_z_flag_bit = 14;
|
||||
constexpr std::size_t x64_c_flag_bit = 8;
|
||||
constexpr std::size_t x64_v_flag_bit = 0;
|
||||
|
||||
/// This is a constant used to create the x64 flags format from the ARM format.
|
||||
/// NZCV * multiplier: NZCV0NZCV000NZCV
|
||||
|
|
@ -46,7 +47,7 @@ inline u32 FromX64(u32 x64_flags) {
|
|||
nzcv |= mcl::bit::get_bit<15>(x64_flags) ? 1 << 31 : 0;
|
||||
nzcv |= mcl::bit::get_bit<14>(x64_flags) ? 1 << 30 : 0;
|
||||
nzcv |= mcl::bit::get_bit<8>(x64_flags) ? 1 << 29 : 0;
|
||||
nzcv |= mcl::bit::get_bit<0>(x64_flags) ? 1 << 28 : 0;
|
||||
nzcv |= mcl::bit::get_bit<0>(x64_flaags) ? 1 << 28 : 0;
|
||||
return nzcv;
|
||||
*/
|
||||
return ((x64_flags & x64_mask) * from_x64_multiplier) & arm_mask;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include <cassert>
|
||||
#include "dynarmic/backend/x64/xbyak.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
|
@ -30,7 +30,7 @@ struct OpArg {
|
|||
case Type::Reg:
|
||||
return inner_reg;
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
void setBit(int bits) {
|
||||
|
|
@ -57,7 +57,7 @@ struct OpArg {
|
|||
return;
|
||||
}
|
||||
}
|
||||
UNREACHABLE();
|
||||
std::terminate(); //unreachable
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <fmt/format.h>
|
||||
|
||||
#include "dynarmic/backend/x64/perf_map.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "common/common_types.h"
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
# include <cstdio>
|
||||
# include <cstdlib>
|
||||
|
|
|
|||
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