fslongjin 2 лет назад
Родитель
Сommit
bf4226f6b9
2 измененных файлов с 63 добавлено и 1 удалено
  1. 55 0
      kernel/arch/x86_64/math/bitcount.h
  2. 8 1
      kernel/common/math.h

+ 55 - 0
kernel/arch/x86_64/math/bitcount.h

@@ -0,0 +1,55 @@
+#include <common/stddef.h>
+
+/**
+ * @brief 统计二进制数的前导0
+ *
+ * @param x 待统计的数
+ * @return int 结果
+ */
+static __always_inline int __clz(uint32_t x)
+{
+    asm volatile("bsr %%eax, %%eax\n\t"
+                 "xor $0x1f, %%eax\n\t"
+                 : "=a"(x)
+                 : "a"(x)
+                 : "memory");
+    return x;
+}
+
+/**
+ * @brief 统计二进制数的前导0 (宽度为unsigned long)
+ *
+ * @param x 待统计的数
+ * @return int 结果
+ */
+static __always_inline int __clzl(unsigned long x)
+{
+    int res = 0;
+    asm volatile("cltq\n\t"
+                 "bsr %%rax, %%rax\n\t"
+                 "xor $0x3f, %%rax\n\t"
+                 "mov %%eax,%0\n\t"
+                 : "=m"(res)
+                 : "a"(x)
+                 : "memory");
+    return res;
+}
+
+/**
+ * @brief 统计二进制数的前导0(宽度为unsigned long long)
+ *
+ * @param x 待统计的数
+ * @return int 结果
+ */
+static __always_inline int __clzll(unsigned long long x)
+{
+    int res = 0;
+    asm volatile("cltq\n\t"
+                 "bsr %%rax, %%rax\n\t"
+                 "xor $0x3f, %%rax\n\t"
+                 "mov %%eax,%0\n\t"
+                 : "=m"(res)
+                 : "a"(x)
+                 : "memory");
+    return res;
+}

+ 8 - 1
kernel/common/math.h

@@ -1,3 +1,10 @@
 #pragma once
 #include "stddef.h"
-int64_t pow(int64_t x, int y);
+#include <arch/arch.h>
+#if ARCH(I386) || ARCH(X86_64)
+#include <arch/x86_64/math/bitcount.h>
+#else
+#error Arch not supported.
+#endif
+
+int64_t pow(int64_t x, int y);