bitcount.h 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #include <common/stddef.h>
  2. /**
  3. * @brief 统计二进制数的前导0
  4. *
  5. * @param x 待统计的数
  6. * @return int 结果
  7. */
  8. static __always_inline int __clz(uint32_t x)
  9. {
  10. asm volatile("bsr %%eax, %%eax\n\t"
  11. "xor $0x1f, %%eax\n\t"
  12. : "=a"(x)
  13. : "a"(x)
  14. : "memory");
  15. return x;
  16. }
  17. /**
  18. * @brief 统计二进制数的前导0 (宽度为unsigned long)
  19. *
  20. * @param x 待统计的数
  21. * @return int 结果
  22. */
  23. static __always_inline int __clzl(unsigned long x)
  24. {
  25. int res = 0;
  26. asm volatile("cltq\n\t"
  27. "bsr %%rax, %%rax\n\t"
  28. "xor $0x3f, %%rax\n\t"
  29. "mov %%eax,%0\n\t"
  30. : "=m"(res)
  31. : "a"(x)
  32. : "memory");
  33. return res;
  34. }
  35. /**
  36. * @brief 统计二进制数的前导0(宽度为unsigned long long)
  37. *
  38. * @param x 待统计的数
  39. * @return int 结果
  40. */
  41. static __always_inline int __clzll(unsigned long long x)
  42. {
  43. int res = 0;
  44. asm volatile("cltq\n\t"
  45. "bsr %%rax, %%rax\n\t"
  46. "xor $0x3f, %%rax\n\t"
  47. "mov %%eax,%0\n\t"
  48. : "=m"(res)
  49. : "a"(x)
  50. : "memory");
  51. return res;
  52. }
  53. static __always_inline int __ctz(uint32_t x)
  54. {
  55. asm volatile("tzcnt %%eax, %%eax":"=a"(x):"a"(x):"memory");
  56. return x;
  57. }
  58. static __always_inline int __ctzl(unsigned long x)
  59. {
  60. asm volatile("tzcnt %%rax, %%rax":"=a"(x):"a"(x):"memory");
  61. return x;
  62. }
  63. #define __ctzll __ctzl