From 79668cdf0249d0cb8405d878b17e1620f19110aa Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Nov 2007 17:42:59 +0000 Subject: [PATCH] Check whether assembler supports numerical local labels. 2007-11-18 Matthias Clasen * configure.in: Check whether assembler supports numerical local labels. * glib/gatomic.c: Fix powerpc implementation of atomic ops for platforms where the assembler doesn't support numerical local labels. (#445362) svn path=/trunk/; revision=5861 --- ChangeLog | 13 +++++++-- configure.in | 11 ++++++++ glib/gatomic.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84271e42..f42a6e31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ -2006-11-15 Ryan Lortie +2007-11-18 Matthias Clasen + + * configure.in: Check whether assembler supports numerical local + labels. + + * glib/gatomic.c: Fix powerpc implementation of atomic ops for + platforms where the assembler doesn't support numerical local + labels. (#445362) + +2007-11-15 Ryan Lortie * docs/reference/glib/tmpl/markup.sgml: * glib/gmarkup.h: @@ -8,7 +17,7 @@ Closes #496046. -2006-11-15 Ryan Lortie +2007-11-15 Ryan Lortie * docs/reference/glib/glib-sections.txt: * glib/glib.symbols: diff --git a/configure.in b/configure.in index 5860a6c0..f18ab6d9 100644 --- a/configure.in +++ b/configure.in @@ -2082,6 +2082,17 @@ if test x"$GCC" = xyes; then AC_DEFINE_UNQUOTED(G_ATOMIC_POWERPC, 1, [powerpc atomic implementation]) glib_memory_barrier_needed=yes + AC_MSG_CHECKING([whether asm supports numbered local labels]) + AC_TRY_COMPILE( + ,[ + __asm__ __volatile__ ("1: nop\n" + " bne- 1b") + ],[ + AC_DEFINE_UNQUOTED(ASM_NUMERIC_LABELS, 1, [define if asm blocks can use numeric local labels]) + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + ]) ;; ia64) AC_MSG_RESULT([ia64]) diff --git a/glib/gatomic.c b/glib/gatomic.c index 5cbcc466..423661bf 100644 --- a/glib/gatomic.c +++ b/glib/gatomic.c @@ -281,6 +281,15 @@ g_atomic_int_exchange_and_add (volatile gint *atomic, gint val) { gint result, temp; +#if ASM_NUMERIC_LABELS + __asm__ __volatile__ ("1: lwarx %0,0,%3\n" + " add %1,%0,%4\n" + " stwcx. %1,0,%3\n" + " bne- 1b" + : "=&b" (result), "=&r" (temp), "=m" (*atomic) + : "b" (atomic), "r" (val), "m" (*atomic) + : "cr0", "memory"); +#else __asm__ __volatile__ (".Lieaa%=: lwarx %0,0,%3\n" " add %1,%0,%4\n" " stwcx. %1,0,%3\n" @@ -288,6 +297,7 @@ g_atomic_int_exchange_and_add (volatile gint *atomic, : "=&b" (result), "=&r" (temp), "=m" (*atomic) : "b" (atomic), "r" (val), "m" (*atomic) : "cr0", "memory"); +#endif return result; } @@ -297,6 +307,15 @@ g_atomic_int_add (volatile gint *atomic, gint val) { gint result, temp; +#if ASM_NUMERIC_LABELS + __asm__ __volatile__ ("1: lwarx %0,0,%3\n" + " add %1,%0,%4\n" + " stwcx. %1,0,%3\n" + " bne- 1b" + : "=&b" (result), "=&r" (temp), "=m" (*atomic) + : "b" (atomic), "r" (val), "m" (*atomic) + : "cr0", "memory"); +#else __asm__ __volatile__ (".Lia%=: lwarx %0,0,%3\n" " add %1,%0,%4\n" " stwcx. %1,0,%3\n" @@ -304,6 +323,7 @@ g_atomic_int_add (volatile gint *atomic, : "=&b" (result), "=&r" (temp), "=m" (*atomic) : "b" (atomic), "r" (val), "m" (*atomic) : "cr0", "memory"); +#endif } # else /* !__OPTIMIZE__ */ gint @@ -336,6 +356,18 @@ g_atomic_int_compare_and_exchange (volatile gint *atomic, gint newval) { gint result; +#if ASM_NUMERIC_LABELS + __asm__ __volatile__ ("sync\n" + "1: lwarx %0,0,%1\n" + " subf. %0,%2,%0\n" + " bne 2f\n" + " stwcx. %3,0,%1\n" + " bne- 1b\n" + "2: isync" + : "=&r" (result) + : "b" (atomic), "r" (oldval), "r" (newval) + : "cr0", "memory"); +#else __asm__ __volatile__ ("sync\n" ".L1icae%=: lwarx %0,0,%1\n" " subf. %0,%2,%0\n" @@ -346,6 +378,7 @@ g_atomic_int_compare_and_exchange (volatile gint *atomic, : "=&r" (result) : "b" (atomic), "r" (oldval), "r" (newval) : "cr0", "memory"); +#endif return result == 0; } @@ -355,6 +388,18 @@ g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic, gpointer newval) { gpointer result; +#if ASM_NUMERIC_LABELS + __asm__ __volatile__ ("sync\n" + "1: lwarx %0,0,%1\n" + " subf. %0,%2,%0\n" + " bne 2f\n" + " stwcx. %3,0,%1\n" + " bne- 1b\n" + "2: isync" + : "=&r" (result) + : "b" (atomic), "r" (oldval), "r" (newval) + : "cr0", "memory"); +#else __asm__ __volatile__ ("sync\n" ".L1pcae%=: lwarx %0,0,%1\n" " subf. %0,%2,%0\n" @@ -365,6 +410,7 @@ g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic, : "=&r" (result) : "b" (atomic), "r" (oldval), "r" (newval) : "cr0", "memory"); +#endif return result == 0; } # elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */ @@ -374,6 +420,19 @@ g_atomic_int_compare_and_exchange (volatile gint *atomic, gint newval) { gpointer result; +#if ASM_NUMERIC_LABELS + __asm__ __volatile__ ("sync\n" + "1: lwarx %0,0,%1\n" + " extsw %0,%0\n" + " subf. %0,%2,%0\n" + " bne 2f\n" + " stwcx. %3,0,%1\n" + " bne- 1b\n" + "2: isync" + : "=&r" (result) + : "b" (atomic), "r" (oldval), "r" (newval) + : "cr0", "memory"); +#else __asm__ __volatile__ ("sync\n" ".L1icae%=: lwarx %0,0,%1\n" " extsw %0,%0\n" @@ -385,6 +444,7 @@ g_atomic_int_compare_and_exchange (volatile gint *atomic, : "=&r" (result) : "b" (atomic), "r" (oldval), "r" (newval) : "cr0", "memory"); +#endif return result == 0; } @@ -394,6 +454,18 @@ g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic, gpointer newval) { gpointer result; +#if ASM_NUMERIC_LABELS + __asm__ __volatile__ ("sync\n" + "1: ldarx %0,0,%1\n" + " subf. %0,%2,%0\n" + " bne 2f\n" + " stdcx. %3,0,%1\n" + " bne- 1b\n" + "2: isync" + : "=&r" (result) + : "b" (atomic), "r" (oldval), "r" (newval) + : "cr0", "memory"); +#else __asm__ __volatile__ ("sync\n" ".L1pcae%=: ldarx %0,0,%1\n" " subf. %0,%2,%0\n" @@ -404,6 +476,7 @@ g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic, : "=&r" (result) : "b" (atomic), "r" (oldval), "r" (newval) : "cr0", "memory"); +#endif return result == 0; } # else /* What's that */ -- 2.34.1