diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index ee36c451a28..4d8294b44f6 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,15 @@ +2012-03-07 Walter Lee + + * config/tilepro/atomic.c: Rename "atomic_" prefix to + "arch_atomic_". + (atomic_xor): Rename and move definition to + config/tilepro/atomic.h. + (atomic_nand): Ditto. + * config/tilepro/atomic.h: Rename "atomic_" prefix to + "arch_atomic_". + (arch_atomic_xor): Move from config/tilepro/atomic.c. + (arch_atomic_nand): Ditto. + 2012-03-07 Georg-Johann Lay PR target/52507 diff --git a/libgcc/config/tilepro/atomic.c b/libgcc/config/tilepro/atomic.c index cafbde8abee..bdf809807be 100644 --- a/libgcc/config/tilepro/atomic.c +++ b/libgcc/config/tilepro/atomic.c @@ -63,18 +63,12 @@ post_atomic_barrier (int model) #define __unused __attribute__((unused)) -/* Provide additional methods not implemented by atomic.h. */ -#define atomic_xor(mem, mask) \ - __atomic_update_cmpxchg(mem, mask, __old ^ __value) -#define atomic_nand(mem, mask) \ - __atomic_update_cmpxchg(mem, mask, ~(__old & __value)) - #define __atomic_fetch_and_do(type, size, opname) \ type \ __atomic_fetch_##opname##_##size(type* p, type i, int model) \ { \ pre_atomic_barrier(model); \ - type rv = atomic_##opname(p, i); \ + type rv = arch_atomic_##opname(p, i); \ post_atomic_barrier(model); \ return rv; \ } @@ -96,7 +90,7 @@ type \ __atomic_##opname##_fetch_##size(type* p, type i, int model) \ { \ pre_atomic_barrier(model); \ - type rv = atomic_##opname(p, i) op i; \ + type rv = arch_atomic_##opname(p, i) op i; \ post_atomic_barrier(model); \ return rv; \ } @@ -120,7 +114,7 @@ __atomic_compare_exchange_##size(volatile type* ptr, type* oldvalp, \ { \ type oldval = *oldvalp; \ pre_atomic_barrier(models); \ - type retval = atomic_val_compare_and_exchange(ptr, oldval, newval); \ + type retval = arch_atomic_val_compare_and_exchange(ptr, oldval, newval); \ post_atomic_barrier(models); \ bool success = (retval == oldval); \ *oldvalp = retval; \ @@ -131,7 +125,7 @@ type \ __atomic_exchange_##size(volatile type* ptr, type val, int model) \ { \ pre_atomic_barrier(model); \ - type retval = atomic_exchange(ptr, val); \ + type retval = arch_atomic_exchange(ptr, val); \ post_atomic_barrier(model); \ return retval; \ } @@ -159,7 +153,7 @@ __atomic_compare_exchange_##size(volatile type* ptr, type* guess, \ type oldval = (oldword >> shift) & valmask; \ if (__builtin_expect((oldval == *guess), 1)) { \ unsigned int word = (oldword & bgmask) | ((val & valmask) << shift); \ - oldword = atomic_val_compare_and_exchange(p, oldword, word); \ + oldword = arch_atomic_val_compare_and_exchange(p, oldword, word); \ oldval = (oldword >> shift) & valmask; \ } \ post_atomic_barrier(models); \ @@ -187,7 +181,7 @@ proto \ oldval = (oldword >> shift) & valmask; \ val = expr; \ unsigned int word = (oldword & bgmask) | ((val & valmask) << shift); \ - xword = atomic_val_compare_and_exchange(p, oldword, word); \ + xword = arch_atomic_val_compare_and_exchange(p, oldword, word); \ } while (__builtin_expect(xword != oldword, 0)); \ bottom \ } diff --git a/libgcc/config/tilepro/atomic.h b/libgcc/config/tilepro/atomic.h index 16306fe0e76..d49d13b3fb0 100644 --- a/libgcc/config/tilepro/atomic.h +++ b/libgcc/config/tilepro/atomic.h @@ -104,8 +104,8 @@ /* 32-bit integer compare-and-exchange. */ static __inline __attribute__ ((always_inline)) - int atomic_val_compare_and_exchange_4 (volatile int *mem, - int oldval, int newval) + int arch_atomic_val_compare_and_exchange_4 (volatile int *mem, + int oldval, int newval) { #ifdef __tilegx__ __insn_mtspr (SPR_CMPEXCH_VALUE, oldval); @@ -123,9 +123,9 @@ static __inline __attribute__ ((always_inline)) /* 64-bit integer compare-and-exchange. */ static __inline __attribute__ ((always_inline)) - int64_t atomic_val_compare_and_exchange_8 (volatile int64_t * mem, - int64_t oldval, - int64_t newval) + int64_t arch_atomic_val_compare_and_exchange_8 (volatile int64_t * mem, + int64_t oldval, + int64_t newval) { #ifdef __tilegx__ __insn_mtspr (SPR_CMPEXCH_VALUE, oldval); @@ -146,41 +146,41 @@ static __inline __attribute__ ((always_inline)) /* This non-existent symbol is called for sizes other than "4" and "8", indicating a bug in the caller. */ -extern int __atomic_error_bad_argument_size (void) +extern int __arch_atomic_error_bad_argument_size (void) __attribute__ ((warning ("sizeof atomic argument not 4 or 8"))); -#define atomic_val_compare_and_exchange(mem, o, n) \ +#define arch_atomic_val_compare_and_exchange(mem, o, n) \ ({ \ (__typeof(*(mem)))(__typeof(*(mem)-*(mem))) \ ((sizeof(*(mem)) == 8) ? \ - atomic_val_compare_and_exchange_8( \ + arch_atomic_val_compare_and_exchange_8( \ (volatile int64_t*)(mem), (__typeof((o)-(o)))(o), \ (__typeof((n)-(n)))(n)) : \ (sizeof(*(mem)) == 4) ? \ - atomic_val_compare_and_exchange_4( \ + arch_atomic_val_compare_and_exchange_4( \ (volatile int*)(mem), (__typeof((o)-(o)))(o), \ (__typeof((n)-(n)))(n)) : \ - __atomic_error_bad_argument_size()); \ + __arch_atomic_error_bad_argument_size()); \ }) -#define atomic_bool_compare_and_exchange(mem, o, n) \ +#define arch_atomic_bool_compare_and_exchange(mem, o, n) \ ({ \ __typeof(o) __o = (o); \ __builtin_expect( \ - __o == atomic_val_compare_and_exchange((mem), __o, (n)), 1); \ + __o == arch_atomic_val_compare_and_exchange((mem), __o, (n)), 1); \ }) /* Loop with compare_and_exchange until we guess the correct value. Normally "expr" will be an expression using __old and __value. */ -#define __atomic_update_cmpxchg(mem, value, expr) \ +#define __arch_atomic_update_cmpxchg(mem, value, expr) \ ({ \ __typeof(value) __value = (value); \ __typeof(*(mem)) *__mem = (mem), __old = *__mem, __guess; \ do { \ __guess = __old; \ - __old = atomic_val_compare_and_exchange(__mem, __old, (expr)); \ + __old = arch_atomic_val_compare_and_exchange(__mem, __old, (expr)); \ } while (__builtin_expect(__old != __guess, 0)); \ __old; \ }) @@ -189,14 +189,14 @@ extern int __atomic_error_bad_argument_size (void) /* Generic atomic op with 8- or 4-byte variant. The _mask, _addend, and _expr arguments are ignored on tilegx. */ -#define __atomic_update(mem, value, op, _mask, _addend, _expr) \ +#define __arch_atomic_update(mem, value, op, _mask, _addend, _expr) \ ({ \ ((__typeof(*(mem))) \ ((sizeof(*(mem)) == 8) ? (__typeof(*(mem)-*(mem)))__insn_##op( \ (void *)(mem), (int64_t)(__typeof((value)-(value)))(value)) : \ (sizeof(*(mem)) == 4) ? (int)__insn_##op##4( \ (void *)(mem), (int32_t)(__typeof((value)-(value)))(value)) : \ - __atomic_error_bad_argument_size())); \ + __arch_atomic_error_bad_argument_size())); \ }) #else @@ -211,7 +211,7 @@ extern int __atomic_error_bad_argument_size (void) Only 32-bit support is provided. */ static __inline __attribute__ ((always_inline)) int - __atomic_update_4 (volatile int *mem, int mask, int addend) + __arch_atomic_update_4 (volatile int *mem, int mask, int addend) { int result; __asm__ __volatile__ ("swint1":"=R00" (result), @@ -224,48 +224,55 @@ static __inline __attribute__ ((always_inline)) /* Generic atomic op with 8- or 4-byte variant. The _op argument is ignored on tilepro. */ -#define __atomic_update(mem, value, _op, mask, addend, expr) \ +#define __arch_atomic_update(mem, value, _op, mask, addend, expr) \ ({ \ (__typeof(*(mem)))(__typeof(*(mem)-*(mem))) \ ((sizeof(*(mem)) == 8) ? \ - __atomic_update_cmpxchg((mem), (value), (expr)) : \ + __arch_atomic_update_cmpxchg((mem), (value), (expr)) : \ (sizeof(*(mem)) == 4) ? \ - __atomic_update_4((volatile int*)(mem), (__typeof((mask)-(mask)))(mask), \ - (__typeof((addend)-(addend)))(addend)) : \ - __atomic_error_bad_argument_size()); \ + __arch_atomic_update_4((volatile int*)(mem), \ + (__typeof((mask)-(mask)))(mask), \ + (__typeof((addend)-(addend)))(addend)) : \ + __arch_atomic_error_bad_argument_size()); \ }) #endif /* __tilegx__ */ -#define atomic_exchange(mem, newvalue) \ - __atomic_update(mem, newvalue, exch, 0, newvalue, __value) +#define arch_atomic_exchange(mem, newvalue) \ + __arch_atomic_update(mem, newvalue, exch, 0, newvalue, __value) -#define atomic_add(mem, value) \ - __atomic_update(mem, value, fetchadd, -1, value, __old + __value) +#define arch_atomic_add(mem, value) \ + __arch_atomic_update(mem, value, fetchadd, -1, value, __old + __value) -#define atomic_sub(mem, value) atomic_add((mem), -(value)) +#define arch_atomic_sub(mem, value) arch_atomic_add((mem), -(value)) -#define atomic_increment(mem) atomic_add((mem), 1) +#define arch_atomic_increment(mem) arch_atomic_add((mem), 1) -#define atomic_decrement(mem) atomic_add((mem), -1) +#define arch_atomic_decrement(mem) arch_atomic_add((mem), -1) -#define atomic_and(mem, mask) \ - __atomic_update(mem, mask, fetchand, mask, 0, __old & __value) +#define arch_atomic_and(mem, mask) \ + __arch_atomic_update(mem, mask, fetchand, mask, 0, __old & __value) -#define atomic_or(mem, mask) \ - __atomic_update(mem, mask, fetchor, ~mask, mask, __old | __value) +#define arch_atomic_or(mem, mask) \ + __arch_atomic_update(mem, mask, fetchor, ~mask, mask, __old | __value) -#define atomic_bit_set(mem, bit) \ +#define arch_atomic_xor(mem, mask) \ + __arch_atomic_update_cmpxchg(mem, mask, __old ^ __value) + +#define arch_atomic_nand(mem, mask) \ + __arch_atomic_update_cmpxchg(mem, mask, ~(__old & __value)) + +#define arch_atomic_bit_set(mem, bit) \ ({ \ __typeof(*(mem)) __mask = (__typeof(*(mem)))1 << (bit); \ - __mask & atomic_or((mem), __mask); \ + __mask & arch_atomic_or((mem), __mask); \ }) -#define atomic_bit_clear(mem, bit) \ +#define arch_atomic_bit_clear(mem, bit) \ ({ \ __typeof(*(mem)) __mask = (__typeof(*(mem)))1 << (bit); \ - __mask & atomic_and((mem), ~__mask); \ + __mask & arch_atomic_and((mem), ~__mask); \ }) #ifdef __tilegx__ @@ -275,9 +282,9 @@ static __inline __attribute__ ((always_inline)) This accessor is provided for compatibility with TILEPro, which required an explicit atomic operation for stores that needed to be atomic with respect to other atomic methods in this header. */ -#define atomic_write(mem, value) ((void) (*(mem) = (value))) +#define arch_atomic_write(mem, value) ((void) (*(mem) = (value))) #else -#define atomic_write(mem, value) \ +#define arch_atomic_write(mem, value) \ do { \ __typeof(mem) __aw_mem = (mem); \ __typeof(value) __aw_val = (value); \ @@ -285,26 +292,26 @@ static __inline __attribute__ ((always_inline)) __aw_intval = (__typeof((value) - (value)))__aw_val; \ switch (sizeof(*__aw_mem)) { \ case 8: \ - __atomic_update_cmpxchg(__aw_mem, __aw_val, __value); \ + __arch_atomic_update_cmpxchg(__aw_mem, __aw_val, __value); \ break; \ case 4: \ - __atomic_update_4((int *)__aw_mem, 0, __aw_intval); \ + __arch_atomic_update_4((int *)__aw_mem, 0, __aw_intval); \ break; \ case 2: \ __aw_off = 8 * ((long)__aw_mem & 0x2); \ __aw_mask = 0xffffU << __aw_off; \ __aw_mem32 = (unsigned int *)((long)__aw_mem & ~0x2); \ __aw_val32 = (__aw_intval << __aw_off) & __aw_mask; \ - __atomic_update_cmpxchg(__aw_mem32, __aw_val32, \ - (__old & ~__aw_mask) | __value); \ + __arch_atomic_update_cmpxchg(__aw_mem32, __aw_val32, \ + (__old & ~__aw_mask) | __value); \ break; \ case 1: \ __aw_off = 8 * ((long)__aw_mem & 0x3); \ __aw_mask = 0xffU << __aw_off; \ __aw_mem32 = (unsigned int *)((long)__aw_mem & ~0x3); \ __aw_val32 = (__aw_intval << __aw_off) & __aw_mask; \ - __atomic_update_cmpxchg(__aw_mem32, __aw_val32, \ - (__old & ~__aw_mask) | __value); \ + __arch_atomic_update_cmpxchg(__aw_mem32, __aw_val32, \ + (__old & ~__aw_mask) | __value); \ break; \ } \ } while (0) @@ -315,15 +322,15 @@ static __inline __attribute__ ((always_inline)) This macro prevents loads or stores from being moved by the compiler across the macro. Any loaded value that was loaded before this macro must then be reloaded by the compiler. */ -#define atomic_compiler_barrier() __asm__ __volatile__("" ::: "memory") +#define arch_atomic_compiler_barrier() __asm__ __volatile__("" ::: "memory") /* Full memory barrier. - This macro has the semantics of atomic_compiler_barrer(), but also + This macro has the semantics of arch_atomic_compiler_barrer(), but also ensures that previous stores are visible to other cores, and that all previous loaded values have been placed into their target register on this core. */ -#define atomic_full_barrier() __insn_mf() +#define arch_atomic_full_barrier() __insn_mf() /* Read memory barrier. @@ -335,9 +342,9 @@ static __inline __attribute__ ((always_inline)) On current TILE chips a read barrier is implemented as a full barrier, but this may not be true in later versions of the architecture. - See also atomic_acquire_barrier() for the appropriate idiom to use + See also arch_atomic_acquire_barrier() for the appropriate idiom to use to ensure no reads are lifted above an atomic lock instruction. */ -#define atomic_read_barrier() atomic_full_barrier() +#define arch_atomic_read_barrier() arch_atomic_full_barrier() /* Write memory barrier. @@ -349,9 +356,9 @@ static __inline __attribute__ ((always_inline)) On current TILE chips a write barrier is implemented as a full barrier, but this may not be true in later versions of the architecture. - See also atomic_release_barrier() for the appropriate idiom to use + See also arch_atomic_release_barrier() for the appropriate idiom to use to ensure all writes are complete prior to an atomic unlock instruction. */ -#define atomic_write_barrier() atomic_full_barrier() +#define arch_atomic_write_barrier() arch_atomic_full_barrier() /* Lock acquisition barrier. @@ -367,10 +374,10 @@ static __inline __attribute__ ((always_inline)) This should be done after the atomic operation that actually acquires the lock, and in conjunction with a "control dependency" that checks the atomic operation result to see if the lock was - in fact acquired. See the atomic_read_barrier() macro + in fact acquired. See the arch_atomic_read_barrier() macro for a heavier-weight barrier to use in certain unusual constructs, - or atomic_acquire_barrier_value() if no control dependency exists. */ -#define atomic_acquire_barrier() atomic_compiler_barrier() + or arch_atomic_acquire_barrier_value() if no control dependency exists. */ +#define arch_atomic_acquire_barrier() arch_atomic_compiler_barrier() /* Lock release barrier. @@ -383,7 +390,7 @@ static __inline __attribute__ ((always_inline)) for locking, that is, when leaving a critical section. This should be done before the operation (such as a store of zero) that actually releases the lock. */ -#define atomic_release_barrier() atomic_write_barrier() +#define arch_atomic_release_barrier() arch_atomic_write_barrier() /* Barrier until the read of a particular value is complete. @@ -400,7 +407,7 @@ static __inline __attribute__ ((always_inline)) atomic instruction, even if the value itself is not checked. This guarantees that if the atomic instruction succeeded in taking the lock, the lock was held before any reads in the critical section issued. */ -#define atomic_acquire_barrier_value(val) \ +#define arch_atomic_acquire_barrier_value(val) \ __asm__ __volatile__("move %0, %0" :: "r"(val)) /* Access the given variable in memory exactly once. @@ -421,8 +428,9 @@ static __inline __attribute__ ((always_inline)) Note that multiple uses of this macro are guaranteed to be ordered, i.e. the compiler will not reorder stores or loads that are wrapped - in atomic_access_once(). */ -#define atomic_access_once(x) (*(volatile __typeof(x) *)&(x)) + in arch_atomic_access_once(). */ +#define arch_atomic_access_once(x) (*(volatile __typeof(x) *)&(x)) + #endif /* !_ATOMIC_H_ */