From 4fa694fe827756b3d5f25ebb5398c9fe5f57e205 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 24 May 2014 20:33:57 -0400 Subject: [PATCH] Some CLZ for other toolchains. --- fold.c | 39 ++++++++++++++++++++++++++++++++++++--- tests/inexact.qc | 5 ++--- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/fold.c b/fold.c index 8227537..e306780 100644 --- 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)) diff --git a/tests/inexact.qc b/tests/inexact.qc index 11dc2c6..a17cccd 100644 --- a/tests/inexact.qc +++ b/tests/inexact.qc @@ -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 } -- 2.39.2