A64: Remove NaN accuracy setting
Always do accuracte NaN handling.
This commit is contained in:
parent
b5df8d1ef8
commit
46445d0866
6 changed files with 8 additions and 28 deletions
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<fsize>(code, result);
|
||||
}
|
||||
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()) {
|
||||
ForceToDefaultNaN<fsize>(code, result);
|
||||
} else if (ctx.AccurateNaN()) {
|
||||
} else {
|
||||
PostProcessNaN<fsize>(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<fsize>(code, result);
|
||||
}
|
||||
ForceToDefaultNaN<fsize>(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]);
|
||||
|
|
|
@ -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<Function>) {
|
||||
|
@ -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]);
|
||||
|
||||
|
|
Loading…
Reference in a new issue