From 69ac655a627d441b8a187fdf7eae9d0a0b50a1b0 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 3 Apr 2026 04:11:55 +0000 Subject: [PATCH] [dynarmic] proper LUT implementation Signed-off-by: lizzie --- src/dynarmic/src/dynarmic/CMakeLists.txt | 1 - .../emit_arm64_vector_floating_point.cpp | 3 +- .../backend/x64/emit_x64_floating_point.cpp | 1 - .../x64/emit_x64_vector_floating_point.cpp | 50 +++++++++-------- .../src/dynarmic/common/lut_from_list.h | 55 ------------------- 5 files changed, 29 insertions(+), 81 deletions(-) delete mode 100644 src/dynarmic/src/dynarmic/common/lut_from_list.h diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index 5d6c05b7c9..f79d18c15a 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -59,7 +59,6 @@ add_library(dynarmic STATIC common/fp/util.h common/llvm_disassemble.cpp common/llvm_disassemble.h - common/lut_from_list.h common/math_util.cpp common/math_util.h common/safe_ops.h 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 9aff36944b..557d6284ed 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 @@ -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. @@ -25,7 +25,6 @@ #include "dynarmic/common/fp/info.h" #include "dynarmic/common/fp/op.h" #include "dynarmic/common/fp/rounding_mode.h" -#include "dynarmic/common/lut_from_list.h" #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/opcodes.h" 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 be9a1450a7..6a3ab005f3 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 @@ -25,7 +25,6 @@ #include "dynarmic/common/fp/info.h" #include "dynarmic/common/fp/op.h" #include "dynarmic/common/fp/rounding_mode.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" 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 d219124208..225742e8a6 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 @@ -26,7 +26,6 @@ #include "dynarmic/common/fp/op.h" #include "dynarmic/common/fp/rounding_mode.h" #include "dynarmic/common/fp/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" @@ -1986,6 +1985,13 @@ void EmitX64::EmitFPVectorToHalf32(EmitContext& ctx, IR::Inst* inst) { // output[i] = FPT(FP::FPToFixed(fsize, input[i], fbits, unsigned_, fpcr, rounding_mode, fpsr)); // } +template +static void EmitFPVectorToFixedThunk(VectorArray>& output, const VectorArray>& input, FP::FPCR fpcr, FP::FPSR& fpsr) { + using FPT = mcl::unsigned_integer_of_size; + for (size_t i = 0; i < output.size(); ++i) + output[i] = FPT(FP::FPToFixed(fsize, input[i], fbits, unsigned_, fpcr, rounding_mode, fpsr)); +} + template void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { const size_t fbits = inst->GetArg(1).GetU8(); @@ -2107,29 +2113,29 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(code, inst, src); return; } + auto const fpt_fn = [fbits, rounding]{ +#define ROUNDING_MODE(CASE) \ + else if (rounding == FP::RoundingMode::CASE && fsize == 8 && fbits == 8) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 16 && fbits == 8) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 16 && fbits == 16) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 32 && fbits == 8) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 32 && fbits == 16) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 32 && fbits == 32) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 64 && fbits == 8) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 64 && fbits == 16) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 64 && fbits == 32) return &EmitFPVectorToFixedThunk; \ + else if (rounding == FP::RoundingMode::CASE && fsize == 64 && fbits == 64) return &EmitFPVectorToFixedThunk; - using fbits_list = mp::lift_sequence>; - using rounding_list = mp::list< - mp::lift_value, - mp::lift_value, - mp::lift_value, - mp::lift_value, - mp::lift_value>; + if (false) { /* ... */ } + ROUNDING_MODE(ToNearest_TieEven) + ROUNDING_MODE(TowardsPlusInfinity) + ROUNDING_MODE(TowardsMinusInfinity) + ROUNDING_MODE(TowardsZero) + ROUNDING_MODE(ToNearest_TieAwayFromZero) + else return &EmitFPVectorToFixedThunk; + }(); - static const auto lut = Common::GenerateLookupTableFromList([](I) { - using FPT = mcl::unsigned_integer_of_size; // 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) { - constexpr size_t fbits = mp::get<0, I>::value; - constexpr FP::RoundingMode rounding_mode = mp::get<1, I>::value; - for (size_t i = 0; i < output.size(); ++i) - output[i] = FPT(FP::FPToFixed(fsize, input[i], fbits, unsigned_, fpcr, rounding_mode, fpsr)); - }) - }; - }, mp::cartesian_product{}); - - EmitTwoOpFallback<3>(code, ctx, inst, lut.at(std::make_tuple(fbits, rounding))); + EmitTwoOpFallback<3>(code, ctx, inst, fpt_fn); } void EmitX64::EmitFPVectorToSignedFixed16(EmitContext& ctx, IR::Inst* inst) { diff --git a/src/dynarmic/src/dynarmic/common/lut_from_list.h b/src/dynarmic/src/dynarmic/common/lut_from_list.h deleted file mode 100644 index 633b62aeda..0000000000 --- a/src/dynarmic/src/dynarmic/common/lut_from_list.h +++ /dev/null @@ -1,55 +0,0 @@ -// 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 -#include -#include - -#include -#include -#include - -#ifdef _MSC_VER -# include -#endif - -namespace Dynarmic::Common { - -// prevents this function from printing 56,000 character warning messages -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wno-stack-usage" -#endif -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wno-stack-usage" -#endif - -template -inline auto GenerateLookupTableFromList(Function f, mcl::mp::list) { -#ifdef _MSC_VER - using PairT = std::invoke_result_t>>; -#else - using PairT = std::common_type_t...>; -#endif - using MapT = mcl::mp::apply; - static_assert(mcl::is_instance_of_template_v); - const std::initializer_list pair_array{f(Values{})...}; - return MapT(pair_array.begin(), pair_array.end()); -} - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -} // namespace Dynarmic::Common