From: Christian Weisgerber Subject: libm i386: make use of __builtin_cpu_supports() To: tech@openbsd.org Date: Sun, 26 Jul 2026 01:05:03 +0200 On i386, libm queries the machdep.sse sysctl to check at runtime whether the CPU supports SSE. kettenis@ has pointed out elsewhere that the compiler runtime on x86 now provides a CPU feature array that we can test with __builtin_cpu_supports(). No need to handroll this ourselves. So let's switch over. OK? Index: arch/i387/fenv.c =================================================================== RCS file: /cvs/src/lib/libm/arch/i387/fenv.c,v diff -u -p -r1.7 fenv.c --- arch/i387/fenv.c 27 Dec 2022 17:10:07 -0000 1.7 +++ arch/i387/fenv.c 25 Jul 2026 22:17:23 -0000 @@ -29,7 +29,6 @@ #include #include -#include #include #include @@ -63,30 +62,10 @@ fenv_t __fe_dfl_env = { }; /* - * Test for SSE support on this processor. - * * We need to use ldmxcsr/stmxcsr to get correct results if any part * of the program was compiled to use SSE floating-point, but we can't * use SSE on older processors. - * - * In order to do so, we need to query the processor capabilities via the CPUID - * instruction. We can make it even simpler though, by querying the machdep.sse - * sysctl. */ -static int __HAS_SSE = 0; - -static void __test_sse(void) __attribute__ ((constructor)); - -static void __test_sse(void) -{ - size_t oldlen = sizeof(__HAS_SSE); - int mib[2] = { CTL_MACHDEP, CPU_SSE }; - int rv; - - rv = sysctl(mib, 2, &__HAS_SSE, &oldlen, NULL, 0); - if (rv == -1) - __HAS_SSE = 0; -} /* * The feclearexcept() function clears the supported floating-point exceptions @@ -110,7 +89,7 @@ feclearexcept(int excepts) __asm__ volatile ("fldenv %0" : : "m" (fenv)); /* Same for SSE environment */ - if (__HAS_SSE) { + if (__builtin_cpu_supports("sse")) { __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr)); mxcsr &= ~excepts; __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr)); @@ -137,7 +116,7 @@ fegetexceptflag(fexcept_t *flagp, int ex __asm__ volatile ("fnstsw %0" : "=am" (status)); /* Store the MXCSR register */ - if (__HAS_SSE) + if (__builtin_cpu_supports("sse")) __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr)); /* Store the results in flagp */ @@ -192,7 +171,7 @@ fesetexceptflag(const fexcept_t *flagp, __asm__ volatile ("fldenv %0" : : "m" (fenv)); /* Same for SSE environment */ - if (__HAS_SSE) { + if (__builtin_cpu_supports("sse")) { __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr)); mxcsr &= ~excepts; mxcsr |= *flagp & excepts; @@ -220,7 +199,7 @@ fetestexcept(int excepts) __asm__ volatile ("fnstsw %0" : "=am" (status)); /* Store the MXCSR register state */ - if (__HAS_SSE) + if (__builtin_cpu_supports("sse")) __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr)); return ((status | mxcsr) & excepts); @@ -273,7 +252,7 @@ fesetround(int round) __asm__ volatile ("fldcw %0" : : "m" (control)); /* Same for the SSE environment */ - if (__HAS_SSE) { + if (__builtin_cpu_supports("sse")) { __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr)); mxcsr &= ~(_X87_ROUND_MASK << _SSE_ROUND_SHIFT); mxcsr |= round << _SSE_ROUND_SHIFT; @@ -295,7 +274,7 @@ fegetenv(fenv_t *envp) __asm__ volatile ("fnstenv %0" : "=m" (*envp)); /* Store the MXCSR register state */ - if (__HAS_SSE) + if (__builtin_cpu_supports("sse")) __asm__ volatile ("stmxcsr %0" : "=m" (envp->__mxcsr)); /* @@ -329,7 +308,7 @@ feholdexcept(fenv_t *envp) /* Clear all exception flags in FPU */ __asm__ volatile ("fnclex"); - if (__HAS_SSE) { + if (__builtin_cpu_supports("sse")) { /* Store the MXCSR register state */ __asm__ volatile ("stmxcsr %0" : "=m" (envp->__mxcsr)); @@ -363,7 +342,7 @@ fesetenv(const fenv_t *envp) __asm__ volatile ("fldenv %0" : : "m" (*envp)); /* Store the MXCSR register */ - if (__HAS_SSE) + if (__builtin_cpu_supports("sse")) __asm__ volatile ("ldmxcsr %0" : : "m" (envp->__mxcsr)); return (0); @@ -388,7 +367,7 @@ feupdateenv(const fenv_t *envp) __asm__ volatile ("fnstsw %0" : "=am" (status)); /* Store the MXCSR register */ - if (__HAS_SSE) + if (__builtin_cpu_supports("sse")) __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr)); /* Install new floating-point environment */ @@ -413,14 +392,14 @@ feenableexcept(int mask) mask &= FE_ALL_EXCEPT; __asm__ volatile ("fnstcw %0" : "=m" (control)); - if (__HAS_SSE) + if (__builtin_cpu_supports("sse")) __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr)); omask = ~(control | (mxcsr >> _SSE_MASK_SHIFT)) & FE_ALL_EXCEPT; control &= ~mask; __asm__ volatile ("fldcw %0" : : "m" (control)); - if (__HAS_SSE) { + if (__builtin_cpu_supports("sse")) { mxcsr &= ~(mask << _SSE_MASK_SHIFT); __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr)); } @@ -437,14 +416,14 @@ fedisableexcept(int mask) mask &= FE_ALL_EXCEPT; __asm__ volatile ("fnstcw %0" : "=m" (control)); - if (__HAS_SSE) + if (__builtin_cpu_supports("sse")) __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr)); omask = ~(control | (mxcsr >> _SSE_MASK_SHIFT)) & FE_ALL_EXCEPT; control |= mask; __asm__ volatile ("fldcw %0" : : "m" (control)); - if (__HAS_SSE) { + if (__builtin_cpu_supports("sse")) { mxcsr |= mask << _SSE_MASK_SHIFT; __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr)); } -- Christian "naddy" Weisgerber naddy@mips.inka.de