qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v4 38/47] target/ppc: Refactor VSX_SCALAR_CMP_DP


From: Richard Henderson
Subject: Re: [PATCH v4 38/47] target/ppc: Refactor VSX_SCALAR_CMP_DP
Date: Thu, 24 Feb 2022 11:24:53 -1000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

On 2/24/22 09:16, Víctor Colombo wrote:
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)

I was thinking along the lines of:

    bool r;
    int flags;

    helper_reset_fpstatus(env);
    if (svxvc) {
        r = tp##cmp(...);
    } else {
        r = tp##cmp##_quiet(...);
    }

    flags = get_float_exception_flags(&env->fp_status);
    if (unlikely(flags & float_flag_invalid)) {
        bool vxvc = svxvc;
        if (flags & float_flag_invalid_snan)) {
            float_invalid_op_vxsnan(...);
            vxvc &= fpscr_ve == 0;
        }
        if (vxvc) {
            float_invalid_op_vxvc(...);
        }
    }

    memset(xt, 0, sizeof(*xt));
    memset(&xt->fld, -r, sizeof(xt->fld));
    do_float_check_status(...);


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]