emit_x64_floating_point: AVX implementation of ForceToDefaultNaN

This commit is contained in:
MerryMage 2018-07-31 21:22:01 +01:00
parent dfb660cd16
commit 90f8dda966

View file

@ -176,12 +176,17 @@ void PostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm tmp) {
} }
template<size_t fsize> template<size_t fsize>
void DefaultNaN(BlockOfCode& code, Xbyak::Xmm xmm_value) { void ForceToDefaultNaN(BlockOfCode& code, Xbyak::Xmm result) {
Xbyak::Label end; if (code.DoesCpuSupport(Xbyak::util::Cpu::tAVX)) {
FCODE(ucomis)(xmm_value, xmm_value); FCODE(vcmpunords)(xmm0, result, result);
code.jnp(end); FCODE(blendvp)(result, code.MConst(xword, fsize == 32 ? f32_nan : f64_nan));
code.movaps(xmm_value, code.MConst(xword, fsize == 32 ? f32_nan : f64_nan)); } else {
code.L(end); Xbyak::Label end;
FCODE(ucomis)(result, result);
code.jnp(end);
code.movaps(result, code.MConst(xword, fsize == 32 ? f32_nan : f64_nan));
code.L(end);
}
} }
template<size_t fsize> template<size_t fsize>
@ -217,7 +222,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
fn(result); fn(result);
} }
if (ctx.FPSCR_DN()) { if (ctx.FPSCR_DN()) {
DefaultNaN<fsize>(code, result); ForceToDefaultNaN<fsize>(code, result);
} else if (ctx.AccurateNaN()) { } else if (ctx.AccurateNaN()) {
PostProcessNaNs<fsize>(code, result, ctx.reg_alloc.ScratchXmm()); PostProcessNaNs<fsize>(code, result, ctx.reg_alloc.ScratchXmm());
} }
@ -257,7 +262,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, [[maybe_unus
fn(result, operand); fn(result, operand);
} }
if (ctx.FPSCR_DN()) { if (ctx.FPSCR_DN()) {
DefaultNaN<fsize>(code, result); ForceToDefaultNaN<fsize>(code, result);
} else if (ctx.AccurateNaN()) { } else if (ctx.AccurateNaN()) {
PostProcessNaNs<fsize>(code, result, operand); PostProcessNaNs<fsize>(code, result, operand);
} }
@ -899,7 +904,7 @@ void EmitX64::EmitFPSingleToDouble(EmitContext& ctx, IR::Inst* inst) {
} }
code.cvtss2sd(result, result); code.cvtss2sd(result, result);
if (ctx.FPSCR_DN()) { if (ctx.FPSCR_DN()) {
DefaultNaN<64>(code, result); ForceToDefaultNaN<64>(code, result);
} }
ctx.reg_alloc.DefineValue(inst, result); ctx.reg_alloc.DefineValue(inst, result);
@ -915,7 +920,7 @@ void EmitX64::EmitFPDoubleToSingle(EmitContext& ctx, IR::Inst* inst) {
} }
code.cvtsd2ss(result, result); code.cvtsd2ss(result, result);
if (ctx.FPSCR_DN()) { if (ctx.FPSCR_DN()) {
DefaultNaN<32>(code, result); ForceToDefaultNaN<32>(code, result);
} }
ctx.reg_alloc.DefineValue(inst, result); ctx.reg_alloc.DefineValue(inst, result);