[WTF] Add clz32 / clz64 for MSVC
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 May 2018 12:26:05 +0000 (12:26 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 May 2018 12:26:05 +0000 (12:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186023

Reviewed by Daniel Bates.

Source/JavaScriptCore:

Move clz32 and clz64 to WTF.

* runtime/MathCommon.h:
(JSC::clz32): Deleted.
(JSC::clz64): Deleted.

Source/WTF:

This patch adds efficient implementations of clz32 and clz64 for MSVC.
While MSVC has _lzcnt intrinsic, it is only valid if the CPU has lzcnt instruction.
Instead of checking cpuid here, we just use _BitScanReverse and _BitScanReverse64.

* wtf/MathExtras.h:
(WTF::clz32):
(WTF::clz64):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232244 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/MathCommon.h
Source/WTF/ChangeLog
Source/WTF/wtf/MathExtras.h

index a6acb1a..c64ee95 100644 (file)
@@ -1,3 +1,16 @@
+2018-05-27  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [WTF] Add clz32 / clz64 for MSVC
+        https://bugs.webkit.org/show_bug.cgi?id=186023
+
+        Reviewed by Daniel Bates.
+
+        Move clz32 and clz64 to WTF.
+
+        * runtime/MathCommon.h:
+        (JSC::clz32): Deleted.
+        (JSC::clz64): Deleted.
+
 2018-05-27  Caio Lima  <ticaiolima@gmail.com>
 
         [ESNext][BigInt] Implement "+" and "-" unary operation
index 0fdc7c3..e919461 100644 (file)
@@ -47,44 +47,6 @@ inline constexpr double minSafeInteger()
     return -9007199254740991.0;
 }
 
-inline int clz32(uint32_t number)
-{
-#if COMPILER(GCC_OR_CLANG)
-    int zeroCount = 32;
-    if (number)
-        zeroCount = __builtin_clz(number);
-    return zeroCount;
-#else
-    int zeroCount = 0;
-    for (int i = 31; i >= 0; i--) {
-        if (!(number >> i))
-            zeroCount++;
-        else
-            break;
-    }
-    return zeroCount;
-#endif
-}
-
-inline int clz64(uint64_t number)
-{
-#if COMPILER(GCC_OR_CLANG)
-    int zeroCount = 64;
-    if (number)
-        zeroCount = __builtin_clzll(number);
-    return zeroCount;
-#else
-    int zeroCount = 0;
-    for (int i = 63; i >= 0; i--) {
-        if (!(number >> i))
-            zeroCount++;
-        else
-            break;
-    }
-    return zeroCount;
-#endif
-}
-
 // This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec.
 // Note that this operation is identical to ToUInt32 other than to interpretation
 // of the resulting bit-pattern (as such this method is also called to implement
index 229f303..025b985 100644 (file)
@@ -1,3 +1,18 @@
+2018-05-27  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [WTF] Add clz32 / clz64 for MSVC
+        https://bugs.webkit.org/show_bug.cgi?id=186023
+
+        Reviewed by Daniel Bates.
+
+        This patch adds efficient implementations of clz32 and clz64 for MSVC.
+        While MSVC has _lzcnt intrinsic, it is only valid if the CPU has lzcnt instruction.
+        Instead of checking cpuid here, we just use _BitScanReverse and _BitScanReverse64.
+
+        * wtf/MathExtras.h:
+        (WTF::clz32):
+        (WTF::clz64):
+
 2018-05-26  Filip Pizlo  <fpizlo@apple.com>
 
         testair sometimes crashes due to races in initialization of ARC4RandomNumberGenerator
index 80d3050..0a166b5 100644 (file)
@@ -524,6 +524,56 @@ void shuffleVector(VectorType& vector, const RandomFunc& randomFunc)
     shuffleVector(vector, vector.size(), randomFunc);
 }
 
+inline unsigned clz32(uint32_t number)
+{
+#if COMPILER(GCC_OR_CLANG)
+    if (number)
+        return __builtin_clz(number);
+    return 32;
+#elif COMPILER(MSVC)
+    // Visual Studio 2008 or upper have __lzcnt, but we can't detect Intel AVX at compile time.
+    // So we use bit-scan-reverse operation to calculate clz.
+    unsigned long ret = 0;
+    if (_BitScanReverse(&ret, number))
+        return 31 - ret;
+    return 32;
+#else
+    unsigned zeroCount = 0;
+    for (int i = 31; i >= 0; i--) {
+        if (!(number >> i))
+            zeroCount++;
+        else
+            break;
+    }
+    return zeroCount;
+#endif
+}
+
+inline unsigned clz64(uint64_t number)
+{
+#if COMPILER(GCC_OR_CLANG)
+    if (number)
+        return __builtin_clzll(number);
+    return 64;
+#elif COMPILER(MSVC)
+    // Visual Studio 2008 or upper have __lzcnt, but we can't detect Intel AVX at compile time.
+    // So we use bit-scan-reverse operation to calculate clz.
+    unsigned long ret = 0;
+    if (_BitScanReverse64(&ret, number))
+        return 63 - ret;
+    return 64;
+#else
+    unsigned zeroCount = 0;
+    for (int i = 63; i >= 0; i--) {
+        if (!(number >> i))
+            zeroCount++;
+        else
+            break;
+    }
+    return zeroCount;
+#endif
+}
+
 } // namespace WTF
 
 using WTF::opaque;
@@ -531,5 +581,7 @@ using WTF::preciseIndexMaskPtr;
 using WTF::preciseIndexMaskShift;
 using WTF::preciseIndexMaskShiftForSize;
 using WTF::shuffleVector;
+using WTF::clz32;
+using WTF::clz64;
 
 #endif // #ifndef WTF_MathExtras_h