[CRT/BUILTINS]
[reactos.git] / reactos / include / crt / mingw32 / intrin_x86.h
index 5b6f32d..60f5ea9 100644 (file)
 extern "C" {
 #endif
 
+/*** memcopy must be memmove ***/
+__INTRIN_INLINE void* memcpy(void* dest, const void* source, size_t num)
+{
+    return memmove(dest, source, num);
+}
+
+
 /*** Stack frame juggling ***/
 #define _ReturnAddress() (__builtin_return_address(0))
 #define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1]))
 /* TODO: __getcallerseflags but how??? */
 
 /* Maybe the same for x86? */
-#ifdef _x86_64
+#ifdef __x86_64__
 #define _alloca(s) __builtin_alloca(s)
 #endif
 
-/*** Atomic operations ***/
+/*** Memory barriers ***/
 
-#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
-#define _ReadWriteBarrier() __sync_synchronize()
-#else
-__INTRIN_INLINE void _MemoryBarrier(void)
+__INTRIN_INLINE void _ReadWriteBarrier(void)
 {
        __asm__ __volatile__("" : : : "memory");
 }
-#define _ReadWriteBarrier() _MemoryBarrier()
-#endif
 
-/* BUGBUG: GCC only supports full barriers */
+/* 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 ***/
+
 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
 
 __INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
@@ -173,7 +205,7 @@ __INTRIN_INLINE long _InterlockedAnd(volatile long * const value, const long mas
 }
 
 #if defined(_M_AMD64)
-__INTRIN_INLINE long _InterlockedAnd64(volatile long long * const value, const long long mask)
+__INTRIN_INLINE long long _InterlockedAnd64(volatile long long * const value, const long long mask)
 {
        return __sync_fetch_and_and(value, mask);
 }
@@ -195,7 +227,7 @@ __INTRIN_INLINE long _InterlockedOr(volatile long * const value, const long mask
 }
 
 #if defined(_M_AMD64)
-__INTRIN_INLINE long _InterlockedOr64(volatile long long * const value, const long long mask)
+__INTRIN_INLINE long long _InterlockedOr64(volatile long long * const value, const long long mask)
 {
        return __sync_fetch_and_or(value, mask);
 }
@@ -216,6 +248,45 @@ __INTRIN_INLINE long _InterlockedXor(volatile long * const value, const long mas
        return __sync_fetch_and_xor(value, mask);
 }
 
+#if defined(_M_AMD64)
+__INTRIN_INLINE long long _InterlockedXor64(volatile long long * const value, const long long mask)
+{
+       return __sync_fetch_and_xor(value, mask);
+}
+#endif
+
+__INTRIN_INLINE long _InterlockedDecrement(volatile long * const lpAddend)
+{
+       return __sync_sub_and_fetch(lpAddend, 1);
+}
+
+__INTRIN_INLINE long _InterlockedIncrement(volatile long * const lpAddend)
+{
+       return __sync_add_and_fetch(lpAddend, 1);
+}
+
+__INTRIN_INLINE short _InterlockedDecrement16(volatile short * const lpAddend)
+{
+       return __sync_sub_and_fetch(lpAddend, 1);
+}
+
+__INTRIN_INLINE short _InterlockedIncrement16(volatile short * const lpAddend)
+{
+       return __sync_add_and_fetch(lpAddend, 1);
+}
+
+#if defined(_M_AMD64)
+__INTRIN_INLINE long long _InterlockedDecrement64(volatile long long * const lpAddend)
+{
+       return __sync_sub_and_fetch(lpAddend, 1);
+}
+
+__INTRIN_INLINE long long _InterlockedIncrement64(volatile long long * const lpAddend)
+{
+       return __sync_add_and_fetch(lpAddend, 1);
+}
+#endif
+
 #else
 
 __INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
@@ -427,6 +498,38 @@ __INTRIN_INLINE long _InterlockedXor(volatile long * const value, const long mas
        return y;
 }
 
+__INTRIN_INLINE long _InterlockedDecrement(volatile long * const lpAddend)
+{
+       return _InterlockedExchangeAdd(lpAddend, -1) - 1;
+}
+
+__INTRIN_INLINE long _InterlockedIncrement(volatile long * const lpAddend)
+{
+       return _InterlockedExchangeAdd(lpAddend, 1) + 1;
+}
+
+__INTRIN_INLINE short _InterlockedDecrement16(volatile short * const lpAddend)
+{
+       return _InterlockedExchangeAdd16(lpAddend, -1) - 1;
+}
+
+__INTRIN_INLINE short _InterlockedIncrement16(volatile short * const lpAddend)
+{
+       return _InterlockedExchangeAdd16(lpAddend, 1) + 1;
+}
+
+#if defined(_M_AMD64)
+__INTRIN_INLINE long long _InterlockedDecrement64(volatile long long * const lpAddend)
+{
+       return _InterlockedExchangeAdd64(lpAddend, -1) - 1;
+}
+
+__INTRIN_INLINE long long _InterlockedIncrement64(volatile long long * const lpAddend)
+{
+       return _InterlockedExchangeAdd64(lpAddend, 1) + 1;
+}
+#endif
+
 #endif
 
 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 && defined(__x86_64__)
@@ -473,38 +576,6 @@ __INTRIN_INLINE long _InterlockedAddLargeStatistic(volatile long long * const Ad
        return Value;
 }
 
-__INTRIN_INLINE long _InterlockedDecrement(volatile long * const lpAddend)
-{
-       return _InterlockedExchangeAdd(lpAddend, -1) - 1;
-}
-
-__INTRIN_INLINE long _InterlockedIncrement(volatile long * const lpAddend)
-{
-       return _InterlockedExchangeAdd(lpAddend, 1) + 1;
-}
-
-__INTRIN_INLINE short _InterlockedDecrement16(volatile short * const lpAddend)
-{
-       return _InterlockedExchangeAdd16(lpAddend, -1) - 1;
-}
-
-__INTRIN_INLINE short _InterlockedIncrement16(volatile short * const lpAddend)
-{
-       return _InterlockedExchangeAdd16(lpAddend, 1) + 1;
-}
-
-#if defined(_M_AMD64)
-__INTRIN_INLINE long long _InterlockedDecrement64(volatile long long * const lpAddend)
-{
-       return _InterlockedExchangeAdd64(lpAddend, -1) - 1;
-}
-
-__INTRIN_INLINE long long _InterlockedIncrement64(volatile long long * const lpAddend)
-{
-       return _InterlockedExchangeAdd64(lpAddend, 1) + 1;
-}
-#endif
-
 __INTRIN_INLINE unsigned char _interlockedbittestandreset(volatile long * a, const long b)
 {
        unsigned char retval;
@@ -896,7 +967,7 @@ __INTRIN_INLINE unsigned int _rotr(unsigned int value, int shift)
 __INTRIN_INLINE unsigned char _rotr8(unsigned char value, unsigned char shift)
 {
        unsigned char retval;
-       __asm__("rorb %b[shift], %b[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
+       __asm__("rorb %b[shift], %b[retval]" : [retval] "=qm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
        return retval;
 }
 
@@ -1113,6 +1184,39 @@ __INTRIN_INLINE void __outdwordstring(unsigned short const Port, const unsigned
        __asm__ __volatile__("rep; outsl" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count));
 }
 
+__INTRIN_INLINE int _inp(unsigned short Port)
+{
+       return __inbyte(Port);
+}
+
+__INTRIN_INLINE unsigned short _inpw(unsigned short Port)
+{
+       return __inword(Port);
+}
+
+__INTRIN_INLINE unsigned long _inpd(unsigned short Port)
+{
+       return __indword(Port);
+}
+
+__INTRIN_INLINE int _outp(unsigned short Port, int databyte)
+{
+       __outbyte(Port, databyte);
+       return databyte;
+}
+
+__INTRIN_INLINE unsigned short _outpw(unsigned short Port, unsigned short dataword)
+{
+       __outword(Port, dataword);
+       return dataword;
+}
+
+__INTRIN_INLINE unsigned long _outpd(unsigned short Port, unsigned long dataword)
+{
+       __outdword(Port, dataword);
+       return dataword;
+}
+
 
 /*** System information ***/
 __INTRIN_INLINE void __cpuid(int CPUInfo[], const int InfoType)
@@ -1146,10 +1250,14 @@ __INTRIN_INLINE uintptr_t __readeflags(void)
 }
 
 /*** Interrupts ***/
+#ifdef __clang__
+#define __debugbreak() __asm__("int $3")
+#else
 __INTRIN_INLINE void __debugbreak(void)
 {
        __asm__("int $3");
 }
+#endif
 
 __INTRIN_INLINE void __int2c(void)
 {
@@ -1158,21 +1266,22 @@ __INTRIN_INLINE void __int2c(void)
 
 __INTRIN_INLINE void _disable(void)
 {
-       __asm__("cli");
+       __asm__("cli" : : : "memory");
 }
 
 __INTRIN_INLINE void _enable(void)
 {
-       __asm__("sti");
+       __asm__("sti" : : : "memory");
 }
 
 __INTRIN_INLINE void __halt(void)
 {
-       __asm__("hlt\n\t");
+       __asm__("hlt\n\t" : : : "memory");
 }
 
 /*** Protected memory management ***/
 
+#ifdef _M_AMD64
 __INTRIN_INLINE void __writecr0(const unsigned __int64 Data)
 {
        __asm__("mov %[Data], %%cr0" : : [Data] "r" (Data) : "memory");
@@ -1188,7 +1297,6 @@ __INTRIN_INLINE void __writecr4(const unsigned __int64 Data)
        __asm__("mov %[Data], %%cr4" : : [Data] "r" (Data) : "memory");
 }
 
-#ifdef _M_AMD64
 __INTRIN_INLINE void __writecr8(const unsigned __int64 Data)
 {
        __asm__("mov %[Data], %%cr8" : : [Data] "r" (Data) : "memory");
@@ -1229,6 +1337,21 @@ __INTRIN_INLINE unsigned __int64 __readcr8(void)
        return value;
 }
 #else
+__INTRIN_INLINE void __writecr0(const unsigned int Data)
+{
+       __asm__("mov %[Data], %%cr0" : : [Data] "r" (Data) : "memory");
+}
+
+__INTRIN_INLINE void __writecr3(const unsigned int Data)
+{
+       __asm__("mov %[Data], %%cr3" : : [Data] "r" (Data) : "memory");
+}
+
+__INTRIN_INLINE void __writecr4(const unsigned int Data)
+{
+       __asm__("mov %[Data], %%cr4" : : [Data] "r" (Data) : "memory");
+}
+
 __INTRIN_INLINE unsigned long __readcr0(void)
 {
        unsigned long value;
@@ -1390,7 +1513,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");
 }
 
 
@@ -1434,7 +1557,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)
@@ -1447,9 +1570,16 @@ __INTRIN_INLINE void __sidt(void *Destination)
        __asm__ __volatile__("sidt %0" : : "m"(*(short*)Destination) : "memory");
 }
 
+/*** Misc operations ***/
+
 __INTRIN_INLINE void _mm_pause(void)
 {
-       __asm__ __volatile__("pause");
+       __asm__ __volatile__("pause" : : : "memory");
+}
+
+__INTRIN_INLINE void __nop(void)
+{
+       __asm__ __volatile__("nop");
 }
 
 #ifdef __cplusplus