aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/math.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/math.c')
-rw-r--r--src/nvim/math.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/nvim/math.c b/src/nvim/math.c
index 96ff1bef10..9a0825823c 100644
--- a/src/nvim/math.c
+++ b/src/nvim/math.c
@@ -7,10 +7,11 @@
#include "nvim/math.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "math.c.generated.h" // IWYU pragma: export
+# include "math.c.generated.h"
#endif
int xfpclassify(double d)
+ FUNC_ATTR_CONST
{
uint64_t m;
@@ -29,11 +30,39 @@ int xfpclassify(double d)
}
int xisinf(double d)
+ FUNC_ATTR_CONST
{
return FP_INFINITE == xfpclassify(d);
}
int xisnan(double d)
+ FUNC_ATTR_CONST
{
return FP_NAN == xfpclassify(d);
}
+
+/// Count trailing zeroes at the end of bit field.
+int xctz(uint64_t x)
+{
+ // If x == 0, that means all bits are zeroes.
+ if (x == 0) {
+ return 8 * sizeof(x);
+ }
+
+ // Use compiler builtin if possible.
+#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 4))
+ return __builtin_ctzll(x);
+#else
+ int count = 0;
+ // Set x's trailing zeroes to ones and zero the rest.
+ x = (x ^ (x - 1)) >> 1;
+
+ // Increment count until there are just zero bits remaining.
+ while (x) {
+ count++;
+ x >>= 1;
+ }
+
+ return count;
+#endif
+}