From: Mike Larkin Subject: Re: libm i386: make use of __builtin_cpu_supports() To: Christian Weisgerber Cc: tech@openbsd.org Date: Sun, 26 Jul 2026 09:22:55 -0700 On Sun, Jul 26, 2026 at 01:05:03AM +0200, Christian Weisgerber wrote: > 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? > makes sense to me. > 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 >