cpu_id.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #pragma once
  2. #include "types.h"
  3. #include "compiler.h"
  4. #include <util/generic/singleton.h>
  5. #define Y_CPU_ID_ENUMERATE(F) \
  6. F(SSE) \
  7. F(SSE2) \
  8. F(SSE3) \
  9. F(SSSE3) \
  10. F(SSE41) \
  11. F(SSE42) \
  12. F(F16C) \
  13. F(POPCNT) \
  14. F(BMI1) \
  15. F(BMI2) \
  16. F(PCLMUL) \
  17. F(AES) \
  18. F(AVX) \
  19. F(FMA) \
  20. F(AVX2) \
  21. F(AVX512F) \
  22. F(AVX512DQ) \
  23. F(AVX512IFMA) \
  24. F(AVX512PF) \
  25. F(AVX512ER) \
  26. F(AVX512CD) \
  27. F(AVX512BW) \
  28. F(AVX512VL) \
  29. F(AVX512VBMI) \
  30. F(PREFETCHWT1) \
  31. F(SHA) \
  32. F(ADX) \
  33. F(RDRAND) \
  34. F(RDSEED) \
  35. F(PCOMMIT) \
  36. F(RDTSCP) \
  37. F(CLFLUSHOPT) \
  38. F(CLWB) \
  39. F(XSAVE) \
  40. F(OSXSAVE)
  41. #define Y_CPU_ID_ENUMERATE_OUTLINED_CACHED_DEFINE(F) \
  42. F(F16C) \
  43. F(BMI1) \
  44. F(BMI2) \
  45. F(PCLMUL) \
  46. F(AES) \
  47. F(AVX) \
  48. F(FMA) \
  49. F(AVX2) \
  50. F(AVX512F) \
  51. F(AVX512DQ) \
  52. F(AVX512IFMA) \
  53. F(AVX512PF) \
  54. F(AVX512ER) \
  55. F(AVX512CD) \
  56. F(AVX512BW) \
  57. F(AVX512VL) \
  58. F(AVX512VBMI) \
  59. F(PREFETCHWT1) \
  60. F(SHA) \
  61. F(ADX) \
  62. F(RDRAND) \
  63. F(RDSEED) \
  64. F(PCOMMIT) \
  65. F(RDTSCP) \
  66. F(CLFLUSHOPT) \
  67. F(CLWB) \
  68. F(XSAVE) \
  69. F(OSXSAVE)
  70. namespace NX86 {
  71. /**
  72. * returns false on non-x86 platforms
  73. */
  74. bool CpuId(ui32 op, ui32 res[4]) noexcept;
  75. bool CpuId(ui32 op, ui32 subOp, ui32 res[4]) noexcept;
  76. #define Y_DEF_NAME(X) Y_CONST_FUNCTION bool Have##X() noexcept;
  77. Y_CPU_ID_ENUMERATE(Y_DEF_NAME)
  78. #undef Y_DEF_NAME
  79. #define Y_DEF_NAME(X) Y_CONST_FUNCTION bool CachedHave##X() noexcept;
  80. Y_CPU_ID_ENUMERATE_OUTLINED_CACHED_DEFINE(Y_DEF_NAME)
  81. #undef Y_DEF_NAME
  82. struct TFlagsCache {
  83. #define Y_DEF_NAME(X) const bool Have##X##_ = NX86::Have##X();
  84. Y_CPU_ID_ENUMERATE(Y_DEF_NAME)
  85. #undef Y_DEF_NAME
  86. };
  87. #define Y_LOOKUP_CPU_ID_IMPL(X) return SingletonWithPriority<TFlagsCache, 0>()->Have##X##_;
  88. inline bool CachedHaveSSE() noexcept {
  89. #ifdef _sse_
  90. return true;
  91. #else
  92. Y_LOOKUP_CPU_ID_IMPL(SSE)
  93. #endif
  94. }
  95. inline bool CachedHaveSSE2() noexcept {
  96. #ifdef _sse2_
  97. return true;
  98. #else
  99. Y_LOOKUP_CPU_ID_IMPL(SSE2)
  100. #endif
  101. }
  102. inline bool CachedHaveSSE3() noexcept {
  103. #ifdef _sse3_
  104. return true;
  105. #else
  106. Y_LOOKUP_CPU_ID_IMPL(SSE3)
  107. #endif
  108. }
  109. inline bool CachedHaveSSSE3() noexcept {
  110. #ifdef _ssse3_
  111. return true;
  112. #else
  113. Y_LOOKUP_CPU_ID_IMPL(SSSE3)
  114. #endif
  115. }
  116. inline bool CachedHaveSSE41() noexcept {
  117. #ifdef _sse4_1_
  118. return true;
  119. #else
  120. Y_LOOKUP_CPU_ID_IMPL(SSE41)
  121. #endif
  122. }
  123. inline bool CachedHaveSSE42() noexcept {
  124. #ifdef _sse4_2_
  125. return true;
  126. #else
  127. Y_LOOKUP_CPU_ID_IMPL(SSE42)
  128. #endif
  129. }
  130. inline bool CachedHavePOPCNT() noexcept {
  131. #ifdef _popcnt_
  132. return true;
  133. #else
  134. Y_LOOKUP_CPU_ID_IMPL(POPCNT)
  135. #endif
  136. }
  137. #undef Y_LOOKUP_CPU_ID_IMPL
  138. } // namespace NX86
  139. const char* CpuBrand(ui32 store[12]) noexcept;