diff options
Diffstat (limited to 'target')
| -rw-r--r-- | target/alpha/cpu.c | 7 | ||||
| -rw-r--r-- | target/arm/cpu.c | 1 | ||||
| -rw-r--r-- | target/hppa/fpu_helper.c | 11 | ||||
| -rw-r--r-- | target/i386/tcg/fpu_helper.c | 8 | ||||
| -rw-r--r-- | target/mips/fpu_helper.h | 6 | ||||
| -rw-r--r-- | target/mips/msa.c | 9 | ||||
| -rw-r--r-- | target/ppc/cpu_init.c | 3 | ||||
| -rw-r--r-- | target/rx/cpu.c | 8 | ||||
| -rw-r--r-- | target/sh4/cpu.c | 8 | ||||
| -rw-r--r-- | target/tricore/helper.c | 1 |
10 files changed, 62 insertions, 0 deletions
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index e1b898e575..f5dd744987 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -202,6 +202,13 @@ static void alpha_cpu_initfn(Object *obj) set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status); /* Default NaN: sign bit clear, msb frac bit set */ set_float_default_nan_pattern(0b01000000, &env->fp_status); + /* + * TODO: this is incorrect. The Alpha Architecture Handbook version 4 + * section 4.7.7.11 says that we flush to zero for underflow cases, so + * this should be float_ftz_after_rounding to match the + * tininess_after_rounding (which is specified in section 4.7.5). + */ + set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); #if defined(CONFIG_USER_ONLY) env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN; cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 32dc7c1e69..8037744300 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -185,6 +185,7 @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, static void arm_set_default_fp_behaviours(float_status *s) { set_float_detect_tininess(float_tininess_before_rounding, s); + set_float_ftz_detection(float_ftz_before_rounding, s); set_float_2nan_prop_rule(float_2nan_prop_s_ab, s); set_float_3nan_prop_rule(float_3nan_prop_s_cab, s); set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s); diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c index 239c027ec5..8ff4b44804 100644 --- a/target/hppa/fpu_helper.c +++ b/target/hppa/fpu_helper.c @@ -67,6 +67,17 @@ void HELPER(loaded_fr0)(CPUHPPAState *env) set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status); /* Default NaN: sign bit clear, msb-1 frac bit set */ set_float_default_nan_pattern(0b00100000, &env->fp_status); + /* + * "PA-RISC 2.0 Architecture" says it is IMPDEF whether the flushing + * enabled by FPSR.D happens before or after rounding. We pick "before" + * for consistency with tininess detection. + */ + set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); + /* + * TODO: "PA-RISC 2.0 Architecture" chapter 10 says that we should + * detect tininess before rounding, but we don't set that here so we + * get the default tininess after rounding. + */ } void cpu_hppa_loaded_fr0(CPUHPPAState *env) diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c index de6d0b252e..f112c6c673 100644 --- a/target/i386/tcg/fpu_helper.c +++ b/target/i386/tcg/fpu_helper.c @@ -188,6 +188,14 @@ void cpu_init_fp_statuses(CPUX86State *env) set_float_default_nan_pattern(0b11000000, &env->fp_status); set_float_default_nan_pattern(0b11000000, &env->mmx_status); set_float_default_nan_pattern(0b11000000, &env->sse_status); + /* + * TODO: x86 does flush-to-zero detection after rounding (the SDM + * section 10.2.3.3 on the FTZ bit of MXCSR says that we flush + * when we detect underflow, which x86 does after rounding). + */ + set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); + set_float_ftz_detection(float_ftz_before_rounding, &env->mmx_status); + set_float_ftz_detection(float_ftz_before_rounding, &env->sse_status); } static inline uint8_t save_exception_flags(CPUX86State *env) diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h index 6ad1e466cf..08fb409390 100644 --- a/target/mips/fpu_helper.h +++ b/target/mips/fpu_helper.h @@ -84,6 +84,12 @@ static inline void fp_reset(CPUMIPSState *env) */ set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->active_fpu.fp_status); + /* + * TODO: the spec does't say clearly whether FTZ happens before + * or after rounding for normal FPU operations. + */ + set_float_ftz_detection(float_ftz_before_rounding, + &env->active_fpu.fp_status); } /* MSA */ diff --git a/target/mips/msa.c b/target/mips/msa.c index fc77bfc7b9..32c6acbcc5 100644 --- a/target/mips/msa.c +++ b/target/mips/msa.c @@ -48,6 +48,15 @@ void msa_reset(CPUMIPSState *env) /* tininess detected after rounding.*/ set_float_detect_tininess(float_tininess_after_rounding, &env->active_tc.msa_fp_status); + /* + * MSACSR.FS detects tiny results to flush to zero before rounding + * (per "MIPS Architecture for Programmers Volume IV-j: The MIPS64 SIMD + * Architecture Module, Revision 1.1" section 3.5.4), even though it + * detects tininess after rounding for underflow purposes (section 3.4.2 + * table 3.3). + */ + set_float_ftz_detection(float_ftz_before_rounding, + &env->active_tc.msa_fp_status); /* * According to MIPS specifications, if one of the two operands is diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 8e49051254..062a6e85fb 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -7262,6 +7262,9 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type) /* tininess for underflow is detected before rounding */ set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status); + /* Similarly for flush-to-zero */ + set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); + /* * PowerPC propagation rules: * 1. A if it sNaN or qNaN diff --git a/target/rx/cpu.c b/target/rx/cpu.c index 8c50c7a1bc..37a6fdd569 100644 --- a/target/rx/cpu.c +++ b/target/rx/cpu.c @@ -103,6 +103,14 @@ static void rx_cpu_reset_hold(Object *obj, ResetType type) set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status); /* Default NaN value: sign bit clear, set frac msb */ set_float_default_nan_pattern(0b01000000, &env->fp_status); + /* + * TODO: "RX Family RXv1 Instruction Set Architecture" is not 100% clear + * on whether flush-to-zero should happen before or after rounding, but + * section 1.3.2 says that it happens when underflow is detected, and + * implies that underflow is detected after rounding. So this may not + * be the correct setting. + */ + set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); } static ObjectClass *rx_cpu_class_by_name(const char *cpu_model) diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index 24a22724c6..4ac693d99b 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -130,6 +130,14 @@ static void superh_cpu_reset_hold(Object *obj, ResetType type) set_default_nan_mode(1, &env->fp_status); /* sign bit clear, set all frac bits other than msb */ set_float_default_nan_pattern(0b00111111, &env->fp_status); + /* + * TODO: "SH-4 CPU Core Architecture ADCS 7182230F" doesn't say whether + * it detects tininess before or after rounding. Section 6.4 is clear + * that flush-to-zero happens when the result underflows, though, so + * either this should be "detect ftz after rounding" or else we should + * be setting "detect tininess before rounding". + */ + set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); } static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) diff --git a/target/tricore/helper.c b/target/tricore/helper.c index e8b0ec5161..9898752eb0 100644 --- a/target/tricore/helper.c +++ b/target/tricore/helper.c @@ -116,6 +116,7 @@ void fpu_set_state(CPUTriCoreState *env) set_flush_inputs_to_zero(1, &env->fp_status); set_flush_to_zero(1, &env->fp_status); set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status); + set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); set_default_nan_mode(1, &env->fp_status); /* Default NaN pattern: sign bit clear, frac msb set */ set_float_default_nan_pattern(0b01000000, &env->fp_status); |