intrin.hpp 2.1 KB

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