aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2021-01-09 13:12:15 -0500
committerJack Lloyd <[email protected]>2021-01-09 13:12:15 -0500
commit5923dee1ca2f1458b675b38dc863a0e5f7da7917 (patch)
tree0eba43757a6b62fca5a661c4d185fb348c8b7107 /src/lib/utils
parent854b79287818a01137aa78e59e36ab10240bf13b (diff)
Avoid using macros in x86 cpuid code
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/cpuid/cpuid.h2
-rw-r--r--src/lib/utils/cpuid/cpuid_x86.cpp65
2 files changed, 41 insertions, 26 deletions
diff --git a/src/lib/utils/cpuid/cpuid.h b/src/lib/utils/cpuid/cpuid.h
index 102ed9593..9e85091b9 100644
--- a/src/lib/utils/cpuid/cpuid.h
+++ b/src/lib/utils/cpuid/cpuid.h
@@ -98,7 +98,7 @@ class BOTAN_PUBLIC_API(2,1) CPUID final
CPUID_AVX512DQ_BIT = (1ULL << 6),
CPUID_AVX512BW_BIT = (1ULL << 7),
- // Ice Lake profile: AVX-512 F, DQ, BW, IFMA, VBMI, VBMI2, BITALG
+ // Ice Lake profile: AVX-512 F, DQ, BW, VL, IFMA, VBMI, VBMI2, BITALG
CPUID_AVX512_ICL_BIT = (1ULL << 11),
// Crypto-specific ISAs
diff --git a/src/lib/utils/cpuid/cpuid_x86.cpp b/src/lib/utils/cpuid/cpuid_x86.cpp
index 51e51fa8e..fb0c2fbcd 100644
--- a/src/lib/utils/cpuid/cpuid_x86.cpp
+++ b/src/lib/utils/cpuid/cpuid_x86.cpp
@@ -25,41 +25,59 @@ namespace Botan {
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
-uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size)
+namespace {
+
+void invoke_cpuid(uint32_t type, uint32_t out[4])
{
#if defined(BOTAN_BUILD_COMPILER_IS_MSVC)
- #define X86_CPUID(type, out) do { __cpuid((int*)out, type); } while(0)
- #define X86_CPUID_SUBLEVEL(type, level, out) do { __cpuidex((int*)out, type, level); } while(0)
+ __cpuid((int*)out, type);
#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL)
- #define X86_CPUID(type, out) do { __cpuid(out, type); } while(0)
- #define X86_CPUID_SUBLEVEL(type, level, out) do { __cpuidex((int*)out, type, level); } while(0)
+ __cpuid(out, type);
#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && defined(BOTAN_USE_GCC_INLINE_ASM)
- #define X86_CPUID(type, out) \
- asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \
- : "0" (type))
-
- #define X86_CPUID_SUBLEVEL(type, level, out) \
- asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \
- : "0" (type), "2" (level))
+ asm("cpuid\n\t"
+ : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3])
+ : "0" (type));
#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG)
- #define X86_CPUID(type, out) do { __get_cpuid(type, out, out+1, out+2, out+3); } while(0)
+ __get_cpuid(type, out, out+1, out+2, out+3);
+#else
+ #warning "No way of calling x86 cpuid instruction for this compiler"
+ clear_mem(out, 4);
+#endif
+ }
+
+void invoke_cpuid_sublevel(uint32_t type, uint32_t level, uint32_t out[4])
+ {
+#if defined(BOTAN_BUILD_COMPILER_IS_MSVC)
+ __cpuidex((int*)out, type, level);
+
+#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL)
+ __cpuidex((int*)out, type, level);
+
+#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && defined(BOTAN_USE_GCC_INLINE_ASM)
+ asm("cpuid\n\t"
+ : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \
+ : "0" (type), "2" (level));
- #define X86_CPUID_SUBLEVEL(type, level, out) \
- do { __cpuid_count(type, level, out[0], out[1], out[2], out[3]); } while(0)
+#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG)
+ __cpuid_count(type, level, out[0], out[1], out[2], out[3]);
#else
- #warning "No way of calling x86 cpuid instruction for this compiler"
- #define X86_CPUID(type, out) do { clear_mem(out, 4); } while(0)
- #define X86_CPUID_SUBLEVEL(type, level, out) do { clear_mem(out, 4); } while(0)
+ #warning "No way of calling x86 cpuid instruction for this compiler"
+ clear_mem(out, 4);
#endif
+ }
+}
+
+uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size)
+ {
uint64_t features_detected = 0;
uint32_t cpuid[4] = { 0 };
// CPUID 0: vendor identification, max sublevel
- X86_CPUID(0, cpuid);
+ invoke_cpuid(0, cpuid);
const uint32_t max_supported_sublevel = cpuid[0];
@@ -71,7 +89,7 @@ uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size)
if(max_supported_sublevel >= 1)
{
// CPUID 1: feature bits
- X86_CPUID(1, cpuid);
+ invoke_cpuid(1, cpuid);
const uint64_t flags0 = (static_cast<uint64_t>(cpuid[2]) << 32) | cpuid[3];
enum x86_CPUID_1_bits : uint64_t {
@@ -111,14 +129,14 @@ uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size)
else if(is_amd)
{
// AMD puts it in vendor zone
- X86_CPUID(0x80000005, cpuid);
+ invoke_cpuid(0x80000005, cpuid);
*cache_line_size = get_byte(3, cpuid[2]);
}
if(max_supported_sublevel >= 7)
{
clear_mem(cpuid, 4);
- X86_CPUID_SUBLEVEL(7, 0, cpuid);
+ invoke_cpuid_sublevel(7, 0, cpuid);
enum x86_CPUID_7_bits : uint64_t {
BMI1 = (1ULL << 3),
@@ -204,9 +222,6 @@ uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size)
features_detected |= CPUID::CPUID_SHA_BIT;
}
-#undef X86_CPUID
-#undef X86_CPUID_SUBLEVEL
-
/*
* If we don't have access to CPUID, we can still safely assume that
* any x86-64 processor has SSE2 and RDTSC