All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Víctor Colombo" <victor.colombo@eldorado.org.br>
To: Rashmica Gupta <rashmica.g@gmail.com>,
	qemu-devel@nongnu.org, qemu-ppc@nongnu.org
Cc: clg@kaod.org, danielhb413@gmail.com, david@gibson.dropbear.id.au,
	groug@kaod.org, richard.henderson@linaro.org,
	Nicholas Piggin <npiggin@gmail.com>,
	Paul Mackerras <paulus@samba.org>
Subject: Re: [PATCH v2 1/3] target/ppc: Fix FPSCR.FI bit being cleared when it shouldn't
Date: Wed, 11 May 2022 15:29:02 -0300	[thread overview]
Message-ID: <276e357e-a757-7d03-3a70-c23dd52dbe53@eldorado.org.br> (raw)
In-Reply-To: <244b0614581cbec66f6cf87dd13f806af036b769.camel@gmail.com>

Hello!

Thanks everyone for your kind reviews

On 11/05/2022 07:12, Rashmica Gupta wrote:
> Hello,
> 
> cc'ing Paul and Nick for clarification on the behaviour of xsrsp (see below)
> 
> 
> On Tue, 2022-05-10 at 17:46 -0300, Víctor Colombo wrote:
>> The FI bit in FPSCR is said to be a non-sticky bit on Power ISA.
>> One could think this means that, if an instruction is said to modify
>> the FPSCR register, the bit FI should be cleared. This is what QEMU
>> does today.
>>
>> However, the following inconsistency was found when comparing results
>> from the hardware (tested on both a Power 9 processor and in
>> Power 10 Mambo):
>>
>> (FI bit is set before the execution of the instruction)
>> Hardware: xscmpeqdp(0xff..ff, 0xff..ff) = FI: SET -> SET
>> QEMU: xscmpeqdp(0xff..ff, 0xff..ff) = FI: SET -> CLEARED
>>
>> This is happening to multiple instructions in the vsx
>> implementations. As the FI bit is non-sticky, one could think that
>> xscmpeqdp, a instruction the ISA states doesn't change FI bit, should
>> result in a cleared FI. However, this is not happening on hardware.
> I would think that if an instruction doesn't change a bit
> then that instruction wouldn't clear or set that bit, regardless of if
> that bit is sticky or not.

I think I might have over-generalized this commit message.
I, as well as other developers of the Power ISA instructions in
QEMU, didn't notice this behavior before, so it's at least confusing
> 
>> An investigation resulted in the following conclusion:
>> If the ISA does not list the FI bit as altered for a particular
>> instruction, then it should be kept as it was before the instruction.
>>
>> QEMU is not following this behavior. Affected instructions include:
>> - xv* (all vsx-vector instructions);
>> - xscmp*, xsmax*, xsmin*;
>> - xstdivdp and similars;
>> (to identify the affected instructions, just search in the ISA for
>>   the instructions that does not list FI in "Special Registers
>> Altered")
> The ISA does state
> "Floating-Point Fraction Inexact (FI)
> This bit is set to 0 or 1 by VSX Scalar
> Floating-Point Arithmetic, VSX Scalar Integer
> Conversion, and VSX Scalar Round to
> Floating-Point Integer class instructions to
> indicate whether or not the rounded result is
> inexact or the instruction caused a disabled
> Overflow exception. See Section 7.3.2.6 on
> page 524. This bit is not sticky."
> 
> So it seems that instruction classes like VSX Vector Round and VSX Vector
> convert don't touch the FI bit.
> 
>> Most instructions use the function do_float_check_status() to commit
>> changes in the inexact flag. So the fix is to add a parameter to it
>> that will control if the bit FI should be changed or not.
>> All users of do_float_check_status() are then modified to provide
>> this
>> argument, controlling if that specific instruction changes bit FI or
>> not.
>> Some macro helpers are responsible for both instructions that change
>> and instructions that aren't suposed to change FI. This seems to
>> always
>> overlap with the sfprf flag. So, reuse this flag for this purpose
>> when
>> applicable.
>>
>> Signed-off-by: Víctor Colombo<victor.colombo@eldorado.org.br>
>>
>> ---
>>
>> v2:
>> - move the FI change from float_inexact_excp to do_float_check_status
>> - sfprf will be renamed to sfifprf in another patch, as suggested by
>>    Richard
>> ---
>>   target/ppc/cpu.h        |   2 +
>>   target/ppc/fpu_helper.c | 122 +++++++++++++++++++++-----------------
>> --
>>   2 files changed, 66 insertions(+), 58 deletions(-)
>>
>> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
>> index 48596cfb25..901ded79e9 100644
>> --- a/target/ppc/cpu.h
>> +++ b/target/ppc/cpu.h
>> @@ -735,6 +735,8 @@ enum {
>>                         (1 << FPSCR_VXSOFT) | (1 << FPSCR_VXSQRT) | \
>>                         (1 << FPSCR_VXCVI))
>>   
>> +FIELD(FPSCR, FI, FPSCR_FI, 1)
>> +
>>   #define FP_DRN2         (1ull << FPSCR_DRN2)
>>   #define FP_DRN1         (1ull << FPSCR_DRN1)
>>   #define FP_DRN0         (1ull << FPSCR_DRN0)
>> diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
>> index f6c8318a71..f1ea4aa10e 100644
>> --- a/target/ppc/fpu_helper.c
>> +++ b/target/ppc/fpu_helper.c
>> @@ -370,7 +370,6 @@ static inline void float_inexact_excp(CPUPPCState
>> *env)
>>   {
>>       CPUState *cs = env_cpu(env);
>>   
>> -    env->fpscr |= FP_FI;
>>       env->fpscr |= FP_XX;
>>       /* Update the floating-point exception summary */
>>       env->fpscr |= FP_FX;
>> @@ -462,7 +461,8 @@ void helper_fpscr_check_status(CPUPPCState *env)
>>       }
>>   }
>>   
>> -static void do_float_check_status(CPUPPCState *env, uintptr_t raddr)
>> +static void do_float_check_status(CPUPPCState *env, bool change_fi,
>> +                                  uintptr_t raddr)
>>   {
>>       CPUState *cs = env_cpu(env);
>>       int status = get_float_exception_flags(&env->fp_status);
>> @@ -474,8 +474,10 @@ static void do_float_check_status(CPUPPCState
>> *env, uintptr_t raddr)
>>       }
>>       if (status & float_flag_inexact) {
>>           float_inexact_excp(env);
>> -    } else {
>> -        env->fpscr &= ~FP_FI; /* clear the FPSCR[FI] bit */
>> +    }
>> +    if (change_fi) {
>> +        env->fpscr = FIELD_DP64(env->fpscr, FPSCR, FI,
>> +                                !!(status & float_flag_inexact));
>>       }
> 
> According to the ISA not all instructions that affect FI, set FI on an
> inexact exception (xsrqpi apparently clears FI on an inexact exception
> -- I have no idea if this actually happens on hardware).

good point,

xsrqpi is handled as it was before already: the inexact flag is being
cleared for fp_status in helper_xsrqpi, causing do_float_check_status to
clear it for fpscr.

I think we should keep it like this. The change I made to
do_float_check_status allow for its callers to request if the FI field
in FPSCR should be updated. What value should be updated to is then
responsibility of these callers, provided as an argument to
do_float_check_status, like xsrqpi is doing.

> 
> 
>>   
>>       if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
>> @@ -490,7 +492,7 @@ static void do_float_check_status(CPUPPCState
>> *env, uintptr_t raddr)
>>   
>>   void helper_float_check_status(CPUPPCState *env)
>>   {
>> -    do_float_check_status(env, GETPC());
>> +    do_float_check_status(env, true, GETPC());
>>   }
>>   
>      
> ... snip ...
> 
>> @@ -3195,7 +3201,7 @@ uint64_t helper_xsrsp(CPUPPCState *env,
>> uint64_t xb)
>>       uint64_t xt = do_frsp(env, xb, GETPC());
>>   
>>       helper_compute_fprf_float64(env, xt);
>> -    do_float_check_status(env, GETPC());
>> +    do_float_check_status(env, true, GETPC());
>>       return xt;
>>   }
> I'm not clear what the behaviour of xsrsp should be.
> 
> Section 7.4.5 Floating-Point Inexact Exception leads me to think it
> shouldn't affect FI but the instruction definition indicates the
> opposite. Maybe Paul or Nick can weigh in on this?
> 

I tested on a Power9 hardware and FI is altered by xsrsp when XE=0.
But indeed, the ISA seems a bit contradictory on this one, section
7.4.5 only states about changing XX in this situation.

> 
>>   
>> @@ -3355,7 +3361,7 @@ void helper_xsrqpi(CPUPPCState *env, uint32_t
>> opcode,
>>       }
>>   
>>       helper_compute_fprf_float128(env, t.f128);
>> -    do_float_check_status(env, GETPC());
>> +    do_float_check_status(env, true, GETPC());
>>       *xt = t;
>>   }
>>   
>> @@ -3408,7 +3414,7 @@ void helper_xsrqpxp(CPUPPCState *env, uint32_t
>> opcode,
>>   
>>       helper_compute_fprf_float128(env, t.f128);
>>       *xt = t;
>> -    do_float_check_status(env, GETPC());
>> +    do_float_check_status(env, true, GETPC());
>>   }
>>   
>>   void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode,
>> @@ -3434,7 +3440,7 @@ void helper_xssqrtqp(CPUPPCState *env, uint32_t
>> opcode,
>>   
>>       helper_compute_fprf_float128(env, t.f128);
>>       *xt = t;
>> -    do_float_check_status(env, GETPC());
>> +    do_float_check_status(env, true, GETPC());
>>   }
>>   
>>   void helper_xssubqp(CPUPPCState *env, uint32_t opcode,
>> @@ -3460,5 +3466,5 @@ void helper_xssubqp(CPUPPCState *env, uint32_t
>> opcode,
>>   
>>       helper_compute_fprf_float128(env, t.f128);
>>       *xt = t;
>> -    do_float_check_status(env, GETPC());
>> +    do_float_check_status(env, true, GETPC());
>>   }
> 
> All the other instruction helpers and definitions look correct to me.

Thank you very much!

--
Víctor Cora Colombo
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>


  reply	other threads:[~2022-05-11 18:31 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-10 20:46 [PATCH v2 0/3] target/ppc: Fix FPSCR.FI bit Víctor Colombo
2022-05-10 20:46 ` [PATCH v2 1/3] target/ppc: Fix FPSCR.FI bit being cleared when it shouldn't Víctor Colombo
2022-05-10 23:56   ` Richard Henderson
2022-05-11 10:12   ` Rashmica Gupta
2022-05-11 18:29     ` Víctor Colombo [this message]
2022-05-10 20:46 ` [PATCH v2 2/3] target/ppc: Fix FPSCR.FI changing in float_overflow_excp() Víctor Colombo
2022-05-10 23:58   ` Richard Henderson
2022-05-11 10:12   ` Rashmica Gupta
2022-05-10 20:46 ` [PATCH v2 3/3] target/ppc: Rename sfprf to sfifprf where it's also used as set fi flag Víctor Colombo
2022-05-10 23:58   ` Richard Henderson
2022-05-11 10:12   ` Rashmica Gupta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=276e357e-a757-7d03-3a70-c23dd52dbe53@eldorado.org.br \
    --to=victor.colombo@eldorado.org.br \
    --cc=clg@kaod.org \
    --cc=danielhb413@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=groug@kaod.org \
    --cc=npiggin@gmail.com \
    --cc=paulus@samba.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=rashmica.g@gmail.com \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.