cpu_id_ut.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. #include "cpu_id.h"
  2. #include "platform.h"
  3. #include <library/cpp/testing/unittest/registar.h>
  4. // There are no tests yet for instructions that use 512-bit wide registers because they are not
  5. // supported by some compilers yet.
  6. // Relevant review in LLVM https://reviews.llvm.org/D16757, we should wait untill it will be in our
  7. // version of Clang.
  8. //
  9. // There are also no tests for PREFETCHWT1, PCOMMIT, CLFLUSHOPT and CLWB as they are not supported
  10. // by our compilers yet (and there are no available processors yet :).
  11. static void ExecuteSSEInstruction();
  12. static void ExecuteSSE2Instruction();
  13. static void ExecuteSSE3Instruction();
  14. static void ExecuteSSSE3Instruction();
  15. static void ExecuteSSE41Instruction();
  16. static void ExecuteSSE42Instruction();
  17. static void ExecuteF16CInstruction();
  18. static void ExecuteAVXInstruction();
  19. static void ExecuteAVX2Instruction();
  20. static void ExecutePOPCNTInstruction();
  21. static void ExecuteBMI1Instruction();
  22. static void ExecuteBMI2Instruction();
  23. static void ExecutePCLMULInstruction();
  24. static void ExecuteAESInstruction();
  25. static void ExecuteAVXInstruction();
  26. static void ExecuteAVX2Instruction();
  27. static void ExecuteAVX512FInstruction();
  28. static void ExecuteAVX512DQInstruction();
  29. static void ExecuteAVX512IFMAInstruction();
  30. static void ExecuteAVX512PFInstruction();
  31. static void ExecuteAVX512ERInstruction();
  32. static void ExecuteAVX512CDInstruction();
  33. static void ExecuteAVX512BWInstruction();
  34. static void ExecuteAVX512VLInstruction();
  35. static void ExecuteAVX512VBMIInstruction();
  36. static void ExecutePREFETCHWT1Instruction();
  37. static void ExecuteSHAInstruction();
  38. static void ExecuteADXInstruction();
  39. static void ExecuteRDRANDInstruction();
  40. static void ExecuteRDSEEDInstruction();
  41. static void ExecutePCOMMITInstruction();
  42. static void ExecuteCLFLUSHOPTInstruction();
  43. static void ExecuteCLWBInstruction();
  44. static void ExecuteFMAInstruction() {
  45. }
  46. static void ExecuteRDTSCPInstruction() {
  47. }
  48. static void ExecuteXSAVEInstruction() {
  49. }
  50. static void ExecuteOSXSAVEInstruction() {
  51. }
  52. Y_UNIT_TEST_SUITE(TestCpuId) {
  53. #define DECLARE_TEST_HAVE_INSTRUCTION(name) \
  54. Y_UNIT_TEST(Test##Have##name) { \
  55. if (NX86::Have##name()) { \
  56. Execute##name##Instruction(); \
  57. } \
  58. }
  59. Y_CPU_ID_ENUMERATE(DECLARE_TEST_HAVE_INSTRUCTION)
  60. #undef DECLARE_TEST_HAVE_INSTRUCTION
  61. Y_UNIT_TEST(TestSSE2) {
  62. #if defined(_x86_64_)
  63. UNIT_ASSERT(NX86::HaveSSE2());
  64. #endif
  65. }
  66. Y_UNIT_TEST(TestCpuBrand) {
  67. ui32 store[12];
  68. // Cout << CpuBrand(store) << Endl;;
  69. UNIT_ASSERT(strlen(CpuBrand(store)) > 0);
  70. }
  71. Y_UNIT_TEST(TestCachedAndNoncached) {
  72. #define Y_DEF_NAME(X) UNIT_ASSERT_VALUES_EQUAL(NX86::Have##X(), NX86::CachedHave##X());
  73. Y_CPU_ID_ENUMERATE(Y_DEF_NAME)
  74. #undef Y_DEF_NAME
  75. }
  76. } // Y_UNIT_TEST_SUITE(TestCpuId)
  77. #if defined(_x86_64_)
  78. #if defined(__GNUC__)
  79. void ExecuteSSEInstruction() {
  80. __asm__ __volatile__("xorps %%xmm0, %%xmm0\n"
  81. :
  82. :
  83. : "xmm0");
  84. }
  85. void ExecuteSSE2Instruction() {
  86. __asm__ __volatile__("psrldq $0, %%xmm0\n"
  87. :
  88. :
  89. : "xmm0");
  90. }
  91. void ExecuteSSE3Instruction() {
  92. __asm__ __volatile__("addsubpd %%xmm0, %%xmm0\n"
  93. :
  94. :
  95. : "xmm0");
  96. }
  97. void ExecuteSSSE3Instruction() {
  98. __asm__ __volatile__("psignb %%xmm0, %%xmm0\n"
  99. :
  100. :
  101. : "xmm0");
  102. }
  103. void ExecuteSSE41Instruction() {
  104. __asm__ __volatile__("pmuldq %%xmm0, %%xmm0\n"
  105. :
  106. :
  107. : "xmm0");
  108. }
  109. void ExecuteSSE42Instruction() {
  110. __asm__ __volatile__("crc32 %%eax, %%eax\n"
  111. :
  112. :
  113. : "eax");
  114. }
  115. void ExecuteF16CInstruction() {
  116. __asm__ __volatile__("vcvtph2ps %%xmm0, %%ymm0\n"
  117. :
  118. :
  119. : "xmm0");
  120. }
  121. void ExecuteAVXInstruction() {
  122. __asm__ __volatile__("vzeroupper\n"
  123. :
  124. :
  125. : "xmm0");
  126. }
  127. void ExecuteAVX2Instruction() {
  128. __asm__ __volatile__("vpunpcklbw %%ymm0, %%ymm0, %%ymm0\n"
  129. :
  130. :
  131. : "xmm0");
  132. }
  133. void ExecutePOPCNTInstruction() {
  134. __asm__ __volatile__("popcnt %%eax, %%eax\n"
  135. :
  136. :
  137. : "eax");
  138. }
  139. void ExecuteBMI1Instruction() {
  140. __asm__ __volatile__("tzcnt %%eax, %%eax\n"
  141. :
  142. :
  143. : "eax");
  144. }
  145. void ExecuteBMI2Instruction() {
  146. __asm__ __volatile__("pdep %%rax, %%rdi, %%rax\n"
  147. :
  148. :
  149. : "rax");
  150. }
  151. void ExecutePCLMULInstruction() {
  152. __asm__ __volatile__("pclmullqlqdq %%xmm0, %%xmm0\n"
  153. :
  154. :
  155. : "xmm0");
  156. }
  157. void ExecuteAESInstruction() {
  158. __asm__ __volatile__("aesimc %%xmm0, %%xmm0\n"
  159. :
  160. :
  161. : "xmm0");
  162. }
  163. void ExecuteAVX512FInstruction() {
  164. }
  165. void ExecuteAVX512DQInstruction() {
  166. }
  167. void ExecuteAVX512IFMAInstruction() {
  168. }
  169. void ExecuteAVX512PFInstruction() {
  170. }
  171. void ExecuteAVX512ERInstruction() {
  172. }
  173. void ExecuteAVX512CDInstruction() {
  174. }
  175. void ExecuteAVX512BWInstruction() {
  176. }
  177. void ExecuteAVX512VLInstruction() {
  178. }
  179. void ExecuteAVX512VBMIInstruction() {
  180. }
  181. void ExecutePREFETCHWT1Instruction() {
  182. }
  183. void ExecuteSHAInstruction() {
  184. __asm__ __volatile__("sha1msg1 %%xmm0, %%xmm0\n"
  185. :
  186. :
  187. : "xmm0");
  188. }
  189. void ExecuteADXInstruction() {
  190. __asm__ __volatile__("adcx %%eax, %%eax\n"
  191. :
  192. :
  193. : "eax");
  194. }
  195. void ExecuteRDRANDInstruction() {
  196. __asm__ __volatile__("rdrand %%eax"
  197. :
  198. :
  199. : "eax");
  200. }
  201. void ExecuteRDSEEDInstruction() {
  202. __asm__ __volatile__("rdseed %%eax"
  203. :
  204. :
  205. : "eax");
  206. }
  207. void ExecutePCOMMITInstruction() {
  208. }
  209. void ExecuteCLFLUSHOPTInstruction() {
  210. }
  211. void ExecuteCLWBInstruction() {
  212. }
  213. #elif defined(_MSC_VER)
  214. void ExecuteSSEInstruction() {
  215. }
  216. void ExecuteSSE2Instruction() {
  217. }
  218. void ExecuteSSE3Instruction() {
  219. }
  220. void ExecuteSSSE3Instruction() {
  221. }
  222. void ExecuteSSE41Instruction() {
  223. }
  224. void ExecuteSSE42Instruction() {
  225. }
  226. void ExecuteF16CInstruction() {
  227. }
  228. void ExecuteAVXInstruction() {
  229. }
  230. void ExecuteAVX2Instruction() {
  231. }
  232. void ExecutePOPCNTInstruction() {
  233. }
  234. void ExecuteBMI1Instruction() {
  235. }
  236. void ExecuteBMI2Instruction() {
  237. }
  238. void ExecutePCLMULInstruction() {
  239. }
  240. void ExecuteAESInstruction() {
  241. }
  242. void ExecuteAVX512FInstruction() {
  243. }
  244. void ExecuteAVX512DQInstruction() {
  245. }
  246. void ExecuteAVX512IFMAInstruction() {
  247. }
  248. void ExecuteAVX512PFInstruction() {
  249. }
  250. void ExecuteAVX512ERInstruction() {
  251. }
  252. void ExecuteAVX512CDInstruction() {
  253. }
  254. void ExecuteAVX512BWInstruction() {
  255. }
  256. void ExecuteAVX512VLInstruction() {
  257. }
  258. void ExecuteAVX512VBMIInstruction() {
  259. }
  260. void ExecutePREFETCHWT1Instruction() {
  261. }
  262. void ExecuteSHAInstruction() {
  263. }
  264. void ExecuteADXInstruction() {
  265. }
  266. void ExecuteRDRANDInstruction() {
  267. }
  268. void ExecuteRDSEEDInstruction() {
  269. }
  270. void ExecutePCOMMITInstruction() {
  271. }
  272. void ExecuteCLFLUSHOPTInstruction() {
  273. }
  274. void ExecuteCLWBInstruction() {
  275. }
  276. #else
  277. #error "unknown compiler"
  278. #endif
  279. #else
  280. void ExecuteSSEInstruction() {
  281. }
  282. void ExecuteSSE2Instruction() {
  283. }
  284. void ExecuteSSE3Instruction() {
  285. }
  286. void ExecuteSSSE3Instruction() {
  287. }
  288. void ExecuteSSE41Instruction() {
  289. }
  290. void ExecuteSSE42Instruction() {
  291. }
  292. void ExecuteF16CInstruction() {
  293. }
  294. void ExecuteAVXInstruction() {
  295. }
  296. void ExecuteAVX2Instruction() {
  297. }
  298. void ExecutePOPCNTInstruction() {
  299. }
  300. void ExecuteBMI1Instruction() {
  301. }
  302. void ExecuteBMI2Instruction() {
  303. }
  304. void ExecutePCLMULInstruction() {
  305. }
  306. void ExecuteAESInstruction() {
  307. }
  308. void ExecuteAVX512FInstruction() {
  309. }
  310. void ExecuteAVX512DQInstruction() {
  311. }
  312. void ExecuteAVX512IFMAInstruction() {
  313. }
  314. void ExecuteAVX512PFInstruction() {
  315. }
  316. void ExecuteAVX512ERInstruction() {
  317. }
  318. void ExecuteAVX512CDInstruction() {
  319. }
  320. void ExecuteAVX512BWInstruction() {
  321. }
  322. void ExecuteAVX512VLInstruction() {
  323. }
  324. void ExecuteAVX512VBMIInstruction() {
  325. }
  326. void ExecutePREFETCHWT1Instruction() {
  327. }
  328. void ExecuteSHAInstruction() {
  329. }
  330. void ExecuteADXInstruction() {
  331. }
  332. void ExecuteRDRANDInstruction() {
  333. }
  334. void ExecuteRDSEEDInstruction() {
  335. }
  336. void ExecutePCOMMITInstruction() {
  337. }
  338. void ExecuteCLFLUSHOPTInstruction() {
  339. }
  340. void ExecuteCLWBInstruction() {
  341. }
  342. #endif