diff options
Diffstat (limited to 'target-alpha')
-rw-r--r-- | target-alpha/cpu.h | 1 | ||||
-rw-r--r-- | target-alpha/fpu_helper.c | 44 | ||||
-rw-r--r-- | target-alpha/helper.c | 8 | ||||
-rw-r--r-- | target-alpha/helper.h | 5 | ||||
-rw-r--r-- | target-alpha/translate.c | 18 |
5 files changed, 26 insertions, 50 deletions
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index c7787f6007..6c5d28bae1 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -234,7 +234,6 @@ struct CPUAlphaState { uint8_t fpcr_exc_mask; uint8_t fpcr_dyn_round; uint8_t fpcr_flush_to_zero; - uint8_t fpcr_dnz; uint8_t fpcr_dnod; uint8_t fpcr_undz; diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c index d38521b6d8..dda110352e 100644 --- a/target-alpha/fpu_helper.c +++ b/target-alpha/fpu_helper.c @@ -88,21 +88,17 @@ void helper_fp_exc_raise_s(CPUAlphaState *env, uint32_t exc, uint32_t regno) } } -/* Input remapping without software completion. Handle denormal-map-to-zero - and trap for all other non-finite numbers. */ -uint64_t helper_ieee_input(CPUAlphaState *env, uint64_t val) +/* Input handing without software completion. Trap for all + non-finite numbers. */ +void helper_ieee_input(CPUAlphaState *env, uint64_t val) { uint32_t exp = (uint32_t)(val >> 52) & 0x7ff; uint64_t frac = val & 0xfffffffffffffull; if (exp == 0) { - if (frac != 0) { - /* If DNZ is set flush denormals to zero on input. */ - if (env->fpcr_dnz) { - val &= 1ull << 63; - } else { - arith_excp(env, GETPC(), EXC_M_UNF, 0); - } + /* Denormals without DNZ set raise an exception. */ + if (frac != 0 && !env->fp_status.flush_inputs_to_zero) { + arith_excp(env, GETPC(), EXC_M_UNF, 0); } } else if (exp == 0x7ff) { /* Infinity or NaN. */ @@ -111,43 +107,23 @@ uint64_t helper_ieee_input(CPUAlphaState *env, uint64_t val) just emulates the insn to figure out what exception to use. */ arith_excp(env, GETPC(), frac ? EXC_M_INV : EXC_M_FOV, 0); } - return val; } /* Similar, but does not trap for infinities. Used for comparisons. */ -uint64_t helper_ieee_input_cmp(CPUAlphaState *env, uint64_t val) +void helper_ieee_input_cmp(CPUAlphaState *env, uint64_t val) { uint32_t exp = (uint32_t)(val >> 52) & 0x7ff; uint64_t frac = val & 0xfffffffffffffull; if (exp == 0) { - if (frac != 0) { - /* If DNZ is set flush denormals to zero on input. */ - if (env->fpcr_dnz) { - val &= 1ull << 63; - } else { - arith_excp(env, GETPC(), EXC_M_UNF, 0); - } + /* Denormals without DNZ set raise an exception. */ + if (frac != 0 && !env->fp_status.flush_inputs_to_zero) { + arith_excp(env, GETPC(), EXC_M_UNF, 0); } } else if (exp == 0x7ff && frac) { /* NaN. */ arith_excp(env, GETPC(), EXC_M_INV, 0); } - return val; -} - -/* Input remapping with software completion enabled. All we have to do - is handle denormal-map-to-zero; all other inputs get exceptions as - needed from the actual operation. */ -uint64_t helper_ieee_input_s(CPUAlphaState *env, uint64_t val) -{ - if (env->fpcr_dnz) { - uint32_t exp = (uint32_t)(val >> 52) & 0x7ff; - if (exp == 0) { - val &= 1ull << 63; - } - } - return val; } /* F floating (VAX) */ diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 3333bfa1b9..765e650002 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -82,7 +82,7 @@ uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env) break; } - if (env->fpcr_dnz) { + if (env->fp_status.flush_inputs_to_zero) { r |= FPCR_DNZ; } if (env->fpcr_dnod) { @@ -151,12 +151,10 @@ void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val) } env->fpcr_dyn_round = t; - env->fpcr_flush_to_zero - = (val & (FPCR_UNDZ|FPCR_UNFD)) == (FPCR_UNDZ|FPCR_UNFD); - - env->fpcr_dnz = (val & FPCR_DNZ) != 0; env->fpcr_dnod = (val & FPCR_DNOD) != 0; env->fpcr_undz = (val & FPCR_UNDZ) != 0; + env->fpcr_flush_to_zero = env->fpcr_dnod & env->fpcr_undz; + env->fp_status.flush_inputs_to_zero = (val & FPCR_DNZ) != 0; } uint64_t helper_load_fpcr(CPUAlphaState *env) diff --git a/target-alpha/helper.h b/target-alpha/helper.h index 03cc185c83..9f97c5d788 100644 --- a/target-alpha/helper.h +++ b/target-alpha/helper.h @@ -95,9 +95,8 @@ DEF_HELPER_FLAGS_1(fp_exc_get, TCG_CALL_CONST | TCG_CALL_PURE, i32, env) DEF_HELPER_3(fp_exc_raise, void, env, i32, i32) DEF_HELPER_3(fp_exc_raise_s, void, env, i32, i32) -DEF_HELPER_2(ieee_input, i64, env, i64) -DEF_HELPER_2(ieee_input_cmp, i64, env, i64) -DEF_HELPER_2(ieee_input_s, i64, env, i64) +DEF_HELPER_2(ieee_input, void, env, i64) +DEF_HELPER_2(ieee_input_cmp, void, env, i64) #if !defined (CONFIG_USER_ONLY) DEF_HELPER_2(hw_ret, void, env, i64) diff --git a/target-alpha/translate.c b/target-alpha/translate.c index dd09ad8bfe..1f4565d794 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -661,15 +661,19 @@ static void gen_qual_flushzero(DisasContext *ctx, int fn11) static TCGv gen_ieee_input(int reg, int fn11, int is_cmp) { - TCGv val = tcg_temp_new(); + TCGv val; if (reg == 31) { - tcg_gen_movi_i64(val, 0); - } else if (fn11 & QUAL_S) { - gen_helper_ieee_input_s(val, cpu_env, cpu_fir[reg]); - } else if (is_cmp) { - gen_helper_ieee_input_cmp(val, cpu_env, cpu_fir[reg]); + val = tcg_const_i64(0); } else { - gen_helper_ieee_input(val, cpu_env, cpu_fir[reg]); + if ((fn11 & QUAL_S) == 0) { + if (is_cmp) { + gen_helper_ieee_input_cmp(cpu_env, cpu_fir[reg]); + } else { + gen_helper_ieee_input(cpu_env, cpu_fir[reg]); + } + } + val = tcg_temp_new(); + tcg_gen_mov_i64(val, cpu_fir[reg]); } return val; } |