/* * Copyright (C) 2007 Atmel Corporation * * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file "COPYING.LIB" in the main directory of this * archive for more details. */ #ifndef _AVR32_BITS_ATOMIC_H #define _AVR32_BITS_ATOMIC_H 1 #include <inttypes.h> typedef int32_t atomic32_t; typedef uint32_t uatomic32_t; typedef int_fast32_t atomic_fast32_t; typedef uint_fast32_t uatomic_fast32_t; typedef intptr_t atomicptr_t; typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ (abort(), 0) #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ (abort(), 0) #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ ({ \ __typeof__(*(mem)) __prev; \ __asm__ __volatile__( \ "/* __arch_compare_and_exchange_val_32_acq */\n" \ "1: ssrf 5\n" \ " ld.w %[result], %[m]\n" \ " cp.w %[result], %[old]\n" \ " brne 2f\n" \ " stcond %[m], %[new]\n" \ " brne 1b\n" \ "2:" \ : [result] "=&r"(__result), [m] "=m"(*(mem)) \ : "m"(*(mem)), [old] "ir"(oldval), \ [new] "r"(newval) \ : "memory", "cc"); \ __prev; \ }) #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ (abort(), 0) #define __arch_exchange_32_acq(mem, newval) \ ({ \ __typeof__(*(mem)) __oldval; \ __asm__ __volatile__( \ "/*__arch_exchange_32_acq */\n" \ " xchg %[old], %[m], %[new]" \ : [old] "=&r"(__oldval) \ : [m] "r"(mem), [new] "r"(newval) \ : "memory"); \ __oldval; \ }) #define __arch_atomic_exchange_and_add_32(mem, value) \ ({ \ __typeof__(*(mem)) __oldval, __tmp; \ __asm__ __volatile__( \ "/* __arch_atomic_exchange_and_add_32 */\n" \ "1: ssrf 5\n" \ " ld.w %[old], %[m]\n" \ " add %[tmp], %[old], %[val]\n" \ " stcond %[m], %[tmp]\n" \ " brne 1b" \ : [old] "=&r"(__oldval), [tmp] "=&r"(__tmp), \ [m] "=m"(*(mem)) \ : "m"(*(mem)), [val] "r"(value) \ : "memory", "cc"); \ __oldval; \ }) #define __arch_atomic_decrement_if_positive_32(mem) \ ({ \ __typeof__(*(mem)) __oldval, __tmp; \ __asm__ __volatile__( \ "/* __arch_atomic_decrement_if_positive_32 */\n" \ "1: ssrf 5\n" \ " ld.w %[old], %[m]\n" \ " sub %[tmp], %[old], 1\n" \ " brlt 2f\n" \ " stcond %[m], %[tmp]\n" \ " brne 1b" \ "2:" \ : [old] "=&r"(__oldval), [tmp] "=&r"(__tmp), \ [m] "=m"(*(mem)) \ : "m"(*(mem)) \ : "memory", "cc"); \ __oldval; \ }) #define atomic_exchange_acq(mem, newval) \ ({ \ if (sizeof(*(mem)) != 4) \ abort(); \ __arch_exchange_32_acq(mem, newval); \ }) #define atomic_exchange_and_add(mem, newval) \ ({ \ if (sizeof(*(mem)) != 4) \ abort(); \ __arch_atomic_exchange_and_add_32(mem, newval); \ }) #define atomic_decrement_if_positive(mem) \ ({ \ if (sizeof(*(mem)) != 4) \ abort(); \ __arch_atomic_decrement_if_positive_32(mem); \ }) #endif /* _AVR32_BITS_ATOMIC_H */