Merged revisions 7797-7917 via svnmerge from
[cacao.git] / src / vm / jit / s390 / machine-instr.h
index a9164c7803a2fab7b99e45e0b4b585efa23a8798..2cbe506318be2eae6b05206391187b2e02df6099 100644 (file)
@@ -1,42 +1,79 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
+/*  Taken from linux kernel source 
+ *  include/asm-s390/atomic.h
+ *
+ *  S390 version
+ *    Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ *               Denis Joseph Barrow,
+ *              Arnd Bergmann (arndb@de.ibm.com)
+ *
+ *  Derived from "include/asm-i386/bitops.h"
+ *    Copyright (C) 1992, Linus Torvalds
+ */
+
+#define __CS_LOOP(ptr, op_val, op_string) ({                           \
+       int old_val, new_val;                           \
+        __asm__ __volatile__("   l     %0,0(%3)\n"                     \
+                             "0: lr    %1,%0\n"                                \
+                             op_string "  %1,%4\n"                     \
+                             "   cs    %0,%1,0(%3)\n"                  \
+                             "   jl    0b"                             \
+                             : "=&d" (old_val), "=&d" (new_val),       \
+                              "=m" (*ptr)      \
+                            : "a" (ptr), "d" (op_val),                 \
+                              "m" (*ptr)       \
+                            : "cc", "memory" );                        \
+       new_val;                                                        \
+})
+
 static inline void
-__attribute__ ((unused))
 atomic_add (volatile int *mem, int val)
 {
-#if 0
-  __asm__ __volatile__ ("lock; addl %1,%0"
-                                               : "=m" (*mem) 
-                                               : "ir" (val), "m" (*mem));
-#endif
+       __CS_LOOP(mem, val, "ar");
 }
 
 static inline long
-__attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
 {
-#if 0
-  long ret;
-
-  __asm__ __volatile__ ("lock; cmpxchgq %2, %1"
-                        : "=a" (ret), "=m" (*p)
-                        : "r" (newval), "m" (*p), "0" (oldval));
-  return ret;
-#endif
+       __asm__ __volatile__("  cs   %0,%3,0(%2)\n"
+                            : "+d" (oldval), "=m" (*p)
+                            : "a" (p), "d" (newval), "m" (*p)
+                            : "cc", "memory" );
+       return oldval;
 }
 
-#if 0
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER() __asm__ __volatile__ ( \
-               "mfence" : : : "memory" )
-#endif
+/*
+ *  Taken from linux kerenl source
+ *  include/asm-s390/system.h
+ *
+ *  S390 version
+ *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ *
+ *  Derived from "include/asm-i386/system.h"
+ */
+
+/*
+ * Force strict CPU ordering.
+ * And yes, this is required on UP too when we're talking
+ * to devices.
+ *
+ * This is very similar to the ppc eieio/sync instruction in that is
+ * does a checkpoint syncronisation & makes sure that 
+ * all memory ops have completed wrt other CPU's ( see 7-15 POP  DJB ).
+ */
+
+#define eieio()  __asm__ __volatile__ ( "bcr 15,0" : : : "memory" ) 
+
+#define STORE_ORDER_BARRIER() eieio()
+#define MEMORY_BARRIER() eieio()
+
+/* TODO not sure if the following two can't be just empty. */
 
-#define STORE_ORDER_BARRIER()
-#define MEMORY_BARRIER_BEFORE_ATOMIC()
-#define MEMORY_BARRIER_AFTER_ATOMIC()
-#define MEMORY_BARRIER()
+#define MEMORY_BARRIER_BEFORE_ATOMIC() eieio()
+#define MEMORY_BARRIER_AFTER_ATOMIC() eieio()
 
 #endif