x86_cpuid.h (2237B)
1 // Copyright 2025 Google LLC 2 // SPDX-License-Identifier: Apache-2.0 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 #ifndef HIGHWAY_HWY_X86_CPUID_H_ 17 #define HIGHWAY_HWY_X86_CPUID_H_ 18 19 // Wrapper for x86 CPUID intrinsics. Empty on other platforms. 20 21 #include <stdint.h> 22 23 #include "hwy/base.h" 24 25 #if HWY_ARCH_X86 26 27 #if HWY_COMPILER_MSVC || HWY_COMPILER_CLANGCL 28 #include <intrin.h> 29 #else 30 #include <cpuid.h> 31 #endif 32 33 namespace hwy { 34 namespace x86 { 35 36 // Calls CPUID instruction with eax=level and ecx=count and returns the result 37 // in abcd array where abcd = {eax, ebx, ecx, edx} (hence the name abcd). 38 static inline void Cpuid(const uint32_t level, const uint32_t count, 39 uint32_t* HWY_RESTRICT abcd) { 40 #if HWY_COMPILER_MSVC || HWY_COMPILER_CLANGCL 41 int regs[4]; 42 __cpuidex(regs, static_cast<int>(level), static_cast<int>(count)); 43 for (int i = 0; i < 4; ++i) { 44 abcd[i] = static_cast<uint32_t>(regs[i]); 45 } 46 #else // HWY_COMPILER_MSVC || HWY_COMPILER_CLANGCL 47 uint32_t a; 48 uint32_t b; 49 uint32_t c; 50 uint32_t d; 51 __cpuid_count(level, count, a, b, c, d); 52 abcd[0] = a; 53 abcd[1] = b; 54 abcd[2] = c; 55 abcd[3] = d; 56 #endif // HWY_COMPILER_MSVC || HWY_COMPILER_CLANGCL 57 } 58 59 static inline bool IsBitSet(const uint32_t reg, const int index) { 60 return (reg & (1U << index)) != 0; 61 } 62 63 static inline uint32_t MaxLevel() { 64 uint32_t abcd[4]; 65 Cpuid(0, 0, abcd); 66 return abcd[0]; 67 } 68 69 static inline bool IsAMD() { 70 uint32_t abcd[4]; 71 Cpuid(0, 0, abcd); 72 const uint32_t max_level = abcd[0]; 73 return max_level >= 1 && abcd[1] == 0x68747541 && abcd[2] == 0x444d4163 && 74 abcd[3] == 0x69746e65; 75 } 76 77 } // namespace x86 78 } // namespace hwy 79 80 #endif // HWY_ARCH_X86 81 #endif // HIGHWAY_HWY_X86_CPUID_H_