From 3ed2aebb20b48b77094eadf12e376fd3b94eb840 Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Mon, 31 May 2021 17:15:48 -0700 Subject: [PATCH] backend/x64: Update `FpFixup` constants with denormal behavior There is an important subtlety that should be documented here. All the operands of `FpFixup` that read from the `Src` register actually do a `DAZ` operation if `MXCSR.DAZ` is set. --- src/dynarmic/backend/x64/constants.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/dynarmic/backend/x64/constants.h b/src/dynarmic/backend/x64/constants.h index 13bf3696..d4044a82 100644 --- a/src/dynarmic/backend/x64/constants.h +++ b/src/dynarmic/backend/x64/constants.h @@ -97,13 +97,13 @@ constexpr u8 SNaN = 0b10000000; // Opcodes for use with vfixupimm enum class FpFixup : u8 { - A = 0b0000, // A - B = 0b0001, // B - QNaN_B = 0b0010, // QNaN with sign of B + Dest = 0b0000, // Preserve destination + Norm_Src = 0b0001, // Source operand (Denormal as positive-zero) + QNaN_Src = 0b0010, // QNaN with sign of source (Denormal as positive-zero) 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 + Inf_Src = 0b0110, // Infinity with sign of source (Denormal as positive-zero) NegZero = 0b0111, // -0.0 PosZero = 0b1000, // +0.0 NegOne = 0b1001, // -1.0 @@ -116,14 +116,14 @@ enum class FpFixup : u8 { }; // 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) { +constexpr u32 FixupLUT(FpFixup src_qnan = FpFixup::Dest, + FpFixup src_snan = FpFixup::Dest, + FpFixup src_zero = FpFixup::Dest, + FpFixup src_posone = FpFixup::Dest, + FpFixup src_neginf = FpFixup::Dest, + FpFixup src_posinf = FpFixup::Dest, + FpFixup src_pos = FpFixup::Dest, + FpFixup src_neg = FpFixup::Dest) { u32 fixup_lut = 0; fixup_lut = mcl::bit::set_bits<0, 3, u32>(fixup_lut, static_cast(src_qnan)); fixup_lut = mcl::bit::set_bits<4, 7, u32>(fixup_lut, static_cast(src_snan));