diff options
Diffstat (limited to 'target/ppc/cpu_init.c')
| -rw-r--r-- | target/ppc/cpu_init.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index efcb80d1c2..1253dbf622 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -7270,6 +7270,25 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type) */ set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status); set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status); + /* + * NaN propagation for fused multiply-add: + * if fRA is a NaN return it; otherwise if fRB is a NaN return it; + * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB + * whereas QEMU labels the operands as (a * b) + c. + */ + set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status); + set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status); + /* + * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer + * to return an input NaN if we have one (ie c) rather than generating + * a default NaN + */ + set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status); + set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status); + + /* Default NaN: sign bit clear, set frac msb */ + set_float_default_nan_pattern(0b01000000, &env->fp_status); + set_float_default_nan_pattern(0b01000000, &env->vec_status); for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { ppc_spr_t *spr = &env->spr_cb[i]; |