OpenMPI  0.1.1
cpuid.h
1 /*
2  * Copyright © 2010-2012 Université Bordeaux 1
3  * Copyright © 2010 Cisco Systems, Inc. All rights reserved.
4  *
5  * See COPYING in top-level directory.
6  */
7 
8 /* Internals for x86's cpuid. */
9 
10 #ifndef HWLOC_PRIVATE_CPUID_H
11 #define HWLOC_PRIVATE_CPUID_H
12 
13 #ifdef HWLOC_X86_32_ARCH
14 static __hwloc_inline int hwloc_have_cpuid(void)
15 {
16  int ret;
17  unsigned tmp, tmp2;
18  asm(
19  "mov $0,%0\n\t" /* Not supported a priori */
20 
21  "pushfl \n\t" /* Save flags */
22 
23  "pushfl \n\t" \
24  "pop %1 \n\t" /* Get flags */ \
25 
26 #define TRY_TOGGLE \
27  "xor $0x00200000,%1\n\t" /* Try to toggle ID */ \
28  "mov %1,%2\n\t" /* Save expected value */ \
29  "push %1 \n\t" \
30  "popfl \n\t" /* Try to toggle */ \
31  "pushfl \n\t" \
32  "pop %1 \n\t" \
33  "cmp %1,%2\n\t" /* Compare with expected value */ \
34  "jnz Lhwloc1\n\t" /* Unexpected, failure */ \
35 
36  TRY_TOGGLE /* Try to set/clear */
37  TRY_TOGGLE /* Try to clear/set */
38 
39  "mov $1,%0\n\t" /* Passed the test! */
40 
41  "Lhwloc1: \n\t"
42  "popfl \n\t" /* Restore flags */
43 
44  : "=r" (ret), "=&r" (tmp), "=&r" (tmp2));
45  return ret;
46 }
47 #endif /* HWLOC_X86_32_ARCH */
48 #ifdef HWLOC_X86_64_ARCH
49 static __hwloc_inline int hwloc_have_cpuid(void) { return 1; }
50 #endif /* HWLOC_X86_64_ARCH */
51 
52 static __hwloc_inline void hwloc_cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
53 {
54 #ifdef HWLOC_X86_64_ARCH
55  unsigned long sav_ebx;
56 #endif
57  asm(
58 #ifdef HWLOC_X86_32_ARCH
59  "push %%ebx\n\t"
60 #else
61  "mov %%rbx,%2\n\t"
62 #endif
63  "cpuid\n\t"
64 #ifdef HWLOC_X86_32_ARCH
65  "mov %%ebx,%1\n\t"
66  "pop %%ebx\n\t"
67 #else
68  "mov %%ebx,%1\n\t"
69  "mov %2,%%rbx\n\t"
70 #endif
71  : "+a" (*eax), "=r" (*ebx), "=r"(sav_ebx), "+c" (*ecx), "=d" (*edx));
72 }
73 
74 #endif /* HWLOC_PRIVATE_CPUID_H */