/* * Copyright © 2010-2011 Université Bordeaux 1 * Copyright © 2010 Cisco Systems, Inc. All rights reserved. * * See COPYING in top-level directory. */ /* Internals for x86's cpuid. */ #ifndef HWLOC_PRIVATE_CPUID_H #define HWLOC_PRIVATE_CPUID_H #ifdef HWLOC_X86_32_ARCH static __hwloc_inline int hwloc_have_cpuid(void) { int ret; unsigned tmp, tmp2; asm( "mov $0,%0\n\t" /* Not supported a priori */ "pushfl \n\t" /* Save flags */ "pushfl \n\t" \ "pop %1 \n\t" /* Get flags */ \ #define TRY_TOGGLE \ "xor $0x00200000,%1\n\t" /* Try to toggle ID */ \ "mov %1,%2\n\t" /* Save expected value */ \ "push %1 \n\t" \ "popfl \n\t" /* Try to toggle */ \ "pushfl \n\t" \ "pop %1 \n\t" \ "cmp %1,%2\n\t" /* Compare with expected value */ \ "jnz Lhwloc1\n\t" /* Unexpected, failure */ \ TRY_TOGGLE /* Try to set/clear */ TRY_TOGGLE /* Try to clear/set */ "mov $1,%0\n\t" /* Passed the test! */ "Lhwloc1: \n\t" "popfl \n\t" /* Restore flags */ : "=r" (ret), "=&r" (tmp), "=&r" (tmp2)); return ret; } #endif /* HWLOC_X86_32_ARCH */ #ifdef HWLOC_X86_64_ARCH static __hwloc_inline int hwloc_have_cpuid(void) { return 1; } #endif /* HWLOC_X86_64_ARCH */ static __hwloc_inline void hwloc_cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) { asm( #ifdef HWLOC_X86_32_ARCH "push %%ebx\n\t" #endif "cpuid\n\t" #ifdef HWLOC_X86_32_ARCH "mov %%ebx,%1\n\t" "pop %%ebx\n\t" #endif : "+a" (*eax), #ifdef HWLOC_X86_32_ARCH "=r" (*ebx), #else "=b" (*ebx), #endif "+c" (*ecx), "=d" (*edx)); } #endif /* HWLOC_PRIVATE_CPUID_H */