diff --git a/include/dynarmic/A64/config.h b/include/dynarmic/A64/config.h index 3bfdb2f0..8cad3e92 100644 --- a/include/dynarmic/A64/config.h +++ b/include/dynarmic/A64/config.h @@ -209,18 +209,6 @@ struct UserConfig { /// This enables the fast dispatcher. bool enable_fast_dispatch = true; - // The below options relate to accuracy of floating-point emulation. - - /// Determines how accurate NaN handling is. - enum class NaNAccuracy { - /// Results of operations with NaNs will exactly match hardware. - Accurate, - /// Behave as if FPCR.DN is always set. - AlwaysForceDefaultNaN, - /// No special handling of NaN, other than setting default NaN when FPCR.DN is set. - NoChecks, - } floating_point_nan_accuracy = NaNAccuracy::Accurate; - // Determines whether AddTicks and GetTicksRemaining are called. // If false, execution will continue until soon after Jit::HaltExecution is called. // bool enable_ticks = true; // TODO diff --git a/src/backend/x64/a64_emit_x64.cpp b/src/backend/x64/a64_emit_x64.cpp index 06188e2c..fe9b6c41 100644 --- a/src/backend/x64/a64_emit_x64.cpp +++ b/src/backend/x64/a64_emit_x64.cpp @@ -52,10 +52,6 @@ FP::FPCR A64EmitContext::FPCR(bool fpcr_controlled) const { return fpcr_controlled ? Location().FPCR() : Location().FPCR().ASIMDStandardValue(); } -bool A64EmitContext::AccurateNaN() const { - return conf.floating_point_nan_accuracy == A64::UserConfig::NaNAccuracy::Accurate; -} - A64EmitX64::A64EmitX64(BlockOfCode& code, A64::UserConfig conf, A64::Jit* jit_interface) : EmitX64(code), conf(conf), jit_interface{jit_interface} { GenMemory128Accessors(); diff --git a/src/backend/x64/a64_emit_x64.h b/src/backend/x64/a64_emit_x64.h index 3817d631..03d57cb3 100644 --- a/src/backend/x64/a64_emit_x64.h +++ b/src/backend/x64/a64_emit_x64.h @@ -28,7 +28,6 @@ struct A64EmitContext final : public EmitContext { A64::LocationDescriptor Location() const; bool IsSingleStep() const; FP::FPCR FPCR(bool fpcr_controlled = true) const override; - bool AccurateNaN() const override; const A64::UserConfig& conf; }; diff --git a/src/backend/x64/emit_x64.h b/src/backend/x64/emit_x64.h index 23a0f957..f6cb486b 100644 --- a/src/backend/x64/emit_x64.h +++ b/src/backend/x64/emit_x64.h @@ -50,7 +50,6 @@ struct EmitContext { void EraseInstruction(IR::Inst* inst); virtual FP::FPCR FPCR(bool fpcr_controlled = true) const = 0; - virtual bool AccurateNaN() const { return true; } RegAlloc& reg_alloc; IR::Block& block; diff --git a/src/backend/x64/emit_x64_floating_point.cpp b/src/backend/x64/emit_x64_floating_point.cpp index 5437dc2d..21b13481 100644 --- a/src/backend/x64/emit_x64_floating_point.cpp +++ b/src/backend/x64/emit_x64_floating_point.cpp @@ -258,7 +258,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) { Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); - if (ctx.AccurateNaN() && !ctx.FPCR().DN()) { + if (!ctx.FPCR().DN()) { end = ProcessNaN(code, result); } if constexpr (std::is_member_function_pointer_v) { @@ -268,7 +268,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) { } if (ctx.FPCR().DN()) { ForceToDefaultNaN(code, result); - } else if (ctx.AccurateNaN()) { + } else { PostProcessNaN(code, result, ctx.reg_alloc.ScratchXmm()); } code.L(end); @@ -282,7 +282,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) auto args = ctx.reg_alloc.GetArgumentInfo(inst); - if (ctx.FPCR().DN() || !ctx.AccurateNaN()) { + if (ctx.FPCR().DN()) { const Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); const Xbyak::Xmm operand = ctx.reg_alloc.UseScratchXmm(args[1]); @@ -292,9 +292,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) fn(result, operand); } - if (ctx.AccurateNaN()) { - ForceToDefaultNaN(code, result); - } + ForceToDefaultNaN(code, result); ctx.reg_alloc.DefineValue(inst, result); return; @@ -437,7 +435,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { code.jmp(end); code.L(nan); - if (ctx.FPCR().DN() || !ctx.AccurateNaN()) { + if (ctx.FPCR().DN()) { code.movaps(result, code.MConst(xword, fsize == 32 ? f32_nan : f64_nan)); code.jmp(end); } else { @@ -677,7 +675,7 @@ static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const bool do_default_nan = ctx.FPCR().DN() || !ctx.AccurateNaN(); + const bool do_default_nan = ctx.FPCR().DN(); const Xbyak::Xmm op1 = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm op2 = ctx.reg_alloc.UseXmm(args[1]); diff --git a/src/backend/x64/emit_x64_vector_floating_point.cpp b/src/backend/x64/emit_x64_vector_floating_point.cpp index c71de89f..ba3f75e3 100644 --- a/src/backend/x64/emit_x64_vector_floating_point.cpp +++ b/src/backend/x64/emit_x64_vector_floating_point.cpp @@ -284,7 +284,7 @@ void EmitTwoOpVectorOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst* ins auto args = ctx.reg_alloc.GetArgumentInfo(inst); const bool fpcr_controlled = args[fpcr_controlled_arg_index].GetImmediateU1(); - if (!ctx.AccurateNaN() || ctx.FPCR(fpcr_controlled).DN()) { + if (ctx.FPCR(fpcr_controlled).DN()) { Xbyak::Xmm result; if constexpr (std::is_member_function_pointer_v) { @@ -336,7 +336,7 @@ void EmitThreeOpVectorOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst* i auto args = ctx.reg_alloc.GetArgumentInfo(inst); const bool fpcr_controlled = args[2].GetImmediateU1(); - if (!ctx.AccurateNaN() || ctx.FPCR(fpcr_controlled).DN()) { + if (ctx.FPCR(fpcr_controlled).DN()) { const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(args[0]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(args[1]);