sal/rtl/math.cxx               |   29 ++++++-----------------------
 tools/source/generic/fract.cxx |   24 +++---------------------
 tools/source/misc/fix16.cxx    |   31 +++----------------------------
 3 files changed, 12 insertions(+), 72 deletions(-)

New commits:
commit c2dca161c0ed455a962d23f8e2fcb64143c5e674
Author:     Mike Kaganski <[email protected]>
AuthorDate: Thu Feb 29 07:39:32 2024 +0600
Commit:     Mike Kaganski <[email protected]>
CommitDate: Thu Feb 29 04:01:48 2024 +0100

    Use <bit> instead of platform-specific intrinsics
    
    Change-Id: I79636ff9c3b2fe601b0b3c94a111b36af0011775
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164131
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx
index fe45b90a8297..5b6c780b5001 100644
--- a/sal/rtl/math.cxx
+++ b/sal/rtl/math.cxx
@@ -24,6 +24,7 @@
 #include <rtl/math.hxx>
 
 #include <algorithm>
+#include <bit>
 #include <cassert>
 #include <cfenv>
 #include <cmath>
@@ -118,18 +119,6 @@ bool isRepresentableInteger(double fAbsValue)
     return nInt == fAbsValue;
 }
 
-// Returns 1-based index of least significant bit in a number, or zero if 
number is zero
-int findFirstSetBit(unsigned n)
-{
-#if defined _WIN32
-    unsigned long pos;
-    unsigned char bNonZero = _BitScanForward(&pos, n);
-    return (bNonZero == 0) ? 0 : pos + 1;
-#else
-    return __builtin_ffs(n);
-#endif
-}
-
 /** Returns number of binary bits for fractional part of the number
     Expects a proper non-negative double value, not +-INF, not NAN
  */
@@ -138,19 +127,13 @@ int getBitsInFracPart(double fAbsValue)
     assert(std::isfinite(fAbsValue) && fAbsValue >= 0.0);
     if (fAbsValue == 0.0)
         return 0;
-    auto pValParts = reinterpret_cast<const sal_math_Double*>(&fAbsValue);
-    int nExponent = pValParts->inf_parts.exponent - 1023;
+    auto& rValParts = reinterpret_cast<const 
sal_math_Double*>(&fAbsValue)->parts;
+    int nExponent = rValParts.exponent - 1023;
     if (nExponent >= 52)
         return 0; // All bits in fraction are in integer part of the number
-    int nLeastSignificant = findFirstSetBit(pValParts->inf_parts.fraction_lo);
-    if (nLeastSignificant == 0)
-    {
-        nLeastSignificant = findFirstSetBit(pValParts->inf_parts.fraction_hi);
-        if (nLeastSignificant == 0)
-            nLeastSignificant = 53; // the implied leading 1 is the least 
significant
-        else
-            nLeastSignificant += 32;
-    }
+    int nLeastSignificant = rValParts.fraction
+                                ? std::countr_zero(rValParts.fraction) + 1
+                                : 53; // the implied leading 1 is the least 
significant
     int nFracSignificant = 53 - nLeastSignificant;
     int nBitsInFracPart = nFracSignificant - nExponent;
 
diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
index abe8ee41b206..7dfddf50a880 100644
--- a/tools/source/generic/fract.cxx
+++ b/tools/source/generic/fract.cxx
@@ -25,18 +25,16 @@
 #include <osl/diagnose.h>
 
 #include <algorithm>
+#include <bit>
 #include <cmath>
 #include <numeric>
 
 #include <boost/rational.hpp>
 
-#ifdef _MSC_VER
-#include <intrin.h>
-#endif
-
 static boost::rational<sal_Int32> rational_FromDouble(double dVal);
 static void rational_ReduceInaccurate(boost::rational<sal_Int32>& rRational, 
unsigned nSignificantBits);
-static int impl_NumberOfBits( sal_uInt32 nNum );
+// Find the number of bits required to represent this number
+static int impl_NumberOfBits(sal_uInt32 nNum) { return 32 - 
std::countl_zero(nNum); }
 
 static boost::rational<sal_Int32> toRational(sal_Int32 n, sal_Int32 d)
 {
@@ -406,22 +404,6 @@ static boost::rational<sal_Int32> 
rational_FromDouble(double dVal)
     return boost::rational<sal_Int32>( sal_Int32(dVal), nDen );
 }
 
-/**
- * Find the number of bits required to represent this number, using the CLZ 
intrinsic
- */
-static int impl_NumberOfBits( sal_uInt32 nNum )
-{
-    if (nNum == 0)
-        return 0;
-#ifdef _MSC_VER
-    unsigned long r = 0;
-    _BitScanReverse(&r, nNum);
-    return r + 1;
-#else
-    return 32 - __builtin_clz(nNum);
-#endif
-}
-
 /** Inaccurate cancellation for a fraction.
 
     Clip both nominator and denominator to said number of bits. If
diff --git a/tools/source/misc/fix16.cxx b/tools/source/misc/fix16.cxx
index 978f77291dce..58c40704d931 100644
--- a/tools/source/misc/fix16.cxx
+++ b/tools/source/misc/fix16.cxx
@@ -24,6 +24,8 @@
 
 #include <tools/fix16.hxx>
 
+#include <bit>
+
 const fix16_t fix16_minimum = 0x80000000; /*!< the minimum value of fix16_t */
 const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicate 
overflows */
 
@@ -74,33 +76,6 @@ fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1)
     return result;
 }
 
-/* 32-bit implementation of fix16_div. Fastest version for e.g. ARM Cortex M3.
- * Performs 32-bit divisions repeatedly to reduce the remainder. For this to
- * be efficient, the processor has to have 32-bit hardware division.
- */
-#ifdef __GNUC__
-// Count leading zeros, using processor-specific instruction if available.
-#define clz(x) (__builtin_clzl(x) - (8 * sizeof(long) - 32))
-#else
-static uint8_t clz(uint32_t x)
-{
-    uint8_t result = 0;
-    if (x == 0)
-        return 32;
-    while (!(x & 0xF0000000))
-    {
-        result += 4;
-        x <<= 4;
-    }
-    while (!(x & 0x80000000))
-    {
-        result += 1;
-        x <<= 1;
-    }
-    return result;
-}
-#endif
-
 fix16_t fix16_div(fix16_t a, fix16_t b)
 {
     // This uses a hardware 32/32 bit division multiple times, until we have
@@ -135,7 +110,7 @@ fix16_t fix16_div(fix16_t a, fix16_t b)
     while (remainder && bit_pos >= 0)
     {
         // Shift remainder as much as we can without overflowing
-        int shift = clz(remainder);
+        int shift = std::countl_zero(remainder);
         if (shift > bit_pos)
             shift = bit_pos;
         remainder <<= shift;

Reply via email to