qemu-ppc
[Top][All Lists]
Advanced

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

Re: [PATCH v3 1/3] target/ppc: Fixed call to deferred exception


From: David Gibson
Subject: Re: [PATCH v3 1/3] target/ppc: Fixed call to deferred exception
Date: Thu, 25 Nov 2021 13:59:57 +1100

On Thu, Nov 25, 2021 at 01:49:46AM +0100, BALATON Zoltan wrote:
> On Wed, 24 Nov 2021, Lucas Mateus Castro (alqotel) wrote:
> > mtfsf, mtfsfi and mtfsb1 instructions call helper_float_check_status
> > after updating the value of FPSCR, but helper_float_check_status
> > checks fp_status and fp_status isn't updated based on FPSCR and
> > since the value of fp_status is reset earlier in the instruction,
> > it's always 0.
> > 
> > Because of this helper_float_check_status would change the FI bit to 0
> > as this bit checks if the last operation was inexact and
> > float_flag_inexact is always 0.
> > 
> > These instructions also don't throw exceptions correctly since
> > helper_float_check_status throw exceptions based on fp_status.
> > 
> > This commit created a new helper, helper_fpscr_check_status that checks
> > FPSCR value instead of fp_status and checks for a larger variety of
> > exceptions than do_float_check_status.
> > 
> > Since fp_status isn't used, gen_reset_fpstatus() was removed.
> > 
> > The hardware used to compare QEMU's behavior to was a Power9.
> > 
> > Signed-off-by: Lucas Mateus Castro (alqotel) <lucas.araujo@eldorado.org.br>
> > ---
> > target/ppc/fpu_helper.c            | 48 ++++++++++++++++++++++++++++++
> > target/ppc/helper.h                |  1 +
> > target/ppc/translate/fp-impl.c.inc |  9 ++----
> > 3 files changed, 52 insertions(+), 6 deletions(-)
> > 
> > diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
> > index c4896cecc8..bb72715827 100644
> > --- a/target/ppc/fpu_helper.c
> > +++ b/target/ppc/fpu_helper.c
> > @@ -414,6 +414,54 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t 
> > val, uint32_t nibbles)
> >     ppc_store_fpscr(env, val);
> > }
> > 
> > +void helper_fpscr_check_status(CPUPPCState *env)
> > +{
> > +    CPUState *cs = env_cpu(env);
> > +    target_ulong fpscr = env->fpscr;
> > +    int error = 0;
> > +
> > +    if ((fpscr & FP_OX) && (fpscr & FP_OE)) {
> > +        error = POWERPC_EXCP_FP_OX;
> > +    } else if ((fpscr & FP_UX) && (fpscr & FP_UE)) {
> > +        error = POWERPC_EXCP_FP_UX;
> > +    } else if ((fpscr & FP_XX) && (fpscr & FP_XE)) {
> > +        error = POWERPC_EXCP_FP_XX;
> > +    } else if ((fpscr & FP_ZX) && (fpscr & FP_ZE)) {
> 
> I wonder if these tests could be simplified by combining the masks if you
> want to test for both bits set so e.g. fpscr & (FP_ZX | FP_ZE) should be the
> same, shouldn't it?

No, it's not.  In fact your version is equivalent as a boolean to
        ((fpscr & FP_ZX) || (fpscr & FP_ZE))

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

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