/*----- Intel x86/AMD64 feature probing -----------------------------------*/
-#ifdef CPUFAM_X86
+#if CPUFAM_X86 || CPUFAM_AMD64
-#define EFLAGS_ID (1u << 21)
-#define CPUID1D_SSE2 (1u << 26)
-#define CPUID1D_FXSR (1u << 24)
-#define CPUID1C_AESNI (1u << 25)
+# define EFLAGS_ID (1u << 21)
+# define CPUID1D_SSE2 (1u << 26)
+# define CPUID1D_FXSR (1u << 24)
+# define CPUID1C_AESNI (1u << 25)
struct cpuid { unsigned a, b, c, d; };
*/
#ifdef __GNUC__
+# if CPUFAM_X86
static __inline__ unsigned getflags(void)
{ unsigned f; __asm__ ("pushf; popl %0" : "=g" (f)); return (f); }
static __inline__ unsigned setflags(unsigned f)
: "g" (f));
return (ff);
}
+# else
+static __inline__ unsigned long getflags(void)
+ { unsigned long f; __asm__ ("pushf; popq %0" : "=g" (f)); return (f); }
+static __inline__ unsigned long long setflags(unsigned long f)
+{
+ unsigned long ff;
+ __asm__ ("pushf; pushq %1; popf; pushf; popq %0; popf"
+ : "=g" (ff)
+ : "g" (f));
+ return (ff);
+}
+# endif
#endif
static void cpuid(struct cpuid *cc, unsigned a, unsigned c)
/* Alas, EBX is magical in PIC code, so abuse ESI instead. This isn't
* pretty, but it works.
*/
+# if CPUFAM_X86
__asm__ ("pushl %%ebx; cpuid; movl %%ebx, %%esi; popl %%ebx"
: "=a" (cc->a), "=S" (cc->b), "=c" (cc->c), "=d" (cc->d)
: "a" (a) , "c" (c));
+# elif CPUFAM_AMD64
+ __asm__ ("pushq %%rbx; cpuid; movl %%ebx, %%esi; popq %%rbx"
+ : "=a" (cc->a), "=S" (cc->b), "=c" (cc->c), "=d" (cc->d)
+ : "a" (a) , "c" (c));
+# else
+# error "I'm confused."
+# endif
+ dispatch_debug("CPUID(%08x, %08x) -> %08x, %08x, %08x, %08x",
+ a, c, cc->a, cc->b, cc->c, cc->d);
#else
dispatch_debug("GNU inline assembler not available; can't CPUID");
#endif
* XMM registers are actually alive.
*/
if (!cpuid_features_p(CPUID1D_FXSR, 0)) return (0);
+# if CPUFAM_X86
__asm__ ("movl %%esp, %%edx; subl $512, %%esp; andl $~15, %%esp\n"
"fxsave (%%esp)\n"
"movl 160(%%esp), %%eax; xorl $0xaaaa5555, 160(%%esp)\n"
: "=a" (f)
: /* no inputs */
: "%ecx", "%edx");
+# elif CPUFAM_AMD64
+ __asm__ ("movq %%rsp, %%rdx; subq $512, %%rsp; andq $~15, %%rsp\n"
+ "fxsave (%%rsp)\n"
+ "movl 160(%%rsp), %%eax; xorl $0xaaaa5555, 160(%%rsp)\n"
+ "fxrstor (%%rsp); fxsave (%%rsp)\n"
+ "movl 160(%%rsp), %%ecx; movl %%eax, 160(%%rsp)\n"
+ "fxrstor (%%rsp); movq %%rdx, %%rsp\n"
+ "xorl %%ecx, %%eax"
+ : "=a" (f)
+ : /* no inputs */
+ : "%ecx", "%rdx");
+# else
+# error "I'm confused."
+# endif
+ dispatch_debug("XMM registers %savailable", f ? "" : "not ");
return (f);
#else
dispatch_debug("GNU inline assembler not available; can't check for XMM");
return (feat_debug(ftok, "runtime probe", cond));
switch (feat) {
-#ifdef CPUFAM_X86
+#if CPUFAM_X86 || CPUFAM_AMD64
CASE_CPUFEAT(X86_SSE2, "x86:sse2",
xmm_registers_available_p() &&
cpuid_features_p(CPUID1D_SSE2, 0));