Prefer __sync_bool_compare_and_swap() over PPC inline asm.
authorAndreas Fredriksson <dep@defmacro.se>
Sun, 10 Feb 2013 04:11:04 +0000 (20:11 -0800)
committerAndreas Fredriksson <dep@defmacro.se>
Sun, 10 Feb 2013 21:55:52 +0000 (13:55 -0800)
Debian's GCC 4.4 in particular does not compile the PPC assembly.

libgc/configure.in
libgc/include/private/gc_locks.h

index be6f6d4259bba4cd59761a84fad03adea161cf47..837e2cb9f158c14f8cdbe47e0abc14091db14edf 100644 (file)
@@ -217,6 +217,22 @@ case "$host" in
 esac
 AM_CONDITIONAL(POWERPC_DARWIN,test x$powerpc_darwin = xtrue)
 
+# Check if the GCC builtin __sync_bool_compare_and_swap is available.
+# It is preferred in gc_locks.h for PPC as GCC 4.4 has a problem with the inline assembly there.
+AC_MSG_CHECKING(for __sync_bool_compare_and_swap)
+AC_TRY_COMPILE([],[
+volatile unsigned int foo = 0;
+int main(int argc, char** argv) {
+    unsigned int r1 = __sync_bool_compare_and_swap(&foo, 0, 1);
+    return 0;
+}
+], [
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAS___SYNC_BOOL_COMPARE_AND_SWAP)
+], [
+AC_MSG_RESULT(no)
+])
+
 AC_MSG_CHECKING(for xlc)
 AC_TRY_COMPILE([],[
  #ifndef __xlC__
index a45553aa7ca9e249d201c0b719ae444e6c4364bf..8705d07a1bbc072365c40381008c9e178821eea3 100644 (file)
         inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
             GC_word old, GC_word new_val) 
         {
+#         if HAS___SYNC_BOOL_COMPARE_AND_SWAP
+            return __sync_bool_compare_and_swap(addr, old, new_val);
+#         else
             unsigned long result, dummy;
             __asm__ __volatile__(
                 "1:\tldarx %0,0,%5\n"
                 :  "r" (new_val), "r" (old), "2"(addr)
                 : "cr0","memory");
             return (GC_bool) result;
+#         endif
         }
 #       else
         /* Returns TRUE if the comparison succeeded. */
         inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
             GC_word old, GC_word new_val) 
         {
+#         if HAS___SYNC_BOOL_COMPARE_AND_SWAP
+            return __sync_bool_compare_and_swap(addr, old, new_val);
+#         else
             int result, dummy;
             __asm__ __volatile__(
                 "1:\tlwarx %0,0,%5\n"
                 :  "r" (new_val), "r" (old), "2"(addr)
                 : "cr0","memory");
             return (GC_bool) result;
+#         endif
         }
 #       endif
 #      endif /* !GENERIC_COMPARE_AND_SWAP */