From: Laurent Vivier <laur...@vivier.eu> Signed-off-by: Laurent Vivier <laur...@vivier.eu> --- target-m68k/helper.c | 69 +++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 60 insertions(+), 9 deletions(-)
diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 081e1d9..7dcac61 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -29,6 +29,17 @@ #include "helpers.h" +#if 0 +#define DBG_FPU(...) do { fprintf(stderr, "0x%08x: ", env->pc); fprintf(stderr, __VA_ARGS__); } while(0) +static inline long double LDOUBLE(floatx80 x) +{ + return *(long double *)&x; +} +#else +#define DBG_FPU(...) +#define LDOUBLE(x) +#endif + #define SIGNBIT (1u << 31) enum m68k_cpuid { @@ -1009,12 +1020,6 @@ static const floatx80 fpu_rom[128] = { [0x3f] = { .high = 0x7525, .low = 0xc46052028a20979bULL }, /* 10^4096 */ }; -void HELPER(const_FP0)(CPUState *env, uint32_t offset) -{ - env->fp0h = fpu_rom[offset].high; - env->fp0l = fpu_rom[offset].low; -} - static inline floatx80 FP0_to_floatx80(CPUState *env) { floatx80 res; @@ -1072,6 +1077,14 @@ static inline floatx80 FP1_to_floatx80(CPUState *env) return res; } +void HELPER(const_FP0)(CPUState *env, uint32_t offset) +{ + env->fp0h = fpu_rom[offset].high; + env->fp0l = fpu_rom[offset].low; + DBG_FPU("ROM[0x%02x] %"PRIxFPH" %"PRIxFPL" %.17Lg\n", + offset, env->fp0h, env->fp0l, LDOUBLE(FP0_to_floatx80(env))); +} + static inline void restore_precision_mode(CPUState *env) { int rounding_precision; @@ -1118,6 +1131,8 @@ static inline void restore_rounding_mode(CPUState *env) void HELPER(set_fpcr)(CPUState *env, uint32_t val) { + DBG_FPU("set_fpcr %04x\n", val); + env->fpcr = val & 0xffff; restore_precision_mode(env); @@ -1128,8 +1143,11 @@ void HELPER(exts32_FP0)(CPUState *env) { floatx80 res; + DBG_FPU("exts32_FP0 %d\n", FP0_to_int32(env)); + res = int32_to_floatx80(FP0_to_int32(env), &env->fp_status); + DBG_FPU(" = %Lg\n", LDOUBLE(res)); floatx80_to_FP0(env, res); } @@ -1137,6 +1155,7 @@ void HELPER(extf32_FP0)(CPUState *env) { floatx80 res; + DBG_FPU("extf32_FP0\n"); res = float32_to_floatx80(FP0_to_float32(env), &env->fp_status); floatx80_to_FP0(env, res); @@ -1145,8 +1164,12 @@ void HELPER(extf32_FP0)(CPUState *env) void HELPER(extf64_FP0)(CPUState *env) { floatx80 res; + uint64_t val; - res = float64_to_floatx80(FP0_to_float64(env), &env->fp_status); + val = FP0_to_float64(env); + DBG_FPU("extf64_FP0 0x%016"PRIx64", %g\n", val, *(double*)&val); + res = float64_to_floatx80(val, &env->fp_status); + DBG_FPU(" = %Lg\n", LDOUBLE(res)); floatx80_to_FP0(env, res); } @@ -1161,7 +1184,9 @@ void HELPER(reds32_FP0)(CPUState *env) int32_t res; val = FP0_to_floatx80(env); + DBG_FPU("reds32_FP0 %Lg\n", LDOUBLE(val)); res = floatx80_to_int32(val, &env->fp_status); + DBG_FPU(" = %d\n", res); int32_to_FP0(env, res); } @@ -1171,6 +1196,7 @@ void HELPER(redf32_FP0)(CPUState *env) floatx80 val; float32 res; + DBG_FPU("redf32_FP0\n"); val = FP0_to_floatx80(env); res = floatx80_to_float32(val, &env->fp_status); @@ -1183,19 +1209,24 @@ void HELPER(redf64_FP0)(CPUState *env) float64 res; val = FP0_to_floatx80(env); + DBG_FPU("redf64_FP0 %Lg\n", LDOUBLE(val)); res = floatx80_to_float64(val, &env->fp_status); + DBG_FPU(" = %g\n", *(double*)&res); float64_to_FP0(env, res); } void HELPER(redp96_FP0)(CPUState *env) { + DBG_FPU("redp96_FP0\n"); } void HELPER(iround_FP0)(CPUState *env) { floatx80 res; + DBG_FPU("iround_FP0\n"); + res = floatx80_round_to_int(FP0_to_floatx80(env), &env->fp_status); floatx80_to_FP0(env, res); @@ -1205,6 +1236,8 @@ void HELPER(itrunc_FP0)(CPUState *env) { floatx80 res; + DBG_FPU("itrunc_FP0\n"); + set_float_rounding_mode(float_round_to_zero, &env->fp_status); res = floatx80_round_to_int(FP0_to_floatx80(env), &env->fp_status); restore_rounding_mode(env); @@ -1216,6 +1249,7 @@ void HELPER(sqrt_FP0)(CPUState *env) { floatx80 res; + DBG_FPU("sqrt_FP0\n"); res = floatx80_sqrt(FP0_to_floatx80(env), &env->fp_status); floatx80_to_FP0(env, res); @@ -1225,6 +1259,7 @@ void HELPER(abs_FP0)(CPUState *env) { floatx80 res; + DBG_FPU("abs_FP0\n"); res = floatx80_abs(FP0_to_floatx80(env)); floatx80_to_FP0(env, res); @@ -1234,6 +1269,7 @@ void HELPER(chs_FP0)(CPUState *env) { floatx80 res; + DBG_FPU("chs_FP0\n"); res = floatx80_chs(FP0_to_floatx80(env)); floatx80_to_FP0(env, res); @@ -1243,8 +1279,11 @@ void HELPER(add_FP0_FP1)(CPUState *env) { floatx80 res; + DBG_FPU("add_FP0_FP1(%Lg,%Lg)\n", LDOUBLE(FP0_to_floatx80(env)), + LDOUBLE(FP1_to_floatx80(env))); res = floatx80_add(FP0_to_floatx80(env), FP1_to_floatx80(env), &env->fp_status); + DBG_FPU(" = %Lg\n", LDOUBLE(res)); floatx80_to_FP0(env, res); } @@ -1253,8 +1292,11 @@ void HELPER(sub_FP0_FP1)(CPUState *env) { floatx80 res; - res = floatx80_sub(FP0_to_floatx80(env), FP1_to_floatx80(env), + DBG_FPU("sub_FP0 %Lg %Lg\n", LDOUBLE(FP0_to_floatx80(env)), + LDOUBLE(FP1_to_floatx80(env))); + res = floatx80_sub(FP1_to_floatx80(env), FP0_to_floatx80(env), &env->fp_status); + DBG_FPU(" = %Lg\n", LDOUBLE(res)); floatx80_to_FP0(env, res); } @@ -1263,8 +1305,11 @@ void HELPER(mul_FP0_FP1)(CPUState *env) { floatx80 res; + DBG_FPU("mul_FP0_FP1 %Lg %Lg\n", + LDOUBLE(FP0_to_floatx80(env)), LDOUBLE(FP1_to_floatx80(env))); res = floatx80_mul(FP0_to_floatx80(env), FP1_to_floatx80(env), &env->fp_status); + DBG_FPU(" = %Lg\n", LDOUBLE(res)); floatx80_to_FP0(env, res); } @@ -1273,7 +1318,8 @@ void HELPER(div_FP0_FP1)(CPUState *env) { floatx80 res; - res = floatx80_div(FP0_to_floatx80(env), FP1_to_floatx80(env), + DBG_FPU("div\n"); + res = floatx80_div(FP1_to_floatx80(env), FP0_to_floatx80(env), &env->fp_status); floatx80_to_FP0(env, res); @@ -1284,6 +1330,8 @@ void HELPER(fcmp_FP0_FP1)(CPUState *env) /* ??? This may incorrectly raise exceptions. */ /* ??? Should flush denormals to zero. */ floatx80 res; + DBG_FPU("cmp_FP0_FP1 %Lg %Lg\n", LDOUBLE(FP1_to_floatx80(env)), + LDOUBLE(FP0_to_floatx80(env))); res = floatx80_sub(FP1_to_floatx80(env), FP0_to_floatx80(env), &env->fp_status); if (floatx80_is_any_nan(res)) { @@ -1295,6 +1343,7 @@ void HELPER(fcmp_FP0_FP1)(CPUState *env) res = floatx80_chs(res); } } + DBG_FPU(" : %Lg\n", LDOUBLE(res)); floatx80_to_FP0(env, res); } @@ -1302,9 +1351,11 @@ uint32_t HELPER(compare_FP0)(CPUState *env) { uint32_t res; + DBG_FPU("compare_FP0 %Lg\n", LDOUBLE(FP0_to_floatx80(env))); res = float64_compare_quiet(floatx80_to_float64(FP0_to_floatx80(env), &env->fp_status), float64_zero, &env->fp_status); + DBG_FPU(" = %d\n", res); return res; } -- 1.7.2.3