]> granicus.if.org Git - php/commitdiff
make use of intrinsics available with VS for bitset lookups
authorAnatol Belski <ab@php.net>
Fri, 19 Sep 2014 23:36:51 +0000 (01:36 +0200)
committerAnatol Belski <ab@php.net>
Fri, 19 Sep 2014 23:43:06 +0000 (01:43 +0200)
Zend/zend_alloc.c

index 751497978ae368857d8580e75fba9ca99c1402a7..77a825115fc8147dd1775a4e3020fa526ad99503 100644 (file)
@@ -477,6 +477,19 @@ static zend_always_inline int zend_mm_bitset_nts(zend_mm_bitset bitset)
 {
 #if defined(__GNUC__)
        return __builtin_ctzl(~bitset);
+#elif defined(_WIN32)
+       unsigned long index;
+
+#if defined(_WIN64)
+       if (!BitScanForward64(&index, ~bitset)) {
+#else
+       if (!BitScanForward(&index, ~bitset)) {
+#endif
+               /* undefined behavior */
+               return 32;
+       }
+
+       return (int)index;
 #else
        int n;
 
@@ -501,6 +514,19 @@ static zend_always_inline int zend_mm_bitset_ntz(zend_mm_bitset bitset)
 {
 #if defined(__GNUC__)
        return __builtin_ctzl(bitset);
+#elif defined(_WIN32)
+       unsigned long index;
+
+#if defined(_WIN64)
+       if (!BitScanForward64(&index, bitset)) {
+#else
+       if (!BitScanForward(&index, bitset)) {
+#endif
+               /* undefined behavior */
+               return 32;
+       }
+
+       return (int)index;
 #else
        int n;
 
@@ -1023,6 +1049,15 @@ static zend_always_inline int zend_mm_small_size_to_bit(int size)
 {
 #if defined(__GNUC__)
        return (__builtin_clz(size) ^ 0x1f) + 1;
+#elif defined(_WIN32)
+       unsigned long index;
+
+       if (!BitScanReverse(&index, (unsigned long)size)) {
+               /* undefined behavior */
+               return 32;
+       }
+
+       return (((31 - (int)index) ^ 0x1f) + 1);
 #else
        int n = 16;
        if (size <= 0x00ff) {n -= 8; size = size << 8;}