qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] fpu/softfloat: Replace countLeadingZeros32/64 w


From: Philippe Mathieu-Daudé
Subject: Re: [Qemu-devel] [PATCH] fpu/softfloat: Replace countLeadingZeros32/64 with clz32/64
Date: Wed, 3 Oct 2018 12:03:56 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0

On 28/09/2018 09:01, Thomas Huth wrote:
> Our minimum required compiler for compiling QEMU is GCC 4.1 these days,
> so we can drop the support for compilers which do not provide the
> __builtin_clz*() functions yet. Since the countLeadingZeros32/64 are
> then identical to the clz32/64 functions, and we do not have to sync
> the softloat 2 codebase with upstream anymore (softloat 3 is a complete
> rewrite) we can simply replace the functions with our QEMU versions.
> 
> Suggested-by: Peter Maydell <address@hidden>
> Signed-off-by: Thomas Huth <address@hidden>

Reviewed-by: Philippe Mathieu-Daudé <address@hidden>

> ---
>  fpu/softfloat.c                | 26 ++++++-------
>  include/fpu/softfloat-macros.h | 87 
> ------------------------------------------
>  2 files changed, 13 insertions(+), 100 deletions(-)
> 
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index 8b91cd6..25a8dd9 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -2681,7 +2681,7 @@ static void
>  {
>      int8_t shiftCount;
>  
> -    shiftCount = countLeadingZeros32( aSig ) - 8;
> +    shiftCount = clz32(aSig) - 8;
>      *zSigPtr = aSig<<shiftCount;
>      *zExpPtr = 1 - shiftCount;
>  
> @@ -2789,7 +2789,7 @@ static float32
>  {
>      int8_t shiftCount;
>  
> -    shiftCount = countLeadingZeros32( zSig ) - 1;
> +    shiftCount = clz32(zSig) - 1;
>      return roundAndPackFloat32(zSign, zExp - shiftCount, zSig<<shiftCount,
>                                 status);
>  
> @@ -2822,7 +2822,7 @@ static void
>  {
>      int8_t shiftCount;
>  
> -    shiftCount = countLeadingZeros64( aSig ) - 11;
> +    shiftCount = clz64(aSig) - 11;
>      *zSigPtr = aSig<<shiftCount;
>      *zExpPtr = 1 - shiftCount;
>  
> @@ -2960,7 +2960,7 @@ static float64
>  {
>      int8_t shiftCount;
>  
> -    shiftCount = countLeadingZeros64( zSig ) - 1;
> +    shiftCount = clz64(zSig) - 1;
>      return roundAndPackFloat64(zSign, zExp - shiftCount, zSig<<shiftCount,
>                                 status);
>  
> @@ -2978,7 +2978,7 @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t 
> *zExpPtr,
>  {
>      int8_t shiftCount;
>  
> -    shiftCount = countLeadingZeros64( aSig );
> +    shiftCount = clz64(aSig);
>      *zSigPtr = aSig<<shiftCount;
>      *zExpPtr = 1 - shiftCount;
>  }
> @@ -3217,7 +3217,7 @@ floatx80 normalizeRoundAndPackFloatx80(int8_t 
> roundingPrecision,
>          zSig1 = 0;
>          zExp -= 64;
>      }
> -    shiftCount = countLeadingZeros64( zSig0 );
> +    shiftCount = clz64(zSig0);
>      shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
>      zExp -= shiftCount;
>      return roundAndPackFloatx80(roundingPrecision, zSign, zExp,
> @@ -3294,7 +3294,7 @@ static void
>      int8_t shiftCount;
>  
>      if ( aSig0 == 0 ) {
> -        shiftCount = countLeadingZeros64( aSig1 ) - 15;
> +        shiftCount = clz64(aSig1) - 15;
>          if ( shiftCount < 0 ) {
>              *zSig0Ptr = aSig1>>( - shiftCount );
>              *zSig1Ptr = aSig1<<( shiftCount & 63 );
> @@ -3306,7 +3306,7 @@ static void
>          *zExpPtr = - shiftCount - 63;
>      }
>      else {
> -        shiftCount = countLeadingZeros64( aSig0 ) - 15;
> +        shiftCount = clz64(aSig0) - 15;
>          shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
>          *zExpPtr = 1 - shiftCount;
>      }
> @@ -3495,7 +3495,7 @@ static float128 normalizeRoundAndPackFloat128(flag 
> zSign, int32_t zExp,
>          zSig1 = 0;
>          zExp -= 64;
>      }
> -    shiftCount = countLeadingZeros64( zSig0 ) - 15;
> +    shiftCount = clz64(zSig0) - 15;
>      if ( 0 <= shiftCount ) {
>          zSig2 = 0;
>          shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
> @@ -3527,7 +3527,7 @@ floatx80 int32_to_floatx80(int32_t a, float_status 
> *status)
>      if ( a == 0 ) return packFloatx80( 0, 0, 0 );
>      zSign = ( a < 0 );
>      absA = zSign ? - a : a;
> -    shiftCount = countLeadingZeros32( absA ) + 32;
> +    shiftCount = clz32(absA) + 32;
>      zSig = absA;
>      return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
>  
> @@ -3549,7 +3549,7 @@ float128 int32_to_float128(int32_t a, float_status 
> *status)
>      if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
>      zSign = ( a < 0 );
>      absA = zSign ? - a : a;
> -    shiftCount = countLeadingZeros32( absA ) + 17;
> +    shiftCount = clz32(absA) + 17;
>      zSig0 = absA;
>      return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
>  
> @@ -3571,7 +3571,7 @@ floatx80 int64_to_floatx80(int64_t a, float_status 
> *status)
>      if ( a == 0 ) return packFloatx80( 0, 0, 0 );
>      zSign = ( a < 0 );
>      absA = zSign ? - a : a;
> -    shiftCount = countLeadingZeros64( absA );
> +    shiftCount = clz64(absA);
>      return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
>  
>  }
> @@ -3593,7 +3593,7 @@ float128 int64_to_float128(int64_t a, float_status 
> *status)
>      if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
>      zSign = ( a < 0 );
>      absA = zSign ? - a : a;
> -    shiftCount = countLeadingZeros64( absA ) + 49;
> +    shiftCount = clz64(absA) + 49;
>      zExp = 0x406E - shiftCount;
>      if ( 64 <= shiftCount ) {
>          zSig1 = 0;
> diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
> index 35e1603..edc6821 100644
> --- a/include/fpu/softfloat-macros.h
> +++ b/include/fpu/softfloat-macros.h
> @@ -80,17 +80,6 @@ this code that are retained.
>   */
>  
>  
> /*----------------------------------------------------------------------------
> -| This macro tests for minimum version of the GNU C compiler.
> -*----------------------------------------------------------------------------*/
> -#if defined(__GNUC__) && defined(__GNUC_MINOR__)
> -# define SOFTFLOAT_GNUC_PREREQ(maj, min) \
> -         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
> -#else
> -# define SOFTFLOAT_GNUC_PREREQ(maj, min) 0
> -#endif
> -
> -
> -/*----------------------------------------------------------------------------
>  | Shifts `a' right by the number of bits given in `count'.  If any nonzero
>  | bits are shifted off, they are ``jammed'' into the least significant bit of
>  | the result by setting the least significant bit to 1.  The value of `count'
> @@ -713,82 +702,6 @@ static inline uint32_t estimateSqrt32(int aExp, uint32_t 
> a)
>  }
>  
>  
> /*----------------------------------------------------------------------------
> -| Returns the number of leading 0 bits before the most-significant 1 bit of
> -| `a'.  If `a' is zero, 32 is returned.
> -*----------------------------------------------------------------------------*/
> -
> -static inline int8_t countLeadingZeros32(uint32_t a)
> -{
> -#if SOFTFLOAT_GNUC_PREREQ(3, 4)
> -    if (a) {
> -        return __builtin_clz(a);
> -    } else {
> -        return 32;
> -    }
> -#else
> -    static const int8_t countLeadingZerosHigh[] = {
> -        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
> -        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
> -        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> -        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> -        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> -        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> -        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> -        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> -        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> -        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> -        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> -        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> -        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> -        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> -        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> -        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
> -    };
> -    int8_t shiftCount;
> -
> -    shiftCount = 0;
> -    if ( a < 0x10000 ) {
> -        shiftCount += 16;
> -        a <<= 16;
> -    }
> -    if ( a < 0x1000000 ) {
> -        shiftCount += 8;
> -        a <<= 8;
> -    }
> -    shiftCount += countLeadingZerosHigh[ a>>24 ];
> -    return shiftCount;
> -#endif
> -}
> -
> -/*----------------------------------------------------------------------------
> -| Returns the number of leading 0 bits before the most-significant 1 bit of
> -| `a'.  If `a' is zero, 64 is returned.
> -*----------------------------------------------------------------------------*/
> -
> -static inline int8_t countLeadingZeros64(uint64_t a)
> -{
> -#if SOFTFLOAT_GNUC_PREREQ(3, 4)
> -    if (a) {
> -        return __builtin_clzll(a);
> -    } else {
> -        return 64;
> -    }
> -#else
> -    int8_t shiftCount;
> -
> -    shiftCount = 0;
> -    if ( a < ( (uint64_t) 1 )<<32 ) {
> -        shiftCount += 32;
> -    }
> -    else {
> -        a >>= 32;
> -    }
> -    shiftCount += countLeadingZeros32( a );
> -    return shiftCount;
> -#endif
> -}
> -
> -/*----------------------------------------------------------------------------
>  | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
>  | is equal to the 128-bit value formed by concatenating `b0' and `b1'.
>  | Otherwise, returns 0.
> 



reply via email to

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