target/i386/fpu_helper: Perform comparison pass against qemu

This commit is contained in:
Lioncash 2018-03-12 13:15:51 -04:00
parent 0d0dd2ba98
commit c1e72be68d
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -245,7 +245,7 @@ int32_t helper_fist_ST0(CPUX86State *env)
{ {
int32_t val; int32_t val;
val = floatx80_to_int64(ST0, &env->fp_status); val = floatx80_to_int32(ST0, &env->fp_status);
if (val != (int16_t)val) { if (val != (int16_t)val) {
val = -32768; val = -32768;
} }
@ -277,7 +277,7 @@ int64_t helper_fistll_ST0(CPUX86State *env)
old_exp_flags = get_float_exception_flags(&env->fp_status); old_exp_flags = get_float_exception_flags(&env->fp_status);
set_float_exception_flags(0, &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) { if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) {
val = 0x8000000000000000ULL; val = 0x8000000000000000ULL;
} }
@ -299,18 +299,12 @@ int32_t helper_fistt_ST0(CPUX86State *env)
int32_t helper_fisttl_ST0(CPUX86State *env) int32_t helper_fisttl_ST0(CPUX86State *env)
{ {
int32_t val; return floatx80_to_int32_round_to_zero(ST0, &env->fp_status);
val = floatx80_to_int32_round_to_zero(ST0, &env->fp_status);
return val;
} }
int64_t helper_fisttll_ST0(CPUX86State *env) int64_t helper_fisttll_ST0(CPUX86State *env)
{ {
int64_t val; return floatx80_to_int64_round_to_zero(ST0, &env->fp_status);
val = floatx80_to_int64_round_to_zero(ST0, &env->fp_status);
return val;
} }
void helper_fldt_ST0(CPUX86State *env, target_ulong ptr) 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) void helper_fld1_ST0(CPUX86State *env)
{ {
//ST0 = floatx80_one; ST0 = floatx80_one;
floatx80 one = { 0x8000000000000000LL, 0x3fff };
ST0 = one;
} }
void helper_fldl2t_ST0(CPUX86State *env) void helper_fldl2t_ST0(CPUX86State *env)
{ {
//ST0 = floatx80_l2t; ST0 = floatx80_l2t;
floatx80 l2t = { 0xd49a784bcd1b8afeLL, 0x4000 };
ST0 = l2t;
} }
void helper_fldl2e_ST0(CPUX86State *env) void helper_fldl2e_ST0(CPUX86State *env)
{ {
//ST0 = floatx80_l2e; ST0 = floatx80_l2e;
floatx80 l2e = { 0xb8aa3b295c17f0bcLL, 0x3fff };
ST0 = l2e;
} }
void helper_fldpi_ST0(CPUX86State *env) void helper_fldpi_ST0(CPUX86State *env)
{ {
//ST0 = floatx80_pi; ST0 = floatx80_pi;
floatx80 pi = { 0xc90fdaa22168c235LL, 0x4000 };
ST0 = pi;
} }
void helper_fldlg2_ST0(CPUX86State *env) void helper_fldlg2_ST0(CPUX86State *env)
{ {
//ST0 = floatx80_lg2; ST0 = floatx80_lg2;
floatx80 lg2 = { 0x9a209a84fbcff799LL, 0x3ffd };
ST0 = lg2;
} }
void helper_fldln2_ST0(CPUX86State *env) void helper_fldln2_ST0(CPUX86State *env)
{ {
//ST0 = floatx80_ln2; ST0 = floatx80_ln2;
floatx80 ln2 = { 0xb17217f7d1cf79acLL, 0x3ffe };
ST0 = ln2;
} }
void helper_fldz_ST0(CPUX86State *env) void helper_fldz_ST0(CPUX86State *env)
{ {
//ST0 = floatx80_zero; ST0 = floatx80_zero;
floatx80 zero = { 0x0000000000000000LL, 0x0000 };
ST0 = zero;
} }
void helper_fldz_FT0(CPUX86State *env) void helper_fldz_FT0(CPUX86State *env)
{ {
//FT0 = floatx80_zero; FT0 = floatx80_zero;
floatx80 zero = { 0x0000000000000000LL, 0x0000 };
ST0 = zero;
} }
uint32_t helper_fnstsw(CPUX86State *env) uint32_t helper_fnstsw(CPUX86State *env)
@ -724,11 +702,10 @@ void helper_fptan(CPUX86State *env)
if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) { if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) {
env->fpus |= 0x400; env->fpus |= 0x400;
} else { } else {
floatx80 one = { 0x8000000000000000LL, 0x3fff };
fptemp = tan(fptemp); fptemp = tan(fptemp);
ST0 = double_to_floatx80(env, fptemp); ST0 = double_to_floatx80(env, fptemp);
fpush(env); fpush(env);
ST0 = one; ST0 = floatx80_one;
env->fpus &= ~0x400; /* C2 <-- 0 */ env->fpus &= ~0x400; /* C2 <-- 0 */
/* the above code is for |arg| < 2**52 only */ /* the above code is for |arg| < 2**52 only */
} }
@ -752,9 +729,7 @@ void helper_fxtract(CPUX86State *env)
if (floatx80_is_zero(ST0)) { if (floatx80_is_zero(ST0)) {
/* Easy way to generate -inf and raising division by 0 exception */ /* Easy way to generate -inf and raising division by 0 exception */
floatx80 zero = { 0x0000000000000000LL, 0x0000 }; ST0 = floatx80_div(floatx80_chs(floatx80_one), floatx80_zero,
floatx80 one = { 0x8000000000000000LL, 0x3fff };
ST0 = floatx80_div(floatx80_chs(one), zero,
&env->fp_status); &env->fp_status);
fpush(env); fpush(env);
ST0 = temp.d; ST0 = temp.d;
@ -781,7 +756,7 @@ void helper_fprem1(CPUX86State *env)
st1 = floatx80_to_double(env, ST1); st1 = floatx80_to_double(env, ST1);
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) { 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 */ env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
return; return;
} }
@ -840,7 +815,7 @@ void helper_fprem(CPUX86State *env)
st1 = floatx80_to_double(env, ST1); st1 = floatx80_to_double(env, ST1);
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) { 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 */ env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
return; return;
} }
@ -1028,17 +1003,7 @@ static void do_fstenv(CPUX86State *env, target_ulong ptr, int data32,
} }
} }
} }
if (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) {
/* 32 bit */ /* 32 bit */
cpu_stl_data_ra(env, ptr, env->fpuc, retaddr); cpu_stl_data_ra(env, ptr, env->fpuc, retaddr);
cpu_stl_data_ra(env, ptr + 4, fpus, 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++) { for (i = 0; i < 8; i++) {
fptag |= (env->fptags[i] << 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.fcw), env->fpuc, ra);
cpu_stw_data_ra(env, ptr + XO(legacy.fsw), fpus, ra); cpu_stw_data_ra(env, ptr + XO(legacy.fsw), fpus, ra);
cpu_stw_data_ra(env, ptr + XO(legacy.ftw), fptag ^ 0xff, 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) void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm)
{ {
uintptr_t ra = GETPC(); uintptr_t ra = GETPC();