openjdk/zero: use double code for atomic64 on powerpc

Sebastian Andrzej Siewior openjdk at ml.breakpoint.cc
Wed Jun 30 08:30:51 PDT 2010


this cute C code does the same thing on powerpc as the assembly code that
was here before. If the compiler was built with the SPE extensions instead
of traditional FPU and double operations are performed in HW then we are
one step further: The compiler turns this into evldd & evstdd. Voila :)

This C code could also be activated on s390. The compiler turns this into
a single mvc instruction which does the copy operation. I don't know if
mvc's copy ability is atomic _or_ not and therefore I leave it as it.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

Index: openjdk-6-6b18-1.8/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp
===================================================================
--- openjdk-6-6b18-1.8.orig/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp	2010-06-30 16:55:28.000000000 +0200
+++ openjdk-6-6b18-1.8/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp	2010-06-30 17:08:49.000000000 +0200
@@ -22,6 +22,15 @@
  * have any questions.
  *
  */
+#if defined(PPC) && !defined(_LP64)
+#ifndef __NO_FPRS__
+#define ATOMIC64_COPY_THROUGH_DOUBLE 1
+
+#elif defined(__SPE__) && !defined(_SOFT_DOUBLE)
+#define ATOMIC64_COPY_THROUGH_DOUBLE 1
+
+#endif
+#endif
 
   static void setup_fpu() {}
 
@@ -33,12 +42,23 @@
 
   // Atomically copy 64 bits of data
   static void atomic_copy64(volatile void *src, volatile void *dst) {
-#if defined(PPC) && !defined(_LP64)
-    double tmp;
-    asm volatile ("lfd  %0, 0(%1)\n"
-                  "stfd %0, 0(%2)\n"
-                  : "=f"(tmp)
-                  : "b"(src), "b"(dst));
+#if ATOMIC64_COPY_THROUGH_DOUBLE
+	  /*
+	   * In order to copy 8 bytes atomicly we rely on the trick that some
+	   * architectures can load and store a double as a single operation.
+	   * gcc picks the correct opcode here and with optimization turned on
+	   * all temporary assignments are gone.                       - bigeasy
+	   */
+	  union {
+		  double *d;
+		  volatile void *v;
+	  } s, d;
+
+	  s.v = src;
+	  d.v = dst;
+
+	  *d.d = *s.d;
+
 #elif defined(S390) && !defined(_LP64)
     double tmp;
     asm volatile ("ld  %0, 0(%1)\n"


More information about the hotspot-compiler-dev mailing list