From fe5abdb3e1746ffed3c844a087247293b4c4190c Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Fri, 28 May 2021 14:24:10 -0700 Subject: [PATCH] backend/x64: Add vfixup constants Adds compile-time `FixupLUT` function for generating the 32-bit LUT of src->dst mappings --- src/dynarmic/backend/x64/constants.h | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/dynarmic/backend/x64/constants.h b/src/dynarmic/backend/x64/constants.h index a458d102..06e947f8 100644 --- a/src/dynarmic/backend/x64/constants.h +++ b/src/dynarmic/backend/x64/constants.h @@ -5,6 +5,7 @@ #pragma once +#include "dynarmic/common/bit_util.h" #include "dynarmic/common/common_types.h" namespace Dynarmic::Backend::X64 { @@ -42,4 +43,46 @@ constexpr u8 b = 0b11001100; constexpr u8 c = 0b10101010; } // namespace Tern +// Opcodes for use with vfixupimm +enum class FpFixup : u8 { + A = 0b0000, // A + B = 0b0001, // B + QNaN_B = 0b0010, // QNaN with sign of B + IndefNaN = 0b0011, // Indefinite QNaN (Negative QNaN with no payload on x86) + NegInf = 0b0100, // -Infinity + PosInf = 0b0101, // +Infinity + Inf_B = 0b0110, // Infinity with sign of B + NegZero = 0b0111, // -0.0 + PosZero = 0b1000, // +0.0 + NegOne = 0b1001, // -1.0 + PosOne = 0b1010, // +1.0 + Half = 0b1011, // 0.5 + Ninety = 0b1100, // 90.0 + HalfPi = 0b1101, // PI/2 + PosMax = 0b1110, // +{FLT_MAX,DBL_MAX} + NegMax = 0b1111, // -{FLT_MAX,DBL_MAX} +}; + +// Generates 32-bit LUT for vfixupimm instruction +constexpr u32 FixupLUT( + FpFixup src_qnan = FpFixup::A, + FpFixup src_snan = FpFixup::A, + FpFixup src_zero = FpFixup::A, + FpFixup src_posone = FpFixup::A, + FpFixup src_neginf = FpFixup::A, + FpFixup src_posinf = FpFixup::A, + FpFixup src_pos = FpFixup::A, + FpFixup src_neg = FpFixup::A) { + u32 fixup_lut = 0; + fixup_lut = Common::ModifyBits<0, 3, u32>(fixup_lut, static_cast(src_qnan)); + fixup_lut = Common::ModifyBits<4, 7, u32>(fixup_lut, static_cast(src_snan)); + fixup_lut = Common::ModifyBits<8, 11, u32>(fixup_lut, static_cast(src_zero)); + fixup_lut = Common::ModifyBits<12, 15, u32>(fixup_lut, static_cast(src_posone)); + fixup_lut = Common::ModifyBits<16, 19, u32>(fixup_lut, static_cast(src_neginf)); + fixup_lut = Common::ModifyBits<20, 23, u32>(fixup_lut, static_cast(src_posinf)); + fixup_lut = Common::ModifyBits<24, 27, u32>(fixup_lut, static_cast(src_pos)); + fixup_lut = Common::ModifyBits<28, 31, u32>(fixup_lut, static_cast(src_neg)); + return fixup_lut; +} + } // namespace Dynarmic::Backend::X64