emit_x64_floating_point: EmitFPToFixed: maxsd optimization
maxsd is not required when doing a signed conversion, because x64 produces a 0x80...00 value for out of range values.
This commit is contained in:
parent
1abf82ac4a
commit
27427595b7
1 changed files with 9 additions and 5 deletions
|
@ -49,11 +49,9 @@ constexpr u64 f64_non_sign_mask = 0x7fffffffffffffffu;
|
||||||
constexpr u64 f64_smallest_normal = 0x0010000000000000u;
|
constexpr u64 f64_smallest_normal = 0x0010000000000000u;
|
||||||
|
|
||||||
constexpr u64 f64_penultimate_positive_denormal = 0x000ffffffffffffeu;
|
constexpr u64 f64_penultimate_positive_denormal = 0x000ffffffffffffeu;
|
||||||
constexpr u64 f64_min_s32 = 0xc1e0000000000000u; // -2147483648 as a double
|
|
||||||
constexpr u64 f64_max_s32 = 0x41dfffffffc00000u; // 2147483647 as a double
|
constexpr u64 f64_max_s32 = 0x41dfffffffc00000u; // 2147483647 as a double
|
||||||
constexpr u64 f64_min_u32 = 0x0000000000000000u; // 0 as a double
|
constexpr u64 f64_min_u32 = 0x0000000000000000u; // 0 as a double
|
||||||
constexpr u64 f64_max_u32 = 0x41efffffffe00000u; // 4294967295 as a double
|
constexpr u64 f64_max_u32 = 0x41efffffffe00000u; // 4294967295 as a double
|
||||||
constexpr u64 f64_min_s64 = 0xc3e0000000000000u; // -2^63 as a double
|
|
||||||
constexpr u64 f64_max_s64_lim = 0x43e0000000000000u; // 2^63 as a double (actual maximum unrepresentable)
|
constexpr u64 f64_max_s64_lim = 0x43e0000000000000u; // 2^63 as a double (actual maximum unrepresentable)
|
||||||
constexpr u64 f64_min_u64 = 0x0000000000000000u; // 0 as a double
|
constexpr u64 f64_min_u64 = 0x0000000000000000u; // 0 as a double
|
||||||
constexpr u64 f64_max_u64_lim = 0x43f0000000000000u; // 2^64 as a double (actual maximum unrepresentable)
|
constexpr u64 f64_max_u64_lim = 0x43f0000000000000u; // 2^64 as a double (actual maximum unrepresentable)
|
||||||
|
@ -1001,7 +999,9 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, s
|
||||||
if (isize == 64) {
|
if (isize == 64) {
|
||||||
Xbyak::Label saturate_max, end;
|
Xbyak::Label saturate_max, end;
|
||||||
|
|
||||||
code.maxsd(src, code.MConst(xword, unsigned_ ? f64_min_u64 : f64_min_s64));
|
if (unsigned_) {
|
||||||
|
code.maxsd(src, code.MConst(xword, f64_min_u64));
|
||||||
|
}
|
||||||
code.movsd(scratch, code.MConst(xword, unsigned_ ? f64_max_u64_lim : f64_max_s64_lim));
|
code.movsd(scratch, code.MConst(xword, unsigned_ ? f64_max_u64_lim : f64_max_s64_lim));
|
||||||
code.comisd(scratch, src);
|
code.comisd(scratch, src);
|
||||||
code.jna(saturate_max, code.T_NEAR);
|
code.jna(saturate_max, code.T_NEAR);
|
||||||
|
@ -1027,8 +1027,12 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, s
|
||||||
code.SwitchToNearCode();
|
code.SwitchToNearCode();
|
||||||
} else {
|
} else {
|
||||||
code.minsd(src, code.MConst(xword, unsigned_ ? f64_max_u32 : f64_max_s32));
|
code.minsd(src, code.MConst(xword, unsigned_ ? f64_max_u32 : f64_max_s32));
|
||||||
code.maxsd(src, code.MConst(xword, unsigned_ ? f64_min_u32 : f64_min_s32));
|
if (unsigned_) {
|
||||||
code.cvttsd2si(result, src); // 64 bit gpr
|
code.maxsd(src, code.MConst(xword, f64_min_u32));
|
||||||
|
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);
|
||||||
|
|
Loading…
Reference in a new issue