X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=blobdiff_plain;f=src%2Fmm%2Fboehm-gc%2Flibatomic_ops-1.2%2Fsrc%2Fatomic_ops%2Fsysdeps%2Fgcc%2Fpowerpc.h;h=49ab63c69f16bb5f788189ab430ffccea4936c29;hp=799722aa37c8ee888a6a5380b70fa447c7a3e356;hb=c83bff94e40ee0a218a39931af17814d1a42cb5c;hpb=db5750e3eaf39a47dbccccfe7cdd180fb686aac6 diff --git a/src/mm/boehm-gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc/powerpc.h b/src/mm/boehm-gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc/powerpc.h index 799722aa3..49ab63c69 100644 --- a/src/mm/boehm-gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc/powerpc.h +++ b/src/mm/boehm-gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc/powerpc.h @@ -15,7 +15,6 @@ * */ -/* FIXME. Incomplete. No support for 64 bits. */ /* Memory model documented at http://www-106.ibm.com/developerworks/ */ /* eserver/articles/archguide.html and (clearer) */ /* http://www-106.ibm.com/developerworks/eserver/articles/powerpc.html. */ @@ -29,6 +28,7 @@ /* from cached memory. */ /* Thanks to Maged Michael, Doug Lea, and Roger Hoover for helping to */ /* track some of this down and correcting my misunderstandings. -HB */ +/* Earl Chew subsequently contributed further fixes & additions. */ #include "../all_aligned_atomic_load_store.h" @@ -37,7 +37,7 @@ /* may really be what we want, at least in the 32-bit case. */ AO_INLINE void -AO_nop_full() +AO_nop_full(void) { __asm__ __volatile__("sync" : : : "memory"); } @@ -46,9 +46,13 @@ AO_nop_full() /* lwsync apparently works for everything but a StoreLoad barrier. */ AO_INLINE void -AO_lwsync() +AO_lwsync(void) { +#ifdef __NO_LWSYNC__ + __asm__ __volatile__("sync" : : : "memory"); +#else __asm__ __volatile__("lwsync" : : : "memory"); +#endif } #define AO_nop_write() AO_lwsync() @@ -66,25 +70,22 @@ AO_lwsync() /* ppc64 uses ld not lwz */ #if defined(__powerpc64__) || defined(__ppc64__) || defined(__64BIT__) AO_INLINE AO_t -AO_load_acquire(volatile AO_t *addr) +AO_load_acquire(const volatile AO_t *addr) { AO_t result; - /* FIXME: We should get gcc to allocate one of the condition */ - /* registers. I always got "impossible constraint" when I */ - /* tried the "y" constraint. */ - __asm__ __volatile__ ( - "ld %0,%1\n" - "cmpw cr7,%0,%0\n" - "bne- cr7,1f\n" + __asm__ __volatile__ ( + "ld%U1%X1 %0,%1\n" + "cmpw %0,%0\n" + "bne- 1f\n" "1: isync\n" : "=r" (result) - : "m"(*addr) : "memory", "cc"); + : "m"(*addr) : "memory", "cr0"); return result; } #else AO_INLINE AO_t -AO_load_acquire(volatile AO_t *addr) +AO_load_acquire(const volatile AO_t *addr) { AO_t result; @@ -92,9 +93,9 @@ AO_load_acquire(volatile AO_t *addr) /* registers. I always got "impossible constraint" when I */ /* tried the "y" constraint. */ __asm__ __volatile__ ( - "lwz%X1 %0,%1\n" - "cmpw cr7,%0,%0\n" - "bne- cr7,1f\n" + "lwz%U1%X1 %0,%1\n" + "cmpw %0,%0\n" + "bne- 1f\n" "1: isync\n" : "=r" (result) : "m"(*addr) : "memory", "cc"); @@ -133,7 +134,7 @@ AO_test_and_set(volatile AO_TS_t *addr) { "2:\n" /* oldval is zero if we set */ : "=&r"(oldval) : "r"(addr), "r"(temp) - : "memory", "cc"); + : "memory", "cr0"); return (AO_TS_VAL_t)oldval; } @@ -154,7 +155,7 @@ AO_test_and_set(volatile AO_TS_t *addr) { "2:\n" /* oldval is zero if we set */ : "=&r"(oldval) : "r"(addr), "r"(temp) - : "memory", "cc"); + : "memory", "cr0"); return (AO_TS_VAL_t)oldval; } @@ -208,7 +209,7 @@ AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) { "2:\n" : "=&r"(oldval), "=&r"(result) : "r"(addr), "r"(new_val), "r"(old), "1"(result) - : "memory", "cc"); + : "memory", "cr0"); return result; } @@ -230,7 +231,7 @@ AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) { "2:\n" : "=&r"(oldval), "=&r"(result) : "r"(addr), "r"(new_val), "r"(old), "1"(result) - : "memory", "cc"); + : "memory", "cr0"); return result; } @@ -266,5 +267,81 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) { #define AO_HAVE_compare_and_swap_full -/* FIXME: We should also implement fetch_and_add and or primitives */ -/* directly. */ +#if defined(__powerpc64__) || defined(__ppc64__) || defined(__64BIT__) +/* FIXME: Completely untested. */ + +AO_INLINE AO_t +AO_fetch_and_add(volatile AO_t *addr, AO_t incr) { + AO_t oldval; + AO_t newval; + + __asm__ __volatile__( + "1:ldarx %0,0,%2\n" /* load and reserve */ + "add %1,%0,%3\n" /* increment */ + "stdcx. %1,0,%2\n" /* store conditional */ + "bne- 1b\n" /* retry if lost reservation */ + : "=&r"(oldval), "=&r"(newval) + : "r"(addr), "r"(incr) + : "memory", "cr0"); + + return oldval; +} + +#define AO_HAVE_fetch_and_add + +#else + +AO_INLINE AO_t +AO_fetch_and_add(volatile AO_t *addr, AO_t incr) { + AO_t oldval; + AO_t newval; + + __asm__ __volatile__( + "1:lwarx %0,0,%2\n" /* load and reserve */ + "add %1,%0,%3\n" /* increment */ + "stwcx. %1,0,%2\n" /* store conditional */ + "bne- 1b\n" /* retry if lost reservation */ + : "=&r"(oldval), "=&r"(newval) + : "r"(addr), "r"(incr) + : "memory", "cr0"); + + return oldval; +} + +#define AO_HAVE_fetch_and_add + +#endif + +AO_INLINE AO_t +AO_fetch_and_add_acquire(volatile AO_t *addr, AO_t incr) { + AO_t result = AO_fetch_and_add(addr, incr); + AO_lwsync(); + return result; +} + +#define AO_HAVE_fetch_and_add_acquire + +AO_INLINE AO_t +AO_fetch_and_add_release(volatile AO_t *addr, AO_t incr) { + AO_lwsync(); + return AO_fetch_and_add(addr, incr); +} + +#define AO_HAVE_fetch_and_add_release + +AO_INLINE AO_t +AO_fetch_and_add_full(volatile AO_t *addr, AO_t incr) { + AO_t result; + AO_lwsync(); + result = AO_fetch_and_add(addr, incr); + AO_lwsync(); + return result; +} + +#define AO_HAVE_fetch_and_add_full + +#if defined(__powerpc64__) || defined(__ppc64__) || defined(__64BIT__) +#else +# include "../ao_t_is_int.h" +#endif +