e2k: add fstoifs and fdtoifd instrs

This commit is contained in:
Alibek Omarov 2021-01-15 06:56:29 +03:00 committed by Denis Drakhnia
parent 3e98a47b0a
commit 1a73a97771
3 changed files with 58 additions and 2 deletions

View File

@ -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

View File

@ -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)

View File

@ -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: