From 61ab1be0e70b6e86a15f4938666d3968e20f59f3 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 28 Oct 2025 03:46:24 +0100 Subject: [PATCH] [dynarmic] replace mcl::bit_cast with std::bit_cast; fix IR_emit codepath warnings for UNREACHABLE(); remove type trait mcl::integer_of_size dependency (#2775) - std::bit_cast already on libc++ (see also #2774) - type trait is a 5-liner for u8/u16/u32/u64 - UNREACHABLE(); can just be converted into __builtin_unreachable() (TODO: eventually phase out to std::unreachable() once all platforms support it)\ The templatery parametrization is creating many copies of the same function, polluting i-cache and just bloating code size for minimal savings (and in fact could be negative net savings because of the bloated code size) - this is mostly in preparation to a partial removal of template in functions to remove instancing (think of the function being copied x4 times... because the compiler is forced to inline it...) Signed-off-by: lizzie lizzie@eden-emu.dev Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2775 Reviewed-by: crueter Reviewed-by: MaranBr Co-authored-by: lizzie Co-committed-by: lizzie --- src/dynarmic/src/dynarmic/CMakeLists.txt | 3 +- .../backend/arm64/a32_address_space.cpp | 22 +-- .../backend/arm64/a64_address_space.cpp | 30 ++-- src/dynarmic/src/dynarmic/backend/arm64/abi.h | 7 +- .../dynarmic/backend/arm64/address_space.cpp | 13 +- .../src/dynarmic/backend/arm64/devirtualize.h | 13 +- .../dynarmic/backend/arm64/emit_arm64_a64.cpp | 12 +- .../backend/arm64/emit_arm64_memory.cpp | 11 +- .../backend/arm64/emit_arm64_vector.cpp | 26 +-- .../emit_arm64_vector_floating_point.cpp | 21 ++- .../arm64/emit_arm64_vector_saturation.cpp | 6 +- .../src/dynarmic/backend/arm64/reg_alloc.cpp | 15 +- .../src/dynarmic/backend/exception_handler.h | 20 +-- .../backend/exception_handler_macos.cpp | 9 +- .../backend/exception_handler_macos_mig.c | 2 - .../backend/exception_handler_posix.cpp | 16 +- .../backend/exception_handler_windows.cpp | 2 - .../dynarmic/backend/riscv64/reg_alloc.cpp | 7 +- .../backend/x64/a32_emit_x64_memory.cpp | 4 +- .../dynarmic/backend/x64/a32_interface.cpp | 5 +- .../src/dynarmic/backend/x64/a64_emit_x64.cpp | 1 - .../backend/x64/a64_emit_x64_memory.cpp | 4 +- .../dynarmic/backend/x64/a64_interface.cpp | 5 +- .../src/dynarmic/backend/x64/block_of_code.h | 2 +- .../src/dynarmic/backend/x64/devirtualize.h | 12 +- .../backend/x64/emit_x64_floating_point.cpp | 162 ++++++++---------- .../backend/x64/emit_x64_memory.cpp.inc | 87 ++++------ .../dynarmic/backend/x64/emit_x64_memory.h | 12 +- .../backend/x64/emit_x64_saturation.cpp | 7 +- .../x64/emit_x64_vector_floating_point.cpp | 58 +++---- .../x64/emit_x64_vector_saturation.cpp | 19 +- .../backend/x64/exception_handler_windows.cpp | 8 +- .../src/dynarmic/backend/x64/perf_map.h | 9 +- .../src/dynarmic/backend/x64/reg_alloc.cpp | 2 +- .../src/dynarmic/common/always_false.h | 13 -- src/dynarmic/src/dynarmic/common/assert.h | 45 +++-- src/dynarmic/src/dynarmic/common/cast_util.h | 18 -- src/dynarmic/src/dynarmic/common/fp/util.h | 4 + .../src/dynarmic/common/llvm_disassemble.cpp | 5 +- src/dynarmic/src/dynarmic/common/type_util.h | 31 ++++ src/dynarmic/src/dynarmic/ir/ir_emitter.cpp | 2 +- src/dynarmic/src/dynarmic/ir/ir_emitter.h | 10 +- src/dynarmic/tests/test_generator.cpp | 1 - 43 files changed, 351 insertions(+), 410 deletions(-) delete mode 100644 src/dynarmic/src/dynarmic/common/always_false.h delete mode 100644 src/dynarmic/src/dynarmic/common/cast_util.h create mode 100644 src/dynarmic/src/dynarmic/common/type_util.h diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index 4e00e8fe0d..cb10b6b168 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -6,10 +6,9 @@ add_library(dynarmic STATIC backend/block_range_information.cpp backend/block_range_information.h backend/exception_handler.h - common/always_false.h common/assert.cpp common/assert.h - common/cast_util.h + common/type_util.h common/common_types.h common/crypto/aes.cpp common/crypto/aes.h diff --git a/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp b/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp index 01af361b27..681efce984 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/a32_address_space.cpp @@ -13,7 +13,7 @@ #include "dynarmic/backend/arm64/devirtualize.h" #include "dynarmic/backend/arm64/emit_arm64.h" #include "dynarmic/backend/arm64/stack_layout.h" -#include "dynarmic/common/cast_util.h" +#include "dynarmic/common/type_util.h" #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/frontend/A32/a32_location_descriptor.h" #include "dynarmic/frontend/A32/translate/a32_translate.h" @@ -93,9 +93,9 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const code.align(8); code.l(l_this); - code.dx(mcl::bit_cast(&conf)); + code.dx(std::bit_cast(&conf)); code.l(l_addr); - code.dx(mcl::bit_cast(Common::FptrCast(fn))); + code.dx(std::bit_cast(Common::FptrCast(fn))); return target; } @@ -151,9 +151,9 @@ static void* EmitExclusiveWriteCallTrampoline(oaknut::CodeGenerator& code, const code.align(8); code.l(l_this); - code.dx(mcl::bit_cast(&conf)); + code.dx(std::bit_cast(&conf)); code.l(l_addr); - code.dx(mcl::bit_cast(Common::FptrCast(fn))); + code.dx(std::bit_cast(Common::FptrCast(fn))); return target; } @@ -219,7 +219,7 @@ void A32AddressSpace::EmitPrelude() { code.MOV(Xstate, X1); code.MOV(Xhalt, X2); if (conf.page_table) { - code.MOV(Xpagetable, mcl::bit_cast(conf.page_table)); + code.MOV(Xpagetable, std::bit_cast(conf.page_table)); } if (conf.fastmem_pointer) { code.MOV(Xfastmem, *conf.fastmem_pointer); @@ -258,7 +258,7 @@ void A32AddressSpace::EmitPrelude() { code.MOV(Xstate, X1); code.MOV(Xhalt, X2); if (conf.page_table) { - code.MOV(Xpagetable, mcl::bit_cast(conf.page_table)); + code.MOV(Xpagetable, std::bit_cast(conf.page_table)); } if (conf.fastmem_pointer) { code.MOV(Xfastmem, *conf.fastmem_pointer); @@ -317,9 +317,9 @@ void A32AddressSpace::EmitPrelude() { code.align(8); code.l(l_this); - code.dx(mcl::bit_cast(this)); + code.dx(std::bit_cast(this)); code.l(l_addr); - code.dx(mcl::bit_cast(Common::FptrCast(fn))); + code.dx(std::bit_cast(Common::FptrCast(fn))); } prelude_info.return_from_run_code = code.xptr(); @@ -347,7 +347,7 @@ void A32AddressSpace::EmitPrelude() { code.align(8); code.l(l_return_to_dispatcher); - code.dx(mcl::bit_cast(prelude_info.return_to_dispatcher)); + code.dx(std::bit_cast(prelude_info.return_to_dispatcher)); prelude_info.end_of_prelude = code.offset(); @@ -369,7 +369,7 @@ EmitConfig A32AddressSpace::GetEmitConfig() { .check_halt_on_memory_access = conf.check_halt_on_memory_access, - .page_table_pointer = mcl::bit_cast(conf.page_table), + .page_table_pointer = std::bit_cast(conf.page_table), .page_table_address_space_bits = 32, .page_table_pointer_mask_bits = conf.page_table_pointer_mask_bits, .silently_mirror_page_table = true, diff --git a/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp b/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp index c4c1c42792..f79f0ea374 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.cpp @@ -13,7 +13,7 @@ #include "dynarmic/backend/arm64/devirtualize.h" #include "dynarmic/backend/arm64/emit_arm64.h" #include "dynarmic/backend/arm64/stack_layout.h" -#include "dynarmic/common/cast_util.h" +#include "dynarmic/common/type_util.h" #include "dynarmic/frontend/A64/a64_location_descriptor.h" #include "dynarmic/frontend/A64/translate/a64_translate.h" #include "dynarmic/interface/A64/config.h" @@ -92,9 +92,9 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const code.align(8); code.l(l_this); - code.dx(mcl::bit_cast(&conf)); + code.dx(std::bit_cast(&conf)); code.l(l_addr); - code.dx(mcl::bit_cast(Common::FptrCast(fn))); + code.dx(std::bit_cast(Common::FptrCast(fn))); return target; } @@ -150,9 +150,9 @@ static void* EmitExclusiveWriteCallTrampoline(oaknut::CodeGenerator& code, const code.align(8); code.l(l_this); - code.dx(mcl::bit_cast(&conf)); + code.dx(std::bit_cast(&conf)); code.l(l_addr); - code.dx(mcl::bit_cast(Common::FptrCast(fn))); + code.dx(std::bit_cast(Common::FptrCast(fn))); return target; } @@ -235,9 +235,9 @@ static void* EmitExclusiveRead128CallTrampoline(oaknut::CodeGenerator& code, con code.align(8); code.l(l_this); - code.dx(mcl::bit_cast(&conf)); + code.dx(std::bit_cast(&conf)); code.l(l_addr); - code.dx(mcl::bit_cast(Common::FptrCast(fn))); + code.dx(std::bit_cast(Common::FptrCast(fn))); return target; } @@ -317,9 +317,9 @@ static void* EmitExclusiveWrite128CallTrampoline(oaknut::CodeGenerator& code, co code.align(8); code.l(l_this); - code.dx(mcl::bit_cast(&conf)); + code.dx(std::bit_cast(&conf)); code.l(l_addr); - code.dx(mcl::bit_cast(Common::FptrCast(fn))); + code.dx(std::bit_cast(Common::FptrCast(fn))); return target; } @@ -396,7 +396,7 @@ void A64AddressSpace::EmitPrelude() { code.MOV(Xstate, X1); code.MOV(Xhalt, X2); if (conf.page_table) { - code.MOV(Xpagetable, mcl::bit_cast(conf.page_table)); + code.MOV(Xpagetable, std::bit_cast(conf.page_table)); } if (conf.fastmem_pointer) { code.MOV(Xfastmem, *conf.fastmem_pointer); @@ -434,7 +434,7 @@ void A64AddressSpace::EmitPrelude() { code.MOV(Xstate, X1); code.MOV(Xhalt, X2); if (conf.page_table) { - code.MOV(Xpagetable, mcl::bit_cast(conf.page_table)); + code.MOV(Xpagetable, std::bit_cast(conf.page_table)); } if (conf.fastmem_pointer) { code.MOV(Xfastmem, *conf.fastmem_pointer); @@ -492,9 +492,9 @@ void A64AddressSpace::EmitPrelude() { code.align(8); code.l(l_this); - code.dx(mcl::bit_cast(this)); + code.dx(std::bit_cast(this)); code.l(l_addr); - code.dx(mcl::bit_cast(Common::FptrCast(fn))); + code.dx(std::bit_cast(Common::FptrCast(fn))); } prelude_info.return_from_run_code = code.xptr(); @@ -522,7 +522,7 @@ void A64AddressSpace::EmitPrelude() { code.align(8); code.l(l_return_to_dispatcher); - code.dx(mcl::bit_cast(prelude_info.return_to_dispatcher)); + code.dx(std::bit_cast(prelude_info.return_to_dispatcher)); prelude_info.end_of_prelude = code.offset(); @@ -544,7 +544,7 @@ EmitConfig A64AddressSpace::GetEmitConfig() { .check_halt_on_memory_access = conf.check_halt_on_memory_access, - .page_table_pointer = mcl::bit_cast(conf.page_table), + .page_table_pointer = std::bit_cast(conf.page_table), .page_table_address_space_bits = conf.page_table_address_space_bits, .page_table_pointer_mask_bits = conf.page_table_pointer_mask_bits, .silently_mirror_page_table = conf.silently_mirror_page_table, diff --git a/src/dynarmic/src/dynarmic/backend/arm64/abi.h b/src/dynarmic/src/dynarmic/backend/arm64/abi.h index 635d64f062..d0258ef5c4 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/abi.h +++ b/src/dynarmic/src/dynarmic/backend/arm64/abi.h @@ -17,7 +17,6 @@ #include "dynarmic/common/assert.h" #include -#include "dynarmic/common/always_false.h" namespace Dynarmic::Backend::Arm64 { @@ -37,7 +36,8 @@ constexpr auto Rscratch0() { } else if constexpr (bitsize == 64) { return Xscratch0; } else { - static_assert(Common::always_false_v>); + // TODO: This codepath is regarded as "takeable" on gcc12 + return Xscratch0; //static_assert(false); } } @@ -48,7 +48,8 @@ constexpr auto Rscratch1() { } else if constexpr (bitsize == 64) { return Xscratch1; } else { - static_assert(Common::always_false_v>); + // TODO: This codepath is regarded as "takeable" on gcc12 + return Xscratch1; //static_assert(false); } } diff --git a/src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp b/src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp index 614ca03364..0b82f4de43 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp @@ -1,11 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2025 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 */ #include - -#include +#include +#include #include "dynarmic/backend/arm64/a64_address_space.h" #include "dynarmic/backend/arm64/a64_jitstate.h" @@ -13,7 +16,7 @@ #include "dynarmic/backend/arm64/devirtualize.h" #include "dynarmic/backend/arm64/emit_arm64.h" #include "dynarmic/backend/arm64/stack_layout.h" -#include "dynarmic/common/cast_util.h" +#include "dynarmic/common/type_util.h" #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/llvm_disassemble.h" #include "dynarmic/interface/exclusive_monitor.h" @@ -99,7 +102,7 @@ void AddressSpace::ClearCache() { void AddressSpace::DumpDisassembly() const { for (u32* ptr = mem.ptr(); ptr < code.xptr(); ptr++) { - std::printf("%s", Common::DisassembleAArch64(*ptr, mcl::bit_cast(ptr)).c_str()); + std::printf("%s", Common::DisassembleAArch64(*ptr, std::bit_cast(ptr)).c_str()); } } @@ -316,7 +319,7 @@ void AddressSpace::RelinkForDescriptor(IR::LocationDescriptor target_descriptor, FakeCall AddressSpace::FastmemCallback(u64 host_pc) { { - const auto host_ptr = mcl::bit_cast(host_pc); + const auto host_ptr = std::bit_cast(host_pc); const auto entry_point = ReverseGetEntryPoint(host_ptr); if (!entry_point) { diff --git a/src/dynarmic/src/dynarmic/backend/arm64/devirtualize.h b/src/dynarmic/src/dynarmic/backend/arm64/devirtualize.h index 14dc3809a5..820fa1dc47 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/devirtualize.h +++ b/src/dynarmic/src/dynarmic/backend/arm64/devirtualize.h @@ -8,7 +8,8 @@ #pragma once -#include +#include +#include #include "dynarmic/common/common_types.h" #include @@ -23,7 +24,7 @@ struct DevirtualizedCall { template DevirtualizedCall DevirtualizeWindows(mcl::class_type* this_) { static_assert(sizeof(mfp) == 8); - return DevirtualizedCall{mcl::bit_cast(mfp), reinterpret_cast(this_)}; + return DevirtualizedCall{std::bit_cast(mfp), reinterpret_cast(this_)}; } // https://github.com/ARM-software/abi-aa/blob/main/cppabi64/cppabi64.rst#representation-of-pointer-to-member-function @@ -34,16 +35,16 @@ DevirtualizedCall DevirtualizeDefault(mcl::class_type* this_) { u64 ptr; // LSB is discriminator for if function is virtual. Other bits are this adjustment. u64 adj; - } mfp_struct = mcl::bit_cast(mfp); + } mfp_struct = std::bit_cast(mfp); static_assert(sizeof(MemberFunctionPointer) == 16); static_assert(sizeof(MemberFunctionPointer) == sizeof(mfp)); u64 fn_ptr = mfp_struct.ptr; - u64 this_ptr = mcl::bit_cast(this_) + (mfp_struct.adj >> 1); + u64 this_ptr = std::bit_cast(this_) + (mfp_struct.adj >> 1); if (mfp_struct.adj & 1) { - u64 vtable = mcl::bit_cast_pointee(this_ptr); - fn_ptr = mcl::bit_cast_pointee(vtable + fn_ptr); + u64 vtable = std::bit_cast(this_ptr); + fn_ptr = std::bit_cast(vtable + fn_ptr); } return DevirtualizedCall{fn_ptr, this_ptr}; } diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a64.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a64.cpp index 5152a54ba2..2650f1e5fc 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a64.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_a64.cpp @@ -1,9 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2025 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 */ -#include +#include +#include #include #include "dynarmic/backend/arm64/a64_jitstate.h" @@ -495,7 +499,7 @@ template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { auto Xvalue = ctx.reg_alloc.WriteX(inst); RegAlloc::Realize(Xvalue); - code.MOV(Xscratch0, mcl::bit_cast(ctx.conf.tpidr_el0)); + code.MOV(Xscratch0, std::bit_cast(ctx.conf.tpidr_el0)); code.LDR(Xvalue, Xscratch0); } @@ -503,7 +507,7 @@ template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { auto Xvalue = ctx.reg_alloc.WriteX(inst); RegAlloc::Realize(Xvalue); - code.MOV(Xscratch0, mcl::bit_cast(ctx.conf.tpidrro_el0)); + code.MOV(Xscratch0, std::bit_cast(ctx.conf.tpidrro_el0)); code.LDR(Xvalue, Xscratch0); } @@ -512,7 +516,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& c auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto Xvalue = ctx.reg_alloc.ReadX(args[0]); RegAlloc::Realize(Xvalue); - code.MOV(Xscratch0, mcl::bit_cast(ctx.conf.tpidr_el0)); + code.MOV(Xscratch0, std::bit_cast(ctx.conf.tpidr_el0)); code.STR(Xvalue, Xscratch0); } diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_memory.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_memory.cpp index 339e2c59a0..58d7885d12 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_memory.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_memory.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 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 @@ -7,8 +10,8 @@ #include #include - -#include +#include +#include #include #include "dynarmic/backend/arm64/abi.h" @@ -548,7 +551,7 @@ void FastmemEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::In FastmemPatchInfo{ .marker = marker, .fc = FakeCall{ - .call_pc = mcl::bit_cast(code.xptr()), + .call_pc = std::bit_cast(code.xptr()), }, .recompile = ctx.conf.recompile_on_fastmem_failure, }); @@ -598,7 +601,7 @@ void FastmemEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::I FastmemPatchInfo{ .marker = marker, .fc = FakeCall{ - .call_pc = mcl::bit_cast(code.xptr()), + .call_pc = std::bit_cast(code.xptr()), }, .recompile = ctx.conf.recompile_on_fastmem_failure, }); diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector.cpp index e14effca3b..faa6810ac0 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 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 @@ -12,7 +15,6 @@ #include "dynarmic/backend/arm64/emit_context.h" #include "dynarmic/backend/arm64/fpsr_manager.h" #include "dynarmic/backend/arm64/reg_alloc.h" -#include "dynarmic/common/always_false.h" #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/opcodes.h" @@ -43,7 +45,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR: } else if constexpr (size == 64) { emit(Qresult->D2(), Qoperand->D2()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -66,7 +68,7 @@ static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx } else if constexpr (size == 32) { emit(Qresult->D2(), Qoperand->toD().S2()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -81,7 +83,7 @@ static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ct } else if constexpr (size == 64) { emit(Qresult->toD().S2(), Qoperand->D2()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -104,7 +106,7 @@ static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext& } else if constexpr (size == 32) { emit(Qresult->D2(), Qoperand->S4()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -119,7 +121,7 @@ static void EmitTwoOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx } else if constexpr (size == 32) { emit(Qresult->toD().S2(), Qoperand->toD().S2()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -147,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 { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -172,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 { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -195,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 { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -217,7 +219,7 @@ static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR } else if constexpr (size == 64) { emit(Qaccumulator->D2(), Qoperand->D2()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } } @@ -238,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 { - static_assert(Common::always_false_v>); + //static_assert(false); } } @@ -266,7 +268,7 @@ static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, } else if constexpr (size == 64) { emit(Vresult, Qoperand->D2()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } } diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector_floating_point.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector_floating_point.cpp index 81cfc0b2db..3e4d5c5912 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector_floating_point.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector_floating_point.cpp @@ -6,7 +6,8 @@ * SPDX-License-Identifier: 0BSD */ -#include +#include +#include #include #include #include @@ -14,7 +15,6 @@ #include #include #include -#include #include #include "dynarmic/backend/arm64/a32_jitstate.h" @@ -24,8 +24,7 @@ #include "dynarmic/backend/arm64/emit_context.h" #include "dynarmic/backend/arm64/fpsr_manager.h" #include "dynarmic/backend/arm64/reg_alloc.h" -#include "dynarmic/common/always_false.h" -#include "dynarmic/common/cast_util.h" +#include "dynarmic/common/type_util.h" #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/fp/fpsr.h" #include "dynarmic/common/fp/info.h" @@ -84,7 +83,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR: } else if constexpr (size == 64) { emit(Qresult->D2(), Qa->D2()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -112,7 +111,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I } else if constexpr (size == 64) { emit(Qresult->D2(), Qa->D2(), Qb->D2()); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -135,7 +134,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 { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -157,7 +156,7 @@ static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Ins } else if constexpr (size == 64) { emit(Qto->D2(), Qfrom->D2(), fbits); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } }); } @@ -179,7 +178,7 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) } else if constexpr (fsize == 64) { return Qto->D2(); } else { - static_assert(Common::always_false_v>); + return Qto->D2(); //static_assert(false); } }(); auto Vfrom = [&] { @@ -188,7 +187,7 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) } else if constexpr (fsize == 64) { return Qfrom->D2(); } else { - static_assert(Common::always_false_v>); + return Qfrom->D2(); //static_assert(false); } }(); @@ -271,7 +270,7 @@ static void EmitTwoOpFallbackWithoutRegAlloc(oaknut::CodeGenerator& code, EmitCo ABI_PushRegisters(code, ABI_CALLER_SAVE & ~(1ull << Qresult.index()), stack_size); - code.MOV(Xscratch0, mcl::bit_cast(fn)); + code.MOV(Xscratch0, std::bit_cast(fn)); code.ADD(X0, SP, 0 * 16); code.ADD(X1, SP, 1 * 16); code.MOV(X2, fpcr); diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector_saturation.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector_saturation.cpp index 722a09176b..0839425bd3 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector_saturation.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector_saturation.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 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 @@ -12,7 +15,6 @@ #include "dynarmic/backend/arm64/emit_context.h" #include "dynarmic/backend/arm64/fpsr_manager.h" #include "dynarmic/backend/arm64/reg_alloc.h" -#include "dynarmic/common/always_false.h" #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/opcodes.h" @@ -39,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 { - static_assert(Common::always_false_v>); + //static_assert(false); } } diff --git a/src/dynarmic/src/dynarmic/backend/arm64/reg_alloc.cpp b/src/dynarmic/src/dynarmic/backend/arm64/reg_alloc.cpp index 07440bd385..d1d1588062 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/reg_alloc.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/reg_alloc.cpp @@ -11,10 +11,10 @@ #include #include #include - +#include +#include #include "dynarmic/common/assert.h" #include -#include #include #include "dynarmic/common/common_types.h" @@ -22,7 +22,6 @@ #include "dynarmic/backend/arm64/emit_context.h" #include "dynarmic/backend/arm64/fpsr_manager.h" #include "dynarmic/backend/arm64/verbose_debugging_output.h" -#include "dynarmic/common/always_false.h" namespace Dynarmic::Backend::Arm64 { @@ -246,7 +245,7 @@ void RegAlloc::AssertNoMoreUses() const { } void RegAlloc::EmitVerboseDebuggingOutput() { - code.MOV(X19, mcl::bit_cast(&PrintVerboseDebuggingOutputLine)); // Non-volatile register + code.MOV(X19, std::bit_cast(&PrintVerboseDebuggingOutputLine)); // Non-volatile register const auto do_location = [&](HostLocInfo& info, HostLocType type, size_t index) { using namespace oaknut::util; @@ -301,7 +300,7 @@ int RegAlloc::GenerateImmediate(const IR::Value& value) { return 0; } else { - static_assert(Common::always_false_v>); + return 0;//static_assert(false); } } @@ -370,7 +369,7 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) { } else if constexpr (required_kind == HostLoc::Kind::Flags) { ASSERT_FALSE("A simple read from flags is likely a logic error."); } else { - static_assert(Common::always_false_v>); + return 0;//static_assert(false); } } @@ -395,7 +394,7 @@ int RegAlloc::RealizeWriteImpl(const IR::Inst* value) { flags.SetupLocation(value); return 0; } else { - static_assert(Common::always_false_v>); + return 0; //static_assert(false); } } @@ -416,7 +415,7 @@ int RegAlloc::RealizeReadWriteImpl(const IR::Value& read_value, const IR::Inst* } else if constexpr (kind == HostLoc::Kind::Flags) { ASSERT_FALSE("Incorrect function for ReadWrite of flags"); } else { - static_assert(Common::always_false_v>); + return write_loc; //static_assert(false); } } diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler.h b/src/dynarmic/src/dynarmic/backend/exception_handler.h index 173949628c..b0e2e4e372 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler.h +++ b/src/dynarmic/src/dynarmic/backend/exception_handler.h @@ -11,19 +11,17 @@ #include #include #include - -#include #include "dynarmic/common/common_types.h" -#if defined(MCL_ARCHITECTURE_X86_64) +#if defined(ARCHITECTURE_x86_64) namespace Dynarmic::Backend::X64 { class BlockOfCode; } // namespace Dynarmic::Backend::X64 -#elif defined(MCL_ARCHITECTURE_ARM64) +#elif defined(ARCHITECTURE_arm64) namespace oaknut { class CodeBlock; } // namespace oaknut -#elif defined(MCL_ARCHITECTURE_RISCV) +#elif defined(ARCHITECTURE_riscv64) namespace Dynarmic::Backend::RV64 { class CodeBlock; } // namespace Dynarmic::Backend::RV64 @@ -33,16 +31,16 @@ class CodeBlock; namespace Dynarmic::Backend { -#if defined(MCL_ARCHITECTURE_X86_64) +#if defined(ARCHITECTURE_x86_64) struct FakeCall { u64 call_rip; u64 ret_rip; }; -#elif defined(MCL_ARCHITECTURE_ARM64) +#elif defined(ARCHITECTURE_arm64) struct FakeCall { u64 call_pc; }; -#elif defined(MCL_ARCHITECTURE_RISCV) +#elif defined(ARCHITECTURE_riscv64) struct FakeCall { }; #else @@ -54,11 +52,11 @@ public: ExceptionHandler(); ~ExceptionHandler(); -#if defined(MCL_ARCHITECTURE_X86_64) +#if defined(ARCHITECTURE_x86_64) void Register(X64::BlockOfCode& code); -#elif defined(MCL_ARCHITECTURE_ARM64) +#elif defined(ARCHITECTURE_arm64) void Register(oaknut::CodeBlock& mem, std::size_t mem_size); -#elif defined(MCL_ARCHITECTURE_RISCV) +#elif defined(ARCHITECTURE_riscv64) void Register(RV64::CodeBlock& mem, std::size_t mem_size); #else # error "Invalid architecture" diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp index 76e517f05b..e1cce19ade 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp @@ -19,8 +19,7 @@ #include #include "dynarmic/common/assert.h" -#include -#include +#include #include "dynarmic/common/common_types.h" #include "dynarmic/backend/exception_handler.h" @@ -146,7 +145,7 @@ kern_return_t MachHandler::HandleRequest(x86_thread_state64_t* ts) { FakeCall fc = iter->cb(ts->__rip); ts->__rsp -= sizeof(u64); - *mcl::bit_cast(ts->__rsp) = fc.ret_rip; + *std::bit_cast(ts->__rsp) = fc.ret_rip; ts->__rip = fc.call_rip; return KERN_SUCCESS; @@ -271,13 +270,13 @@ ExceptionHandler::~ExceptionHandler() = default; #if defined(ARCHITECTURE_x86_64) void ExceptionHandler::Register(X64::BlockOfCode& code) { - const u64 code_begin = mcl::bit_cast(code.getCode()); + const u64 code_begin = std::bit_cast(code.getCode()); const u64 code_end = code_begin + code.GetTotalCodeSize(); impl = std::make_unique(code_begin, code_end); } #elif defined(ARCHITECTURE_arm64) void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) { - const u64 code_begin = mcl::bit_cast(mem.ptr()); + const u64 code_begin = std::bit_cast(mem.ptr()); const u64 code_end = code_begin + size; impl = std::make_unique(code_begin, code_end); } diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c b/src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c index 25678ab115..ebbe5a079f 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c @@ -3,8 +3,6 @@ * SPDX-License-Identifier: 0BSD */ -#include - #if defined(ARCHITECTURE_x86_64) # include "dynarmic/backend/x64/mig/mach_exc_server.c" #elif defined(ARCHITECTURE_arm64) diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp index f1f208179f..d9fa71e5f6 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp @@ -27,7 +27,7 @@ #else # error "Invalid architecture" #endif -#include +#include namespace Dynarmic::Backend { @@ -122,7 +122,7 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_RIP); iter != sig_handler->code_block_infos.end()) { FakeCall fc = iter->second.cb(CTX_RIP); CTX_RSP -= sizeof(u64); - *mcl::bit_cast(CTX_RSP) = fc.ret_rip; + *std::bit_cast(CTX_RSP) = fc.ret_rip; CTX_RIP = fc.call_rip; return; } @@ -187,17 +187,17 @@ private: ExceptionHandler::ExceptionHandler() = default; ExceptionHandler::~ExceptionHandler() = default; -#if defined(MCL_ARCHITECTURE_X86_64) +#if defined(ARCHITECTURE_x86_64) void ExceptionHandler::Register(X64::BlockOfCode& code) { - impl = std::make_unique(mcl::bit_cast(code.getCode()), code.GetTotalCodeSize()); + impl = std::make_unique(std::bit_cast(code.getCode()), code.GetTotalCodeSize()); } -#elif defined(MCL_ARCHITECTURE_ARM64) +#elif defined(ARCHITECTURE_arm64) void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) { - impl = std::make_unique(mcl::bit_cast(mem.ptr()), size); + impl = std::make_unique(std::bit_cast(mem.ptr()), size); } -#elif defined(MCL_ARCHITECTURE_RISCV) +#elif defined(ARCHITECTURE_riscv64) void ExceptionHandler::Register(RV64::CodeBlock& mem, std::size_t size) { - impl = std::make_unique(mcl::bit_cast(mem.ptr()), size); + impl = std::make_unique(std::bit_cast(mem.ptr()), size); } #else # error "Invalid architecture" diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp index 58a3325e17..332a7cbe07 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp @@ -6,8 +6,6 @@ * SPDX-License-Identifier: 0BSD */ -#include - #if defined(ARCHITECTURE_x86_64) # include "dynarmic/backend/x64/exception_handler_windows.cpp" #elif defined(ARCHITECTURE_arm64) diff --git a/src/dynarmic/src/dynarmic/backend/riscv64/reg_alloc.cpp b/src/dynarmic/src/dynarmic/backend/riscv64/reg_alloc.cpp index e09bd696b8..b0128d6202 100644 --- a/src/dynarmic/src/dynarmic/backend/riscv64/reg_alloc.cpp +++ b/src/dynarmic/src/dynarmic/backend/riscv64/reg_alloc.cpp @@ -15,7 +15,6 @@ #include #include "dynarmic/common/common_types.h" -#include "dynarmic/common/always_false.h" namespace Dynarmic::Backend::RV64 { @@ -164,7 +163,7 @@ u32 RegAlloc::GenerateImmediate(const IR::Value& value) { } else if constexpr (kind == HostLoc::Kind::Fpr) { UNIMPLEMENTED(); } else { - static_assert(Common::always_false_v>); + //static_assert(false); } return 0; @@ -227,7 +226,7 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) { fprs[new_location_index].realized = true; return new_location_index; } else { - static_assert(Common::always_false_v>); + return 0; //static_assert(false); } } @@ -254,7 +253,7 @@ u32 RegAlloc::RealizeWriteImpl(const IR::Inst* value) { setup_location(fprs[new_location_index]); return new_location_index; } else { - static_assert(Common::always_false_v>); + return 0;//static_assert(false); } } diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp index a1fca21f47..92f5cae602 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 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 @@ -10,7 +13,6 @@ #include #include -#include #include #include "dynarmic/backend/x64/a32_emit_x64.h" diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp index 382eb70f3f..f87cfb438e 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp @@ -9,11 +9,12 @@ #include #include #include +#include #include #include #include "dynarmic/common/assert.h" -#include +#include #include #include "dynarmic/common/common_types.h" @@ -47,7 +48,7 @@ static RunCodeCallbacks GenRunCodeCallbacks(A32::UserCallbacks* cb, CodePtr (*Lo static std::function GenRCP(const A32::UserConfig& conf) { return [conf](BlockOfCode& code) { if (conf.page_table) { - code.mov(code.r14, mcl::bit_cast(conf.page_table)); + code.mov(code.r14, std::bit_cast(conf.page_table)); } if (conf.fastmem_pointer) { code.mov(code.r13, *conf.fastmem_pointer); diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp index b5da18701c..e897cef7cb 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp @@ -13,7 +13,6 @@ #include "dynarmic/common/assert.h" #include #include "dynarmic/common/common_types.h" -#include #include #include "dynarmic/backend/x64/a64_jitstate.h" diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp index 8fd6777542..fc0cd8c1f3 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 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 @@ -10,7 +13,6 @@ #include #include -#include #include #include "dynarmic/backend/x64/a64_emit_x64.h" diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp index c65b582982..baa5071328 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp @@ -9,10 +9,11 @@ #include #include #include +#include #include #include "dynarmic/common/assert.h" -#include +#include #include #include "dynarmic/backend/x64/a64_emit_x64.h" @@ -43,7 +44,7 @@ static RunCodeCallbacks GenRunCodeCallbacks(A64::UserCallbacks* cb, CodePtr (*Lo static std::function GenRCP(const A64::UserConfig& conf) { return [conf](BlockOfCode& code) { if (conf.page_table) { - code.mov(code.r14, mcl::bit_cast(conf.page_table)); + code.mov(code.r14, std::bit_cast(conf.page_table)); } if (conf.fastmem_pointer) { code.mov(code.r13, *conf.fastmem_pointer); diff --git a/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h b/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h index 095e75336b..42e5fb0982 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h +++ b/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h @@ -23,7 +23,7 @@ #include "dynarmic/backend/x64/constant_pool.h" #include "dynarmic/backend/x64/host_feature.h" #include "dynarmic/backend/x64/jitstate_info.h" -#include "dynarmic/common/cast_util.h" +#include "dynarmic/common/type_util.h" #include "dynarmic/interface/halt_reason.h" #include "dynarmic/ir/cond.h" diff --git a/src/dynarmic/src/dynarmic/backend/x64/devirtualize.h b/src/dynarmic/src/dynarmic/backend/x64/devirtualize.h index 318a702194..428ea749fa 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/devirtualize.h +++ b/src/dynarmic/src/dynarmic/backend/x64/devirtualize.h @@ -10,8 +10,8 @@ #include #include - -#include +#include +#include #include "dynarmic/common/common_types.h" #include @@ -42,7 +42,7 @@ ArgCallback DevirtualizeGeneric(mcl::class_type* this_) { template ArgCallback DevirtualizeWindows(mcl::class_type* this_) { static_assert(sizeof(mfp) == 8); - return ArgCallback{mcl::bit_cast(mfp), reinterpret_cast(this_)}; + return ArgCallback{std::bit_cast(mfp), reinterpret_cast(this_)}; } template @@ -53,7 +53,7 @@ ArgCallback DevirtualizeItanium(mcl::class_type* this_) { u64 ptr; /// The required adjustment to `this`, prior to the call. u64 adj; - } mfp_struct = mcl::bit_cast(mfp); + } mfp_struct = std::bit_cast(mfp); static_assert(sizeof(MemberFunctionPointer) == 16); static_assert(sizeof(MemberFunctionPointer) == sizeof(mfp)); @@ -61,8 +61,8 @@ ArgCallback DevirtualizeItanium(mcl::class_type* this_) { u64 fn_ptr = mfp_struct.ptr; u64 this_ptr = reinterpret_cast(this_) + mfp_struct.adj; if (mfp_struct.ptr & 1) { - u64 vtable = mcl::bit_cast_pointee(this_ptr); - fn_ptr = mcl::bit_cast_pointee(vtable + fn_ptr - 1); + u64 vtable = std::bit_cast(this_ptr); + fn_ptr = std::bit_cast(vtable + fn_ptr - 1); } return ArgCallback{fn_ptr, this_ptr}; } diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_floating_point.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_floating_point.cpp index a2fe4001a9..5d03697882 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_floating_point.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_floating_point.cpp @@ -18,14 +18,13 @@ #include #include #include "dynarmic/common/common_types.h" -#include #include #include "dynarmic/backend/x64/abi.h" #include "dynarmic/backend/x64/block_of_code.h" #include "dynarmic/backend/x64/constants.h" #include "dynarmic/backend/x64/emit_x64.h" -#include "dynarmic/common/cast_util.h" +#include "dynarmic/common/type_util.h" #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/fp/fpsr.h" #include "dynarmic/common/fp/info.h" @@ -36,22 +35,8 @@ #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/microinstruction.h" -#define FCODE(NAME) \ - [&code](auto... args) { \ - if constexpr (fsize == 32) { \ - code.NAME##s(args...); \ - } else { \ - code.NAME##d(args...); \ - } \ - } -#define ICODE(NAME) \ - [&code](auto... args) { \ - if constexpr (fsize == 32) { \ - code.NAME##d(args...); \ - } else { \ - code.NAME##q(args...); \ - } \ - } +#define FCODE(NAME) [&](auto... args) { if (fsize == 32) code.NAME##s(args...); else code.NAME##d(args...); } +#define ICODE(NAME) [&](auto... args) { if (fsize == 32) code.NAME##d(args...); else code.NAME##q(args...); } namespace Dynarmic::Backend::X64 { @@ -105,7 +90,7 @@ void ForceDenormalsToZero(BlockOfCode& code, std::initializer_list t for (const Xbyak::Xmm& xmm : to_daz) { code.movaps(xmm0, code.Const(xword, fsize == 32 ? f32_non_sign_mask : f64_non_sign_mask)); code.andps(xmm0, xmm); - if constexpr (fsize == 32) { + if (fsize == 32) { code.pcmpgtd(xmm0, code.Const(xword, f32_smallest_normal - 1)); } else if (code.HasHostFeature(HostFeature::SSE42)) { code.pcmpgtq(xmm0, code.Const(xword, f64_smallest_normal - 1)); @@ -120,13 +105,11 @@ void ForceDenormalsToZero(BlockOfCode& code, std::initializer_list t template void DenormalsAreZero(BlockOfCode& code, EmitContext& ctx, std::initializer_list to_daz) { - if (ctx.FPCR().FZ()) { + if (ctx.FPCR().FZ()) ForceDenormalsToZero(code, to_daz); - } } -template -void ZeroIfNaN(BlockOfCode& code, Xbyak::Xmm xmm_value, Xbyak::Xmm xmm_scratch) { +void ZeroIfNaN(BlockOfCode& code, Xbyak::Xmm xmm_value, Xbyak::Xmm xmm_scratch, size_t fsize) { if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) { constexpr u32 nan_to_zero = FixupLUT(FpFixup::PosZero, FpFixup::PosZero); @@ -141,8 +124,7 @@ void ZeroIfNaN(BlockOfCode& code, Xbyak::Xmm xmm_value, Xbyak::Xmm xmm_scratch) } } -template -void ForceToDefaultNaN(BlockOfCode& code, Xbyak::Xmm result) { +void ForceToDefaultNaN(BlockOfCode& code, Xbyak::Xmm result, size_t fsize) { if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) { const Xbyak::Opmask nan_mask = k1; FCODE(vfpclasss)(nan_mask, result, u8(FpClass::QNaN | FpClass::SNaN)); @@ -208,7 +190,7 @@ void PostProcessNaN(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm tmp) { // We allow for the case where op1 and result are the same register. We do not read from op1 once result is written to. template void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, Xbyak::Xmm op2, Xbyak::Reg64 tmp, Xbyak::Label end) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; constexpr FPT exponent_mask = FP::FPInfo::exponent_mask; constexpr FPT mantissa_msb = FP::FPInfo::mantissa_msb; constexpr u8 mantissa_msb_bit = static_cast(FP::FPInfo::explicit_mantissa_width - 1); @@ -236,7 +218,7 @@ void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, X } constexpr size_t shift = fsize == 32 ? 0 : 48; - if constexpr (fsize == 32) { + if (fsize == 32) { code.movd(tmp.cvt32(), xmm0); } else { // We do this to avoid requiring 64-bit immediates @@ -252,7 +234,7 @@ void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, X // op1 == QNaN && op2 == SNaN <<< The problematic case // op1 == QNaN && op2 == Inf - if constexpr (fsize == 32) { + if (fsize == 32) { code.movd(tmp.cvt32(), op2); code.shl(tmp.cvt32(), 32 - mantissa_msb_bit); } else { @@ -291,7 +273,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) { if (ctx.HasOptimization(OptimizationFlag::Unsafe_InaccurateNaN)) { // Do nothing } else if (ctx.FPCR().DN()) { - ForceToDefaultNaN(code, result); + ForceToDefaultNaN(code, result, fsize); } else { PostProcessNaN(code, result, xmm0); } @@ -302,7 +284,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) { template void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -317,7 +299,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) } if (!ctx.HasOptimization(OptimizationFlag::Unsafe_InaccurateNaN)) { - ForceToDefaultNaN(code, result); + ForceToDefaultNaN(code, result, fsize); } ctx.reg_alloc.DefineValue(inst, result); @@ -361,7 +343,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) template void FPAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; constexpr FPT non_sign_mask = FP::FPInfo::sign_mask - FPT(1u); auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -387,7 +369,7 @@ void EmitX64::EmitFPAbs64(EmitContext& ctx, IR::Inst* inst) { template void FPNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; constexpr FPT sign_mask = FP::FPInfo::sign_mask; auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -442,7 +424,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { FCODE(ucomis)(result, operand); code.jz(*equal, code.T_NEAR); - if constexpr (is_max) { + if (is_max) { FCODE(maxs)(result, operand); } else { FCODE(mins)(result, operand); @@ -454,7 +436,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { code.L(*equal); code.jp(nan); - if constexpr (is_max) { + if (is_max) { code.andps(result, operand); } else { code.orps(result, operand); @@ -477,7 +459,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { template static inline void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) noexcept { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; constexpr FPT default_nan = FP::FPInfo::DefaultNaN(); auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -502,7 +484,7 @@ static inline void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR:: tmp.setBit(fsize); const auto move_to_tmp = [=, &code](const Xbyak::Xmm& xmm) { - if constexpr (fsize == 32) { + if (fsize == 32) { code.movd(tmp.cvt32(), xmm); } else { code.movq(tmp.cvt64(), xmm); @@ -513,7 +495,7 @@ static inline void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR:: FCODE(ucomis)(op1, op2); code.jz(*z, code.T_NEAR); - if constexpr (is_max) { + if (is_max) { FCODE(maxs)(op2, op1); } else { FCODE(mins)(op2, op1); @@ -527,7 +509,7 @@ static inline void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR:: code.L(*z); code.jp(nan); - if constexpr (is_max) { + if (is_max) { code.andps(op2, op1); } else { code.orps(op2, op1); @@ -629,12 +611,12 @@ void EmitX64::EmitFPMul64(EmitContext& ctx, IR::Inst* inst) { template static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; const auto fallback_fn = negate_product ? &FP::FPMulSub : &FP::FPMulAdd; auto args = ctx.reg_alloc.GetArgumentInfo(inst); - if constexpr (fsize != 16) { + if (fsize != 16) { const bool needs_rounding_correction = ctx.FPCR().FZ(); const bool needs_nan_correction = !ctx.FPCR().DN(); @@ -643,13 +625,13 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { const Xbyak::Xmm operand2 = ctx.reg_alloc.UseXmm(args[1]); const Xbyak::Xmm operand3 = ctx.reg_alloc.UseXmm(args[2]); - if constexpr (negate_product) { + if (negate_product) { FCODE(vfnmadd231s)(result, operand2, operand3); } else { FCODE(vfmadd231s)(result, operand2, operand3); } if (ctx.FPCR().DN()) { - ForceToDefaultNaN(code, result); + ForceToDefaultNaN(code, result, fsize); } ctx.reg_alloc.DefineValue(inst, result); @@ -665,7 +647,7 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(); code.movaps(result, operand1); - if constexpr (negate_product) { + if (negate_product) { FCODE(vfnmadd231s)(result, operand2, operand3); } else { FCODE(vfmadd231s)(result, operand2, operand3); @@ -686,9 +668,8 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { } else { UNREACHABLE(); } - if (ctx.FPCR().DN()) { - ForceToDefaultNaN(code, result); - } + if (ctx.FPCR().DN()) + ForceToDefaultNaN(code, result, fsize); code.L(*end); ctx.deferred_emits.emplace_back([=, &code, &ctx] { @@ -769,7 +750,7 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { code.ptest(operand2, xmm0); code.jnz(op2_done); code.vorps(result, operand2, xmm0); - if constexpr (negate_product) { + if (negate_product) { code.xorps(result, code.Const(xword, FP::FPInfo::sign_mask)); } code.jmp(*end); @@ -785,7 +766,7 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { // at this point, all SNaNs have been handled // if op1 was not a QNaN and op2 is, negate the result - if constexpr (negate_product) { + if (negate_product) { FCODE(ucomis)(operand1, operand1); code.jp(*end); FCODE(ucomis)(operand2, operand2); @@ -806,7 +787,7 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { const Xbyak::Xmm operand2 = ctx.reg_alloc.UseScratchXmm(args[1]); const Xbyak::Xmm operand3 = ctx.reg_alloc.UseXmm(args[2]); - if constexpr (negate_product) { + if (negate_product) { code.xorps(operand2, code.Const(xword, FP::FPInfo::sign_mask)); } FCODE(muls)(operand2, operand3); @@ -857,7 +838,7 @@ void EmitX64::EmitFPMulSub64(EmitContext& ctx, IR::Inst* inst) { template static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -917,9 +898,9 @@ void EmitX64::EmitFPMulX64(EmitContext& ctx, IR::Inst* inst) { template static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; - if constexpr (fsize != 16) { + if (fsize != 16) { if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Xmm operand = ctx.reg_alloc.UseXmm(args[0]); @@ -928,7 +909,7 @@ static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* i if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) { FCODE(vrcp14s)(result, operand, operand); } else { - if constexpr (fsize == 32) { + if (fsize == 32) { code.rcpss(result, operand); } else { code.cvtsd2ss(result, operand); @@ -963,7 +944,7 @@ void EmitX64::EmitFPRecipEstimate64(EmitContext& ctx, IR::Inst* inst) { template static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(inst, args[0]); @@ -986,11 +967,11 @@ void EmitX64::EmitFPRecipExponent64(EmitContext& ctx, IR::Inst* inst) { template static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; auto args = ctx.reg_alloc.GetArgumentInfo(inst); - if constexpr (fsize != 16) { + if (fsize != 16) { if (code.HasHostFeature(HostFeature::FMA) && ctx.HasOptimization(OptimizationFlag::Unsafe_InaccurateNaN)) { Xbyak::Label end, fallback; @@ -1123,9 +1104,9 @@ void EmitX64::EmitFPRoundInt64(EmitContext& ctx, IR::Inst* inst) { template static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; - if constexpr (fsize != 16) { + if (fsize != 16) { if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); const Xbyak::Xmm operand = ctx.reg_alloc.UseXmm(args[0]); @@ -1134,7 +1115,7 @@ static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* i if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) { FCODE(vrsqrt14s)(result, operand, operand); } else { - if constexpr (fsize == 32) { + if (fsize == 32) { code.rsqrtss(result, operand); } else { code.cvtsd2ss(result, operand); @@ -1180,7 +1161,7 @@ static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* i bool needs_fallback = false; code.L(*bad_values); - if constexpr (fsize == 32) { + if (fsize == 32) { code.movd(tmp, operand); if (!ctx.FPCR().FZ()) { @@ -1302,11 +1283,11 @@ void EmitX64::EmitFPRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) { template static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; auto args = ctx.reg_alloc.GetArgumentInfo(inst); - if constexpr (fsize != 16) { + if (fsize != 16) { if (code.HasHostFeature(HostFeature::FMA | HostFeature::AVX) && ctx.HasOptimization(OptimizationFlag::Unsafe_InaccurateNaN)) { const Xbyak::Xmm operand1 = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm operand2 = ctx.reg_alloc.UseXmm(args[1]); @@ -1485,9 +1466,8 @@ void EmitX64::EmitFPHalfToDouble(EmitContext& ctx, IR::Inst* inst) { // Double-conversion here is acceptable as this is expanding precision. code.vcvtph2ps(result, value); code.vcvtps2pd(result, result); - if (ctx.FPCR().DN()) { - ForceToDefaultNaN<64>(code, result); - } + if (ctx.FPCR().DN()) + ForceToDefaultNaN(code, result, 64); ctx.reg_alloc.DefineValue(inst, result); return; @@ -1509,9 +1489,8 @@ void EmitX64::EmitFPHalfToSingle(EmitContext& ctx, IR::Inst* inst) { const Xbyak::Xmm value = ctx.reg_alloc.UseXmm(args[0]); code.vcvtph2ps(result, value); - if (ctx.FPCR().DN()) { - ForceToDefaultNaN<32>(code, result); - } + if (ctx.FPCR().DN()) + ForceToDefaultNaN(code, result, 32); ctx.reg_alloc.DefineValue(inst, result); return; @@ -1519,23 +1498,22 @@ void EmitX64::EmitFPHalfToSingle(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.HostCall(inst, args[0]); code.mov(code.ABI_PARAM2.cvt32(), ctx.FPCR().Value()); - code.mov(code.ABI_PARAM3.cvt32(), static_cast(rounding_mode)); + code.mov(code.ABI_PARAM3.cvt32(), u32(rounding_mode)); code.lea(code.ABI_PARAM4, code.ptr[code.ABI_JIT_PTR + code.GetJitStateInfo().offsetof_fpsr_exc]); code.CallFunction(&FP::FPConvert); } void EmitX64::EmitFPSingleToDouble(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto rounding_mode = static_cast(args[1].GetImmediateU8()); + const auto rounding_mode = FP::RoundingMode(args[1].GetImmediateU8()); // We special-case the non-IEEE-defined ToOdd rounding mode. if (rounding_mode == ctx.FPCR().RMode() && rounding_mode != FP::RoundingMode::ToOdd) { const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); code.cvtss2sd(result, result); - if (ctx.FPCR().DN()) { - ForceToDefaultNaN<64>(code, result); - } + if (ctx.FPCR().DN()) + ForceToDefaultNaN(code, result, 64); ctx.reg_alloc.DefineValue(inst, result); } else { ctx.reg_alloc.HostCall(inst, args[0]); @@ -1553,12 +1531,9 @@ void EmitX64::EmitFPSingleToHalf(EmitContext& ctx, IR::Inst* inst) { if (code.HasHostFeature(HostFeature::F16C) && !ctx.FPCR().AHP() && !ctx.FPCR().FZ16()) { const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - - if (ctx.FPCR().DN()) { - ForceToDefaultNaN<32>(code, result); - } - code.vcvtps2ph(result, result, static_cast(*round_imm)); - + if (ctx.FPCR().DN()) + ForceToDefaultNaN(code, result, 32); + code.vcvtps2ph(result, result, u8(*round_imm)); ctx.reg_alloc.DefineValue(inst, result); return; } @@ -1586,21 +1561,18 @@ void EmitX64::EmitFPDoubleToHalf(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitFPDoubleToSingle(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const auto rounding_mode = static_cast(args[1].GetImmediateU8()); - + const auto rounding_mode = FP::RoundingMode(args[1].GetImmediateU8()); // We special-case the non-IEEE-defined ToOdd rounding mode. if (rounding_mode == ctx.FPCR().RMode() && rounding_mode != FP::RoundingMode::ToOdd) { const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - code.cvtsd2ss(result, result); - if (ctx.FPCR().DN()) { - ForceToDefaultNaN<32>(code, result); - } + if (ctx.FPCR().DN()) + ForceToDefaultNaN(code, result, 32); ctx.reg_alloc.DefineValue(inst, result); } else { ctx.reg_alloc.HostCall(inst, args[0]); code.mov(code.ABI_PARAM2.cvt32(), ctx.FPCR().Value()); - code.mov(code.ABI_PARAM3.cvt32(), static_cast(rounding_mode)); + code.mov(code.ABI_PARAM3.cvt32(), u32(rounding_mode)); code.lea(code.ABI_PARAM4, code.ptr[code.ABI_JIT_PTR + code.GetJitStateInfo().offsetof_fpsr_exc]); code.CallFunction(&FP::FPConvert); } @@ -1615,7 +1587,7 @@ void EmitX64::EmitFPDoubleToSingle(EmitContext& ctx, IR::Inst* inst) { /// Better than spamming thousands of templates aye? template static u64 EmitFPToFixedThunk(u64 input, FP::FPSR& fpsr, FP::FPCR fpcr, u32 extra_args) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; auto const unsigned_ = ((extra_args >> 24) & 0xff) != 0; auto const isize = ((extra_args >> 16) & 0xff); auto const rounding = FP::RoundingMode((extra_args >> 8) & 0xff); @@ -1630,7 +1602,7 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { const size_t fbits = args[1].GetImmediateU8(); const auto rounding_mode = FP::RoundingMode(args[2].GetImmediateU8()); - if constexpr (fsize != 16) { + if (fsize != 16) { const auto round_imm = ConvertRoundingModeToX64Immediate(rounding_mode); // cvttsd2si truncates during operation so rounding (and thus SSE4.1) not required @@ -1640,7 +1612,7 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { const Xbyak::Xmm src = ctx.reg_alloc.UseScratchXmm(args[0]); const Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr().cvt64(); - if constexpr (fsize == 64) { + if (fsize == 64) { if (fbits != 0) { const u64 scale_factor = static_cast((fbits + 1023) << 52); code.mulsd(src, code.Const(xword, scale_factor)); @@ -1662,13 +1634,13 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { code.cvtss2sd(src, src); } - if constexpr (isize == 64) { + if (isize == 64) { const Xbyak::Xmm scratch = ctx.reg_alloc.ScratchXmm(); if (!unsigned_) { SharedLabel saturate_max = GenSharedLabel(), end = GenSharedLabel(); - ZeroIfNaN<64>(code, src, scratch); + ZeroIfNaN(code, src, scratch, 64); code.movsd(scratch, code.Const(xword, f64_max_s64_lim)); code.comisd(scratch, src); @@ -1706,11 +1678,11 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { code.sar(result2, 63); code.or_(result, result2); } - } else if constexpr (isize == 32) { + } else if (isize == 32) { if (!unsigned_) { const Xbyak::Xmm scratch = ctx.reg_alloc.ScratchXmm(); - ZeroIfNaN<64>(code, src, scratch); + ZeroIfNaN(code, src, scratch, 64); code.minsd(src, code.Const(xword, f64_max_s32)); // maxsd not required as cvttsd2si results in 0x8000'0000 when out of range code.cvttsd2si(result.cvt32(), src); // 32 bit gpr @@ -1723,7 +1695,7 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { } else { const Xbyak::Xmm scratch = ctx.reg_alloc.ScratchXmm(); - ZeroIfNaN<64>(code, src, scratch); + ZeroIfNaN(code, src, scratch, 64); code.maxsd(src, code.Const(xword, unsigned_ ? f64_min_u16 : f64_min_s16)); code.minsd(src, code.Const(xword, unsigned_ ? f64_max_u16 : f64_max_s16)); code.cvttsd2si(result, src); // 64 bit gpr diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.cpp.inc b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.cpp.inc index 34f77b0446..3d6a64148a 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.cpp.inc +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.cpp.inc @@ -4,6 +4,7 @@ */ #include +#include "dynarmic/common/type_util.h" #define AxxEmitX64 CONCATENATE_TOKENS(Axx, EmitX64) #define AxxEmitContext CONCATENATE_TOKENS(Axx, EmitContext) @@ -15,14 +16,11 @@ using Vector = std::array; } std::optional AxxEmitX64::ShouldFastmem(AxxEmitContext& ctx, IR::Inst* inst) const { - if (!conf.fastmem_pointer || !exception_handler.SupportsFastmem()) { + if (!conf.fastmem_pointer || !exception_handler.SupportsFastmem()) return std::nullopt; - } - const auto marker = std::make_tuple(ctx.Location(), inst->GetName()); - if (do_not_fastmem.count(marker) > 0) { + if (do_not_fastmem.count(marker) > 0) return std::nullopt; - } return marker; } @@ -58,16 +56,12 @@ void AxxEmitX64::EmitMemoryRead(AxxEmitContext& ctx, IR::Inst* inst) { // Neither fastmem nor page table: Use callbacks if constexpr (bitsize == 128) { ctx.reg_alloc.HostCall(nullptr, {}, args[1]); - if (ordered) { - code.mfence(); - } + if (ordered) code.mfence(); code.CallFunction(memory_read_128); ctx.reg_alloc.DefineValue(inst, xmm1); } else { ctx.reg_alloc.HostCall(inst, {}, args[1]); - if (ordered) { - code.mfence(); - } + if (ordered) code.mfence(); Devirtualize(conf.callbacks).EmitCall(code); code.ZeroExtendFrom(bitsize, code.ABI_RETURN); } @@ -102,10 +96,10 @@ void AxxEmitX64::EmitMemoryRead(AxxEmitContext& ctx, IR::Inst* inst) { code.call(wrapped_fn); fastmem_patch_info.emplace( - mcl::bit_cast(location), + std::bit_cast(location), FastmemPatchInfo{ - mcl::bit_cast(code.getCurr()), - mcl::bit_cast(wrapped_fn), + std::bit_cast(code.getCurr()), + std::bit_cast(wrapped_fn), *fastmem_marker, conf.recompile_on_fastmem_failure, }); @@ -153,9 +147,7 @@ void AxxEmitX64::EmitMemoryWrite(AxxEmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.HostCall(nullptr, {}, args[1], args[2]); Devirtualize(conf.callbacks).EmitCall(code); } - if (ordered) { - code.mfence(); - } + if (ordered) code.mfence(); EmitCheckMemoryAbort(ctx, inst); return; } @@ -189,10 +181,10 @@ void AxxEmitX64::EmitMemoryWrite(AxxEmitContext& ctx, IR::Inst* inst) { code.call(wrapped_fn); fastmem_patch_info.emplace( - mcl::bit_cast(location), + std::bit_cast(location), FastmemPatchInfo{ - mcl::bit_cast(code.getCurr()), - mcl::bit_cast(wrapped_fn), + std::bit_cast(code.getCurr()), + std::bit_cast(wrapped_fn), *fastmem_marker, conf.recompile_on_fastmem_failure, }); @@ -223,7 +215,7 @@ void AxxEmitX64::EmitExclusiveReadMemory(AxxEmitContext& ctx, IR::Inst* inst) { const bool ordered = IsOrdered(args[2].GetImmediateAccType()); if constexpr (bitsize != 128) { - using T = mcl::unsigned_integer_of_size; + using T = Common::UnsignedIntegerN; ctx.reg_alloc.HostCall(inst, {}, args[1]); @@ -290,16 +282,14 @@ void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) { code.mov(code.byte[code.ABI_JIT_PTR + offsetof(AxxJitState, exclusive_state)], u8(0)); code.mov(code.ABI_PARAM1, reinterpret_cast(&conf)); if constexpr (bitsize != 128) { - using T = mcl::unsigned_integer_of_size; + using T = Common::UnsignedIntegerN; code.CallLambda( [](AxxUserConfig& conf, Axx::VAddr vaddr, T value) -> u32 { return conf.global_monitor->DoExclusiveOperation(conf.processor_id, vaddr, - [&](T expected) -> bool { - return (conf.callbacks->*callback)(vaddr, value, expected); - }) - ? 0 - : 1; + [&](T expected) -> bool { + return (conf.callbacks->*callback)(vaddr, value, expected); + }) ? 0 : 1; }); if (ordered) { code.mfence(); @@ -311,11 +301,9 @@ void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) { code.CallLambda( [](AxxUserConfig& conf, Axx::VAddr vaddr, Vector& value) -> u32 { return conf.global_monitor->DoExclusiveOperation(conf.processor_id, vaddr, - [&](Vector expected) -> bool { - return (conf.callbacks->*callback)(vaddr, value, expected); - }) - ? 0 - : 1; + [&](Vector expected) -> bool { + return (conf.callbacks->*callback)(vaddr, value, expected); + }) ? 0 : 1; }); if (ordered) { code.mfence(); @@ -356,7 +344,7 @@ void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* in EmitExclusiveLock(code, conf, tmp, tmp2.cvt32()); code.mov(code.byte[code.ABI_JIT_PTR + offsetof(AxxJitState, exclusive_state)], u8(1)); - code.mov(tmp, mcl::bit_cast(GetExclusiveMonitorAddressPointer(conf.global_monitor, conf.processor_id))); + code.mov(tmp, std::bit_cast(GetExclusiveMonitorAddressPointer(conf.global_monitor, conf.processor_id))); code.mov(qword[tmp], vaddr); const auto fastmem_marker = ShouldFastmem(ctx, inst); @@ -369,10 +357,10 @@ void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* in const auto location = EmitReadMemoryMov(code, value_idx, src_ptr, ordered); fastmem_patch_info.emplace( - mcl::bit_cast(location), + std::bit_cast(location), FastmemPatchInfo{ - mcl::bit_cast(code.getCurr()), - mcl::bit_cast(wrapped_fn), + std::bit_cast(code.getCurr()), + std::bit_cast(wrapped_fn), *fastmem_marker, conf.recompile_on_exclusive_fastmem_failure, }); @@ -390,7 +378,7 @@ void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* in code.call(wrapped_fn); } - code.mov(tmp, mcl::bit_cast(GetExclusiveMonitorValuePointer(conf.global_monitor, conf.processor_id))); + code.mov(tmp, std::bit_cast(GetExclusiveMonitorValuePointer(conf.global_monitor, conf.processor_id))); EmitWriteMemoryMov(code, tmp, value_idx, false); EmitExclusiveUnlock(code, conf, tmp, tmp2.cvt32()); @@ -437,7 +425,7 @@ void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* i SharedLabel end = GenSharedLabel(); - code.mov(tmp, mcl::bit_cast(GetExclusiveMonitorAddressPointer(conf.global_monitor, conf.processor_id))); + code.mov(tmp, std::bit_cast(GetExclusiveMonitorAddressPointer(conf.global_monitor, conf.processor_id))); code.mov(status, u32(1)); code.cmp(code.byte[code.ABI_JIT_PTR + offsetof(AxxJitState, exclusive_state)], u8(0)); code.je(*end, code.T_NEAR); @@ -447,7 +435,7 @@ void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* i EmitExclusiveTestAndClear(code, conf, vaddr, tmp, rax); code.mov(code.byte[code.ABI_JIT_PTR + offsetof(AxxJitState, exclusive_state)], u8(0)); - code.mov(tmp, mcl::bit_cast(GetExclusiveMonitorValuePointer(conf.global_monitor, conf.processor_id))); + code.mov(tmp, std::bit_cast(GetExclusiveMonitorValuePointer(conf.global_monitor, conf.processor_id))); if constexpr (bitsize == 128) { code.mov(rax, qword[tmp + 0]); @@ -475,25 +463,20 @@ void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* i const auto location = code.getCurr(); if constexpr (bitsize == 128) { - code.lock(); - code.cmpxchg16b(ptr[dest_ptr]); + code.lock(); code.cmpxchg16b(ptr[dest_ptr]); } else { switch (bitsize) { case 8: - code.lock(); - code.cmpxchg(code.byte[dest_ptr], value.cvt8()); + code.lock(); code.cmpxchg(code.byte[dest_ptr], value.cvt8()); break; case 16: - code.lock(); - code.cmpxchg(word[dest_ptr], value.cvt16()); + code.lock(); code.cmpxchg(word[dest_ptr], value.cvt16()); break; case 32: - code.lock(); - code.cmpxchg(dword[dest_ptr], value.cvt32()); + code.lock(); code.cmpxchg(dword[dest_ptr], value.cvt32()); break; case 64: - code.lock(); - code.cmpxchg(qword[dest_ptr], value.cvt64()); + code.lock(); code.cmpxchg(qword[dest_ptr], value.cvt64()); break; default: UNREACHABLE(); @@ -506,10 +489,10 @@ void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* i code.call(wrapped_fn); fastmem_patch_info.emplace( - mcl::bit_cast(location), + std::bit_cast(location), FastmemPatchInfo{ - mcl::bit_cast(code.getCurr()), - mcl::bit_cast(wrapped_fn), + std::bit_cast(code.getCurr()), + std::bit_cast(wrapped_fn), *fastmem_marker, conf.recompile_on_exclusive_fastmem_failure, }); diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.h b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.h index 75a47c6a80..4fc006ec4c 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.h +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.h @@ -1,9 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2025 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 */ -#include +#include +#include #include #include "dynarmic/backend/x64/a32_emit_x64.h" @@ -342,7 +346,7 @@ void EmitExclusiveLock(BlockOfCode& code, const UserConfig& conf, Xbyak::Reg64 p return; } - code.mov(pointer, mcl::bit_cast(GetExclusiveMonitorLockPointer(conf.global_monitor))); + code.mov(pointer, std::bit_cast(GetExclusiveMonitorLockPointer(conf.global_monitor))); EmitSpinLockLock(code, pointer, tmp); } @@ -352,7 +356,7 @@ void EmitExclusiveUnlock(BlockOfCode& code, const UserConfig& conf, Xbyak::Reg64 return; } - code.mov(pointer, mcl::bit_cast(GetExclusiveMonitorLockPointer(conf.global_monitor))); + code.mov(pointer, std::bit_cast(GetExclusiveMonitorLockPointer(conf.global_monitor))); EmitSpinLockUnlock(code, pointer, tmp); } @@ -369,7 +373,7 @@ void EmitExclusiveTestAndClear(BlockOfCode& code, const UserConfig& conf, Xbyak: continue; } Xbyak::Label ok; - code.mov(pointer, mcl::bit_cast(GetExclusiveMonitorAddressPointer(conf.global_monitor, processor_index))); + code.mov(pointer, std::bit_cast(GetExclusiveMonitorAddressPointer(conf.global_monitor, processor_index))); code.cmp(qword[pointer], vaddr); code.jne(ok, code.T_NEAR); code.mov(qword[pointer], tmp); diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_saturation.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_saturation.cpp index 31231c02aa..84eae8c02a 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_saturation.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_saturation.cpp @@ -11,13 +11,14 @@ #include "dynarmic/common/assert.h" #include #include "dynarmic/common/common_types.h" -#include #include "dynarmic/backend/x64/block_of_code.h" #include "dynarmic/backend/x64/emit_x64.h" #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/opcodes.h" +#include "dynarmic/common/fp/util.h" +#include "dynarmic/common/type_util.h" namespace Dynarmic::Backend::X64 { @@ -38,7 +39,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) Xbyak::Reg addend = ctx.reg_alloc.UseGpr(args[1]).changeBit(size); Xbyak::Reg overflow = ctx.reg_alloc.ScratchGpr().changeBit(size); - constexpr u64 int_max = static_cast((std::numeric_limits>::max)()); + constexpr u64 int_max = static_cast((std::numeric_limits>::max)()); if constexpr (size < 64) { code.xor_(overflow.cvt32(), overflow.cvt32()); code.bt(result.cvt32(), size - 1); @@ -82,7 +83,7 @@ void EmitUnsignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst Xbyak::Reg op_result = ctx.reg_alloc.UseScratchGpr(args[0]).changeBit(size); Xbyak::Reg addend = ctx.reg_alloc.UseScratchGpr(args[1]).changeBit(size); - constexpr u64 boundary = op == Op::Add ? (std::numeric_limits>::max)() : 0; + constexpr u64 boundary = op == Op::Add ? (std::numeric_limits>::max)() : 0; if constexpr (op == Op::Add) { code.add(op_result, addend); diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp index 66a179a481..bc0d86509c 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "dynarmic/backend/x64/abi.h" @@ -31,27 +30,14 @@ #include "dynarmic/common/fp/info.h" #include "dynarmic/common/fp/op.h" #include "dynarmic/common/fp/util.h" +#include "dynarmic/common/type_util.h" #include "dynarmic/common/lut_from_list.h" #include "dynarmic/interface/optimization_flags.h" #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/microinstruction.h" -#define FCODE(NAME) \ - [&code](auto... args) { \ - if constexpr (fsize == 32) { \ - code.NAME##s(args...); \ - } else { \ - code.NAME##d(args...); \ - } \ - } -#define ICODE(NAME) \ - [&code](auto... args) { \ - if constexpr (fsize == 32) { \ - code.NAME##d(args...); \ - } else { \ - code.NAME##q(args...); \ - } \ - } +#define FCODE(NAME) [&](auto... args) { if (fsize == 32) code.NAME##s(args...); else code.NAME##d(args...); } +#define ICODE(NAME) [&](auto... args) { if (fsize == 32) code.NAME##d(args...); else code.NAME##q(args...); } namespace Dynarmic::Backend::X64 { @@ -76,7 +62,7 @@ void MaybeStandardFPSCRValue(BlockOfCode& code, EmitContext& ctx, bool fpcr_cont template class Indexer, size_t narg> struct NaNHandler { public: - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; using function_type = void (*)(std::array, narg>&, FP::FPCR); @@ -158,33 +144,33 @@ Xbyak::Address GetVectorOf(BlockOfCode& code) { template Xbyak::Address GetNaNVector(BlockOfCode& code) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; return GetVectorOf::DefaultNaN()>(code); } template Xbyak::Address GetNegativeZeroVector(BlockOfCode& code) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; return GetVectorOf::Zero(true)>(code); } template Xbyak::Address GetNonSignMaskVector(BlockOfCode& code) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; constexpr FPT non_sign_mask = FP::FPInfo::exponent_mask | FP::FPInfo::mantissa_mask; return GetVectorOf(code); } template Xbyak::Address GetSmallestNormalVector(BlockOfCode& code) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; constexpr FPT smallest_normal_number = FP::FPValue::exponent_min, 1>(); return GetVectorOf(code); } -template value> +template value> Xbyak::Address GetVectorOf(BlockOfCode& code) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; return GetVectorOf()>(code); } @@ -1085,7 +1071,7 @@ static void EmitFPVectorMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::I if (code.HasHostFeature(HostFeature::AVX)) { MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; // result = xmm_a == SNaN || xmm_b == QNaN { @@ -1158,7 +1144,7 @@ static void EmitFPVectorMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::I } MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; // result = xmm_a == SNaN || xmm_b == QNaN { @@ -1314,7 +1300,7 @@ static void EmitFPVectorMulAddFallback(VectorArray& result, const VectorArr template void EmitFPVectorMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; const auto fallback_fn = [](VectorArray& result, const VectorArray& addend, const VectorArray& op1, const VectorArray& op2, FP::FPCR fpcr, FP::FPSR& fpsr) { for (size_t i = 0; i < result.size(); i++) { @@ -1425,7 +1411,7 @@ void EmitX64::EmitFPVectorMulAdd64(EmitContext& ctx, IR::Inst* inst) { template static void EmitFPVectorMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; auto args = ctx.reg_alloc.GetArgumentInfo(inst); const bool fpcr_controlled = args[2].GetImmediateU1(); @@ -1491,7 +1477,7 @@ void EmitX64::EmitFPVectorMulX64(EmitContext& ctx, IR::Inst* inst) { template void FPVectorNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; constexpr FPT sign_mask = FP::FPInfo::sign_mask; auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -1544,7 +1530,7 @@ void EmitX64::EmitFPVectorPairedAddLower64(EmitContext& ctx, IR::Inst* inst) { template static void EmitRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; if constexpr (fsize != 16) { if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) { @@ -1590,7 +1576,7 @@ void EmitX64::EmitFPVectorRecipEstimate64(EmitContext& ctx, IR::Inst* inst) { template static void EmitRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; const auto fallback_fn = [](VectorArray& result, const VectorArray& op1, const VectorArray& op2, FP::FPCR fpcr, FP::FPSR& fpsr) { for (size_t i = 0; i < result.size(); i++) { @@ -1714,7 +1700,7 @@ void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { } // Do not make a LUT out of this, let the compiler do it's thing - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; switch (rounding) { case FP::RoundingMode::ToNearest_TieEven: exact @@ -1760,7 +1746,7 @@ void EmitX64::EmitFPVectorRoundInt64(EmitContext& ctx, IR::Inst* inst) { template static void EmitRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; const auto fallback_fn = [](VectorArray& result, const VectorArray& operand, FP::FPCR fpcr, FP::FPSR& fpsr) { for (size_t i = 0; i < result.size(); i++) { @@ -1852,7 +1838,7 @@ void EmitX64::EmitFPVectorRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) { template static void EmitRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; + using FPT = Common::UnsignedIntegerN; const auto fallback_fn = [](VectorArray& result, const VectorArray& op1, const VectorArray& op2, FP::FPCR fpcr, FP::FPSR& fpsr) { for (size_t i = 0; i < result.size(); i++) { @@ -2126,7 +2112,7 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { FCODE(orp)(src, exceed_unsigned); } } else { - using FPT = mcl::unsigned_integer_of_size; // WORKAROUND: For issue 678 on MSVC + using FPT = Common::UnsignedIntegerN; // WORKAROUND: For issue 678 on MSVC constexpr u64 integer_max = FPT((std::numeric_limits>>::max)()); code.movaps(xmm0, GetVectorOf(code)); @@ -2150,7 +2136,7 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { mp::lift_value>; static const auto lut = Common::GenerateLookupTableFromList([](I) { - using FPT = mcl::unsigned_integer_of_size; // WORKAROUND: For issue 678 on MSVC + using FPT = Common::UnsignedIntegerN; // WORKAROUND: For issue 678 on MSVC return std::pair{ mp::lower_to_tuple_v, Common::FptrCast([](VectorArray& output, const VectorArray& input, FP::FPCR fpcr, FP::FPSR& fpsr) { diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_saturation.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_saturation.cpp index 580a32dec8..412bb2bfaa 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_saturation.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64_vector_saturation.cpp @@ -14,23 +14,8 @@ #include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/opcodes.h" -#define FCODE(NAME) \ - [&code](auto... args) { \ - if constexpr (esize == 32) { \ - code.NAME##s(args...); \ - } else { \ - code.NAME##d(args...); \ - } \ - } - -#define ICODE(NAME) \ - [&code](auto... args) { \ - if constexpr (esize == 32) { \ - code.NAME##d(args...); \ - } else { \ - code.NAME##q(args...); \ - } \ - } +#define FCODE(NAME) [&](auto... args) { if (esize == 32) code.NAME##s(args...); else code.NAME##d(args...); } +#define ICODE(NAME) [&](auto... args) { if (esize == 32) code.NAME##d(args...); else code.NAME##q(args...); } namespace Dynarmic::Backend::X64 { diff --git a/src/dynarmic/src/dynarmic/backend/x64/exception_handler_windows.cpp b/src/dynarmic/src/dynarmic/backend/x64/exception_handler_windows.cpp index 95eacaae9b..4d2ca9de9a 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/exception_handler_windows.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/exception_handler_windows.cpp @@ -13,7 +13,7 @@ #include #include "dynarmic/common/assert.h" -#include +#include #include "dynarmic/common/common_types.h" #include "dynarmic/backend/exception_handler.h" @@ -184,20 +184,20 @@ struct ExceptionHandler::Impl final { // Our 3rd argument is a PCONTEXT. // If not within our codeblock, ignore this exception. - code.mov(code.rax, Safe::Negate(mcl::bit_cast(code.getCode()))); + code.mov(code.rax, Safe::Negate(std::bit_cast(code.getCode()))); code.add(code.rax, code.qword[code.ABI_PARAM3 + Xbyak::RegExp(offsetof(CONTEXT, Rip))]); code.cmp(code.rax, static_cast(code.GetTotalCodeSize())); code.ja(exception_handler_without_cb); code.lea(code.rsp, code.ptr[code.rsp - 8]); - code.mov(code.ABI_PARAM1, mcl::bit_cast(&cb)); + code.mov(code.ABI_PARAM1, std::bit_cast(&cb)); code.mov(code.ABI_PARAM2, code.ABI_PARAM3); code.CallLambda( [](const std::function& cb_, PCONTEXT ctx) { FakeCall fc = cb_(ctx->Rip); ctx->Rsp -= sizeof(u64); - *mcl::bit_cast(ctx->Rsp) = fc.ret_rip; + *std::bit_cast(ctx->Rsp) = fc.ret_rip; ctx->Rip = fc.call_rip; }); code.add(code.rsp, 8); diff --git a/src/dynarmic/src/dynarmic/backend/x64/perf_map.h b/src/dynarmic/src/dynarmic/backend/x64/perf_map.h index 7d739ae63e..5f9eea7c17 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/perf_map.h +++ b/src/dynarmic/src/dynarmic/backend/x64/perf_map.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2018 MerryMage * SPDX-License-Identifier: 0BSD @@ -6,8 +9,8 @@ #pragma once #include - -#include +#include +#include namespace Dynarmic::Backend::X64 { @@ -17,7 +20,7 @@ void PerfMapRegister(const void* start, const void* end, std::string_view friend template void PerfMapRegister(T start, const void* end, std::string_view friendly_name) { - detail::PerfMapRegister(mcl::bit_cast(start), end, friendly_name); + detail::PerfMapRegister(std::bit_cast(start), end, friendly_name); } void PerfMapClear(); diff --git a/src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp b/src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp index 29eab7908b..fc59dbcb2d 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp @@ -11,10 +11,10 @@ #include #include #include +#include #include #include "dynarmic/common/assert.h" -#include #include #include "dynarmic/backend/x64/abi.h" diff --git a/src/dynarmic/src/dynarmic/common/always_false.h b/src/dynarmic/src/dynarmic/common/always_false.h deleted file mode 100644 index b980fea00c..0000000000 --- a/src/dynarmic/src/dynarmic/common/always_false.h +++ /dev/null @@ -1,13 +0,0 @@ -/* This file is part of the dynarmic project. - * Copyright (c) 2023 MerryMage - * SPDX-License-Identifier: 0BSD - */ - -#pragma once - -namespace Dynarmic::Common { - -template -inline constexpr bool always_false_v = false; - -} // namespace Dynarmic::Common diff --git a/src/dynarmic/src/dynarmic/common/assert.h b/src/dynarmic/src/dynarmic/common/assert.h index 0a3cb5331d..ce5e66edf9 100644 --- a/src/dynarmic/src/dynarmic/common/assert.h +++ b/src/dynarmic/src/dynarmic/common/assert.h @@ -16,38 +16,33 @@ template // Temporary until MCL is fully removed #ifndef ASSERT_MSG -#define ASSERT_MSG(_a_, ...) \ - ([&]() { \ - if (!(_a_)) [[unlikely]] { \ - assert_terminate(#_a_, __VA_ARGS__); \ - } \ - }()) +# define ASSERT_MSG(_a_, ...) do if (!(_a_)) [[unlikely]] assert_terminate(#_a_, __VA_ARGS__); while(0) #endif #ifndef ASSERT_FALSE -#define ASSERT_FALSE(...) \ - ([&]() { \ - assert_terminate("false", __VA_ARGS__); \ - }()) +# define ASSERT_FALSE(...) assert_terminate("false", __VA_ARGS__) #endif - #ifndef ASSERT -#define ASSERT(_a_) ASSERT_MSG(_a_, "") +# define ASSERT(_a_) ASSERT_MSG(_a_, "") #endif #ifndef UNREACHABLE -#define UNREACHABLE() ASSERT_MSG(false, "unreachable") +# ifdef _MSC_VER +# define UNREACHABLE() ASSERT_FALSE("unreachable") +# else +# define UNREACHABLE() __builtin_unreachable(); +# endif #endif #ifdef _DEBUG -#ifndef DEBUG_ASSERT -#define DEBUG_ASSERT(_a_) ASSERT(_a_) -#endif -#ifndef DEBUG_ASSERT_MSG -#define DEBUG_ASSERT_MSG(_a_, ...) ASSERT_MSG(_a_, __VA_ARGS__) -#endif +# ifndef DEBUG_ASSERT +# define DEBUG_ASSERT(_a_) ASSERT(_a_) +# endif +# ifndef DEBUG_ASSERT_MSG +# define DEBUG_ASSERT_MSG(_a_, ...) ASSERT_MSG(_a_, __VA_ARGS__) +# endif #else // not debug -#ifndef DEBUG_ASSERT -#define DEBUG_ASSERT(_a_) -#endif -#ifndef DEBUG_ASSERT_MSG -#define DEBUG_ASSERT_MSG(_a_, _desc_, ...) -#endif +# ifndef DEBUG_ASSERT +# define DEBUG_ASSERT(_a_) +# endif +# ifndef DEBUG_ASSERT_MSG +# define DEBUG_ASSERT_MSG(_a_, _desc_, ...) +# endif #endif diff --git a/src/dynarmic/src/dynarmic/common/cast_util.h b/src/dynarmic/src/dynarmic/common/cast_util.h deleted file mode 100644 index 92c9a259b3..0000000000 --- a/src/dynarmic/src/dynarmic/common/cast_util.h +++ /dev/null @@ -1,18 +0,0 @@ -/* This file is part of the dynarmic project. - * Copyright (c) 2018 MerryMage - * SPDX-License-Identifier: 0BSD - */ - -#pragma once - -#include - -namespace Dynarmic::Common { - -/// Cast a lambda into an equivalent function pointer. -template -inline auto FptrCast(Function f) noexcept { - return static_cast*>(f); -} - -} // namespace Dynarmic::Common diff --git a/src/dynarmic/src/dynarmic/common/fp/util.h b/src/dynarmic/src/dynarmic/common/fp/util.h index fda34e3ee5..903c144ea6 100644 --- a/src/dynarmic/src/dynarmic/common/fp/util.h +++ b/src/dynarmic/src/dynarmic/common/fp/util.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2018 MerryMage * SPDX-License-Identifier: 0BSD @@ -6,6 +9,7 @@ #pragma once #include +#include #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/fp/info.h" diff --git a/src/dynarmic/src/dynarmic/common/llvm_disassemble.cpp b/src/dynarmic/src/dynarmic/common/llvm_disassemble.cpp index 31d55c134c..3830e1885e 100644 --- a/src/dynarmic/src/dynarmic/common/llvm_disassemble.cpp +++ b/src/dynarmic/src/dynarmic/common/llvm_disassemble.cpp @@ -7,7 +7,7 @@ */ #include - +#include #include #ifdef DYNARMIC_USE_LLVM @@ -16,7 +16,6 @@ #endif #include "dynarmic/common/assert.h" -#include #include "dynarmic/common/common_types.h" #include "dynarmic/common/llvm_disassemble.h" @@ -53,7 +52,7 @@ std::string DisassembleX64(const void* begin, const void* end) { LLVMDisasmDispose(llvm_ctx); #else result += fmt::format("(recompile with DYNARMIC_USE_LLVM=ON to disassemble the generated x86_64 code)\n"); - result += fmt::format("start: {:016x}, end: {:016x}\n", mcl::bit_cast(begin), mcl::bit_cast(end)); + result += fmt::format("start: {:016x}, end: {:016x}\n", std::bit_cast(begin), std::bit_cast(end)); #endif return result; diff --git a/src/dynarmic/src/dynarmic/common/type_util.h b/src/dynarmic/src/dynarmic/common/type_util.h new file mode 100644 index 0000000000..8c9e0101d0 --- /dev/null +++ b/src/dynarmic/src/dynarmic/common/type_util.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * SPDX-License-Identifier: 0BSD + */ + +#pragma once + +#include + +namespace Dynarmic::Common { + +/// Cast a lambda into an equivalent function pointer. +template +inline auto FptrCast(Function f) noexcept { + return static_cast*>(f); +} + +namespace Detail { +template struct IntegerOfSize {}; +template<> struct IntegerOfSize<8> { using U = std::uint8_t; using S = std::int8_t; }; +template<> struct IntegerOfSize<16> { using U = std::uint16_t; using S = std::int16_t; }; +template<> struct IntegerOfSize<32> { using U = std::uint32_t; using S = std::int32_t; }; +template<> struct IntegerOfSize<64> { using U = std::uint64_t; using S = std::int64_t; }; +} +template using UnsignedIntegerN = typename Detail::IntegerOfSize::U; +template using SignedIntegerN = typename Detail::IntegerOfSize::S; + +} // namespace Dynarmic::Common diff --git a/src/dynarmic/src/dynarmic/ir/ir_emitter.cpp b/src/dynarmic/src/dynarmic/ir/ir_emitter.cpp index a8ef7e2989..08758f0e6d 100644 --- a/src/dynarmic/src/dynarmic/ir/ir_emitter.cpp +++ b/src/dynarmic/src/dynarmic/ir/ir_emitter.cpp @@ -11,7 +11,7 @@ #include #include "dynarmic/common/assert.h" -#include +#include #include "dynarmic/ir/opcodes.h" diff --git a/src/dynarmic/src/dynarmic/ir/ir_emitter.h b/src/dynarmic/src/dynarmic/ir/ir_emitter.h index dba34bcc56..d041337ae1 100644 --- a/src/dynarmic/src/dynarmic/ir/ir_emitter.h +++ b/src/dynarmic/src/dynarmic/ir/ir_emitter.h @@ -12,7 +12,7 @@ #include "dynarmic/common/common_types.h" #include "dynarmic/common/assert.h" -#include +#include #include "dynarmic/ir/opcodes.h" #include "dynarmic/ir/acc_type.h" @@ -2931,19 +2931,19 @@ public: } void CallHostFunction(void (*fn)(void)) { - Inst(Opcode::CallHostFunction, Imm64(mcl::bit_cast(fn)), Value{}, Value{}, Value{}); + Inst(Opcode::CallHostFunction, Imm64(std::bit_cast(fn)), Value{}, Value{}, Value{}); } void CallHostFunction(void (*fn)(u64), const U64& arg1) { - Inst(Opcode::CallHostFunction, Imm64(mcl::bit_cast(fn)), arg1, Value{}, Value{}); + Inst(Opcode::CallHostFunction, Imm64(std::bit_cast(fn)), arg1, Value{}, Value{}); } void CallHostFunction(void (*fn)(u64, u64), const U64& arg1, const U64& arg2) { - Inst(Opcode::CallHostFunction, Imm64(mcl::bit_cast(fn)), arg1, arg2, Value{}); + Inst(Opcode::CallHostFunction, Imm64(std::bit_cast(fn)), arg1, arg2, Value{}); } void CallHostFunction(void (*fn)(u64, u64, u64), const U64& arg1, const U64& arg2, const U64& arg3) { - Inst(Opcode::CallHostFunction, Imm64(mcl::bit_cast(fn)), arg1, arg2, arg3); + Inst(Opcode::CallHostFunction, Imm64(std::bit_cast(fn)), arg1, arg2, arg3); } void SetTerm(const Terminal& terminal) { diff --git a/src/dynarmic/tests/test_generator.cpp b/src/dynarmic/tests/test_generator.cpp index c8f05d06f8..70ae62a1a9 100644 --- a/src/dynarmic/tests/test_generator.cpp +++ b/src/dynarmic/tests/test_generator.cpp @@ -17,7 +17,6 @@ #include #include -#include #include "dynarmic/common/common_types.h" #include "./A32/testenv.h"