From: Laurent Vivier <laur...@vivier.eu> Signed-off-by: Laurent Vivier <laur...@vivier.eu> --- fpu/softfloat.h | 2 ++ target-m68k/helper.c | 38 ++++++++++++++++++++++++++++++++++++-- target-m68k/helpers.h | 2 ++ target-m68k/translate.c | 6 ++++++ tests/m68k/Makefile | 2 +- tests/m68k/fetox.S | 8 ++++++++ tests/m68k/flogn.S | 8 ++++++++ 7 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 tests/m68k/fetox.S create mode 100644 tests/m68k/flogn.S
diff --git a/fpu/softfloat.h b/fpu/softfloat.h index 3bb7d8f..f6d5fce 100644 --- a/fpu/softfloat.h +++ b/fpu/softfloat.h @@ -532,6 +532,8 @@ INLINE int floatx80_is_any_nan(floatx80 a) #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL) #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL) #define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL) +#define floatx80_e make_floatx80(0x4000, 0xadf85458a2bb4a9aULL) +#define floatx80_log2e make_floatx80(0x3fff, 0xb8aa3b295c17f0bcULL) /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 77d88e7..f67bfba 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -997,8 +997,8 @@ static const floatx80 fpu_rom[128] = { [0x00] = floatx80_pi, /* Pi */ [0x0b] = { .high = 0x3ffd, .low = 0x9a209a84fbcff798ULL }, /* Log10(2) */ - [0x0c] = { .high = 0x4000, .low = 0xadf85458a2bb4a9aULL }, /* e */ - [0x0d] = { .high = 0x3fff, .low = 0xb8aa3b295c17f0bcULL }, /* Log2(e) */ + [0x0c] = floatx80_e, /* e */ + [0x0d] = floatx80_log2e, /* Log2(e) */ [0x0e] = { .high = 0x3ffd, .low = 0xde5bd8a937287195ULL }, /* Log10(e) */ [0x0f] = floatx80_zero, /* Zero */ @@ -1255,6 +1255,40 @@ void HELPER(sqrt_FP0)(CPUState *env) floatx80_to_FP0(env, res); } +void HELPER(ln_FP0)(CPUState *env) +{ + float64 f, log2; + floatx80 res; + + /* ln(x) = log2(x) / log2(e) */ + + DBG_FPU("ln_FP0\n"); + + f = floatx80_to_float64(FP0_to_floatx80(env), &env->fp_status); + + log2 = float64_log2(f, &env->fp_status); + res = floatx80_div(float64_to_floatx80(log2, &env->fp_status), + floatx80_log2e, &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(exp_FP0)(CPUState *env) +{ + floatx80 f; + float32 res; + + /* exp(x) = exp2(x * log2(e)) */ + + DBG_FPU("exp_FP0\n"); + + f = floatx80_mul(FP0_to_floatx80(env), floatx80_log2e, &env->fp_status); + res = float32_exp2(floatx80_to_float32(f, &env->fp_status), + &env->fp_status); + + floatx80_to_FP0(env, float32_to_floatx80(res, &env->fp_status)); +} + void HELPER(abs_FP0)(CPUState *env) { floatx80 res; diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h index f6578ee..53ab1a9 100644 --- a/target-m68k/helpers.h +++ b/target-m68k/helpers.h @@ -65,6 +65,8 @@ DEF_HELPER_2(const_FP0, void, env, i32) DEF_HELPER_1(iround_FP0, void, env) DEF_HELPER_1(itrunc_FP0, void, env) DEF_HELPER_1(sqrt_FP0, void, env) +DEF_HELPER_1(exp_FP0, void, env) +DEF_HELPER_1(ln_FP0, void, env) DEF_HELPER_1(abs_FP0, void, env) DEF_HELPER_1(chs_FP0, void, env) DEF_HELPER_1(getexp_FP0, void, env) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index fb12f3b..1901b1b 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -3641,6 +3641,12 @@ DISAS_INSN(fpu) case 4: case 0x41: case 0x45: /* fsqrt */ gen_helper_sqrt_FP0(cpu_env); break; + case 0x10: /* fetox */ + gen_helper_exp_FP0(cpu_env); + break; + case 0x14: /* flogn */ + gen_helper_ln_FP0(cpu_env); + break; case 0x18: case 0x58: case 0x5c: /* fabs */ gen_helper_abs_FP0(cpu_env); break; diff --git a/tests/m68k/Makefile b/tests/m68k/Makefile index 28a998f..8e90986 100644 --- a/tests/m68k/Makefile +++ b/tests/m68k/Makefile @@ -1,4 +1,4 @@ -TESTS=fmovecr fmove fmovem fsub fdiv fmul fabs fgetexp fscale +TESTS=fmovecr fmove fmovem fsub fdiv fmul fabs fgetexp fscale flogn fetox all: $(TESTS) diff --git a/tests/m68k/fetox.S b/tests/m68k/fetox.S new file mode 100644 index 0000000..302072b --- /dev/null +++ b/tests/m68k/fetox.S @@ -0,0 +1,8 @@ + .include "trap.i" + + .text + .globl _start +_start: + fmove.l #1,%fp0 // 1 + fetox.x %fp0,%fp0 // e + exit 0 diff --git a/tests/m68k/flogn.S b/tests/m68k/flogn.S new file mode 100644 index 0000000..a27835e --- /dev/null +++ b/tests/m68k/flogn.S @@ -0,0 +1,8 @@ + .include "trap.i" + + .text + .globl _start +_start: + fmovecr.x #0x0C,%fp0 // e + flogn.x %fp0,%fp0 // 1 + exit 0 -- 1.7.2.3