Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -601,11 +601,12 @@ ]) AC_MSG_CHECKING(whether we have an atomic ops assembly implementation) AC_EGREP_CPP(yes, [ #if defined(__GNUC__) && (defined(__i386__) || \ - defined(__x86_64__) || defined(__amd64__)) + defined(__x86_64__) || defined(__amd64__)) || + defined(__ppc__) yes #endif ], [ AC_MSG_RESULT(yes) test x"$atomic_ops" = x"none" && \ Index: src/atomic.h ================================================================== --- src/atomic.h +++ src/atomic.h @@ -54,10 +54,22 @@ : "r"(i), "m"(*p) ); # endif else abort(); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "add %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicAdd32Barrier(i, p); #else @@ -78,10 +90,22 @@ "xaddl %0, %2\n\t" "addl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "add %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicAdd32Barrier(i, p); #else @@ -112,10 +136,22 @@ "xaddl %0, %2\n\t" "addl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); + + return (void*)i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "add %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return (void*)i; #elif defined(OF_HAVE_OSATOMIC) # ifdef __LP64__ return (void*)OSAtomicAdd64Barrier(i, (int64_t*)p); @@ -155,10 +191,22 @@ : "r"(i), "m"(*p) ); # endif else abort(); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "sub %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicAdd32Barrier(-i, p); #else @@ -180,10 +228,22 @@ "xaddl %0, %2\n\t" "subl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "sub %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicAdd32Barrier(-i, p); #else @@ -216,10 +276,22 @@ "xaddl %0, %2\n\t" "subl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); + + return (void*)i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "sub %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return (void*)i; #elif defined(OF_HAVE_OSATOMIC) # ifdef __LP64__ return (void*)OSAtomicAdd64Barrier(-i, (int64_t*)p); @@ -263,10 +335,24 @@ : "m"(*p) ); # endif else abort(); + + return i; +#elif defined(OF_PPC_ASM) + int i; + + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %1\n\t" + "addi %0, %0, 1\n\t" + "stwcx. %0, 0, %1\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicIncrement32Barrier(p); #else @@ -291,10 +377,24 @@ "xaddl %0, %1\n\t" "incl %0" : "=&r"(i) : "m"(*p) ); + + return i; +#elif defined(OF_PPC_ASM) + int32_t i; + + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %1\n\t" + "addi %0, %0, 1\n\t" + "stwcx. %0, 0, %1\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicIncrement32Barrier(p); #else @@ -334,10 +434,24 @@ : "m"(*p) ); # endif else abort(); + + return i; +#elif defined(OF_PPC_ASM) + int i; + + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %1\n\t" + "subi %0, %0, 1\n\t" + "stwcx. %0, 0, %1\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicDecrement32Barrier(p); #else @@ -362,10 +476,24 @@ "xaddl %0, %1\n\t" "decl %0" : "=&r"(i) : "m"(*p) ); + + return i; +#elif defined(OF_PPC_ASM) + int32_t i; + + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %1\n\t" + "subi %0, %0, 1\n\t" + "stwcx. %0, 0, %1\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicDecrement32Barrier(p); #else @@ -409,10 +537,22 @@ : "rax", "cc" ); # endif else abort(); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "or %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicOr32Barrier(i, p); #else @@ -438,10 +578,22 @@ "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "or %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicOr32Barrier(i, p); #else @@ -485,10 +637,22 @@ : "rax", "cc" ); # endif else abort(); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "and %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicAnd32Barrier(i, p); #else @@ -514,10 +678,22 @@ "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "and %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicAnd32Barrier(i, p); #else @@ -561,10 +737,22 @@ : "rax", "cc" ); # endif else abort(); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "xor %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicXor32Barrier(i, p); #else @@ -590,10 +778,22 @@ "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); + + return i; +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %2\n\t" + "xor %0, %0, %1\n\t" + "stwcx. %0, 0, %2\n\t" + "bne- 0b" + : "=&r"(i) + : "r"(i), "r"(p) + ); return i; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicXor32Barrier(i, p); #else @@ -623,10 +823,32 @@ "movzbl %b0, %0" : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */ : "r"(n), "m"(*p) : "cc" ); + + return r; +#elif defined(OF_PPC_ASM) + int r; + + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %3\n\t" + "cmpw %0, %1\n\t" + "bne 1f\n\t" + "stwcx. %2, 0, %3\n\t" + "bne- 0b\n\t" + "li %0, 1\n\t" + "b 2f\n\t" + "1:\n\t" + "stwcx. %0, 0, %3\n\t" + "li %0, 0\n\t" + "2:" + : "=&r"(r) + : "r"(o), "r"(n), "r"(p) + : "cc" + ); return r; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicCompareAndSwapIntBarrier(o, n, p); #else @@ -656,10 +878,32 @@ "movzbl %b0, %0" : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */ : "r"(n), "m"(*p) : "cc" ); + + return r; +#elif defined(OF_PPC_ASM) + int r; + + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %3\n\t" + "cmpw %0, %1\n\t" + "bne 1f\n\t" + "stwcx. %2, 0, %3\n\t" + "bne- 0b\n\t" + "li %0, 1\n\t" + "b 2f\n\t" + "1:\n\t" + "stwcx. %0, 0, %3\n\t" + "li %0, 0\n\t" + "2:" + : "=&r"(r) + : "r"(o), "r"(n), "r"(p) + : "cc" + ); return r; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicCompareAndSwap32Barrier(o, n, p); #else @@ -689,10 +933,32 @@ "movzbl %b0, %0" : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */ : "r"(n), "m"(*p) : "cc" ); + + return r; +#elif defined(OF_PPC_ASM) + int r; + + __asm__ __volatile__ ( + "0:\n\t" + "lwarx %0, 0, %3\n\t" + "cmpw %0, %1\n\t" + "bne 1f\n\t" + "stwcx. %2, 0, %3\n\t" + "bne- 0b\n\t" + "li %0, 1\n\t" + "b 2f\n\t" + "1:\n\t" + "stwcx. %0, 0, %3\n\t" + "li %0, 0\n\t" + "2:" + : "=&r"(r) + : "r"(o), "r"(n), "r"(p) + : "cc" + ); return r; #elif defined(OF_HAVE_OSATOMIC) return OSAtomicCompareAndSwapPtrBarrier(o, n, p); #else @@ -705,10 +971,14 @@ { #if !defined(OF_HAVE_THREADS) #elif defined(OF_X86_64_ASM) || defined(OF_X86_ASM) __asm__ __volatile__ ( "mfence" + ); +#elif defined(OF_PPC_ASM) + __asm__ __volatile__ ( + "sync" ); #elif defined(OF_HAVE_GCC_ATOMIC_OPS) __sync_synchronize(); #elif defined(OF_HAVE_OSATOMIC) OSMemoryBarrier();