static float32 propagateFloat32NaN( float32 a, float32 b ) { flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; aIsNaN = float32_is_nan( a ); aIsSignalingNaN = float32_is_signaling_nan( a ); bIsNaN = float32_is_nan( b ); bIsSignalingNaN = float32_is_signaling_nan( b ); a |= 0x00400000; b |= 0x00400000; if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); if ( aIsSignalingNaN ) { if ( bIsSignalingNaN ) goto returnLargerSignificand; return bIsNaN ? b : a; } else if ( aIsNaN ) { if ( bIsSignalingNaN | ! bIsNaN ) return a; returnLargerSignificand: if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b; if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a; return ( a < b ) ? a : b; } else { return b; } }
uint32_t helper_fcmp_un(uint32_t a, uint32_t b) { CPU_FloatU fa, fb; uint32_t r = 0; fa.l = a; fb.l = b; if (float32_is_signaling_nan(fa.f) || float32_is_signaling_nan(fb.f)) { update_fpu_flags(float_flag_invalid); r = 1; } if (float32_is_quiet_nan(fa.f) || float32_is_quiet_nan(fb.f)) { r = 1; } return r; }
uint32_t helper_fcmp_un(CPUMBState *env, uint32_t a, uint32_t b) { CPU_FloatU fa, fb; uint32_t r = 0; fa.l = a; fb.l = b; if (float32_is_signaling_nan(fa.f, &env->fp_status) || float32_is_signaling_nan(fb.f, &env->fp_status)) { update_fpu_flags(env, float_flag_invalid); r = 1; } if (float32_is_quiet_nan(fa.f, &env->fp_status) || float32_is_quiet_nan(fb.f, &env->fp_status)) { r = 1; } return r; }
/* test data class 32-bit */ uint32_t HELPER(tceb)(CPUS390XState *env, uint32_t f1, uint64_t m2) { float32 v1 = env->fregs[f1].l.upper; int neg = float32_is_neg(v1); uint32_t cc = 0; HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg); if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) || (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) || (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) || (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) { cc = 1; } else if (m2 & (1 << (9-neg))) { /* assume normalized number */ cc = 1; } /* FIXME: denormalized? */ return cc; }