mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-07 07:55:04 -05:00
87 lines
2.6 KiB
C
87 lines
2.6 KiB
C
/*
|
|
* Copyright © 2010-2012, 2014 Université Bordeaux
|
|
* Copyright © 2010 Cisco Systems, Inc. All rights reserved.
|
|
* Copyright © 2014 Inria. All rights reserved.
|
|
*
|
|
* See COPYING in top-level directory.
|
|
*/
|
|
|
|
/* Internals for x86's cpuid. */
|
|
|
|
#ifndef HWLOC_PRIVATE_CPUID_X86_H
|
|
#define HWLOC_PRIVATE_CPUID_X86_H
|
|
|
|
#if (defined HWLOC_X86_32_ARCH) && (!defined HWLOC_HAVE_MSVC_CPUIDEX)
|
|
static __hwloc_inline int hwloc_have_x86_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 0f\n\t" /* Unexpected, failure */ \
|
|
|
|
TRY_TOGGLE /* Try to set/clear */
|
|
TRY_TOGGLE /* Try to clear/set */
|
|
|
|
"mov $1,%0\n\t" /* Passed the test! */
|
|
|
|
"0: \n\t"
|
|
"popfl \n\t" /* Restore flags */
|
|
|
|
: "=r" (ret), "=&r" (tmp), "=&r" (tmp2));
|
|
return ret;
|
|
}
|
|
#endif /* !defined HWLOC_X86_32_ARCH && !defined HWLOC_HAVE_MSVC_CPUIDEX*/
|
|
#if (defined HWLOC_X86_64_ARCH) || (defined HWLOC_HAVE_MSVC_CPUIDEX)
|
|
static __hwloc_inline int hwloc_have_x86_cpuid(void) { return 1; }
|
|
#endif /* HWLOC_X86_64_ARCH */
|
|
|
|
static __hwloc_inline void hwloc_x86_cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
|
|
{
|
|
#ifdef HWLOC_HAVE_MSVC_CPUIDEX
|
|
int regs[4];
|
|
__cpuidex(regs, *eax, *ecx);
|
|
*eax = regs[0];
|
|
*ebx = regs[1];
|
|
*ecx = regs[2];
|
|
*edx = regs[3];
|
|
#else /* HWLOC_HAVE_MSVC_CPUIDEX */
|
|
/* Note: gcc might want to use bx or the stack for %1 addressing, so we can't
|
|
* use them :/ */
|
|
#ifdef HWLOC_X86_64_ARCH
|
|
hwloc_uint64_t sav_rbx;
|
|
__asm__(
|
|
"mov %%rbx,%2\n\t"
|
|
"cpuid\n\t"
|
|
"xchg %2,%%rbx\n\t"
|
|
"movl %k2,%1\n\t"
|
|
: "+a" (*eax), "=m" (*ebx), "=&r"(sav_rbx),
|
|
"+c" (*ecx), "=&d" (*edx));
|
|
#elif defined(HWLOC_X86_32_ARCH)
|
|
__asm__(
|
|
"mov %%ebx,%1\n\t"
|
|
"cpuid\n\t"
|
|
"xchg %%ebx,%1\n\t"
|
|
: "+a" (*eax), "=&SD" (*ebx), "+c" (*ecx), "=&d" (*edx));
|
|
#else
|
|
#error unknown architecture
|
|
#endif
|
|
#endif /* HWLOC_HAVE_MSVC_CPUIDEX */
|
|
}
|
|
|
|
#endif /* HWLOC_PRIVATE_X86_CPUID_H */
|