diff options
Diffstat (limited to 'target/mips')
| -rw-r--r-- | target/mips/cpu.c | 2 | ||||
| -rw-r--r-- | target/mips/fpu_helper.h | 20 | ||||
| -rw-r--r-- | target/mips/msa.c | 10 |
3 files changed, 31 insertions, 1 deletions
diff --git a/target/mips/cpu.c b/target/mips/cpu.c index d0a43b6d5c..4feacc88c0 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -626,7 +626,7 @@ static void mips_register_cpudef_type(const struct mips_def_t *def) .class_data = (void *)def, }; - type_register(&ti); + type_register_static(&ti); g_free(typename); } diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h index 7c3c7897b4..6ad1e466cf 100644 --- a/target/mips/fpu_helper.h +++ b/target/mips/fpu_helper.h @@ -28,6 +28,8 @@ static inline void restore_flush_mode(CPUMIPSState *env) static inline void restore_snan_bit_mode(CPUMIPSState *env) { bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008); + FloatInfZeroNaNRule izn_rule; + Float3NaNPropRule nan3_rule; /* * With nan2008, SNaNs are silenced in the usual way. @@ -35,6 +37,24 @@ static inline void restore_snan_bit_mode(CPUMIPSState *env) */ set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status); set_default_nan_mode(!nan2008, &env->active_fpu.fp_status); + /* + * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan) + * case sets InvalidOp and returns the default NaN. + * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan) + * case sets InvalidOp and returns the input value 'c'. + */ + izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always; + set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status); + nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc; + set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status); + /* + * With nan2008, the default NaN value has the sign bit clear and the + * frac msb set; with the older mode, the sign bit is clear, and all + * frac bits except the msb are set. + */ + set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111, + &env->active_fpu.fp_status); + } static inline void restore_fp_status(CPUMIPSState *env) diff --git a/target/mips/msa.c b/target/mips/msa.c index 9dffc428f5..fc77bfc7b9 100644 --- a/target/mips/msa.c +++ b/target/mips/msa.c @@ -66,6 +66,9 @@ void msa_reset(CPUMIPSState *env) set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->active_tc.msa_fp_status); + set_float_3nan_prop_rule(float_3nan_prop_s_cab, + &env->active_tc.msa_fp_status); + /* clear float_status exception flags */ set_float_exception_flags(0, &env->active_tc.msa_fp_status); @@ -74,4 +77,11 @@ void msa_reset(CPUMIPSState *env) /* set proper signanling bit meaning ("1" means "quiet") */ set_snan_bit_is_one(0, &env->active_tc.msa_fp_status); + + /* Inf * 0 + NaN returns the input NaN */ + set_float_infzeronan_rule(float_infzeronan_dnan_never, + &env->active_tc.msa_fp_status); + /* Default NaN: sign bit clear, frac msb set */ + set_float_default_nan_pattern(0b01000000, + &env->active_tc.msa_fp_status); } |