emit_x64_floating_point: Correct error in s16 rounding in EmitFPToFixed

This commit is contained in:
MerryMage 2020-06-22 22:54:38 +01:00
parent 3ea49fc6d6
commit 2008fda88b
2 changed files with 23 additions and 6 deletions

View file

@ -50,6 +50,7 @@ constexpr u64 f64_nan = 0x7ff8000000000000u;
constexpr u64 f64_non_sign_mask = 0x7fffffffffffffffu; constexpr u64 f64_non_sign_mask = 0x7fffffffffffffffu;
constexpr u64 f64_smallest_normal = 0x0010000000000000u; 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_max_s16 = 0x40dfffc000000000u; // 32767 as a double
constexpr u64 f64_min_u16 = 0x0000000000000000u; // 0 as a double constexpr u64 f64_min_u16 = 0x0000000000000000u; // 0 as a double
constexpr u64 f64_max_u16 = 0x40efffe000000000u; // 65535 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 { } else {
code.minsd(src, code.MConst(xword, unsigned_ ? f64_max_u16 : f64_max_s16)); code.minsd(src, code.MConst(xword, unsigned_ ? f64_max_u16 : f64_max_s16));
if (unsigned_) { code.maxsd(src, code.MConst(xword, unsigned_ ? f64_min_u16 : f64_min_s16));
code.maxsd(src, code.MConst(xword, f64_min_u16));
code.cvttsd2si(result, src); // 64 bit gpr code.cvttsd2si(result, src); // 64 bit gpr
} else {
code.cvttsd2si(result.cvt32(), src);
}
} }
ctx.reg_alloc.DefineValue(inst, result); ctx.reg_alloc.DefineValue(inst, result);

View file

@ -485,3 +485,23 @@ TEST_CASE("arm: vclt.f32 with zero", "[arm][A32]") {
REQUIRE(jit.ExtRegs()[6] == 0x00000000); REQUIRE(jit.ExtRegs()[6] == 0x00000000);
REQUIRE(jit.ExtRegs()[7] == 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);
}