blob: 60522d2dcea795e50af61fc52c46d29029d91f29 [file] [log] [blame] [raw]
/*
* 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 */