Hardware.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "Hardware.h"
  2. #include <array>
  3. #include <vector>
  4. #include <bitset>
  5. #include <cstring>
  6. #if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
  7. #ifdef __GNUC__
  8. #include <cpuid.h>
  9. #else
  10. #include <intrin.h>
  11. #endif
  12. #endif
  13. using mnd::CpuInfo;
  14. #if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
  15. CpuInfo::CpuInfo(void)
  16. {
  17. #if defined(__x86_64__) || defined(_M_X64)
  18. arch = Arch::X86_64;
  19. #else
  20. arch = Arch::X86;
  21. #endif
  22. std::array<unsigned int, 4> dat;
  23. std::vector<std::array<unsigned int, 4>> cpuData;
  24. std::vector<std::array<unsigned int, 4>> extData;
  25. unsigned int nData;
  26. unsigned int nExtData;
  27. #ifdef __GNUC__
  28. __cpuid(0, dat[0], dat[1], dat[2], dat[3]);
  29. nData = dat[0];
  30. __cpuid(0x80000000, dat[0], dat[1], dat[2], dat[3]);
  31. nExtData = dat[0];
  32. #else
  33. __cpuid((int*) dat.data(), 0);
  34. nData = dat[0];
  35. __cpuid((int*) dat.data(), 0x80000000);
  36. nExtData = dat[0];
  37. #endif
  38. for (int i = 0; i <= nData; i++) {
  39. #ifdef __GNUC__
  40. __get_cpuid(i, &dat[0], &dat[1], &dat[2], &dat[3]);
  41. #else
  42. __cpuidex((int*) dat.data(), i, 0);
  43. #endif
  44. cpuData.push_back(dat);
  45. }
  46. for (int i = 0x80000000; i <= nExtData; i++) {
  47. #ifdef __GNUC__
  48. __get_cpuid(i, &dat[0], &dat[1], &dat[2], &dat[3]);
  49. #else
  50. __cpuidex((int*) dat.data(), i, 0);
  51. #endif
  52. extData.push_back(dat);
  53. }
  54. char vendor[32];
  55. memset(vendor, 0, sizeof vendor);
  56. *reinterpret_cast<int*>(vendor) = cpuData[0][1];
  57. *reinterpret_cast<int*>(vendor + 4) = cpuData[0][3];
  58. *reinterpret_cast<int*>(vendor + 8) = cpuData[0][2];
  59. this->vendor = vendor;
  60. char brand[64];
  61. memset(brand, 0, sizeof brand);
  62. if (nExtData >= 0x80000004) {
  63. memcpy(brand, extData[2].data(), sizeof(dat));
  64. memcpy(brand + 16, extData[3].data(), sizeof(dat));
  65. memcpy(brand + 32, extData[4].data(), sizeof(dat));
  66. this->brand = brand;
  67. // trim
  68. this->brand.erase(0, this->brand.find_first_not_of(" \n\r\t"));
  69. this->brand.erase(this->brand.find_last_not_of(" \n\r\t") + 1);
  70. }
  71. std::bitset<32> ecx1 = 0;
  72. std::bitset<32> edx1 = 0;
  73. std::bitset<32> ebx7 = 0;
  74. std::bitset<32> ecx7 = 0;
  75. if (nData >= 1) {
  76. ecx1 = cpuData[1][2];
  77. edx1 = cpuData[1][3];
  78. }
  79. if (nData >= 7) {
  80. ebx7 = cpuData[7][1];
  81. ecx7 = cpuData[7][2];
  82. }
  83. sse2 = edx1[26];
  84. avx = ecx1[28];
  85. avx512 = ebx7[16];
  86. }
  87. #elif defined(__arm__) || defined(__aarch64__)
  88. CpuInfo::CpuInfo(void)
  89. {
  90. #if defined(__aarch64__)
  91. arch = Arch::ARM64;
  92. #else
  93. arch = Arch::ARM;
  94. // TODO implement check
  95. neon = false;
  96. #endif
  97. }
  98. #endif