From: VMware, Inc <> Date: Thu, 22 Dec 2011 00:15:52 +0000 (-0800) Subject: Changes in shared code that don't affect open-vm-tools functionality. X-Git-Tag: 2011.12.20-562307~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0888ef1feaf14e2c98df82507450ad847abe0dc8;p=thirdparty%2Fopen-vm-tools.git Changes in shared code that don't affect open-vm-tools functionality. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/include/vm_atomic.h b/open-vm-tools/lib/include/vm_atomic.h index 06bad3fb6..80a050040 100644 --- a/open-vm-tools/lib/include/vm_atomic.h +++ b/open-vm-tools/lib/include/vm_atomic.h @@ -66,61 +66,6 @@ typedef struct Atomic_uint64 { } Atomic_uint64 ALIGNED(8); -/* - * Prototypes for msft atomics. These are defined & inlined by the - * compiler so no function definition is needed. The prototypes are - * needed for c++. Since amd64 compiler doesn't support inline asm we - * have to use these. Unfortunately, we still have to use some inline asm - * for the 32 bit code since the and/or/xor implementations didn't show up - * untill xp or 2k3. - * - * The declarations for the intrinsic functions were taken from ntddk.h - * in the DDK. The declarations must match otherwise the 64-bit c++ - * compiler will complain about second linkage of the intrinsic functions. - * We define the intrinsic using the basic types corresponding to the - * Windows typedefs. This avoids having to include windows header files - * to get to the windows types. - */ -#if defined(_MSC_VER) && _MSC_VER >= 1310 -#ifdef __cplusplus -extern "C" { -#endif -long _InterlockedExchange(long volatile*, long); -long _InterlockedCompareExchange(long volatile*, long, long); -long _InterlockedExchangeAdd(long volatile*, long); -long _InterlockedDecrement(long volatile*); -long _InterlockedIncrement(long volatile*); -#pragma intrinsic(_InterlockedExchange, _InterlockedCompareExchange) -#pragma intrinsic(_InterlockedExchangeAdd, _InterlockedDecrement) -#pragma intrinsic(_InterlockedIncrement) - -#if defined(VM_X86_64) -long _InterlockedAnd(long volatile*, long); -__int64 _InterlockedAnd64(__int64 volatile*, __int64); -long _InterlockedOr(long volatile*, long); -__int64 _InterlockedOr64(__int64 volatile*, __int64); -long _InterlockedXor(long volatile*, long); -__int64 _InterlockedXor64(__int64 volatile*, __int64); -__int64 _InterlockedExchangeAdd64(__int64 volatile*, __int64); -__int64 _InterlockedIncrement64(__int64 volatile*); -__int64 _InterlockedDecrement64(__int64 volatile*); -__int64 _InterlockedExchange64(__int64 volatile*, __int64); -__int64 _InterlockedCompareExchange64(__int64 volatile*, __int64, __int64); -#if !defined(_WIN64) -#pragma intrinsic(_InterlockedAnd, _InterlockedAnd64) -#pragma intrinsic(_InterlockedOr, _InterlockedOr64) -#pragma intrinsic(_InterlockedXor, _InterlockedXor64) -#pragma intrinsic(_InterlockedExchangeAdd64, _InterlockedIncrement64) -#pragma intrinsic(_InterlockedDecrement64, _InterlockedExchange64) -#pragma intrinsic(_InterlockedCompareExchange64) -#endif /* !_WIN64 */ -#endif /* __x86_64__ */ - -#ifdef __cplusplus -} -#endif -#endif /* _MSC_VER */ - /* * LDREX without STREX or CLREX may cause problems in environments where the * context switch may not clear the reference monitor - according ARM manual @@ -400,20 +345,8 @@ Atomic_ReadWrite(Atomic_uint32 *var, // IN return val; #endif // VM_ARM_V7 #elif defined _MSC_VER -#if _MSC_VER >= 1310 return _InterlockedExchange((long *)&var->value, (long)val); #else -#pragma warning(push) -#pragma warning(disable : 4035) // disable no-return warning - { - __asm mov eax, val - __asm mov ebx, var - __asm xchg [ebx]Atomic_uint32.value, eax - // eax is the return value, this is documented to work - edward - } -#pragma warning(pop) -#endif // _MSC_VER >= 1310 -#else #error No compiler defined for Atomic_ReadWrite #endif // __GNUC__ } @@ -479,24 +412,9 @@ Atomic_ReadIfEqualWrite(Atomic_uint32 *var, // IN return val; #endif // VM_ARM_V7 #elif defined _MSC_VER -#if _MSC_VER >= 1310 return _InterlockedCompareExchange((long *)&var->value, (long)newVal, (long)oldVal); -#else -#pragma warning(push) -#pragma warning(disable : 4035) // disable no-return warning - { - __asm mov eax, oldVal - __asm mov ebx, var - __asm mov ecx, newVal - __asm lock cmpxchg [ebx]Atomic_uint32.value, ecx - // eax is the return value, this is documented to work - edward - } -#pragma warning(pop) -#endif -#else -#error No compiler defined for Atomic_ReadIfEqualWrite #endif } #define Atomic_ReadIfEqualWrite32 Atomic_ReadIfEqualWrite @@ -623,13 +541,7 @@ Atomic_And(Atomic_uint32 *var, // IN AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER -#if defined(__x86_64__) _InterlockedAnd((long *)&var->value, (long)val); -#else - __asm mov eax, val - __asm mov ebx, var - __asm lock and [ebx]Atomic_uint32.value, eax -#endif #else #error No compiler defined for Atomic_And #endif @@ -687,13 +599,7 @@ Atomic_Or(Atomic_uint32 *var, // IN AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER -#if defined(__x86_64__) _InterlockedOr((long *)&var->value, (long)val); -#else - __asm mov eax, val - __asm mov ebx, var - __asm lock or [ebx]Atomic_uint32.value, eax -#endif #else #error No compiler defined for Atomic_Or #endif @@ -751,13 +657,7 @@ Atomic_Xor(Atomic_uint32 *var, // IN AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER -#if defined(__x86_64__) _InterlockedXor((long *)&var->value, (long)val); -#else - __asm mov eax, val - __asm mov ebx, var - __asm lock xor [ebx]Atomic_uint32.value, eax -#endif #else #error No compiler defined for Atomic_Xor #endif @@ -854,13 +754,7 @@ Atomic_Add(Atomic_uint32 *var, // IN AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER -#if _MSC_VER >= 1310 _InterlockedExchangeAdd((long *)&var->value, (long)val); -#else - __asm mov eax, val - __asm mov ebx, var - __asm lock add [ebx]Atomic_uint32.value, eax -#endif #else #error No compiler defined for Atomic_Add #endif @@ -957,13 +851,7 @@ Atomic_Sub(Atomic_uint32 *var, // IN AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER -#if _MSC_VER >= 1310 _InterlockedExchangeAdd((long *)&var->value, (long)-val); -#else - __asm mov eax, val - __asm mov ebx, var - __asm lock sub [ebx]Atomic_uint32.value, eax -#endif #else #error No compiler defined for Atomic_Sub #endif @@ -1043,12 +931,7 @@ Atomic_Inc(Atomic_uint32 *var) // IN AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER -#if _MSC_VER >= 1310 _InterlockedIncrement((long *)&var->value); -#else - __asm mov ebx, var - __asm lock inc [ebx]Atomic_uint32.value -#endif #else #error No compiler defined for Atomic_Inc #endif @@ -1089,12 +972,7 @@ Atomic_Dec(Atomic_uint32 *var) // IN AtomicEpilogue(); #endif // VM_ARM_V7 #elif defined _MSC_VER -#if _MSC_VER >= 1310 _InterlockedDecrement((long *)&var->value); -#else - __asm mov ebx, var - __asm lock dec [ebx]Atomic_uint32.value -#endif #else #error No compiler defined for Atomic_Dec #endif @@ -1291,19 +1169,8 @@ Atomic_FetchAndAddUnfenced(Atomic_uint32 *var, // IN return val; #endif // VM_ARM_V7 #elif defined _MSC_VER -#if _MSC_VER >= 1310 return _InterlockedExchangeAdd((long *)&var->value, (long)val); #else -#pragma warning(push) -#pragma warning(disable : 4035) // disable no-return warning - { - __asm mov eax, val - __asm mov ebx, var - __asm lock xadd [ebx]Atomic_uint32.value, eax - } -#pragma warning(pop) -#endif -#else #error No compiler defined for Atomic_FetchAndAdd #endif } @@ -1667,29 +1534,10 @@ Atomic_CMPXCHG64(Atomic_uint64 *var, // IN/OUT return equal; #endif //VM_ARM_V7 #elif defined _MSC_VER -#if defined(__x86_64__) return (__int64)*oldVal == _InterlockedCompareExchange64((__int64 *)&var->value, (__int64)*newVal, (__int64)*oldVal); #else -#pragma warning(push) -#pragma warning(disable : 4035) // disable no-return warning - { - __asm mov esi, var - __asm mov edx, oldVal - __asm mov ecx, newVal - __asm mov eax, [edx]S_uint64.lowValue - __asm mov edx, [edx]S_uint64.highValue - __asm mov ebx, [ecx]S_uint64.lowValue - __asm mov ecx, [ecx]S_uint64.highValue - __asm lock cmpxchg8b [esi] - __asm sete al - __asm movzx eax, al - // eax is the return value, this is documented to work - edward - } -#pragma warning(pop) -#endif -#else #error No compiler defined for Atomic_CMPXCHG64 #endif // !GNUC } @@ -1807,6 +1655,7 @@ Atomic_Read64(Atomic_uint64 const *var) // IN */ return var->value; #elif defined (_MSC_VER) && defined(__i386__) +// _InterlockedCompareExchange64 is not optimal here, see the comment for gcc. # pragma warning(push) # pragma warning(disable : 4035) // disable no-return warning { @@ -2250,12 +2099,8 @@ Atomic_SetBit64(Atomic_uint64 *var, // IN/OUT ); AtomicEpilogue(); #elif defined _MSC_VER - uint64 oldVal; - uint64 newVal; - do { - oldVal = var->value; - newVal = oldVal | (CONST64U(1) << bit); - } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); + // It also works as a memory barrier for MSVC (_ReadWriteBarrier). + _interlockedbittestandset64((__int64*)&var->value, (__int64)bit); #else #error No compiler defined for Atomic_SetBit64 #endif @@ -2301,12 +2146,8 @@ Atomic_ClearBit64(Atomic_uint64 *var, // IN/OUT ); AtomicEpilogue(); #elif defined _MSC_VER - uint64 oldVal; - uint64 newVal; - do { - oldVal = var->value; - newVal = oldVal & ~(CONST64U(1) << bit); - } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal)); + // It also works as a memory barrier for MSVC (_ReadWriteBarrier). + _interlockedbittestandreset64((__int64*) &var->value, (__int64)bit); #else #error No compiler defined for Atomic_ClearBit64 #endif @@ -2354,7 +2195,7 @@ Atomic_TestBit64(Atomic_uint64 *var, // IN ); return out; #elif defined _MSC_VER - return (var->value & (CONST64U(1) << bit)) != 0; + return _bittest64((__int64*)&var->value, (__int64)bit); #else #error No compiler defined for Atomic_TestBit64 #endif diff --git a/open-vm-tools/lib/include/vm_basic_asm.h b/open-vm-tools/lib/include/vm_basic_asm.h index b47c94d2f..b62cb88ef 100644 --- a/open-vm-tools/lib/include/vm_basic_asm.h +++ b/open-vm-tools/lib/include/vm_basic_asm.h @@ -60,89 +60,6 @@ #include "vm_basic_asm_x86.h" #endif -/* - * x86-64 windows doesn't support inline asm so we have to use these - * intrinsic functions defined in the compiler. Not all of these are well - * documented. There is an array in the compiler dll (c1.dll) which has - * an array of the names of all the intrinsics minus the leading - * underscore. Searching around in the ntddk.h file can also be helpful. - * - * The declarations for the intrinsic functions were taken from the DDK. - * Our declarations must match the ddk's otherwise the 64-bit c++ compiler - * will complain about second linkage of the intrinsic functions. - * We define the intrinsic using the basic types corresponding to the - * Windows typedefs. This avoids having to include windows header files - * to get to the windows types. - */ -#ifdef _MSC_VER -#ifdef __cplusplus -extern "C" { -#endif -/* - * It seems x86 & x86-64 windows still implements these intrinsic - * functions. The documentation for the x86-64 suggest the - * __inbyte/__outbyte intrinsics even though the _in/_out work fine and - * __inbyte/__outbyte aren't supported on x86. - */ -int _inp(unsigned short); -unsigned short _inpw(unsigned short); -unsigned long _inpd(unsigned short); - -int _outp(unsigned short, int); -unsigned short _outpw(unsigned short, unsigned short); -unsigned long _outpd(uint16, unsigned long); -#pragma intrinsic(_inp, _inpw, _inpd, _outp, _outpw, _outpw, _outpd) - -/* - * Prevents compiler from re-ordering reads, writes and reads&writes. - * These functions do not add any instructions thus only affect - * the compiler ordering. - * - * See: - * `Lockless Programming Considerations for Xbox 360 and Microsoft Windows' - * http://msdn.microsoft.com/en-us/library/bb310595(VS.85).aspx - */ -void _ReadBarrier(void); -void _WriteBarrier(void); -void _ReadWriteBarrier(void); -#pragma intrinsic(_ReadBarrier, _WriteBarrier, _ReadWriteBarrier) - -void _mm_mfence(void); -void _mm_lfence(void); -#pragma intrinsic(_mm_mfence, _mm_lfence) - -#ifdef VM_X86_64 -/* - * intrinsic functions only supported by x86-64 windows as of 2k3sp1 - */ -unsigned __int64 __rdtsc(void); -void __stosw(unsigned short *, unsigned short, size_t); -void __stosd(unsigned long *, unsigned long, size_t); -void _mm_pause(void); -#pragma intrinsic(__rdtsc, __stosw, __stosd, _mm_pause) - -unsigned char _BitScanForward64(unsigned long *, unsigned __int64); -unsigned char _BitScanReverse64(unsigned long *, unsigned __int64); -#pragma intrinsic(_BitScanForward64, _BitScanReverse64) -#endif /* VM_X86_64 */ - -unsigned char _BitScanForward(unsigned long *, unsigned long); -unsigned char _BitScanReverse(unsigned long *, unsigned long); -#pragma intrinsic(_BitScanForward, _BitScanReverse) - -unsigned char _bittestandset(long *, long); -unsigned char _bittestandreset(long *, long); -#pragma intrinsic(_bittestandset, _bittestandreset) -#ifdef VM_X86_64 -unsigned char _bittestandset64(__int64 *, __int64); -unsigned char _bittestandreset64(__int64 *, __int64); -#pragma intrinsic(_bittestandset64, _bittestandreset64) -#endif /* VM_X86_64 */ -#ifdef __cplusplus -} -#endif -#endif /* _MSC_VER */ - #ifdef __GNUC__ // { #if defined(__i386__) || defined(__x86_64__) // Only on x86* @@ -196,55 +113,40 @@ __GCC_IN(l, uint32, IN32) #define OUTW(port, val) __GCC_OUT(w, w, port, val) #define OUT32(port, val) __GCC_OUT(l, , port, val) -#define GET_CURRENT_EIP(_eip) \ - __asm__ __volatile("call 0\n\tpopl %0" : "=r" (_eip): ); - #endif // x86* #elif defined(_MSC_VER) // } { static INLINE uint8 INB(uint16 port) { - return (uint8)_inp(port); + return __inbyte(port); } static INLINE void OUTB(uint16 port, uint8 value) { - _outp(port, value); + __outbyte(port, value); } static INLINE uint16 INW(uint16 port) { - return _inpw(port); + return __inword(port); } static INLINE void OUTW(uint16 port, uint16 value) { - _outpw(port, value); + __outword(port, value); } static INLINE uint32 IN32(uint16 port) { - return _inpd(port); + return __indword(port); } static INLINE void OUT32(uint16 port, uint32 value) { - _outpd(port, value); + __outdword(port, value); } -#ifndef VM_X86_64 -#ifdef NEAR -#undef NEAR -#endif - -#define GET_CURRENT_EIP(_eip) do { \ - __asm call NEAR PTR $+5 \ - __asm pop eax \ - __asm mov _eip, eax \ -} while (0) -#endif // VM_X86_64 - #else // } { #error #endif // } @@ -674,36 +576,14 @@ uint32set(void *dst, uint32 val, size_t count) static INLINE void * uint16set(void *dst, uint16 val, size_t count) { -#ifdef VM_X86_64 __stosw((uint16*)dst, val, count); -#else - __asm { pushf; - mov ax, val; - mov ecx, count; - mov edi, dst; - cld; - rep stosw; - popf; - } -#endif return dst; } static INLINE void * uint32set(void *dst, uint32 val, size_t count) { -#ifdef VM_X86_64 __stosd((unsigned long*)dst, (unsigned long)val, count); -#else - __asm { pushf; - mov eax, val; - mov ecx, count; - mov edi, dst; - cld; - rep stosd; - popf; - } -#endif return dst; } @@ -816,17 +696,9 @@ PAUSE(void) #endif } #elif defined(_MSC_VER) -#ifdef VM_X86_64 { _mm_pause(); } -#else /* VM_X86_64 */ -#pragma warning( disable : 4035) -{ - __asm _emit 0xf3 __asm _emit 0x90 -} -#pragma warning (default: 4035) -#endif /* VM_X86_64 */ #else /* __GNUC__ */ #error No compiler defined for PAUSE #endif @@ -868,17 +740,9 @@ RDTSC(void) #endif } #elif defined(_MSC_VER) -#ifdef VM_X86_64 { return __rdtsc(); } -#else -#pragma warning( disable : 4035) -{ - __asm _emit 0x0f __asm _emit 0x31 -} -#pragma warning (default: 4035) -#endif /* VM_X86_64 */ #else /* __GNUC__ */ #error No compiler defined for RDTSC #endif /* __GNUC__ */ diff --git a/open-vm-tools/lib/include/vm_basic_asm_x86_64.h b/open-vm-tools/lib/include/vm_basic_asm_x86_64.h index 64d95122c..1e27a779c 100644 --- a/open-vm-tools/lib/include/vm_basic_asm_x86_64.h +++ b/open-vm-tools/lib/include/vm_basic_asm_x86_64.h @@ -53,24 +53,6 @@ #error "This file is x86-64 only!" #endif -#ifdef _MSC_VER - -#ifdef __cplusplus -extern "C" { -#endif -uint64 _umul128(uint64 multiplier, uint64 multiplicand, - uint64 *highProduct); -int64 _mul128(int64 multiplier, int64 multiplicand, - int64 *highProduct); -uint64 __shiftright128(uint64 lowPart, uint64 highPart, uint8 shift); -#ifdef __cplusplus -} -#endif - -#pragma intrinsic(_umul128, _mul128, __shiftright128) - -#endif // _MSC_VER - /* * GET_CURRENT_RIP * diff --git a/open-vm-tools/lib/include/vm_basic_types.h b/open-vm-tools/lib/include/vm_basic_types.h index f871d474f..df53e16e0 100644 --- a/open-vm-tools/lib/include/vm_basic_types.h +++ b/open-vm-tools/lib/include/vm_basic_types.h @@ -134,6 +134,42 @@ typedef char Bool; #endif +// Intrinsic funtions. WDK/DDK has its own pragmas for intrinsic functions. +#if defined(_MSC_VER) && !defined (WINNT_DDK) +#ifndef _IVEC_H_INCLUDED +#define _IVEC_H_INCLUDED +#define _IVEC_H_INCLUDED_2 +#endif + +#ifndef _FVEC_H_INCLUDED +#define _FVEC_H_INCLUDED +#define _FVEC_H_INCLUDED_2 +#endif + +#ifndef _DVEC_H_INCLUDED +#define _DVEC_H_INCLUDED +#define _DVEC_H_INCLUDED_2 +#endif + +#include + +#ifdef _IVEC_H_INCLUDED_2 +#undef _IVEC_H_INCLUDED +#undef _IVEC_H_INCLUDED_2 +#endif + +#ifdef _FVEC_H_INCLUDED_2 +#undef _FVEC_H_INCLUDED +#undef _FVEC_H_INCLUDED_2 +#endif + +#ifdef _DVEC_H_INCLUDED_2 +#undef _DVEC_H_INCLUDED +#undef _DVEC_H_INCLUDED_2 +#endif +#endif /* _MSC_VER */ + + #if defined(__APPLE__) || defined(HAVE_STDINT_H) /* diff --git a/open-vm-tools/lib/include/x86cpuid_asm.h b/open-vm-tools/lib/include/x86cpuid_asm.h index a3b5e484c..1de11615d 100644 --- a/open-vm-tools/lib/include/x86cpuid_asm.h +++ b/open-vm-tools/lib/include/x86cpuid_asm.h @@ -49,42 +49,11 @@ #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" +#include "vm_basic_types.h" #include "vm_basic_asm.h" #include "x86cpuid.h" -/* - * x86-64 windows doesn't support inline asm so we have to use these - * intrinsic functions defined in the compiler. Not all of these are well - * documented. There is an array in the compiler dll (c1.dll) which has - * an array of the names of all the intrinsics minus the leading - * underscore. Searching around in the ntddk.h file can also be helpful. - * - * The declarations for the intrinsic functions were taken from the DDK. - * Our declarations must match the ddk's otherwise the 64-bit c++ compiler - * will complain about second linkage of the intrinsic functions. - * We define the intrinsic using the basic types corresponding to the - * Windows typedefs. This avoids having to include windows header files - * to get to the windows types. - */ -#ifdef _MSC_VER -#ifdef __cplusplus -extern "C" { -#endif -#ifdef VM_X86_64 -/* - * intrinsic functions only supported by x86-64 windows as of 2k3sp1 - */ -void __cpuid(unsigned int*, unsigned int); -#pragma intrinsic(__cpuid) -#endif /* VM_X86_64 */ - -#ifdef __cplusplus -} -#endif -#endif /* _MSC_VER */ - - #ifdef __GNUC__ // { /* @@ -236,209 +205,55 @@ __GET_EAX_FROM_CPUID4(int ecx) // IN static INLINE void __GET_CPUID(int input, CPUIDRegs *regs) { -#ifdef VM_X86_64 - __cpuid((unsigned int *)regs, input); -#else - __asm push esi - __asm push ebx - __asm push ecx - __asm push edx - - __asm mov eax, input - __asm mov esi, regs - __asm _emit 0x0f __asm _emit 0xa2 - __asm mov 0x0[esi], eax - __asm mov 0x4[esi], ebx - __asm mov 0x8[esi], ecx - __asm mov 0xC[esi], edx - - __asm pop edx - __asm pop ecx - __asm pop ebx - __asm pop esi -#endif + __cpuid((int *)regs, input); } -#ifdef VM_X86_64 - -/* - * No inline assembly in Win64. Implemented in bora/lib/misc in - * cpuidMasm64.asm. - */ - -extern void -__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs); - -#else // VM_X86_64 - static INLINE void __GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs) { - __asm push esi - __asm push ebx - __asm push ecx - __asm push edx - - __asm mov eax, inputEax - __asm mov ecx, inputEcx - __asm mov esi, regs - __asm _emit 0x0f __asm _emit 0xa2 - __asm mov 0x0[esi], eax - __asm mov 0x4[esi], ebx - __asm mov 0x8[esi], ecx - __asm mov 0xC[esi], edx - - __asm pop edx - __asm pop ecx - __asm pop ebx - __asm pop esi + __cpuidex((int *)regs, inputEax, inputEcx); } -#endif static INLINE uint32 __GET_EAX_FROM_CPUID(int input) { -#ifdef VM_X86_64 CPUIDRegs regs; - __cpuid((unsigned int *)®s, input); + __cpuid((int *)®s, input); return regs.eax; -#else - uint32 output; - - //NOT_TESTED(); - __asm push ebx - __asm push ecx - __asm push edx - - __asm mov eax, input - __asm _emit 0x0f __asm _emit 0xa2 - __asm mov output, eax - - __asm pop edx - __asm pop ecx - __asm pop ebx - - return output; -#endif } static INLINE uint32 __GET_EBX_FROM_CPUID(int input) { -#ifdef VM_X86_64 CPUIDRegs regs; - __cpuid((unsigned int *)®s, input); + __cpuid((int *)®s, input); return regs.ebx; -#else - uint32 output; - - //NOT_TESTED(); - __asm push ebx - __asm push ecx - __asm push edx - - __asm mov eax, input - __asm _emit 0x0f __asm _emit 0xa2 - __asm mov output, ebx - - __asm pop edx - __asm pop ecx - __asm pop ebx - - return output; -#endif } static INLINE uint32 __GET_ECX_FROM_CPUID(int input) { -#ifdef VM_X86_64 CPUIDRegs regs; - __cpuid((unsigned int *)®s, input); + __cpuid((int *)®s, input); return regs.ecx; -#else - uint32 output; - - //NOT_TESTED(); - __asm push ebx - __asm push ecx - __asm push edx - - __asm mov eax, input - __asm _emit 0x0f __asm _emit 0xa2 - __asm mov output, ecx - - __asm pop edx - __asm pop ecx - __asm pop ebx - - return output; -#endif } static INLINE uint32 __GET_EDX_FROM_CPUID(int input) { -#ifdef VM_X86_64 CPUIDRegs regs; - __cpuid((unsigned int *)®s, input); + __cpuid(( int *)®s, input); return regs.edx; -#else - uint32 output; - - //NOT_TESTED(); - __asm push ebx - __asm push ecx - __asm push edx - - __asm mov eax, input - __asm _emit 0x0f __asm _emit 0xa2 - __asm mov output, edx - - __asm pop edx - __asm pop ecx - __asm pop ebx - - return output; -#endif } -#ifdef VM_X86_64 - -/* - * No inline assembly in Win64. Implemented in bora/lib/misc in - * cpuidMasm64.asm. - */ - -extern uint32 -__GET_EAX_FROM_CPUID4(int inputEcx); - -#else // VM_X86_64 - static INLINE uint32 __GET_EAX_FROM_CPUID4(int inputEcx) { - uint32 output; - - //NOT_TESTED(); - __asm push ebx - __asm push ecx - __asm push edx - - __asm mov eax, 4 - __asm mov ecx, inputEcx - __asm _emit 0x0f __asm _emit 0xa2 - __asm mov output, eax - - __asm pop edx - __asm pop ecx - __asm pop ebx - - return output; + CPUIDRegs regs; + __GET_CPUID2(4, inputEcx, ®s); + return regs.eax; } -#endif // VM_X86_64 - #else // } #error #endif