From 1a73a977714cbbe13c1ff87180423fea27c21fcd Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 15 Jan 2021 06:56:29 +0300 Subject: [PATCH] e2k: add fstoifs and fdtoifd instrs --- target/e2k/helper.h | 4 +++ target/e2k/helper_fpu.c | 52 ++++++++++++++++++++++++++++++++++++++ target/e2k/translate/alc.c | 4 +-- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/target/e2k/helper.h b/target/e2k/helper.h index 7c01264f92..fe2a793153 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -112,5 +112,9 @@ DEF_HELPER_2(fdtoistr, i32, env, i64) DEF_HELPER_2(fxtofs, i32, env, f80) DEF_HELPER_2(fxtofd, i64, env, f80) +/* Float Rounding */ +DEF_HELPER_3(fstoifs, i32, env, i32, i32) +DEF_HELPER_3(fdtoifd, i64, env, i64, i64) + #undef DEF_HELPER_3_32_64_80 #undef DEF_HELPER_3_32_64 diff --git a/target/e2k/helper_fpu.c b/target/e2k/helper_fpu.c index e4b9ebf030..b4112b4d71 100644 --- a/target/e2k/helper_fpu.c +++ b/target/e2k/helper_fpu.c @@ -235,6 +235,58 @@ uint32_t HELPER(fxcmpudxf)(CPUE2KState *env, floatx80 *x, floatx80 *y) return HELPER(fxcmpodxf)(env, x, y); } +#define TOIF_RC_CURRENT 0x4 +#define TOIF_RC_IGNORE_INEXACT 0x8 + +static inline void toif_set_round_mode(CPUE2KState *env, uint32_t flags) +{ + if(flags <= FPCR_RC_CHOP) { + FloatRoundMode rm; + switch(flags) { + case FPCR_RC_NEAR: rm = float_round_nearest_even; break; + case FPCR_RC_DOWN: rm = float_round_down; break; + case FPCR_RC_UP: rm = float_round_up; break; + case FPCR_RC_CHOP: rm = float_round_to_zero; break; + } + set_float_rounding_mode(rm, &env->fp_status); + } +} + +static inline void toif_clear_inexact(CPUE2KState *env, uint32_t flags) +{ + if(flags & TOIF_RC_IGNORE_INEXACT) { + int new_flags = get_float_exception_flags(&env->fp_status); + new_flags = new_flags & (~float_flag_inexact); + set_float_exception_flags(new_flags, &env->fp_status); + } +} + +uint32_t HELPER(fstoifs)(CPUE2KState *env, uint32_t flags, uint32_t f) +{ + int old_flags = save_exception_flags(env); + FloatRoundMode oldrm = get_float_rounding_mode(&env->fp_status); + uint32_t ret; + toif_set_round_mode(env, flags); + ret = float32_val(float32_round_to_int(make_float32(f), &env->fp_status)); + set_float_rounding_mode(oldrm, &env->fp_status); + toif_clear_inexact(env, flags); + merge_exception_flags(env, old_flags); + return ret; +} + +uint64_t HELPER(fdtoifd)(CPUE2KState *env, uint64_t flags, uint64_t f) +{ + int old_flags = save_exception_flags(env); + FloatRoundMode oldrm = get_float_rounding_mode(&env->fp_status); + uint64_t ret; + toif_set_round_mode(env, flags); + ret = float64_val(float64_round_to_int(make_float64(f), &env->fp_status)); + set_float_rounding_mode(oldrm, &env->fp_status); + toif_clear_inexact(env, flags); + merge_exception_flags(env, old_flags); + return ret; +} + /* TODO: test if valid, test exception flags */ #if 0 uint32_t HELPER(frcps)(CPUE2KState *env, uint32_t x) diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index fb29b8037c..bd9e0dc74b 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -2992,6 +2992,8 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_FXCMPUDDF: gen_alopf1_sexd(instr, gen_helper_fxcmpudxf); break; case OP_FXCMPODXF: gen_alopf1_sexx(instr, gen_helper_fxcmpodxf); break; case OP_FXCMPUDXF: gen_alopf1_sexx(instr, gen_helper_fxcmpudxf); break; + case OP_FSTOIFS: gen_alopf1_sess(instr, gen_helper_fstoifs); break; + case OP_FDTOIFD: gen_alopf1_dedd(instr, gen_helper_fdtoifd); break; case OP_UDIVX: case OP_UMODX: case OP_SDIVX: @@ -3295,8 +3297,6 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_MOVXA: case OP_MOVXC: case OP_PMULUBHH: - case OP_FSTOIFS: - case OP_FDTOIFD: case OP_MPSADBH: case OP_PACKUSWH: case OP_PCMPEQD: