Hardware.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "Hardware.h"
  2. #include <array>
  3. #include <vector>
  4. #include <bitset>
  5. #include <cstring>
  6. #ifdef __GNUC__
  7. #include <cpuid.h>
  8. #else
  9. #include <intrin.h>
  10. #endif
  11. using mnd::CpuInfo;
  12. CpuInfo::CpuInfo(void)
  13. {
  14. std::array<unsigned int, 4> dat;
  15. std::vector<std::array<unsigned int, 4>> cpuData;
  16. std::vector<std::array<unsigned int, 4>> extData;
  17. unsigned int nData;
  18. unsigned int nExtData;
  19. #ifdef __GNUC__
  20. __cpuid(0, dat[0], dat[1], dat[2], dat[3]);
  21. nData = dat[0];
  22. __cpuid(0x80000000, dat[0], dat[1], dat[2], dat[3]);
  23. nExtData = dat[0];
  24. #else
  25. __cpuid((int*) dat.data(), 0);
  26. nData = dat[0];
  27. __cpuid((int*) dat.data(), 0x80000000);
  28. nExtData = dat[0];
  29. #endif
  30. for (int i = 0; i <= nData; i++) {
  31. #ifdef __GNUC__
  32. __get_cpuid(i, &dat[0], &dat[1], &dat[2], &dat[3]);
  33. #else
  34. __cpuidex((int*) dat.data(), i, 0);
  35. #endif
  36. cpuData.push_back(dat);
  37. }
  38. for (int i = 0x80000000; i <= nExtData; 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. extData.push_back(dat);
  45. }
  46. char vendor[32];
  47. memset(vendor, 0, sizeof vendor);
  48. *reinterpret_cast<int*>(vendor) = cpuData[0][1];
  49. *reinterpret_cast<int*>(vendor + 4) = cpuData[0][3];
  50. *reinterpret_cast<int*>(vendor + 8) = cpuData[0][2];
  51. this->vendor = vendor;
  52. char brand[64];
  53. memset(brand, 0, sizeof brand);
  54. if (nExtData >= 0x80000004) {
  55. memcpy(brand, extData[2].data(), sizeof(dat));
  56. memcpy(brand + 16, extData[3].data(), sizeof(dat));
  57. memcpy(brand + 32, extData[4].data(), sizeof(dat));
  58. this->brand = brand;
  59. // trim
  60. this->brand.erase(0, this->brand.find_first_not_of(" \n\r\t"));
  61. this->brand.erase(this->brand.find_last_not_of(" \n\r\t") + 1);
  62. }
  63. std::bitset<32> ecx1 = 0;
  64. std::bitset<32> edx1 = 0;
  65. std::bitset<32> ebx7 = 0;
  66. std::bitset<32> ecx7 = 0;
  67. if (nData >= 1) {
  68. ecx1 = cpuData[1][2];
  69. edx1 = cpuData[1][3];
  70. }
  71. if (nData >= 7) {
  72. ebx7 = cpuData[7][1];
  73. ecx7 = cpuData[7][2];
  74. }
  75. sse2 = edx1[26];
  76. avx = ecx1[28];
  77. avx512 = ebx7[16];
  78. }