summaryrefslogtreecommitdiff
path: root/src/common/x64/cpu_detect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/x64/cpu_detect.cpp')
-rw-r--r--src/common/x64/cpu_detect.cpp37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index 23adc5c75..65369bfbe 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -3,7 +3,9 @@
3 3
4#include <array> 4#include <array>
5#include <cstring> 5#include <cstring>
6#include <iterator>
6#include <span> 7#include <span>
8#include <string_view>
7#include "common/bit_util.h" 9#include "common/bit_util.h"
8#include "common/common_types.h" 10#include "common/common_types.h"
9#include "common/x64/cpu_detect.h" 11#include "common/x64/cpu_detect.h"
@@ -47,6 +49,17 @@ static inline u64 _xgetbv(u32 index) {
47 49
48namespace Common { 50namespace Common {
49 51
52CPUCaps::Manufacturer CPUCaps::ParseManufacturer(std::string_view brand_string) {
53 if (brand_string == "GenuineIntel") {
54 return Manufacturer::Intel;
55 } else if (brand_string == "AuthenticAMD") {
56 return Manufacturer::AMD;
57 } else if (brand_string == "HygonGenuine") {
58 return Manufacturer::Hygon;
59 }
60 return Manufacturer::Unknown;
61}
62
50// Detects the various CPU features 63// Detects the various CPU features
51static CPUCaps Detect() { 64static CPUCaps Detect() {
52 CPUCaps caps = {}; 65 CPUCaps caps = {};
@@ -55,30 +68,24 @@ static CPUCaps Detect() {
55 // yuzu at all anyway 68 // yuzu at all anyway
56 69
57 std::array<u32, 4> cpu_id; 70 std::array<u32, 4> cpu_id;
58 std::memset(caps.brand_string, 0, sizeof(caps.brand_string));
59 71
60 // Detect CPU's CPUID capabilities and grab CPU string 72 // Detect CPU's CPUID capabilities and grab manufacturer string
61 __cpuid(cpu_id, 0x00000000); 73 __cpuid(cpu_id, 0x00000000);
62 u32 max_std_fn = cpu_id[0]; // EAX 74 const u32 max_std_fn = cpu_id[0]; // EAX
63 75
76 std::memset(caps.brand_string, 0, std::size(caps.brand_string));
64 std::memcpy(&caps.brand_string[0], &cpu_id[1], sizeof(u32)); 77 std::memcpy(&caps.brand_string[0], &cpu_id[1], sizeof(u32));
65 std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(u32)); 78 std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(u32));
66 std::memcpy(&caps.brand_string[8], &cpu_id[2], sizeof(u32)); 79 std::memcpy(&caps.brand_string[8], &cpu_id[2], sizeof(u32));
67 if (cpu_id[1] == 0x756e6547 && cpu_id[2] == 0x6c65746e && cpu_id[3] == 0x49656e69)
68 caps.manufacturer = Manufacturer::Intel;
69 else if (cpu_id[1] == 0x68747541 && cpu_id[2] == 0x444d4163 && cpu_id[3] == 0x69746e65)
70 caps.manufacturer = Manufacturer::AMD;
71 else if (cpu_id[1] == 0x6f677948 && cpu_id[2] == 0x656e6975 && cpu_id[3] == 0x6e65476e)
72 caps.manufacturer = Manufacturer::Hygon;
73 else
74 caps.manufacturer = Manufacturer::Unknown;
75 80
76 __cpuid(cpu_id, 0x80000000); 81 caps.manufacturer = CPUCaps::ParseManufacturer(caps.brand_string);
82
83 // Set reasonable default cpu string even if brand string not available
84 std::strncpy(caps.cpu_string, caps.brand_string, std::size(caps.brand_string));
77 85
78 u32 max_ex_fn = cpu_id[0]; 86 __cpuid(cpu_id, 0x80000000);
79 87
80 // Set reasonable default brand string even if brand string not available 88 const u32 max_ex_fn = cpu_id[0];
81 std::strcpy(caps.cpu_string, caps.brand_string);
82 89
83 // Detect family and other miscellaneous features 90 // Detect family and other miscellaneous features
84 if (max_std_fn >= 1) { 91 if (max_std_fn >= 1) {