intrin.hpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #ifndef INTRIN_HPP
  2. #define INTRIN_HPP
  3. #include <cstdint>
  4. #ifdef _DEF_INT128
  5. #error _DEF_INT128 cannot be directly set
  6. #elif defined(__SIZEOF_INT128__)
  7. #if (defined(__clang__) && !defined(_WIN32) && !defined(__aarch64__)) || \
  8. (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \
  9. (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__))
  10. #define _DEF_INT128 1
  11. #elif defined(__CUDACC__)
  12. #if __CUDACC_VER__ >= 70000
  13. #define _DEF_INT128 1
  14. #endif
  15. #endif
  16. #endif
  17. #ifndef _DEF_INT128
  18. #include "uint128_t.h"
  19. using uint_128bit = uint128_t;
  20. #else
  21. using uint_128bit = unsigned __int128;
  22. #endif
  23. #if defined(__GNUC__) || defined(__clang__)
  24. inline int _leading_zeros(unsigned long long x){
  25. return __builtin_clzll(x);
  26. }
  27. inline int _trailing_zeros(unsigned long long x){
  28. return __builtin_ctzll(x);
  29. }
  30. bool _adc_u64(unsigned long long a,unsigned long long b,unsigned long long* c){
  31. return __builtin_uaddll_overflow(a, b, c);
  32. }
  33. bool _sbc_u64(unsigned long long a,unsigned long long b,unsigned long long* c){
  34. return __builtin_usubll_overflow(a, b, c);
  35. }
  36. inline unsigned long long _mulx_u64(unsigned long long a, unsigned long long b, unsigned long long* hi){
  37. __uint128_t r = ((__uint128_t)a) * b;
  38. *hi = (unsigned long long)(r >> 64);
  39. return r;
  40. }
  41. #endif
  42. #ifdef _MSC_VER
  43. #include <intrin.h>
  44. inline int _leading_zeros(unsigned long long x){
  45. int index = 0;
  46. _BitScanForward64((unsigned long*)&index, x);
  47. return index;
  48. }
  49. inline int _trailing_zeros(unsigned long long x){
  50. int index = 0;
  51. _BitScanReverse64((unsigned long*)&index, x);
  52. return index;
  53. }
  54. bool _adc_u64(unsigned long long a,unsigned long long b,unsigned long long* c){
  55. return _addcarry_u64(0, a, b, c);
  56. }
  57. bool _sbc_u64(unsigned long long a,unsigned long long b,unsigned long long* c){
  58. *c = a - b;
  59. return b > a;
  60. }
  61. #endif
  62. #endif //INTRIN_HPP