From 571c73a8f30388f38387b017d745b84e2cf881b3 Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Thu, 27 Oct 2022 08:20:48 +0200 Subject: [PATCH] Add edge case for FCMP with 0 immediate. (#8) * Add edge case for FCMP with 0 immediate. * Update emit_a64_floating_point.cpp --- .../backend/A64/emit_a64_floating_point.cpp | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/dynarmic/backend/A64/emit_a64_floating_point.cpp b/src/dynarmic/backend/A64/emit_a64_floating_point.cpp index bc09ee4b..340da303 100644 --- a/src/dynarmic/backend/A64/emit_a64_floating_point.cpp +++ b/src/dynarmic/backend/A64/emit_a64_floating_point.cpp @@ -183,13 +183,21 @@ static ARM64Reg SetFpscrNzcvFromFlags(BlockOfCode& code, EmitContext& ctx) { void EmitA64::EmitFPCompare32(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ARM64Reg reg_a = EncodeRegToSingle(ctx.reg_alloc.UseFpr(args[0])); - ARM64Reg reg_b = EncodeRegToSingle(ctx.reg_alloc.UseFpr(args[1])); bool exc_on_qnan = args[2].GetImmediateU1(); - if (exc_on_qnan) { - code.fp_emitter.FCMPE(reg_a, reg_b); + if (args[1].IsImmediate() && args[1].GetImmediateU64() == 0) { + if (exc_on_qnan) { + code.fp_emitter.FCMPE(reg_a); + } else { + code.fp_emitter.FCMP(reg_a); + } } else { - code.fp_emitter.FCMP(reg_a, reg_b); + ARM64Reg reg_b = EncodeRegToSingle(ctx.reg_alloc.UseFpr(args[1])); + if (exc_on_qnan) { + code.fp_emitter.FCMPE(reg_a, reg_b); + } else { + code.fp_emitter.FCMP(reg_a, reg_b); + } } ARM64Reg nzcv = SetFpscrNzcvFromFlags(code, ctx); @@ -199,13 +207,21 @@ void EmitA64::EmitFPCompare32(EmitContext& ctx, IR::Inst* inst) { void EmitA64::EmitFPCompare64(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); const ARM64Reg reg_a = EncodeRegToDouble(ctx.reg_alloc.UseFpr(args[0])); - const ARM64Reg reg_b = EncodeRegToDouble(ctx.reg_alloc.UseFpr(args[1])); bool exc_on_qnan = args[2].GetImmediateU1(); - if (exc_on_qnan) { - code.fp_emitter.FCMPE(reg_a, reg_b); + if (args[1].IsImmediate() && args[1].GetImmediateU64() == 0) { + if (exc_on_qnan) { + code.fp_emitter.FCMPE(reg_a); + } else { + code.fp_emitter.FCMP(reg_a); + } } else { - code.fp_emitter.FCMP(reg_a, reg_b); + const ARM64Reg reg_b = EncodeRegToDouble(ctx.reg_alloc.UseFpr(args[1])); + if (exc_on_qnan) { + code.fp_emitter.FCMPE(reg_a, reg_b); + } else { + code.fp_emitter.FCMP(reg_a, reg_b); + } } ARM64Reg nzcv = SetFpscrNzcvFromFlags(code, ctx);