Partially fixed up tree after merge from HEAD. More to do.
[reactos.git] / reactos / include / psdk / intrin.h
index 4a9d940..ab36de3 100644 (file)
@@ -1096,6 +1096,951 @@ static __inline__ __attribute__((always_inline)) void __wbinvd(void)
        __asm__("wbinvd");\r
 }\r
 \r
+#elif defined(_M_PPC)\r
+\r
+/*** Stack frame juggling ***/\r
+#define _ReturnAddress() (__builtin_return_address(0))\r
+#define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1]))\r
+/* TODO: __getcallerseflags but how??? */\r
+\r
+\r
+/*** Atomic operations ***/\r
+/* TODO: _ReadBarrier */\r
+/* TODO: _WriteBarrier */\r
+\r
+#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100\r
+#define _ReadWriteBarrier() __sync_synchronize()\r
+#else\r
+/* TODO: _ReadWriteBarrier() */\r
+#endif\r
+\r
+#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100\r
+\r
+static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)\r
+{\r
+       return __sync_val_compare_and_swap(Destination, Comperand, Exchange);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)\r
+{\r
+       return __sync_val_compare_and_swap(Destination, Comperand, Exchange);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)\r
+{\r
+       return __sync_val_compare_and_swap(Destination, Comperand, Exchange);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)\r
+{\r
+       return __sync_val_compare_and_swap(Destination, Comperand, Exchange);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)\r
+{\r
+       return __sync_val_compare_and_swap(Destination, Comperand, Exchange);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value)\r
+{\r
+       /* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */\r
+       __sync_synchronize();\r
+       return __sync_lock_test_and_set(Target, Value);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)\r
+{\r
+       /* NOTE: ditto */\r
+       __sync_synchronize();\r
+       return __sync_lock_test_and_set(Target, Value);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)\r
+{\r
+       return __sync_fetch_and_add(Addend, Value);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)\r
+{\r
+       return __sync_fetch_and_and(value, mask);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask)\r
+{\r
+       return __sync_fetch_and_and(value, mask);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask)\r
+{\r
+       return __sync_fetch_and_and(value, mask);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask)\r
+{\r
+       return __sync_fetch_and_or(value, mask);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask)\r
+{\r
+       return __sync_fetch_and_or(value, mask);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask)\r
+{\r
+       return __sync_fetch_and_or(value, mask);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask)\r
+{\r
+       return __sync_fetch_and_xor(value, mask);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask)\r
+{\r
+       return __sync_fetch_and_xor(value, mask);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask)\r
+{\r
+       return __sync_fetch_and_xor(value, mask);\r
+}\r
+\r
+#else\r
+\r
+static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)\r
+{\r
+       char retval = Comperand;\r
+       __asm__ __volatile__ (\r
+           "sync\n"\r
+           "1: lbarx   %0,0,%1\n"\r
+           "   subf.   %0,%2,%0\n"\r
+           "   bne     2f\n"\r
+           "   stbcx.  %3,0,%1\n"\r
+           "   bne-    1b\n"\r
+           "2: isync"\r
+           : "=b" (retval)\r
+           : "b" (Destination), "r" (Comperand), "r" (Exchange)\r
+           : "cr0", "memory");\r
+       return retval;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)\r
+{\r
+       short retval = Comperand;\r
+       __asm__ __volatile__ (\r
+           "sync\n"\r
+           "1: lharx   %0,0,%1\n"\r
+           "   subf.   %0,%2,%0\n"\r
+           "   bne     2f\n"\r
+           "   sthcx.  %3,0,%1\n"\r
+           "   bne-    1b\n"\r
+           "2: isync"\r
+           : "=b" (retval)\r
+           : "b" (Destination), "r" (Comperand), "r" (Exchange)\r
+           : "cr0", "memory");\r
+       return retval;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)\r
+{\r
+       long retval = Comperand;\r
+       __asm__ __volatile__ (\r
+           "sync\n"\r
+           "1: lwarx   %0,0,%1\n"\r
+           "   subf.   %0,%2,%0\n"\r
+           "   bne     2f\n"\r
+           "   stwcx.  %3,0,%1\n"\r
+           "   bne-    1b\n"\r
+           "2: isync"\r
+           : "=b" (retval)\r
+           : "b" (Destination), "r" (Comperand), "r" (Exchange)\r
+           : "cr0", "memory");\r
+       return retval;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)\r
+{\r
+       unsigned long lo32Retval = (unsigned long)((Comperand >>  0) & 0xFFFFFFFF);\r
+       long hi32Retval = (unsigned long)((Comperand >> 32) & 0xFFFFFFFF);\r
+\r
+       unsigned long lo32Exchange = (unsigned long)((Exchange >>  0) & 0xFFFFFFFF);\r
+       long hi32Exchange = (unsigned long)((Exchange >> 32) & 0xFFFFFFFF);\r
+\r
+#if 0\r
+       __asm__\r
+       (\r
+               "cmpxchg8b %[Destination]" :\r
+               "a" (lo32Retval), "d" (hi32Retval) :\r
+               [Destination] "rm" (Destination), "b" (lo32Exchange), "c" (hi32Exchange) :\r
+               "memory"\r
+       );\r
+#endif\r
+       {\r
+               union u_\r
+               {\r
+                       long long ll;\r
+                       struct s_\r
+                       {\r
+                               unsigned long lo32;\r
+                               long hi32;\r
+                       }\r
+                       s;\r
+               }\r
+               u = { s : { lo32 : lo32Retval, hi32 : hi32Retval } };\r
+\r
+               return u.ll;\r
+       }\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)\r
+{\r
+    return (void *)_InterlockedCompareExchange\r
+       ((long *)Destination, (long) Exchange, (long) Comperand);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value)\r
+{\r
+        long retval;\r
+       __asm__ __volatile__ (\r
+           "sync\n"\r
+           "1: lwarx   %0,0,%1\n"\r
+           "   stwcx.  %2,0,%1\n"\r
+           "   bne-    1b\n"\r
+           : "=b" (retval)\r
+           : "b" (Target), "b" (Value)\r
+           : "cr0", "memory");\r
+       return retval;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)\r
+{\r
+        void * retval;\r
+       __asm__ __volatile__ (\r
+           "sync\n"\r
+           "1: lwarx   %0,0,%1\n"\r
+           "   stwcx.  %2,0,%1\n"\r
+           "   bne-    1b\n"\r
+           : "=b" (retval)\r
+           : "b" (Target), "b" (Value)\r
+           : "cr0", "memory");\r
+       return retval;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)\r
+{\r
+        long x;\r
+       long y = *Addend;\r
+       long addend = y;\r
+       \r
+       do\r
+       {\r
+           x = y;\r
+           y = _InterlockedCompareExchange(Addend, addend + Value, x);\r
+       } \r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)\r
+{\r
+       char x;\r
+       char y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange8(value, x & mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask)\r
+{\r
+       short x;\r
+       short y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange16(value, x & mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask)\r
+{\r
+       long x;\r
+       long y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange(value, x & mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask)\r
+{\r
+       char x;\r
+       char y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange8(value, x | mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask)\r
+{\r
+       short x;\r
+       short y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange16(value, x | mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask)\r
+{\r
+       long x;\r
+       long y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange(value, x | mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask)\r
+{\r
+       char x;\r
+       char y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange8(value, x ^ mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask)\r
+{\r
+       short x;\r
+       short y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange16(value, x ^ mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask)\r
+{\r
+       long x;\r
+       long y;\r
+\r
+       y = *value;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange(value, x ^ mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return y;\r
+}\r
+\r
+#endif\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value)\r
+{\r
+#if 0\r
+       __asm__\r
+       (\r
+               "lock; add %[Value], %[Lo32];"\r
+               "jae LABEL%=;"\r
+               "lock; adc $0, %[Hi32];"\r
+               "LABEL%=:;" :\r
+               [Lo32] "=m" (*((volatile long *)(Addend) + 0)), [Hi32] "=m" (*((volatile long *)(Addend) + 1)) :\r
+               [Value] "ir" (Value)\r
+       );\r
+#endif\r
+       return Value;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedDecrement(volatile long * const lpAddend)\r
+{\r
+       return _InterlockedExchangeAdd(lpAddend, -1) - 1;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long _InterlockedIncrement(volatile long * const lpAddend)\r
+{\r
+       return _InterlockedExchangeAdd(lpAddend, 1) + 1;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandreset(volatile long * const a, const long b)\r
+{\r
+       long x;\r
+       long y;\r
+       long mask = ~(1<<b);\r
+\r
+       y = *a;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange(a, x & mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return (y & ~mask) != 0;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandset(volatile long * const a, const long b)\r
+{\r
+       long x;\r
+       long y;\r
+       long mask = 1<<b;\r
+\r
+       y = *a;\r
+\r
+       do\r
+       {\r
+               x = y;\r
+               y = _InterlockedCompareExchange(a, x | mask, x);\r
+       }\r
+       while(y != x);\r
+\r
+       return (y & ~mask) != 0;\r
+}\r
+\r
+\r
+/*** String operations ***/\r
+/* NOTE: we don't set a memory clobber in the __stosX functions because Visual C++ doesn't */\r
+/* Note that the PPC store multiple operations may raise an exception in LE \r
+ * mode */\r
+static __inline__ __attribute__((always_inline)) void __stosb(unsigned char * Dest, const unsigned char Data, size_t Count)\r
+{\r
+    memset(Dest, Data, Count);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __stosw(unsigned short * Dest, const unsigned short Data, size_t Count)\r
+{\r
+    while(Count--) \r
+       *Dest++ = Data;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __stosd(unsigned long * Dest, const unsigned long Data, size_t Count)\r
+{\r
+    while(Count--)\r
+       *Dest++ = Data;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __movsb(unsigned char * Destination, const unsigned char * Source, size_t Count)\r
+{\r
+    memcpy(Destination, Source, Count);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __movsw(unsigned short * Destination, const unsigned short * Source, size_t Count)\r
+{\r
+    memcpy(Destination, Source, Count * sizeof(*Source));\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __movsd(unsigned long * Destination, const unsigned long * Source, size_t Count)\r
+{\r
+    memcpy(Destination, Source, Count * sizeof(*Source));\r
+}\r
+\r
+\r
+/*** FS segment addressing ***/\r
+/* On PowerPC, r13 points to TLS data, including the TEB at 0(r13) from what I\r
+ * can tell */\r
+static __inline__ __attribute__((always_inline)) void __writefsbyte(const unsigned long Offset, const unsigned char Data)\r
+{\r
+    char *addr;\r
+    __asm__("\tadd %2,13,%0\n"\r
+           "\tstb %1,0(%2)\n" \r
+           : \r
+           : "b" (Offset), "b" (Data), "b" (addr));\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __writefsword(const unsigned long Offset, const unsigned short Data)\r
+{\r
+    char *addr;\r
+    __asm__("\tadd %2,13,%0\n"\r
+           "\tsth %1,0(%2)\n"\r
+           : \r
+           : "b" (Offset), "b" (Data), "b" (addr));\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __writefsdword(const unsigned long Offset, const unsigned long Data)\r
+{\r
+    char *addr;\r
+    __asm__("\tadd %2,13,%0\n"\r
+           "\tstw %1,0(%2)\n" \r
+           : \r
+           : "b" (Offset), "b" (Data), "b" (addr));\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned char __readfsbyte(const unsigned long Offset)\r
+{\r
+    char result;\r
+    char *addr;\r
+    __asm__("\tadd %2,13,%1\n"\r
+           "\tlbz %0,0(%2)\n"\r
+           : "=b" (result)\r
+           : "b" (Offset), "b" (addr));\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned short __readfsword(const unsigned long Offset)\r
+{\r
+    unsigned short result;\r
+    char *addr;\r
+    __asm__("\tadd %2,13,%1\n"\r
+           "\tlhz %0,0(%2)\n"\r
+           : "=b" (result)\r
+           : "b" (Offset), "b" (addr));\r
+    return result;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned long __readfsdword(const unsigned long Offset)\r
+{\r
+    unsigned long result;\r
+    char *addr;\r
+    __asm__("\tadd %2,13,%1\n"\r
+           "\tlwz %0,0(%2)\n"\r
+           : "=b" (result)\r
+           : "b" (Offset), "b" (addr));\r
+    return result;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __incfsbyte(const unsigned long Offset)\r
+{\r
+    __writefsbyte(Offset, __readfsbyte(Offset)+1);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __incfsword(const unsigned long Offset)\r
+{\r
+    __writefsword(Offset, __readfsword(Offset)+1);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __incfsdword(const unsigned long Offset)\r
+{\r
+    __writefsdword(Offset, __readfsdword(Offset)+1);\r
+}\r
+\r
+/* NOTE: the bizarre implementation of __addfsxxx mimics the broken Visual C++ behavior */\r
+/* PPC Note: Not sure about the bizarre behavior.  We'll try to emulate it later */\r
+static __inline__ __attribute__((always_inline)) void __addfsbyte(const unsigned long Offset, const unsigned char Data)\r
+{\r
+    __writefsbyte(Offset, __readfsbyte(Offset) + Data);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __addfsword(const unsigned long Offset, const unsigned short Data)\r
+{\r
+    __writefsword(Offset, __readfsword(Offset) + Data);\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __addfsdword(const unsigned long Offset, const unsigned int Data)\r
+{\r
+    __writefsdword(Offset, __readfsdword(Offset) + Data);\r
+}\r
+\r
+\r
+/*** Bit manipulation ***/\r
+static  __inline__ __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask)\r
+{\r
+    if(Mask == 0) return 0;\r
+    else {\r
+       unsigned long mask = Mask;\r
+       mask &= -mask;\r
+       *Index = \r
+           ((mask & 0xffff0000) ? 16 : 0) +\r
+           ((mask & 0xff00ff00) ? 8  : 0) +\r
+           ((mask & 0xf0f0f0f0) ? 4  : 0) +\r
+           ((mask & 0xcccccccc) ? 2  : 0) +\r
+           ((mask & 0xaaaaaaaa) ? 1  : 0);\r
+       return 1;\r
+    }\r
+}\r
+\r
+/* Thanks http://www.jjj.de/bitwizardry/files/bithigh.h */\r
+static  __inline__ __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask)\r
+{\r
+    unsigned long check = 16, checkmask;\r
+    if(Mask == 0) return 0;\r
+    else {\r
+       unsigned long mask = Mask;\r
+       *Index = 0;\r
+       while(check) {\r
+           checkmask = ((1<<check)-1) << check;\r
+           if( mask & checkmask ) {\r
+               mask >>= check;\r
+               *Index += check;\r
+           }\r
+           check >>= 1;\r
+       }\r
+       return 1;\r
+    }\r
+}\r
+\r
+/* NOTE: again, the bizarre implementation follows Visual C++ */\r
+static  __inline__ __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b)\r
+{\r
+    return ((*a) & (1<<b)) != 0;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned char _bittestandcomplement(long * const a, const long b)\r
+{\r
+    unsigned char ret = ((*a) & (1<<b)) != 0;\r
+    (*a) ^= (1<<b);\r
+    return ret;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned char _bittestandreset(long * const a, const long b)\r
+{\r
+    unsigned char ret = ((*a) & (1<<b)) != 0;\r
+    (*a) &= ~(1<<b);\r
+    return ret;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned char _bittestandset(long * const a, const long b)\r
+{\r
+    unsigned char ret = ((*a) & (1<<b)) != 0;\r
+    (*a) |= (1<<b);\r
+    return ret;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned char _rotl8(const unsigned char value, const unsigned char shift)\r
+{\r
+    return (value << shift) | (value >> (8-shift));\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned short _rotl16(const unsigned short value, const unsigned char shift)\r
+{\r
+    return (value << shift) | (value >> (16-shift));    \r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned char _rotr8(const unsigned char value, const unsigned char shift)\r
+{\r
+    return (value >> shift) | (value << (8-shift));    \r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned short _rotr16(const unsigned short value, const unsigned char shift)\r
+{\r
+    return (value >> shift) | (value << (16-shift));    \r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)\r
+{\r
+    return Mask << Bit;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit)\r
+{\r
+    return Mask >> Bit;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)\r
+{\r
+    return Mask >> Bit;\r
+}\r
+\r
+\r
+/*** 64-bit math ***/\r
+static __inline__ __attribute__((always_inline)) long long __emul(const int a, const int b)\r
+{\r
+    return a * b;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned long long __emulu(const unsigned int a, const unsigned int b)\r
+{\r
+    return a * b;\r
+}\r
+\r
+\r
+/*** Port I/O ***/\r
+static __inline__ __attribute__((always_inline)) unsigned char __inbyte(const unsigned short Port)\r
+{\r
+    int ret;\r
+    __asm__(\r
+       "mfmsr 5\n\t"\r
+       "xori  %1,%1,7\n\t"     /* Undo effects of LE without swapping */\r
+       "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */\r
+       "mtmsr 6\n\t"\r
+       "isync\n\t"\r
+       "sync\n\t"\r
+       "lbz   %0,0(%1)\n\t"    /* Get actual value at phys addr r3 */\r
+       "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)\r
+    );\r
+    return ret;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned short __inword(const unsigned short Port)\r
+{\r
+    int ret;\r
+    __asm__(\r
+       "mfmsr 5\n\t"\r
+       "xori  %1,%1,6\n\t"     /* Undo effects of LE without swapping */\r
+       "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */\r
+       "mtmsr 6\n\t"\r
+       "isync\n\t"\r
+       "sync\n\t"\r
+       "lhz   %0,0(%1)\n\t"    /* Get actual value at phys addr r3 */\r
+       "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)\r
+    );\r
+    return ret;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned long __indword(const unsigned short Port)\r
+{\r
+    int ret;\r
+    __asm__(\r
+       "mfmsr 5\n\t"\r
+       "xori  %1,%1,4\n\t"     /* Undo effects of LE without swapping */\r
+       "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */\r
+       "mtmsr 6\n\t"\r
+       "isync\n\t"\r
+       "sync\n\t"\r
+       "lwz   %0,0(%1)\n\t"    /* Get actual value at phys addr r3 */\r
+       "mtmsr 5\n\t" : "=r" (ret) : "b" (Port)\r
+    );\r
+    return ret;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __inbytestring(unsigned short Port, unsigned char * Buffer, unsigned long Count)\r
+{\r
+    while(Count--) {\r
+       *Buffer++ = __inbyte(Port);\r
+    }\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __inwordstring(unsigned short Port, unsigned short * Buffer, unsigned long Count)\r
+{\r
+    while(Count--) {\r
+       *Buffer++ = __inword(Port);\r
+    }\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __indwordstring(unsigned short Port, unsigned long * Buffer, unsigned long Count)\r
+{\r
+    while(Count--) {\r
+       *Buffer++ = __indword(Port);\r
+    }\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __outbyte(unsigned short const Port, const unsigned char Data)\r
+{\r
+    __asm__(\r
+       "mfmsr 5\n\t"\r
+       "xori  %0,%0,7\n\t"     /* Undo effects of LE without swapping */\r
+       "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */\r
+       "mtmsr 6\n\t"\r
+       "sync\n\t"\r
+       "eieio\n\t"\r
+       "stb   %1,0(%0)\n\t"    /* Set actual value at phys addr r3 */\r
+       "dcbst 0,%1\n\t"\r
+       "mtmsr 5\n\t"\r
+       "sync\n\t"\r
+       "eieio\n\t" : : "b" (Port), "r" (Data)\r
+       );\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __outword(unsigned short const Port, const unsigned short Data)\r
+{\r
+    __asm__(\r
+       "mfmsr 5\n\t"\r
+       "xori  %0,%0,7\n\t"     /* Undo effects of LE without swapping */\r
+       "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */\r
+       "mtmsr 6\n\t"\r
+       "sync\n\t"\r
+       "eieio\n\t"\r
+       "sth   %1,0(%0)\n\t"    /* Set actual value at phys addr r3 */\r
+       "dcbst 0,%1\n\t"\r
+       "mtmsr 5\n\t"\r
+       "sync\n\t"\r
+       "eieio\n\t" : : "b" (Port), "b" (Data)\r
+       );\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __outdword(unsigned short const Port, const unsigned long Data)\r
+{\r
+    __asm__(\r
+       "mfmsr 5\n\t"\r
+       "xori  %0,%0,7\n\t"     /* Undo effects of LE without swapping */\r
+       "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */\r
+       "mtmsr 6\n\t"\r
+       "sync\n\t"\r
+       "eieio\n\t"\r
+       "stw   %1,0(%0)\n\t"    /* Set actual value at phys addr r3 */\r
+       "dcbst 0,%1\n\t"\r
+       "mtmsr 5\n\t"\r
+       "sync\n\t"\r
+       "eieio\n\t" : : "b" (Port), "b" (Data)\r
+       );\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __outbytestring(unsigned short const Port, const unsigned char * const Buffer, const unsigned long Count)\r
+{\r
+    unsigned long count = Count;\r
+    unsigned char *buffer = Buffer;\r
+    while(count--) {\r
+       __outbyte(Port, *buffer++);\r
+    }\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __outwordstring(unsigned short const Port, const unsigned short * const Buffer, const unsigned long Count)\r
+{\r
+    unsigned long count = Count;\r
+    unsigned short *buffer = Buffer;\r
+    while(count--) {\r
+       __outword(Port, *buffer++);\r
+    }\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __outdwordstring(unsigned short const Port, const unsigned long * const Buffer, const unsigned long Count)\r
+{\r
+    unsigned long count = Count;\r
+    unsigned long *buffer = Buffer;\r
+    while(count--) {\r
+       __outdword(Port, *buffer++);\r
+    }\r
+}\r
+\r
+\r
+/*** System information ***/\r
+static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType)\r
+{\r
+    unsigned long lo32;\r
+    __asm__("mfpvr" : "=b" (lo32));\r
+    return lo32;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void)\r
+{\r
+    unsigned long lo32;\r
+    __asm__("mfdec" : "=b" (lo32));\r
+    return lo32;\r
+}\r
+\r
+\r
+/*** Interrupts ***/\r
+/* Finally decided to do this by enabling single step trap */\r
+static __inline__ __attribute__((always_inline)) void __debugbreak(void)\r
+{\r
+    \r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __int2c(void)\r
+{\r
+    /* Not sure yet */\r
+}\r
+\r
+#ifndef _ENABLE_DISABLE_DEFINED\r
+#define _ENABLE_DISABLE_DEFINED\r
+static __inline__ __attribute__((always_inline)) void _disable(void)\r
+{\r
+    __asm__ __volatile__("mfmsr 0\n\t" \\r
+                        "li    8,0x7fff\n\t" \\r
+                        "and   0,8,0\n\t" \\r
+                        "mtmsr 0\n\t");\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void _enable(void)\r
+{\r
+ __asm__ __volatile__("mfmsr 0\n\t" \\r
+                      "lis    8,0x8000@ha\n\t" \\r
+                      "or    0,8,0\n\t" \\r
+                      "mtmsr 0\n\t");\r
+}\r
+#endif\r
+\r
+/*** Protected memory management ***/\r
+static __inline__ __attribute__((always_inline)) unsigned long __readsdr1(void)\r
+{\r
+    unsigned long value;\r
+    __asm__("mfsdr1 %0" : "=b" (value));\r
+    return value;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __writesdr1(const unsigned long long Data)\r
+{\r
+    __asm__("mtsdr1 %0" : : "b" (Data));\r
+}\r
+\r
+/*** System operations ***/\r
+/* This likely has a different meaning from the X86 equivalent.  We'll keep\r
+ * the name cause it fits */\r
+static __inline__ __attribute__((always_inline)) unsigned long long __readmsr()\r
+{\r
+    unsigned long temp;\r
+    __asm__("mfmsr %0" : "=b" (temp));\r
+    return temp;\r
+}\r
+\r
+static __inline__ __attribute__((always_inline)) void __writemsr(const unsigned long Value)\r
+{\r
+    __asm__("mtmsr %0" : : "b" (Value));\r
+}\r
+\r
+/* We'll make sure of the following:\r
+ * IO operations have completed\r
+ * Write operations through cache have completed\r
+ * We've reloaded anything in the data or instruction cache that might have\r
+ * changed in real ram.\r
+ */\r
+static __inline__ __attribute__((always_inline)) void __wbinvd(void)\r
+{\r
+    __asm__("eieio\n\t"\r
+           "dcs\n\t"\r
+           "sync\n\t"\r
+           "isync\n\t");\r
+}\r
 #else\r
 /* TODO: the x64 architecture shares most of the intrinsics. It should be easy to support */\r
 #error Unsupported architecture\r