mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Common: Add CPU feature detection for ARM64
This commit is contained in:
		
							parent
							
								
									f1c2f63aa1
								
							
						
					
					
						commit
						0af8406e44
					
				
					 3 changed files with 149 additions and 0 deletions
				
			
		|  | @ -125,6 +125,12 @@ if(ARCHITECTURE_x86_64) | |||
|             x64/xbyak_abi.h | ||||
|             x64/xbyak_util.h | ||||
|     ) | ||||
| elseif(ARCHITECTURE_ARM64) | ||||
|     target_sources(common | ||||
|         PRIVATE | ||||
|             aarch64/cpu_detect.cpp | ||||
|             aarch64/cpu_detect.h | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| create_target_directory_groups(common) | ||||
|  |  | |||
							
								
								
									
										112
									
								
								src/common/aarch64/cpu_detect.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/common/aarch64/cpu_detect.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,112 @@ | |||
| // Copyright 2013 Dolphin Emulator Project / 2022 Citra Emulator Project
 | ||||
| // Licensed under GPLv2+
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <cstring> | ||||
| #include <fstream> | ||||
| #include <string> | ||||
| 
 | ||||
| #ifdef __APPLE__ | ||||
| // clang-format off
 | ||||
| #include <sys/types.h> | ||||
| #include <sys/sysctl.h> | ||||
| // clang-format on
 | ||||
| #elif !defined(_WIN32) | ||||
| #ifndef __FreeBSD__ | ||||
| #include <asm/hwcap.h> | ||||
| #endif // __FreeBSD__
 | ||||
| #include <sys/auxv.h> | ||||
| #include <unistd.h> | ||||
| #endif // __APPLE__
 | ||||
| 
 | ||||
| #include "common/aarch64/cpu_detect.h" | ||||
| #include "common/file_util.h" | ||||
| 
 | ||||
| namespace Common { | ||||
| 
 | ||||
| #ifdef __APPLE__ | ||||
| static std::string GetCPUString() { | ||||
|     char buf[128]; | ||||
|     size_t buf_len = sizeof(buf); | ||||
|     if (sysctlbyname("machdep.cpu.brand_string", &buf, &buf_len, NULL, 0) == -1) { | ||||
|         return "Unknown"; | ||||
|     } | ||||
|     return buf; | ||||
| } | ||||
| #elif !defined(WIN32) | ||||
| static std::string GetCPUString() { | ||||
|     constexpr char procfile[] = "/proc/cpuinfo"; | ||||
|     constexpr char marker[] = "Hardware\t: "; | ||||
|     std::string cpu_string = "Unknown"; | ||||
| 
 | ||||
|     std::string line; | ||||
|     std::ifstream file; | ||||
|     OpenFStream(file, procfile, std::ios_base::in); | ||||
| 
 | ||||
|     if (!file) | ||||
|         return cpu_string; | ||||
| 
 | ||||
|     while (std::getline(file, line)) { | ||||
|         if (line.find(marker) != std::string::npos) { | ||||
|             cpu_string = line.substr(strlen(marker)); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return cpu_string; | ||||
| } | ||||
| #endif // __APPLE__
 | ||||
| 
 | ||||
| // Detects the various CPU features
 | ||||
| static CPUCaps Detect() { | ||||
|     CPUCaps caps; | ||||
|     // Set some defaults here
 | ||||
|     caps.fma = true; | ||||
|     caps.afp = false; | ||||
| 
 | ||||
| #ifdef __APPLE__ | ||||
|     // M-series CPUs have all of these
 | ||||
|     caps.fp = true; | ||||
|     caps.asimd = true; | ||||
|     caps.aes = true; | ||||
|     caps.crc32 = true; | ||||
|     caps.sha1 = true; | ||||
|     caps.sha2 = true; | ||||
|     caps.cpu_string = GetCPUString(); | ||||
| #elif defined(_WIN32) | ||||
|     // Windows does not provide any mechanism for querying the system registers on ARMv8, unlike
 | ||||
|     // Linux which traps the register reads and emulates them in the kernel. There are environment
 | ||||
|     // variables containing some of the CPU-specific values, which we could use for a lookup table
 | ||||
|     // in the future. For now, assume all features are present as all known devices which are
 | ||||
|     // Windows-on-ARM compatible also support these extensions.
 | ||||
|     caps.fp = true; | ||||
|     caps.asimd = true; | ||||
|     caps.aes = true; | ||||
|     caps.crc32 = true; | ||||
|     caps.sha1 = true; | ||||
|     caps.sha2 = true; | ||||
| #else | ||||
|     caps.cpu_string = GetCPUString(); | ||||
| 
 | ||||
| #ifdef __FreeBSD__ | ||||
|     u_long hwcaps = 0; | ||||
|     elf_aux_info(AT_HWCAP, &hwcaps, sizeof(u_long)); | ||||
| #else | ||||
|     unsigned long hwcaps = getauxval(AT_HWCAP); | ||||
| #endif // __FreeBSD__
 | ||||
|     caps.fp = hwcaps & HWCAP_FP; | ||||
|     caps.asimd = hwcaps & HWCAP_ASIMD; | ||||
|     caps.aes = hwcaps & HWCAP_AES; | ||||
|     caps.crc32 = hwcaps & HWCAP_CRC32; | ||||
|     caps.sha1 = hwcaps & HWCAP_SHA1; | ||||
|     caps.sha2 = hwcaps & HWCAP_SHA2; | ||||
| #endif // __APPLE__
 | ||||
|     return caps; | ||||
| } | ||||
| 
 | ||||
| const CPUCaps& GetCPUCaps() { | ||||
|     static CPUCaps caps = Detect(); | ||||
|     return caps; | ||||
| } | ||||
| 
 | ||||
| } // namespace Common
 | ||||
							
								
								
									
										31
									
								
								src/common/aarch64/cpu_detect.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/common/aarch64/cpu_detect.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| // Copyright 2013 Dolphin Emulator Project / 2021 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| namespace Common { | ||||
| 
 | ||||
| /// Arm64 CPU capabilities that may be detected by this module
 | ||||
| struct CPUCaps { | ||||
|     std::string cpu_string; | ||||
| 
 | ||||
|     bool aes; | ||||
|     bool afp; // Alternate floating-point behavior
 | ||||
|     bool asimd; | ||||
|     bool crc32; | ||||
|     bool fma; | ||||
|     bool fp; | ||||
|     bool sha1; | ||||
|     bool sha2; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the supported capabilities of the host CPU | ||||
|  * @return Reference to a CPUCaps struct with the detected host CPU capabilities | ||||
|  */ | ||||
| const CPUCaps& GetCPUCaps(); | ||||
| 
 | ||||
| } // namespace Common
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue