From acbe16df89091f3b120c59155a5683aac4dd8b1f Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 30 May 2015 20:26:39 +0100 Subject: [PATCH] base/dispatch.c: Check operating system support for XMM registers. I found a technique for doing this described by Agner Fog: see http://www.agner.org/optimize/#manual_asm which is conveniently independent of any particular system. Quite why Intel don't document this clearly is something of a mystery to me. --- base/dispatch.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/base/dispatch.c b/base/dispatch.c index 08c189cd..87d41b3a 100644 --- a/base/dispatch.c +++ b/base/dispatch.c @@ -43,6 +43,7 @@ #define EFLAGS_ID (1u << 21) #define CPUID1D_SSE2 (1u << 26) +#define CPUID1D_FXSR (1u << 24) struct cpuid { unsigned a, b, c, d; }; @@ -107,6 +108,30 @@ static int cpuid_features_p(unsigned dbits, unsigned cbits) return ((c.d & dbits) == dbits && (c.c & cbits) == cbits); } +static int xmm_registers_available_p(void) +{ +#ifdef __GNUC__ + unsigned f; + /* This hack is by Agner Fog. Use FXSAVE/FXRSTOR to figure out whether the + * XMM registers are actually alive. + */ + if (!cpuid_features_p(CPUID1D_FXSR, 0)) return (0); + __asm__ ("movl %%esp, %%edx; subl $512, %%esp; andl $~15, %%esp\n" + "fxsave (%%esp)\n" + "movl 160(%%esp), %%eax; xorl $0xaaaa5555, 160(%%esp)\n" + "fxrstor (%%esp); fxsave (%%esp)\n" + "movl 160(%%esp), %%ecx; movl %%eax, 160(%%esp)\n" + "fxrstor (%%esp); movl %%edx, %%esp\n" + "xorl %%ecx, %%eax" + : "=a" (f) + : /* no inputs */ + : "%ecx", "%edx"); + return (f); +#else + return (0); +#endif +} + #endif /* --- @check_env@ --- * @@ -168,7 +193,8 @@ int cpu_feature_p(int feat) #ifdef CPUFAM_X86 case CPUFEAT_X86_SSE2: { CHECK_ENV("x86:sse2"); - return (cpuid_features_p(CPUID1D_SSE2, 0)); + return (xmm_registers_available_p() && + cpuid_features_p(CPUID1D_SSE2, 0)); } #endif default: -- 2.11.0