Re: [PATCH v4 07/15] ARC: hardware floating point support

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

 



On 3/26/20 4:22 PM, Joseph Myers wrote:
> On Thu, 12 Mar 2020, Vineet Gupta via Libc-alpha wrote:
> 
>> +int
>> +fegetmode (femode_t *modep)
>> +{
>> +  unsigned int fpcr;
>> +
>> +  _FPU_GETCW (fpcr);
>> +  *modep = fpcr >> __FPU_RND_SHIFT;
> 
> The bits to enable exception traps look like dynamic control mode bits to 
> me.  In general fegetmode should only need to mask off bits on 
> architectures where the same register has both control and status bits, 
> not on architectures where those are separate registers and fegetmode / 
> fesetmode can work with the whole control register.

Yeah, looking back into my old dev branch, that is how I did it initially, but
then switched to current implementation to "make get/set mode functions
inter-operate with get/set round" - although there was no inter-calling between
the two. We can go back to that implementation as it seems slightly better in
generated code, but I'm curious if it is wrong too....

>> +int
>> +__fesetround (int round)
>> +{
>> +  unsigned int fpcr;
>> +
>> +  _FPU_GETCW (fpcr);
>> +
>> +  if (__glibc_unlikely (((fpcr >> __FPU_RND_SHIFT) & FE_DOWNWARD) != round))
>> +    {
>> +      fpcr = (fpcr & ~(FE_DOWNWARD << __FPU_RND_SHIFT)) | (round << __FPU_RND_SHIFT);
>> +      _FPU_SETCW (fpcr);
>> +    }
> 
> I don't think the use of __glibc_unlikely is appropriate here.  It's not 
> at all clear to me that the normal fesetround case is setting the rounding 
> mode to the value it already has, as the use of __glibc_unlikely would 
> suggest.

Ok removed.


>> +int
>> +__feupdateenv (const fenv_t *envp)
>> +{
>> +  unsigned int fpcr;
>> +  unsigned int fpsr;
>> +
>> +  _FPU_GETCW (fpcr);
>> +  _FPU_GETS (fpsr);
>> +
>> +  /* rounding mode set to what is in env.  */
>> +  fpcr = envp->__fpcr;
>> +
>> +  /* currently raised exceptions are OR'ed with env.  */
>> +  fpsr |= envp->__fpsr;
> 
> This looks like it wouldn't work for FE_DFL_ENV, which is a valid argument 
> to feupdateenv.

Is following pseudo-code correct for semantics ?

fesetenv(env)

   if FE_DFL_ENV
      fpcr = _FPU_DEFAULT;
      fpsr = _FPU_FPSR_DEFAULT;
   else
      fpcr = envp->__fpcr;
      fpsr = envp->__fpsr;

feupdateenv(env)

   if FE_DFL_ENV
      fpcr = _FPU_DEFAULT;
      fpsr = _FPU_FPSR_DEFAULT;
   else
      fpcr = envp->__fpcr;
      fpsr |= envp->__fpsr;   <-- this is different


>  It looks like we're missing test coverage for feupdateenv 
> (FE_DFL_ENV) (we have coverage for feupdateenv (FE_NOMASK_ENV) and 
> fesetenv (FE_DFL_ENV)).
> 
>> +static inline int
>> +get_rounding_mode (void)
>> +{
>> +#if defined(__ARC_FPU_SP__) ||  defined(__ARC_FPU_DP__)
>> +  unsigned int fpcr;
>> +  _FPU_GETCW (fpcr);
>> +
>> +  return fpcr >> __FPU_RND_SHIFT;
> 
> Both here and in fegetround you're not doing anything to mask off high 
> bits of the control register.  That seems unsafe to me, should future 
> processors add new control bits in the high bits that might sometimes be 
> nonzero.

Yeah we can certainly add masking for future proofing.

In some places I have following:

  if (((fpcr >> __FPU_RND_SHIFT) & FE_DOWNWARD) != round)

So FE_DOWNWARD (0x3) is used as mask, is that OK or would you rather see

  #define __FPU_RND_MASK 0x3
_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/linux-snps-arc



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux