Compare commits

...

22 commits

Author SHA1 Message Date
lizzie
88d0ea45e8 license 2026-03-30 05:02:52 +00:00
lizzie
696c6d903c fix unreachable? 2026-03-30 05:02:29 +00:00
crueter
0c1fdd8be0 Spinlock/exclusive_monitor
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:29 +00:00
lizzie
b4516101ad fix asserts 2026-03-30 05:02:29 +00:00
crueter
c4bc5b8ca3 Partially fix build (fr)
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
crueter
02eeace2b2 Partially fix dynarmiuc tests
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
crueter
e18cd4a87d more size_t fixes
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
crueter
21a3d5b975 Partially fix size_t
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
crueter
4ce80ad503 hm?
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
crueter
ebe1e4d43b Fix a64 interface
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
crueter
8a5acdbc1f Build fixes
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
lizzie
70e53f86c4 fix licenses 2026-03-30 05:02:03 +00:00
lizzie
cb0c5aa196 stub rv64 a64 impl 2026-03-30 05:02:03 +00:00
crueter
9f4f807f58 remove assert/common types, and fix memory barrier
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
crueter
6fb304e11e Fix unimplemented
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:02:03 +00:00
crueter
7fe1639fa9 Enable riscv64 dynarmic backend
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-03-30 05:01:39 +00:00
lizzie
db34c0ef0b more robust 2026-03-30 05:01:39 +00:00
lizzie
7a87b88650 fixup 2026-03-30 05:01:39 +00:00
lizzie
13ee8bedc8 [dynarmic] initial posix EH for rv64
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-03-30 05:01:39 +00:00
lizzie
5322bce4b8
[dynarmic] fix ODR violations (#3749)
Some checks are pending
tx-src / sources (push) Waiting to run
Check Strings / check-strings (push) Waiting to run
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3749
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2026-03-30 04:58:30 +02:00
lizzie
276dcdd8ea
[dynarmic] fix constexpr build issue on gcc-debian-stable (#3798)
Some checks are pending
tx-src / sources (push) Waiting to run
Check Strings / check-strings (push) Waiting to run
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3798
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2026-03-30 00:09:51 +02:00
lizzie
59254cd1e7
[dynarmic] restore proper backtraces for A64 (#3794)
Some checks are pending
tx-src / sources (push) Waiting to run
Check Strings / check-strings (push) Waiting to run
trivial changes, fixes hard crashes

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3794
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2026-03-29 13:57:49 +02:00
241 changed files with 2661 additions and 2204 deletions

View file

@ -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()

View file

@ -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

View file

@ -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;
},

View file

@ -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;
}

View file

@ -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()

View file

@ -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()

View file

@ -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;

View file

@ -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 {

View file

@ -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"

View file

@ -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);

View file

@ -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"

View file

@ -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 {

View file

@ -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;
}

View file

@ -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

View file

@ -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>

View file

@ -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 {

View file

@ -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
}
}

View file

@ -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"

View file

@ -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)) {

View file

@ -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<>

View file

@ -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<>

View file

@ -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]);

View file

@ -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<>

View file

@ -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);
}

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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<>

View file

@ -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<>

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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)));
}
};

View file

@ -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;
};

View file

@ -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

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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"

View file

@ -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 {

View file

@ -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"

View file

@ -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));

View file

@ -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

View file

@ -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
}
}
}

View file

@ -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();

View file

@ -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 {

View file

@ -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"

View 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

View file

@ -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 {

View file

@ -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
}
}

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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 {

View file

@ -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
}
}

View file

@ -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 = {};
}

View file

@ -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;

View file

@ -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;

View file

@ -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
}
}

View file

@ -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 = {};
}

View file

@ -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"

View file

@ -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"

View file

@ -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 {

View file

@ -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);
}

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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;

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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;
}

View file

@ -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"

View file

@ -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];

View file

@ -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]);

View file

@ -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());

View file

@ -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;
}

View file

@ -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

View file

@ -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]);

View file

@ -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

View file

@ -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
}
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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 {

View file

@ -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 {

View file

@ -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));
}

View file

@ -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;

View file

@ -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:

View file

@ -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