e2k: add fstoifs and fdtoifd instrs
This commit is contained in:
parent
3e98a47b0a
commit
1a73a97771
|
@ -112,5 +112,9 @@ DEF_HELPER_2(fdtoistr, i32, env, i64)
|
||||||
DEF_HELPER_2(fxtofs, i32, env, f80)
|
DEF_HELPER_2(fxtofs, i32, env, f80)
|
||||||
DEF_HELPER_2(fxtofd, i64, 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_80
|
||||||
#undef DEF_HELPER_3_32_64
|
#undef DEF_HELPER_3_32_64
|
||||||
|
|
|
@ -235,6 +235,58 @@ uint32_t HELPER(fxcmpudxf)(CPUE2KState *env, floatx80 *x, floatx80 *y)
|
||||||
return HELPER(fxcmpodxf)(env, x, 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 */
|
/* TODO: test if valid, test exception flags */
|
||||||
#if 0
|
#if 0
|
||||||
uint32_t HELPER(frcps)(CPUE2KState *env, uint32_t x)
|
uint32_t HELPER(frcps)(CPUE2KState *env, uint32_t x)
|
||||||
|
|
|
@ -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_FXCMPUDDF: gen_alopf1_sexd(instr, gen_helper_fxcmpudxf); break;
|
||||||
case OP_FXCMPODXF: gen_alopf1_sexx(instr, gen_helper_fxcmpodxf); 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_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_UDIVX:
|
||||||
case OP_UMODX:
|
case OP_UMODX:
|
||||||
case OP_SDIVX:
|
case OP_SDIVX:
|
||||||
|
@ -3295,8 +3297,6 @@ static void gen_op(DisasContext *ctx, Instr *instr)
|
||||||
case OP_MOVXA:
|
case OP_MOVXA:
|
||||||
case OP_MOVXC:
|
case OP_MOVXC:
|
||||||
case OP_PMULUBHH:
|
case OP_PMULUBHH:
|
||||||
case OP_FSTOIFS:
|
|
||||||
case OP_FDTOIFD:
|
|
||||||
case OP_MPSADBH:
|
case OP_MPSADBH:
|
||||||
case OP_PACKUSWH:
|
case OP_PACKUSWH:
|
||||||
case OP_PCMPEQD:
|
case OP_PCMPEQD:
|
||||||
|
|
Loading…
Reference in New Issue