mirror of
				https://github.com/google/cpu_features.git
				synced 2025-10-31 05:00:44 +01:00 
			
		
		
		
	Add CpuIdEx function to pass inputs in ecx register (required for E.g. leaf4) (#77)
This commit is contained in:
		 Artem Alekseev
					Artem Alekseev
				
			
				
					committed by
					
						 Guillaume Chatelet
						Guillaume Chatelet
					
				
			
			
				
	
			
			
			 Guillaume Chatelet
						Guillaume Chatelet
					
				
			
						parent
						
							3ee4a9e801
						
					
				
				
					commit
					bfb4cf99cc
				
			| @@ -26,8 +26,7 @@ typedef struct { | |||||||
|   uint32_t eax, ebx, ecx, edx; |   uint32_t eax, ebx, ecx, edx; | ||||||
| } Leaf; | } Leaf; | ||||||
|  |  | ||||||
| // Retrieves the leaf for a particular cpuid. | Leaf CpuIdEx(uint32_t leaf_id, int ecx); | ||||||
| Leaf CpuId(uint32_t leaf_id); |  | ||||||
|  |  | ||||||
| // Returns the eax value of the XCR0 register. | // Returns the eax value of the XCR0 register. | ||||||
| uint32_t GetXCR0Eax(void); | uint32_t GetXCR0Eax(void); | ||||||
|   | |||||||
| @@ -33,9 +33,9 @@ | |||||||
|  |  | ||||||
| #include <cpuid.h> | #include <cpuid.h> | ||||||
|  |  | ||||||
| Leaf CpuId(uint32_t leaf_id) { | Leaf CpuIdEx(uint32_t leaf_id, int ecx) { | ||||||
|   Leaf leaf; |   Leaf leaf; | ||||||
|   __cpuid_count(leaf_id, 0, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx); |   __cpuid_count(leaf_id, ecx, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx); | ||||||
|   return leaf; |   return leaf; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -53,10 +53,10 @@ uint32_t GetXCR0Eax(void) { | |||||||
| #include <immintrin.h> | #include <immintrin.h> | ||||||
| #include <intrin.h>  // For __cpuidex() | #include <intrin.h>  // For __cpuidex() | ||||||
|  |  | ||||||
| Leaf CpuId(uint32_t leaf_id) { | Leaf CpuIdEx(uint32_t leaf_id, int ecx) { | ||||||
|   Leaf leaf; |   Leaf leaf; | ||||||
|   int data[4]; |   int data[4]; | ||||||
|   __cpuid(data, leaf_id); |   __cpuidex(data, leaf_id, ecx); | ||||||
|   leaf.eax = data[0]; |   leaf.eax = data[0]; | ||||||
|   leaf.ebx = data[1]; |   leaf.ebx = data[1]; | ||||||
|   leaf.ecx = data[2]; |   leaf.ecx = data[2]; | ||||||
| @@ -70,16 +70,24 @@ uint32_t GetXCR0Eax(void) { return _xgetbv(0); } | |||||||
| #error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC." | #error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC." | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | static Leaf CpuId(uint32_t leaf_id) { | ||||||
|  |   return CpuIdEx(leaf_id, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
| static const Leaf kEmptyLeaf; | static const Leaf kEmptyLeaf; | ||||||
|  |  | ||||||
| static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) { | static Leaf SafeCpuIdEx(uint32_t max_cpuid_leaf, uint32_t leaf_id, int ecx) { | ||||||
|   if (leaf_id <= max_cpuid_leaf) { |   if (leaf_id <= max_cpuid_leaf) { | ||||||
|     return CpuId(leaf_id); |     return CpuIdEx(leaf_id, ecx); | ||||||
|   } else { |   } else { | ||||||
|     return kEmptyLeaf; |     return kEmptyLeaf; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) { | ||||||
|  |   return SafeCpuIdEx(max_cpuid_leaf, leaf_id, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
| #define MASK_XMM 0x2 | #define MASK_XMM 0x2 | ||||||
| #define MASK_YMM 0x4 | #define MASK_YMM 0x4 | ||||||
| #define MASK_MASKREG 0x20 | #define MASK_MASKREG 0x20 | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ namespace cpu_features { | |||||||
|  |  | ||||||
| class FakeCpu { | class FakeCpu { | ||||||
|  public: |  public: | ||||||
|   Leaf CpuId(uint32_t leaf_id) const { |   Leaf CpuIdEx(uint32_t leaf_id, int ecx) const { | ||||||
|     const auto itr = cpuid_leaves_.find(leaf_id); |     const auto itr = cpuid_leaves_.find(leaf_id); | ||||||
|     EXPECT_TRUE(itr != cpuid_leaves_.end()) << "Missing leaf " << leaf_id; |     EXPECT_TRUE(itr != cpuid_leaves_.end()) << "Missing leaf " << leaf_id; | ||||||
|     return itr->second; |     return itr->second; | ||||||
| @@ -48,7 +48,8 @@ class FakeCpu { | |||||||
|  |  | ||||||
| auto* g_fake_cpu = new FakeCpu(); | auto* g_fake_cpu = new FakeCpu(); | ||||||
|  |  | ||||||
| extern "C" Leaf CpuId(uint32_t leaf_id) { return g_fake_cpu->CpuId(leaf_id); } | extern "C" Leaf CpuIdEx(uint32_t leaf_id, int ecx) { return g_fake_cpu->CpuIdEx(leaf_id, ecx); } | ||||||
|  |  | ||||||
| extern "C" uint32_t GetXCR0Eax(void) { return g_fake_cpu->GetXCR0Eax(); } | extern "C" uint32_t GetXCR0Eax(void) { return g_fake_cpu->GetXCR0Eax(); } | ||||||
|  |  | ||||||
| namespace { | namespace { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user