From c1e72be68d63576e4a82a5304e65d1ccaebeebbe Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 12 Mar 2018 13:15:51 -0400 Subject: [PATCH] target/i386/fpu_helper: Perform comparison pass against qemu --- qemu/target/i386/fpu_helper.c | 82 +++++++++++++---------------------- 1 file changed, 30 insertions(+), 52 deletions(-) diff --git a/qemu/target/i386/fpu_helper.c b/qemu/target/i386/fpu_helper.c index 90a97231..ea5a0c48 100644 --- a/qemu/target/i386/fpu_helper.c +++ b/qemu/target/i386/fpu_helper.c @@ -245,7 +245,7 @@ int32_t helper_fist_ST0(CPUX86State *env) { int32_t val; - val = floatx80_to_int64(ST0, &env->fp_status); + val = floatx80_to_int32(ST0, &env->fp_status); if (val != (int16_t)val) { val = -32768; } @@ -277,7 +277,7 @@ int64_t helper_fistll_ST0(CPUX86State *env) old_exp_flags = get_float_exception_flags(&env->fp_status); set_float_exception_flags(0, &env->fp_status); - val = floatx80_to_int32(ST0, &env->fp_status); + val = floatx80_to_int64(ST0, &env->fp_status); if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) { val = 0x8000000000000000ULL; } @@ -299,18 +299,12 @@ int32_t helper_fistt_ST0(CPUX86State *env) int32_t helper_fisttl_ST0(CPUX86State *env) { - int32_t val; - - val = floatx80_to_int32_round_to_zero(ST0, &env->fp_status); - return val; + return floatx80_to_int32_round_to_zero(ST0, &env->fp_status); } int64_t helper_fisttll_ST0(CPUX86State *env) { - int64_t val; - - val = floatx80_to_int64_round_to_zero(ST0, &env->fp_status); - return val; + return floatx80_to_int64_round_to_zero(ST0, &env->fp_status); } void helper_fldt_ST0(CPUX86State *env, target_ulong ptr) @@ -511,58 +505,42 @@ void helper_fabs_ST0(CPUX86State *env) void helper_fld1_ST0(CPUX86State *env) { - //ST0 = floatx80_one; - floatx80 one = { 0x8000000000000000LL, 0x3fff }; - ST0 = one; + ST0 = floatx80_one; } void helper_fldl2t_ST0(CPUX86State *env) { - //ST0 = floatx80_l2t; - floatx80 l2t = { 0xd49a784bcd1b8afeLL, 0x4000 }; - ST0 = l2t; + ST0 = floatx80_l2t; } void helper_fldl2e_ST0(CPUX86State *env) { - //ST0 = floatx80_l2e; - floatx80 l2e = { 0xb8aa3b295c17f0bcLL, 0x3fff }; - ST0 = l2e; + ST0 = floatx80_l2e; } void helper_fldpi_ST0(CPUX86State *env) { - //ST0 = floatx80_pi; - floatx80 pi = { 0xc90fdaa22168c235LL, 0x4000 }; - ST0 = pi; + ST0 = floatx80_pi; } void helper_fldlg2_ST0(CPUX86State *env) { - //ST0 = floatx80_lg2; - floatx80 lg2 = { 0x9a209a84fbcff799LL, 0x3ffd }; - ST0 = lg2; + ST0 = floatx80_lg2; } void helper_fldln2_ST0(CPUX86State *env) { - //ST0 = floatx80_ln2; - floatx80 ln2 = { 0xb17217f7d1cf79acLL, 0x3ffe }; - ST0 = ln2; + ST0 = floatx80_ln2; } void helper_fldz_ST0(CPUX86State *env) { - //ST0 = floatx80_zero; - floatx80 zero = { 0x0000000000000000LL, 0x0000 }; - ST0 = zero; + ST0 = floatx80_zero; } void helper_fldz_FT0(CPUX86State *env) { - //FT0 = floatx80_zero; - floatx80 zero = { 0x0000000000000000LL, 0x0000 }; - ST0 = zero; + FT0 = floatx80_zero; } uint32_t helper_fnstsw(CPUX86State *env) @@ -724,11 +702,10 @@ void helper_fptan(CPUX86State *env) if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) { env->fpus |= 0x400; } else { - floatx80 one = { 0x8000000000000000LL, 0x3fff }; fptemp = tan(fptemp); ST0 = double_to_floatx80(env, fptemp); fpush(env); - ST0 = one; + ST0 = floatx80_one; env->fpus &= ~0x400; /* C2 <-- 0 */ /* the above code is for |arg| < 2**52 only */ } @@ -752,9 +729,7 @@ void helper_fxtract(CPUX86State *env) if (floatx80_is_zero(ST0)) { /* Easy way to generate -inf and raising division by 0 exception */ - floatx80 zero = { 0x0000000000000000LL, 0x0000 }; - floatx80 one = { 0x8000000000000000LL, 0x3fff }; - ST0 = floatx80_div(floatx80_chs(one), zero, + ST0 = floatx80_div(floatx80_chs(floatx80_one), floatx80_zero, &env->fp_status); fpush(env); ST0 = temp.d; @@ -781,7 +756,7 @@ void helper_fprem1(CPUX86State *env) st1 = floatx80_to_double(env, ST1); if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) { - ST0 = double_to_floatx80(env, NAN); /* NaN */ + ST0 = double_to_floatx80(env, 0.0 / 0.0); /* NaN */ env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */ return; } @@ -840,7 +815,7 @@ void helper_fprem(CPUX86State *env) st1 = floatx80_to_double(env, ST1); if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) { - ST0 = double_to_floatx80(env, NAN); /* NaN */ + ST0 = double_to_floatx80(env, 0.0 / 0.0); /* NaN */ env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */ return; } @@ -1028,17 +1003,7 @@ static void do_fstenv(CPUX86State *env, target_ulong ptr, int data32, } } } - - // DFLAG enum: tcg.h, case here to int - if (env->hflags & HF_CS64_MASK) { - cpu_stl_data(env, ptr, env->fpuc); - cpu_stl_data(env, ptr + 4, fpus); - cpu_stl_data(env, ptr + 8, fptag); - cpu_stl_data(env, ptr + 12, (uint32_t)env->fpip); /* fpip */ - cpu_stl_data(env, ptr + 20, 0); /* fpcs */ - cpu_stl_data(env, ptr + 24, 0); /* fpoo */ - cpu_stl_data(env, ptr + 28, 0); /* fpos */ - } else if (data32) { + if (data32) { /* 32 bit */ cpu_stl_data_ra(env, ptr, env->fpuc, retaddr); cpu_stl_data_ra(env, ptr + 4, fpus, retaddr); @@ -1158,6 +1123,7 @@ static void do_xsave_fpu(CPUX86State *env, target_ulong ptr, uintptr_t ra) for (i = 0; i < 8; i++) { fptag |= (env->fptags[i] << i); } + cpu_stw_data_ra(env, ptr + XO(legacy.fcw), env->fpuc, ra); cpu_stw_data_ra(env, ptr + XO(legacy.fsw), fpus, ra); cpu_stw_data_ra(env, ptr + XO(legacy.ftw), fptag ^ 0xff, ra); @@ -1412,6 +1378,18 @@ void helper_fxrstor(CPUX86State *env, target_ulong ptr) } } +#if defined(CONFIG_USER_ONLY) +void cpu_x86_fxsave(CPUX86State *env, target_ulong ptr) +{ + helper_fxsave(env, ptr); +} + +void cpu_x86_fxrstor(CPUX86State *env, target_ulong ptr) +{ + helper_fxrstor(env, ptr); +} +#endif + void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm) { uintptr_t ra = GETPC();