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 

svn path=/trunk/; revision=53151
This commit is contained in:
Timo Kreuzer 2011-08-09 14:22:29 +00:00
parent e6f0664b39
commit bb14fcf0ac
2 changed files with 59 additions and 21 deletions

View file

@ -81,24 +81,6 @@ extern "C" {
/*** 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");
@ -108,6 +90,34 @@ __INTRIN_INLINE void _ReadWriteBarrier(void)
#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 ***/
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
@ -1438,7 +1448,7 @@ __INTRIN_INLINE void __writedr(unsigned reg, unsigned int value)
__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 unsigned long __segmentlimit(const unsigned long a)
__INTRIN_INLINE void __wbinvd(void)
{
__asm__ __volatile__("wbinvd");
__asm__ __volatile__("wbinvd" : : : "memory");
}
__INTRIN_INLINE void __lidt(void *Source)

View file

@ -13,14 +13,25 @@ void * _AddressOfReturnAddress(void);
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 __writedr(unsigned reg, unsigned int value);
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)