SMP support (xchg(), cas() and mb()) for PowerPC
[ghc-hetmet.git] / ghc / includes / SMP.h
index 88fc339..f4c8605 100644 (file)
@@ -2,25 +2,24 @@
  *
  * (c) The GHC Team, 2005
  *
- * Macros for SMP support
+ * Macros for THREADED_RTS support
  *
  * -------------------------------------------------------------------------- */
 
 #ifndef SMP_H
 #define SMP_H
 
-/* SMP is currently not compatible with the following options:
+/* THREADED_RTS is currently not compatible with the following options:
  *
- *      INTERPRETER
- *      PROFILING
+ *      PROFILING (but only 1 CPU supported)
  *      TICKY_TICKY
- *      and unregisterised builds.
+ *      Unregisterised builds are ok, but only 1 CPU supported.
  */
 
-#if defined(SMP)
+#if defined(THREADED_RTS)
 
-#if  defined(PROFILING)  || defined(TICKY_TICKY)
-#error Build options incompatible with SMP.
+#if  defined(TICKY_TICKY)
+#error Build options incompatible with THREADED_RTS.
 #endif
 
 /* 
@@ -34,12 +33,24 @@ INLINE_HEADER StgWord
 xchg(StgPtr p, StgWord w)
 {
     StgWord result;
+#if i386_HOST_ARCH || x86_64_HOST_ARCH
     result = w;
     __asm__ __volatile__ (
          "xchg %1,%0"
           :"+r" (result), "+m" (*p)
           : /* no input-only operands */
        );
+#elif powerpc_HOST_ARCH
+    __asm__ __volatile__ (
+        "1:     lwarx     %0, 0, %2\n"
+        "       stwcx.    %1, 0, %2\n"
+        "       bne-      1b"
+        :"=r" (result)
+        :"r" (w), "r" (p)
+    );
+#else
+#error xchg() unimplemented on this architecture
+#endif
     return result;
 }
 
@@ -50,11 +61,28 @@ xchg(StgPtr p, StgWord w)
 INLINE_HEADER StgWord
 cas(StgVolatilePtr p, StgWord o, StgWord n)
 {
+#if i386_HOST_ARCH || x86_64_HOST_ARCH
     __asm__ __volatile__ (
          "lock cmpxchg %3,%1"
           :"=a"(o), "=m" (*(volatile unsigned int *)p) 
           :"0" (o), "r" (n));
     return o;
+#elif powerpc_HOST_ARCH
+    StgWord result;
+    __asm__ __volatile__ (
+        "1:     lwarx     %0, 0, %3\n"
+        "       cmpw      %0, %1\n"
+        "       bne       2f\n"
+        "       stwcx.    %2, 0, %3\n"
+        "       bne-      1b\n"
+        "2:"
+        :"=r" (result)
+        :"r" (o), "r" (n), "r" (p)
+    );
+    return result;
+#else
+#error cas() unimplemented on this architecture
+#endif
 }
 
 /*
@@ -71,6 +99,8 @@ INLINE_HEADER void
 wb(void) {
 #if i386_HOST_ARCH || x86_64_HOST_ARCH
     __asm__ __volatile__ ("" : : : "memory");
+#elif powerpc_HOST_ARCH
+    __asm__ __volatile__ ("lwsync" : : : "memory");
 #else
 #error memory barriers unimplemented on this architecture
 #endif
@@ -86,7 +116,7 @@ wb(void) {
 INLINE_HEADER StgInfoTable *
 lockClosure(StgClosure *p)
 {
-#if i386_HOST_ARCH || x86_64_HOST_ARCH
+#if i386_HOST_ARCH || x86_64_HOST_ARCH || powerpc_HOST_ARCH
     StgWord info;
     do {
        nat i = 0;
@@ -104,7 +134,7 @@ lockClosure(StgClosure *p)
 INLINE_HEADER void
 unlockClosure(StgClosure *p, StgInfoTable *info)
 {
-#if i386_HOST_ARCH || x86_64_HOST_ARCH
+#if i386_HOST_ARCH || x86_64_HOST_ARCH || powerpc_HOST_ARCH
     // This is a strictly ordered write, so we need a wb():
     wb();
     p->header.info = info;
@@ -113,7 +143,7 @@ unlockClosure(StgClosure *p, StgInfoTable *info)
 #endif
 }
 
-#else /* !SMP */
+#else /* !THREADED_RTS */
 
 #define wb() /* nothing */
 
@@ -125,6 +155,6 @@ xchg(StgPtr p, StgWord w)
     return old;
 }
 
-#endif /* !SMP */
+#endif /* !THREADED_RTS */
 
 #endif /* SMP_H */