boost::winapi::HMODULE_ hKernel32 = boost::winapi::GetModuleHandleW(L"kernel32.dll");
if (hKernel32)
{
- typedef uint64_t (WINAPI* get_enabled_extended_features_t)(uint64_t);
+ typedef uint64_t (BOOST_WINAPI_WINAPI_CC* get_enabled_extended_features_t)(uint64_t);
get_enabled_extended_features_t get_enabled_extended_features = (get_enabled_extended_features_t)boost::winapi::get_proc_address(hKernel32, "GetEnabledExtendedFeatures");
if (get_enabled_extended_features)
{
static void cpuid(uint32_t& eax, uint32_t& ebx, uint32_t& ecx, uint32_t& edx)
{
#if defined(__GNUC__)
-#if defined(__i386__) && defined(__PIC__) && __PIC__ != 0
- // We have to backup ebx in 32 bit PIC code because it is reserved by the ABI
- uint32_t ebx_backup;
+#if (defined(__i386__) || defined(__VXWORKS__)) && (defined(__PIC__) || defined(__PIE__)) && !(defined(__clang__) || (defined(BOOST_GCC) && BOOST_GCC >= 50100))
+ // Unless the compiler can do it automatically, we have to backup ebx in 32-bit PIC/PIE code because it is reserved by the ABI.
+ // For VxWorks ebx is reserved on 64-bit as well.
+#if defined(__x86_64__)
+ uint64_t rbx = ebx;
__asm__ __volatile__
(
- "movl %%ebx, %0\n\t"
- "movl %1, %%ebx\n\t"
+ "xchgq %%rbx, %0\n\t"
"cpuid\n\t"
- "movl %%ebx, %1\n\t"
- "movl %0, %%ebx\n\t"
- : "=m" (ebx_backup), "+m" (ebx), "+a" (eax), "+c" (ecx), "+d" (edx)
+ "xchgq %%rbx, %0\n\t"
+ : "+DS" (rbx), "+a" (eax), "+c" (ecx), "+d" (edx)
);
+ ebx = static_cast< uint32_t >(rbx);
+#else // defined(__x86_64__)
+ __asm__ __volatile__
+ (
+ "xchgl %%ebx, %0\n\t"
+ "cpuid\n\t"
+ "xchgl %%ebx, %0\n\t"
+ : "+DS" (ebx), "+a" (eax), "+c" (ecx), "+d" (edx)
+ );
+#endif // defined(__x86_64__)
#else
__asm__ __volatile__
(