Index: blcr-0.8.2/libcr/arch/arm/cr_atomic.h
===================================================================
--- blcr-0.8.2.orig/libcr/arch/arm/cr_atomic.h	2010-01-19 10:57:05.000000000 +0000
+++ blcr-0.8.2/libcr/arch/arm/cr_atomic.h	2010-01-19 10:57:36.000000000 +0000
@@ -33,6 +33,25 @@
 #ifndef _CR_ATOMIC_H
 #define _CR_ATOMIC_H	1
 
+#if defined(__ARM_ARCH_2__) || defined(__ARM_ARCH_3__)
+  // Sanity-check that we're not building on a really old architecture,
+  // so that the using #ifdef __ARM_ARCH_4__ works to test for
+  // lack of blx <register> support.
+  #error "ARM Architecture versions prior to ARMv4 not supported."
+#elif defined(__ARM_ARCH_4T__) && defined(__thumb__)
+  // The inline asm is not compatible with Thumb-1 anyway, but in particular
+  // we assume later that if __ARM_ARCH_4__ is not defined, we have ARMv5
+  // or above.  Ensure here that this assumption will be valid.
+  #error "Building for Thumb on ARMv4 is not supported."
+#endif
+
+// Determine whether to use BLX <register> for function calls to
+// computed addresses:
+#undef ARM_HAVE_BLX_REG
+#if !(defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__))
+  #define ARM_HAVE_BLX_REG 1
+#endif
+
 #include "blcr_config.h"
 
 #ifndef _STRINGIFY
@@ -83,10 +102,15 @@
 
     __asm__ __volatile__ (
 	"0:	ldr	r0, [r2]	@ r0 = *p		\n"
+	"	add	r1, r0, %2	@ r1 = r0 + op		\n"
 	"	mov	r3, #" _STRINGIFY(cri_kuser_base) "	\n"
+#ifdef ARM_HAVE_BLX_REG
+	"	sub	r3, r3, #" _STRINGIFY(cri_kuser_offset) "\n"
+	"	blx	r3\n"
+#else // ARMv4T and below
 	"	adr	lr, 1f		@ lr = return address	\n"
-	"	add	r1, r0, %2	@ r1 = r0 + op		\n"
 	"	sub	pc, r3, #" _STRINGIFY(cri_kuser_offset) "\n"
+#endif
 	"1:	bcc     0b		@ retry on Carry Clear"
 	: "=&r" (__sum)
 	: "r" (__ptr), "rIL" (op)
@@ -135,9 +159,14 @@
     __asm__ __volatile__ (
 	"0:     mov     r0, r4          @ r0 = oldval           \n"
 	"	mov	r3, #" _STRINGIFY(cri_kuser_base) "	\n"
-	"	mov	lr, pc		@ lr = return addr	\n"
+#ifdef ARM_HAVE_BLX_REG
+	"	sub	r3, r3, #" _STRINGIFY(cri_kuser_offset) "\n"
+	"	blx	r3\n"
+#else // ARMv4T and below
+	"	adr	lr, 1f		@ lr = return addr	\n"
 	"	sub	pc, r3, #" _STRINGIFY(cri_kuser_offset) "\n"
-	"       ldrcc   ip, [r2]        @ if (!swapped) ip=*p   \n"
+#endif
+	"1:	ldrcc   ip, [r2]        @ if (!swapped) ip=*p   \n"
 	"       eorcs   ip, r4, #1      @ else ip=oldval^1      \n"
 	"       teq     r4, ip          @ if (ip == oldval)     \n"
 	"       beq     0b              @    then retry           "
