From 2008fda88b945b7f0eb27bf4434a13a156679e2f Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 22 Jun 2020 22:54:38 +0100 Subject: [PATCH] emit_x64_floating_point: Correct error in s16 rounding in EmitFPToFixed --- src/backend/x64/emit_x64_floating_point.cpp | 9 +++------ tests/A32/test_arm_instructions.cpp | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/backend/x64/emit_x64_floating_point.cpp b/src/backend/x64/emit_x64_floating_point.cpp index 715f6cb3..5437dc2d 100644 --- a/src/backend/x64/emit_x64_floating_point.cpp +++ b/src/backend/x64/emit_x64_floating_point.cpp @@ -50,6 +50,7 @@ constexpr u64 f64_nan = 0x7ff8000000000000u; constexpr u64 f64_non_sign_mask = 0x7fffffffffffffffu; constexpr u64 f64_smallest_normal = 0x0010000000000000u; +constexpr u64 f64_min_s16 = 0xc0e0000000000000u; // -32768 as a double constexpr u64 f64_max_s16 = 0x40dfffc000000000u; // 32767 as a double constexpr u64 f64_min_u16 = 0x0000000000000000u; // 0 as a double constexpr u64 f64_max_u16 = 0x40efffe000000000u; // 65535 as a double @@ -1275,12 +1276,8 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { } } else { code.minsd(src, code.MConst(xword, unsigned_ ? f64_max_u16 : f64_max_s16)); - if (unsigned_) { - code.maxsd(src, code.MConst(xword, f64_min_u16)); - code.cvttsd2si(result, src); // 64 bit gpr - } else { - code.cvttsd2si(result.cvt32(), src); - } + code.maxsd(src, code.MConst(xword, unsigned_ ? f64_min_u16 : f64_min_s16)); + code.cvttsd2si(result, src); // 64 bit gpr } ctx.reg_alloc.DefineValue(inst, result); diff --git a/tests/A32/test_arm_instructions.cpp b/tests/A32/test_arm_instructions.cpp index 23d0c35a..3c82ae42 100644 --- a/tests/A32/test_arm_instructions.cpp +++ b/tests/A32/test_arm_instructions.cpp @@ -485,3 +485,23 @@ TEST_CASE("arm: vclt.f32 with zero", "[arm][A32]") { REQUIRE(jit.ExtRegs()[6] == 0x00000000); REQUIRE(jit.ExtRegs()[7] == 0x00000000); } + +TEST_CASE("arm: vcvt.s16.f64", "[arm][A32]") { + ArmTestEnv test_env; + A32::Jit jit{GetUserConfig(&test_env)}; + test_env.code_mem = { + 0xeebe8b45, // vcvt.s16.f64 d8, d8, #6 + 0xeafffffe, // b +#0 + }; + + jit.ExtRegs()[16] = 0x9a7110b0; + jit.ExtRegs()[17] = 0xcd78f4e7; + + jit.SetCpsr(0x000001d0); // User-mode + + test_env.ticks_left = 2; + jit.Run(); + + REQUIRE(jit.ExtRegs()[16] == 0xffff8000); + REQUIRE(jit.ExtRegs()[17] == 0xffffffff); +}