assembly code for atomic memory modifications.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10991
tc22_exit_w_lock
endif
+if VGCONF_PLATFORMS_INCLUDE_ARM_LINUX
+annotate_hbefore_CFLAGS = $(AM_CFLAGS) -mcpu=cortex-a8
+tc07_hbl1_CFLAGS = $(AM_CFLAGS) -mcpu=cortex-a8
+tc08_hbl2_CFLAGS = $(AM_CFLAGS) -mcpu=cortex-a8
+else
+annotate_hbefore_CFLAGS = $(AM_CFLAGS)
+tc07_hbl1_CFLAGS = $(AM_CFLAGS)
+tc08_hbl2_CFLAGS = $(AM_CFLAGS)
+endif
+
if HAVE_PTHREAD_BARRIER
check_PROGRAMS += bar_bad bar_trivial
endif
return block[3] & 1;
}
+#elif defined(VGA_arm)
+
+// arm
+/* return 1 if success, 0 if failure */
+UWord do_acasW ( UWord* addr, UWord expected, UWord nyu )
+{
+ UWord old, success;
+ UWord block[2] = { (UWord)addr, nyu };
+
+ /* Fetch the old value, and set the reservation */
+ __asm__ __volatile__ (
+ "ldrex %0, [%1]" "\n"
+ : /*out*/ "=r"(old)
+ : /*in*/ "r"(addr)
+ );
+
+ /* If the old value isn't as expected, we've had it */
+ if (old != expected) return 0;
+
+ /* otherwise try to stuff the new value in */
+ __asm__ __volatile__(
+ "ldr r4, [%1, #0]" "\n\t"
+ "ldr r5, [%1, #4]" "\n\t"
+ "strex r6, r5, [r4, #0]" "\n\t"
+ "eor %0, r6, #1" "\n\t"
+ : /*out*/ "=r"(success)
+ : /*in*/ "r"(&block[0])
+ : /*trash*/ "r4","r5","r6","memory"
+ );
+ assert(success == 0 || success == 1);
+ return success;
+}
+
#endif
void atomic_incW ( UWord* w )
/* Simple test program, no race. Parent and child both modify x and
use the hardware bus lock. */
+#undef PLAT_ppc64_aix5
+#undef PLAT_ppc32_aix5
+#undef PLAT_x86_darwin
+#undef PLAT_amd64_darwin
#undef PLAT_x86_linux
#undef PLAT_amd64_linux
#undef PLAT_ppc32_linux
#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
+#undef PLAT_arm_linux
-#if !defined(_AIX) && defined(__i386__)
+#if defined(_AIX) && defined(__64BIT__)
+# define PLAT_ppc64_aix5 1
+#elif defined(_AIX) && !defined(__64BIT__)
+# define PLAT_ppc32_aix5 1
+#elif defined(__APPLE__) && defined(__i386__)
+# define PLAT_x86_darwin 1
+#elif defined(__APPLE__) && defined(__x86_64__)
+# define PLAT_amd64_darwin 1
+#elif defined(__linux__) && defined(__i386__)
# define PLAT_x86_linux 1
-#elif !defined(_AIX) && defined(__x86_64__)
+#elif defined(__linux__) && defined(__x86_64__)
# define PLAT_amd64_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
+#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
# define PLAT_ppc32_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
+#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
# define PLAT_ppc64_linux 1
-#elif defined(_AIX) && defined(__64BIT__)
-# define PLAT_ppc64_aix5 1
-#elif defined(_AIX) && !defined(__64BIT__)
-# define PLAT_ppc32_aix5 1
+#elif defined(__linux__) && defined(__arm__)
+# define PLAT_arm_linux 1
#endif
#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux)
: /*out*/ : /*in*/ "b"(&(_lval)) \
: /*trash*/ "r15", "cr0", "memory" \
)
+#elif defined(PLAT_arm_linux)
+# define INC(_lval,_lqual) \
+ __asm__ __volatile__( \
+ "L1xyzzy1" _lqual ":\n" \
+ " ldrex r8, [%0, #0]\n" \
+ " add r8, r8, #1\n" \
+ " strex r9, r8, [%0, #0]\n" \
+ " cmp r9, #0\n" \
+ " bne L1xyzzy1" _lqual \
+ : /*out*/ : /*in*/ "r"(&(_lval)) \
+ : /*trash*/ "r8", "r9", "cc", "memory" \
+ );
#else
# error "Fix Me for this platform"
#endif
child joins back to parent. Parent (writer) uses hardware bus lock;
child is only reading and so does not need to use a bus lock. */
-
+#undef PLAT_ppc64_aix5
+#undef PLAT_ppc32_aix5
+#undef PLAT_x86_darwin
+#undef PLAT_amd64_darwin
#undef PLAT_x86_linux
#undef PLAT_amd64_linux
#undef PLAT_ppc32_linux
#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
+#undef PLAT_arm_linux
-#if !defined(_AIX) && defined(__i386__)
+#if defined(_AIX) && defined(__64BIT__)
+# define PLAT_ppc64_aix5 1
+#elif defined(_AIX) && !defined(__64BIT__)
+# define PLAT_ppc32_aix5 1
+#elif defined(__APPLE__) && defined(__i386__)
+# define PLAT_x86_darwin 1
+#elif defined(__APPLE__) && defined(__x86_64__)
+# define PLAT_amd64_darwin 1
+#elif defined(__linux__) && defined(__i386__)
# define PLAT_x86_linux 1
-#elif !defined(_AIX) && defined(__x86_64__)
+#elif defined(__linux__) && defined(__x86_64__)
# define PLAT_amd64_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
+#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
# define PLAT_ppc32_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
+#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
# define PLAT_ppc64_linux 1
-#elif defined(_AIX) && defined(__64BIT__)
-# define PLAT_ppc64_aix5 1
-#elif defined(_AIX) && !defined(__64BIT__)
-# define PLAT_ppc32_aix5 1
+#elif defined(__linux__) && defined(__arm__)
+# define PLAT_arm_linux 1
#endif
+
#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux)
# define INC(_lval,_lqual) \
__asm__ __volatile__ ( \
: /*out*/ : /*in*/ "b"(&(_lval)) \
: /*trash*/ "r15", "cr0", "memory" \
)
+#elif defined(PLAT_arm_linux)
+# define INC(_lval,_lqual) \
+ __asm__ __volatile__( \
+ "L1xyzzy1" _lqual ":\n" \
+ " ldrex r8, [%0, #0]\n" \
+ " add r8, r8, #1\n" \
+ " strex r9, r8, [%0, #0]\n" \
+ " cmp r9, #0\n" \
+ " bne L1xyzzy1" _lqual \
+ : /*out*/ : /*in*/ "r"(&(_lval)) \
+ : /*trash*/ "r8", "r9", "cc", "memory" \
+ );
#else
# error "Fix Me for this platform"
#endif
use the hardware bus lock (implicitly, since XCHG r,m on x86/amd64
does not require an explicit LOCK prefix.). */
+#undef PLAT_ppc64_aix5
+#undef PLAT_ppc32_aix5
+#undef PLAT_x86_darwin
+#undef PLAT_amd64_darwin
#undef PLAT_x86_linux
#undef PLAT_amd64_linux
#undef PLAT_ppc32_linux
#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
+#undef PLAT_arm_linux
-#if !defined(_AIX) && defined(__i386__)
+#if defined(_AIX) && defined(__64BIT__)
+# define PLAT_ppc64_aix5 1
+#elif defined(_AIX) && !defined(__64BIT__)
+# define PLAT_ppc32_aix5 1
+#elif defined(__APPLE__) && defined(__i386__)
+# define PLAT_x86_darwin 1
+#elif defined(__APPLE__) && defined(__x86_64__)
+# define PLAT_amd64_darwin 1
+#elif defined(__linux__) && defined(__i386__)
# define PLAT_x86_linux 1
-#elif !defined(_AIX) && defined(__x86_64__)
+#elif defined(__linux__) && defined(__x86_64__)
# define PLAT_amd64_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
+#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
# define PLAT_ppc32_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
+#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
# define PLAT_ppc64_linux 1
-#elif defined(_AIX) && defined(__64BIT__)
-# define PLAT_ppc64_aix5 1
-#elif defined(_AIX) && !defined(__64BIT__)
-# define PLAT_ppc32_aix5 1
+#elif defined(__linux__) && defined(__arm__)
+# define PLAT_arm_linux 1
#endif
)
#elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \
- || defined(PLAT_ppc32_aix5) || defined(PLAT_ppc64_aix5)
+ || defined(PLAT_ppc32_aix5) || defined(PLAT_ppc64_aix5) \
+ || defined(PLAT_arm_linux)
# if defined(HAVE_BUILTIN_ATOMIC)
# define XCHG_M_R(_addr,_lval) \
do { \