A64: Remove NaN accuracy setting

Always do accuracte NaN handling.
This commit is contained in:
MerryMage 2020-06-24 22:25:51 +01:00
parent b5df8d1ef8
commit 46445d0866
6 changed files with 8 additions and 28 deletions

View file

@ -209,18 +209,6 @@ struct UserConfig {
/// This enables the fast dispatcher. /// This enables the fast dispatcher.
bool enable_fast_dispatch = true; 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. // Determines whether AddTicks and GetTicksRemaining are called.
// If false, execution will continue until soon after Jit::HaltExecution is called. // If false, execution will continue until soon after Jit::HaltExecution is called.
// bool enable_ticks = true; // TODO // bool enable_ticks = true; // TODO

View file

@ -52,10 +52,6 @@ FP::FPCR A64EmitContext::FPCR(bool fpcr_controlled) const {
return fpcr_controlled ? Location().FPCR() : Location().FPCR().ASIMDStandardValue(); 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) A64EmitX64::A64EmitX64(BlockOfCode& code, A64::UserConfig conf, A64::Jit* jit_interface)
: EmitX64(code), conf(conf), jit_interface{jit_interface} { : EmitX64(code), conf(conf), jit_interface{jit_interface} {
GenMemory128Accessors(); GenMemory128Accessors();

View file

@ -28,7 +28,6 @@ struct A64EmitContext final : public EmitContext {
A64::LocationDescriptor Location() const; A64::LocationDescriptor Location() const;
bool IsSingleStep() const; bool IsSingleStep() const;
FP::FPCR FPCR(bool fpcr_controlled = true) const override; FP::FPCR FPCR(bool fpcr_controlled = true) const override;
bool AccurateNaN() const override;
const A64::UserConfig& conf; const A64::UserConfig& conf;
}; };

View file

@ -50,7 +50,6 @@ struct EmitContext {
void EraseInstruction(IR::Inst* inst); void EraseInstruction(IR::Inst* inst);
virtual FP::FPCR FPCR(bool fpcr_controlled = true) const = 0; virtual FP::FPCR FPCR(bool fpcr_controlled = true) const = 0;
virtual bool AccurateNaN() const { return true; }
RegAlloc& reg_alloc; RegAlloc& reg_alloc;
IR::Block& block; IR::Block& block;

View file

@ -258,7 +258,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]);
if (ctx.AccurateNaN() && !ctx.FPCR().DN()) { if (!ctx.FPCR().DN()) {
end = ProcessNaN<fsize>(code, result); end = ProcessNaN<fsize>(code, result);
} }
if constexpr (std::is_member_function_pointer_v<Function>) { if constexpr (std::is_member_function_pointer_v<Function>) {
@ -268,7 +268,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
} }
if (ctx.FPCR().DN()) { if (ctx.FPCR().DN()) {
ForceToDefaultNaN<fsize>(code, result); ForceToDefaultNaN<fsize>(code, result);
} else if (ctx.AccurateNaN()) { } else {
PostProcessNaN<fsize>(code, result, ctx.reg_alloc.ScratchXmm()); PostProcessNaN<fsize>(code, result, ctx.reg_alloc.ScratchXmm());
} }
code.L(end); 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); 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 result = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm operand = ctx.reg_alloc.UseScratchXmm(args[1]); 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); fn(result, operand);
} }
if (ctx.AccurateNaN()) {
ForceToDefaultNaN<fsize>(code, result); ForceToDefaultNaN<fsize>(code, result);
}
ctx.reg_alloc.DefineValue(inst, result); ctx.reg_alloc.DefineValue(inst, result);
return; return;
@ -437,7 +435,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
code.jmp(end); code.jmp(end);
code.L(nan); 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.movaps(result, code.MConst(xword, fsize == 32 ? f32_nan : f64_nan));
code.jmp(end); code.jmp(end);
} else { } else {
@ -677,7 +675,7 @@ static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(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 op1 = ctx.reg_alloc.UseXmm(args[0]);
const Xbyak::Xmm op2 = ctx.reg_alloc.UseXmm(args[1]); const Xbyak::Xmm op2 = ctx.reg_alloc.UseXmm(args[1]);

View file

@ -284,7 +284,7 @@ void EmitTwoOpVectorOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst* ins
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool fpcr_controlled = args[fpcr_controlled_arg_index].GetImmediateU1(); 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; Xbyak::Xmm result;
if constexpr (std::is_member_function_pointer_v<Function>) { if constexpr (std::is_member_function_pointer_v<Function>) {
@ -336,7 +336,7 @@ void EmitThreeOpVectorOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst* i
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool fpcr_controlled = args[2].GetImmediateU1(); 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_a = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(args[1]); const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(args[1]);