x86: check if we can use an xgetbv inline asm implementation

This only checks whether a call to the instruction can be made,
not that a supported function ABI can be used with asm code
like HAVE_AVX_ASM does.

The former can work while the later fails (which still allows
intrinsics-based AVX code to work).
This commit is contained in:
Frank Denis
2026-08-31 08:00:08 +02:00
parent 9608bca840
commit 403efe612e
3 changed files with 17 additions and 1 deletions
+1
View File
@@ -138,6 +138,7 @@ fn initLibConfig(b: *std.Build, target: std.Build.ResolvedTarget, lib: *Compile)
}, },
} }
lib.root_module.addCMacro("HAVE_CPUID", "1"); lib.root_module.addCMacro("HAVE_CPUID", "1");
lib.root_module.addCMacro("HAVE_XGETBV_ASM", "1");
lib.root_module.addCMacro("HAVE_MMINTRIN_H", "1"); lib.root_module.addCMacro("HAVE_MMINTRIN_H", "1");
lib.root_module.addCMacro("HAVE_EMMINTRIN_H", "1"); lib.root_module.addCMacro("HAVE_EMMINTRIN_H", "1");
lib.root_module.addCMacro("HAVE_PMMINTRIN_H", "1"); lib.root_module.addCMacro("HAVE_PMMINTRIN_H", "1");
+15
View File
@@ -840,6 +840,21 @@ __asm__ __volatile__ ("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1" :
]) ])
AC_SUBST(HAVE_CPUID_V) AC_SUBST(HAVE_CPUID_V)
AS_CASE([$host_cpu], [i?86|amd64|x86_64], [
AS_IF([test "$enable_asm" != "no"],[
AC_MSG_CHECKING(whether XGETBV can be used with inline assembly)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[
unsigned int xcr0;
__asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" :
"=a" (xcr0) :
"c" ((unsigned int) 0U) : "%edx");
]])],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_XGETBV_ASM], [1], [XGETBV can be used with inline assembly])],
[AC_MSG_RESULT(no)])
])
])
asm_hide_symbol="unsupported" asm_hide_symbol="unsupported"
AS_IF([test "$enable_asm" != "no"],[ AS_IF([test "$enable_asm" != "no"],[
AC_MSG_CHECKING(if the .private_extern asm directive is supported) AC_MSG_CHECKING(if the .private_extern asm directive is supported)
+1 -1
View File
@@ -260,7 +260,7 @@ _sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features)
pop ecx pop ecx
pop eax pop eax
} }
# elif defined(HAVE_AVX_ASM) # elif defined(HAVE_AVX_ASM) || defined(HAVE_XGETBV_ASM)
__asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" /* XGETBV */ __asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" /* XGETBV */
: "=a"(xcr0) : "=a"(xcr0)
: "c"((uint32_t) 0U) : "c"((uint32_t) 0U)