Author: tkreuzer Date: Tue Aug 9 14:22:29 2011 New Revision: 53151
URL: http://svn.reactos.org/svn/reactos?rev=53151&view=rev Log: [INTRIN] memory barriers - implement a fixed version of __invlpg for MSVC, since the intrinsic is broken and can generate wrong instructions, when optimization is enabled - add MSVC versions of _mm_mfence, _mm_lfence, _mm_sfence and __faststorefence - add _mm_mfence() for gcc - give _mm_lfence, _mm_sfence, __invlpg and __wbinvd proper
Modified: trunk/reactos/include/crt/mingw32/intrin_x86.h trunk/reactos/include/crt/msc/intrin.h
Modified: trunk/reactos/include/crt/mingw32/intrin_x86.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/crt/mingw32/intrin_... ============================================================================== --- trunk/reactos/include/crt/mingw32/intrin_x86.h [iso-8859-1] (original) +++ trunk/reactos/include/crt/mingw32/intrin_x86.h [iso-8859-1] Tue Aug 9 14:22:29 2011 @@ -81,24 +81,6 @@
/*** Memory barriers ***/
-#ifdef _x86_64 -__INTRIN_INLINE void __faststorefence(void) -{ - long local; - __asm__ __volatile__("lock; orl $0, %0;" : : "m"(local)); -} -#endif - -__INTRIN_INLINE void _mm_lfence(void) -{ - __asm__ __volatile__("lfence"); -} - -__INTRIN_INLINE void _mm_sfence(void) -{ - __asm__ __volatile__("sfence"); -} - __INTRIN_INLINE void _ReadWriteBarrier(void) { __asm__ __volatile__("" : : : "memory"); @@ -107,6 +89,34 @@ /* GCC only supports full barriers */ #define _ReadBarrier _ReadWriteBarrier #define _WriteBarrier _ReadWriteBarrier + +__INTRIN_INLINE void _mm_mfence(void) +{ + __asm__ __volatile__("mfence" : : : "memory"); +} + +__INTRIN_INLINE void _mm_lfence(void) +{ + _ReadBarrier(); + __asm__ __volatile__("lfence"); + _ReadBarrier(); +} + +__INTRIN_INLINE void _mm_sfence(void) +{ + _WriteBarrier(); + __asm__ __volatile__("sfence"); + _WriteBarrier(); +} + +#ifdef _x86_64 +__INTRIN_INLINE void __faststorefence(void) +{ + long local; + __asm__ __volatile__("lock; orl $0, %0;" : : "m"(local)); +} +#endif +
/*** Atomic operations ***/
@@ -1438,7 +1448,7 @@
__INTRIN_INLINE void __invlpg(void * const Address) { - __asm__("invlpg %[Address]" : : [Address] "m" (*((unsigned char *)(Address)))); + __asm__("invlpg %[Address]" : : [Address] "m" (*((unsigned char *)(Address))) : "memory"); }
@@ -1482,7 +1492,7 @@
__INTRIN_INLINE void __wbinvd(void) { - __asm__ __volatile__("wbinvd"); + __asm__ __volatile__("wbinvd" : : : "memory"); }
__INTRIN_INLINE void __lidt(void *Source)
Modified: trunk/reactos/include/crt/msc/intrin.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/crt/msc/intrin.h?re... ============================================================================== --- trunk/reactos/include/crt/msc/intrin.h [iso-8859-1] (original) +++ trunk/reactos/include/crt/msc/intrin.h [iso-8859-1] Tue Aug 9 14:22:29 2011 @@ -13,14 +13,25 @@ unsigned int __getcallerseflags(void); #pragma intrinsic(__getcallerseflags)
-/*** Atomic operations ***/ +/*** Memory barriers ***/ void _ReadWriteBarrier(void); #pragma intrinsic(_ReadWriteBarrier) void _ReadBarrier(void); #pragma intrinsic(_ReadBarrier) void _WriteBarrier(void); #pragma intrinsic(_WriteBarrier) - +void _mm_mfence(void); +#pragma intrinsic(_mm_mfence) +void _mm_lfence(void); +#pragma intrinsic(_mm_lfence) +void _mm_sfence(void); +#pragma intrinsic(_mm_sfence) +#ifdef _M_AMD64 +void __faststorefence(void); +#pragma intrinsic(__faststorefence) +#endif + +/*** Atomic operations ***/ long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand); #pragma intrinsic(_InterlockedCompareExchange) long _InterlockedExchange(volatile long * const Target, const long Value); @@ -297,6 +308,23 @@ void __invlpg(void * const Address); #pragma intrinsic(__invlpg)
+// This intrinsic is broken and generates wrong opcodes, +// when optimization is enabled! +#pragma warning(push) +#pragma warning(disable:4711) +void __forceinline __invlpg_fixed(void * const Address) +{ + _ReadWriteBarrier(); + __asm + { + mov eax, Address + invlpg [eax] + } + _ReadWriteBarrier(); +} +#pragma warning(pop) +#define __invlpg __invlpg_fixed + /*** System operations ***/ unsigned __int64 __readmsr(const int reg); #pragma intrinsic(__readmsr)