]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
Win32 ctz and clz
authorMatthew Barr <matthew.barr@intel.com>
Thu, 7 Apr 2016 03:17:55 +0000 (13:17 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Tue, 24 May 2016 01:26:20 +0000 (11:26 +1000)
src/util/bitutils.h

index 979a2c045b3c348c42298155cf222613224ecdef..c863fba9bd902e327f85368c2698ec97b7618811 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Intel Corporation
+ * Copyright (c) 2015-2016, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -86,10 +86,20 @@ u32 clz32(u32 x) {
 static really_inline
 u32 clz64(u64a x) {
     assert(x); // behaviour not defined for x == 0
-#if defined(_WIN32)
+#if defined(_WIN64)
     unsigned long r;
     _BitScanReverse64(&r, x);
     return 63 - r;
+#elif defined(_WIN32)
+    unsigned long x1 = (u32)x;
+    unsigned long x2 = (u32)(x >> 32);
+    unsigned long r;
+    if (x2) {
+        _BitScanReverse(&r, x2);
+        return (u32)(31 - r);
+    }
+    _BitScanReverse(&r, (u32)x1);
+    return (u32)(63 - r);
 #else
     return (u32)__builtin_clzll(x);
 #endif
@@ -111,10 +121,17 @@ u32 ctz32(u32 x) {
 static really_inline
 u32 ctz64(u64a x) {
     assert(x); // behaviour not defined for x == 0
-#if defined(_WIN32)
+#if defined(_WIN64)
     unsigned long r;
     _BitScanForward64(&r, x);
     return r;
+#elif defined(_WIN32)
+    unsigned long r;
+    if (_BitScanForward(&r, (u32)x)) {
+        return (u32)r;
+    }
+    _BitScanForward(&r, x >> 32);
+    return (u32)(r + 32);
 #else
     return (u32)__builtin_ctzll(x);
 #endif
@@ -177,8 +194,8 @@ u32 findAndClearLSB_64(u64a *v) {
 #else
     // fall back to doing things with two 32-bit cases, since gcc-4.1 doesn't
     // inline calls to __builtin_ctzll
-    u32 v1 = *v;
-    u32 v2 = (*v >> 32);
+    u32 v1 = (u32)*v;
+    u32 v2 = (u32)(*v >> 32);
     u32 offset;
     if (v1) {
         offset = findAndClearLSB_32(&v1);
@@ -233,7 +250,7 @@ u32 findAndClearMSB_64(u64a *v) {
 #else
     // fall back to doing things with two 32-bit cases, since gcc-4.1 doesn't
     // inline calls to __builtin_ctzll
-    u32 v1 = *v;
+    u32 v1 = (u32)*v;
     u32 v2 = (*v >> 32);
     u32 offset;
     if (v2) {