Could you please elaborate more on how do you think using
float*_compare and its FloatRelation result would work here?
I noticed do_scalar_cmp modifies CR and sets FPCC flag, which
is not what VSX_SCALAR_CMP do. Using that function would require a
rework.
An option I though would be to bring into VSX_SCALAR_CMP the
important necessary parts, something like this:
#define VSX_SCALAR_CMP(op, tp, cmp, fld, svxvc, expr) ...
r = tp##_compare(xa->fld, xb->fld, &env->fp_status); \
if (expr) { \
memset(&t.fld, 0xFF, sizeof(t.fld)); \
} else if (r == float_relation_unordered) { \
if (env->fp_status.float_exception_flags & float_flag_invalid_snan) { \
float_invalid_op_vxsnan(env, GETPC()); \
if (fpscr_ve == 0 && svxvc) { \
float_invalid_op_vxvc(env, 0, GETPC()); \
} \
} else if (svxvc) { \
if (tp##_is_quiet_nan(xa->fld, &env->fp_status) || \
tp##_is_quiet_nan(xb->fld, &env->fp_status)) { \
float_invalid_op_vxvc(env, 0, GETPC()); \
} \
} \
} \
...
VSX_SCALAR_CMP(XSCMPEQDP, float64, eq, VsrD(0), 0, r == float_relation_equal)
VSX_SCALAR_CMP(XSCMPGEDP, float64, le, VsrD(0), 1, \
r == float_relation_equal || r == float_relation_greater)
VSX_SCALAR_CMP(XSCMPGTDP, float64, lt, VsrD(0), 1, r == float_relation_greater)