Some CLZ for other toolchains.
authorDale Weiler <weilercdale@gmail.com>
Sun, 25 May 2014 00:33:57 +0000 (20:33 -0400)
committerDale Weiler <weilercdale@gmail.com>
Sun, 25 May 2014 00:33:57 +0000 (20:33 -0400)
fold.c
tests/inexact.qc

diff --git a/fold.c b/fold.c
index 8227537bc68f20793b45fcf199c7f35146966341..e306780674c3d471462cc73ee22050e368a31fc6 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -73,11 +73,44 @@ typedef struct {
     sfloat_tdetect_t        tiny;
 } sfloat_state_t;
 
+/* Count of leading zero bits before the most-significand 1 bit. */
+#ifdef _MSC_VER
+/* MSVC has an intrinsic for this */
+    static GMQCC_INLINE uint32_t sfloat_clz(uint32_t x) {
+        int r = 0;
+        _BitScanForward(&r, x);
+        return r;
+    }
+#   define SFLOAT_CLZ(X, SUB) \
+        (sfloat_clz((X)) - (SUB))
+#elif defined(__GNUC__) || defined(__CLANG__)
+/* Clang and GCC have a builtin for this */
+#   define SFLOAT_CLZ(X, SUB) \
+        (__builtin_clz((X)) - (SUB))
+#else
+/* Native fallback */
+    static GMQCC_INLINE uint32_t sfloat_popcnt(uint32_t x) {
+        x -= ((x >> 1) & 0x55555555);
+        x  = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+        x  = (((x >> 4) + x) & 0x0F0F0F0F);
+        x += x >> 8;
+        x += x >> 16;
+        return x & 0x0000003F;
+    }
+    static GMQCC_INLINE uint32_t sfloat_clz(uint32_t x) {
+        x |= (x >> 1);
+        x |= (x >> 2);
+        x |= (x >> 4);
+        x |= (x >> 8);
+        x |= (x >> 16);
+        return 32 - sfloat_popcnt(x);
+    }
+#   define SFLOAT_CLZ(X, SUB) \
+        (sfloat_clz((X) - (SUB)))
+#endif
+
 /* The value of a NaN */
 #define SFLOAT_NAN 0xFFC00000
-/* Count of leading zero bits before the most-significand 1 bit. */
-#define SFLOAT_CLZ(X, SUB) \
-    (__builtin_clz((X)) - (SUB))
 /* Test if NaN */
 #define SFLOAT_ISNAN(A) \
     (0xFF000000 < (uint32_t)((A) << 1))
index 11dc2c62521d0ce9e87ffb8f898f214f647a9edd..a17cccddcc73e467e632fde908c80fc78dc2e249 100644 (file)
@@ -1,7 +1,6 @@
-const float a = 1.0 / 3.0;
-const float b = 0.33333333333;
-
 void main() {
+    const float a = 1.0 / 3.0;
+    const float b = 0.33333333333;
     if (a == b) {
         // Should trigger warning
     }