&& !defined(__ARM_ARCH_5TEJ__) && !defined(__ARM_ARCH_6M__)) \
|| defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__))
# define AO_ARM_HAVE_LDREX
+# if !defined(__ARM_ARCH_6__) && !defined(__ARM_ARCH_6J__) \
+ && !defined(__ARM_ARCH_6T2__)
+ /* LDREXB/STREXB and LDREXH/STREXH are present in ARMv6K/Z+. */
+# define AO_ARM_HAVE_LDREXBH
+# endif
# if !defined(__ARM_ARCH_6__) && !defined(__ARM_ARCH_6J__) \
&& !defined(__ARM_ARCH_6T2__) && !defined(__ARM_ARCH_6Z__) \
&& !defined(__ARM_ARCH_6ZT2__)
}
# define AO_HAVE_store
- AO_INLINE void AO_char_store(volatile unsigned char *addr,
- unsigned char value)
- {
- int flag;
+# ifdef AO_ARM_HAVE_LDREXBH
+ AO_INLINE void AO_char_store(volatile unsigned char *addr,
+ unsigned char value)
+ {
+ int flag;
- __asm__ __volatile__("@AO_char_store\n"
- AO_THUMB_GO_ARM
- "1: ldrexb %0, [%2]\n"
- " strexb %0, %3, [%2]\n"
- " teq %0, #0\n"
- " bne 1b\n"
- AO_THUMB_RESTORE_MODE
- : "=&r" (flag), "+m" (*addr)
- : "r" (addr), "r" (value)
- : AO_THUMB_SWITCH_CLOBBERS "cc");
- }
-# define AO_HAVE_char_store
-
- AO_INLINE void AO_short_store(volatile unsigned short *addr,
- unsigned short value)
- {
- int flag;
-
- __asm__ __volatile__("@AO_short_store\n"
- AO_THUMB_GO_ARM
- "1: ldrexh %0, [%2]\n"
- " strexh %0, %3, [%2]\n"
- " teq %0, #0\n"
- " bne 1b\n"
- AO_THUMB_RESTORE_MODE
- : "=&r" (flag), "+m" (*addr)
- : "r" (addr), "r" (value)
- : AO_THUMB_SWITCH_CLOBBERS "cc");
- }
-# define AO_HAVE_short_store
+ __asm__ __volatile__("@AO_char_store\n"
+ AO_THUMB_GO_ARM
+ "1: ldrexb %0, [%2]\n"
+ " strexb %0, %3, [%2]\n"
+ " teq %0, #0\n"
+ " bne 1b\n"
+ AO_THUMB_RESTORE_MODE
+ : "=&r" (flag), "+m" (*addr)
+ : "r" (addr), "r" (value)
+ : AO_THUMB_SWITCH_CLOBBERS "cc");
+ }
+# define AO_HAVE_char_store
+
+ AO_INLINE void AO_short_store(volatile unsigned short *addr,
+ unsigned short value)
+ {
+ int flag;
+
+ __asm__ __volatile__("@AO_short_store\n"
+ AO_THUMB_GO_ARM
+ "1: ldrexh %0, [%2]\n"
+ " strexh %0, %3, [%2]\n"
+ " teq %0, #0\n"
+ " bne 1b\n"
+ AO_THUMB_RESTORE_MODE
+ : "=&r" (flag), "+m" (*addr)
+ : "r" (addr), "r" (value)
+ : AO_THUMB_SWITCH_CLOBBERS "cc");
+ }
+# define AO_HAVE_short_store
+# endif /* AO_ARM_HAVE_LDREXBH */
# else
# include "../loadstore/atomic_store.h"
-# include "../loadstore/char_atomic_store.h"
-# include "../loadstore/short_atomic_store.h"
/* AO_int_store is defined in ao_t_is_int.h. */
# endif /* !AO_BROKEN_TASKSWITCH_CLREX */
+# ifndef AO_HAVE_char_store
+# include "../loadstore/char_atomic_store.h"
+# include "../loadstore/short_atomic_store.h"
+# endif
+
/* NEC LE-IT: replace the SWAP as recommended by ARM:
"Applies to: ARM11 Cores
Though the SWP instruction will still work with ARM V6 cores, it is
#define AO_HAVE_fetch_and_sub1
#endif /* !AO_PREFER_GENERALIZED */
-AO_INLINE unsigned char
-AO_char_fetch_and_add(volatile unsigned char *p, unsigned char incr)
-{
- unsigned char result, tmp;
- int flag;
+#ifdef AO_ARM_HAVE_LDREXBH
+ AO_INLINE unsigned char
+ AO_char_fetch_and_add(volatile unsigned char *p, unsigned char incr)
+ {
+ unsigned char result, tmp;
+ int flag;
- __asm__ __volatile__("@AO_char_fetch_and_add\n"
- AO_THUMB_GO_ARM
- "1: ldrexb %0, [%5]\n"
- " add %2, %0, %4\n"
- " strexb %1, %2, [%5]\n"
- " teq %1, #0\n"
- " bne 1b\n"
- AO_THUMB_RESTORE_MODE
- : "=&r" (result), "=&r" (flag), "=&r" (tmp), "+m" (*p)
- : "r" (incr), "r" (p)
- : AO_THUMB_SWITCH_CLOBBERS "cc");
- return result;
-}
-#define AO_HAVE_char_fetch_and_add
+ __asm__ __volatile__("@AO_char_fetch_and_add\n"
+ AO_THUMB_GO_ARM
+ "1: ldrexb %0, [%5]\n"
+ " add %2, %0, %4\n"
+ " strexb %1, %2, [%5]\n"
+ " teq %1, #0\n"
+ " bne 1b\n"
+ AO_THUMB_RESTORE_MODE
+ : "=&r" (result), "=&r" (flag), "=&r" (tmp), "+m" (*p)
+ : "r" (incr), "r" (p)
+ : AO_THUMB_SWITCH_CLOBBERS "cc");
+ return result;
+ }
+# define AO_HAVE_char_fetch_and_add
-AO_INLINE unsigned short
-AO_short_fetch_and_add(volatile unsigned short *p, unsigned short incr)
-{
- unsigned short result, tmp;
- int flag;
+ AO_INLINE unsigned short
+ AO_short_fetch_and_add(volatile unsigned short *p, unsigned short incr)
+ {
+ unsigned short result, tmp;
+ int flag;
- __asm__ __volatile__("@AO_short_fetch_and_add\n"
- AO_THUMB_GO_ARM
- "1: ldrexh %0, [%5]\n"
- " add %2, %0, %4\n"
- " strexh %1, %2, [%5]\n"
- " teq %1, #0\n"
- " bne 1b\n"
- AO_THUMB_RESTORE_MODE
- : "=&r" (result), "=&r" (flag), "=&r" (tmp), "+m" (*p)
- : "r" (incr), "r" (p)
- : AO_THUMB_SWITCH_CLOBBERS "cc");
- return result;
-}
-#define AO_HAVE_short_fetch_and_add
+ __asm__ __volatile__("@AO_short_fetch_and_add\n"
+ AO_THUMB_GO_ARM
+ "1: ldrexh %0, [%5]\n"
+ " add %2, %0, %4\n"
+ " strexh %1, %2, [%5]\n"
+ " teq %1, #0\n"
+ " bne 1b\n"
+ AO_THUMB_RESTORE_MODE
+ : "=&r" (result), "=&r" (flag), "=&r" (tmp), "+m" (*p)
+ : "r" (incr), "r" (p)
+ : AO_THUMB_SWITCH_CLOBBERS "cc");
+ return result;
+ }
+# define AO_HAVE_short_fetch_and_add
+#endif /* AO_ARM_HAVE_LDREXBH */
#ifndef AO_GENERALIZE_ASM_BOOL_CAS
/* Returns nonzero if the comparison succeeded. */