+/* helper functions for the Realview compiler: LDREXD is not usable
+ * with inline assembler, so use the "embedded" assembler as
+ * suggested by ARM Dev. support (June 2008). */
+__asm inline double_ptr_storage load_ex(volatile AO_double_t *addr) {
+ LDREXD r0,r1,[r0]
+}
+
+__asm inline int store_ex(AO_t val1, AO_t val2, volatile AO_double_t *addr) {
+ STREXD r3,r0,r1,[r2]
+ MOV r0,r3
+}
+
+AO_INLINE int
+AO_compare_double_and_swap_double(volatile AO_double_t *addr,
+ AO_t old_val1, AO_t old_val2,
+ AO_t new_val1, AO_t new_val2)
+{
+ double_ptr_storage old_val = ((double_ptr_storage)old_val2 << 32) | old_val1;
+
+ double_ptr_storage tmp;
+ int result;
+
+ while(1) {
+ tmp = load_ex(addr);
+ if(tmp != old_val) return false;
+ result = store_ex(new_val1, new_val2, addr);
+ if(!result) return true;
+ }
+}
+
+#define AO_HAVE_compare_double_and_swap_double
+
+