about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@bell.net>2014-08-10 09:39:25 -0400
committerMike Frysinger <vapier@gentoo.org>2014-08-10 09:40:22 -0400
commit8e9c9f8f712392fc9c9c3abee93d2ac8bcac6c6e (patch)
tree322cc3bc3f6a616c6c4692db0c95d8e2a6af3071
parentfcf3bc5b09f1a97943999360921f9be730c2116d (diff)
downloadglibc-8e9c9f8f712392fc9c9c3abee93d2ac8bcac6c6e.tar.gz
glibc-8e9c9f8f712392fc9c9c3abee93d2ac8bcac6c6e.tar.xz
glibc-8e9c9f8f712392fc9c9c3abee93d2ac8bcac6c6e.zip
hppa: fix build problems with atomic code
Specifically:
../ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h:68:6: error:
	can’t find a register in class ‘R1_REGS’ while reloading ‘asm’
-rw-r--r--ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h66
1 files changed, 35 insertions, 31 deletions
diff --git a/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h b/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
index 76ca0b15e5..06fa9af458 100644
--- a/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
+++ b/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
@@ -61,42 +61,46 @@ typedef uintmax_t uatomic_max_t;
 
 #if __ASSUME_LWS_CAS
 /* The only basic operation needed is compare and exchange.  */
-# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) 	\
-  ({									\
-     volatile int lws_errno;						\
-     volatile int lws_ret;						\
-     asm volatile(							\
-	"0:					\n\t"			\
-	"copy	%2, %%r26			\n\t"			\
-	"copy	%3, %%r25			\n\t"			\
-	"copy	%4, %%r24			\n\t"			\
-	"ble	" _LWS "(%%sr2, %%r0)		\n\t"			\
-	"ldi	" _LWS_CAS ", %%r20		\n\t"			\
-	"ldi	" _ASM_EAGAIN ", %%r24		\n\t"			\
-	"cmpb,=,n %%r24, %%r21, 0b		\n\t"			\
-	"nop					\n\t"			\
-	"ldi	" _ASM_EDEADLOCK ", %%r25	\n\t"			\
-	"cmpb,=,n %%r25, %%r21, 0b		\n\t"			\
-	"nop					\n\t"			\
-	"stw	%%r28, %0			\n\t"			\
-	"stw	%%r21, %1			\n\t"			\
-	: "=m" (lws_ret), "=m" (lws_errno) 				\
-        : "r" (mem), "r" (oldval), "r" (newval)				\
-	: _LWS_CLOBBER							\
-     );									\
-    									\
-     if(lws_errno == -EFAULT || lws_errno == -ENOSYS)			\
-     	ABORT_INSTRUCTION;						\
-    									\
-     lws_ret;								\
-   })
+static int __attribute__((noinline))
+__atomic_compare_and_exchange_val_acq (int mem, int newval, int oldval)
+{
+  volatile int lws_errno;
+  volatile int lws_ret;
+  asm volatile(
+	"0:					\n\t"
+	"copy	%2, %%r26			\n\t"
+	"copy	%3, %%r25			\n\t"
+	"copy	%4, %%r24			\n\t"
+	"ble	" _LWS "(%%sr2, %%r0)		\n\t"
+	"ldi	" _LWS_CAS ", %%r20		\n\t"
+	"ldi	" _ASM_EAGAIN ", %%r24		\n\t"
+	"cmpb,=,n %%r24, %%r21, 0b		\n\t"
+	"nop					\n\t"
+	"ldi	" _ASM_EDEADLOCK ", %%r25	\n\t"
+	"cmpb,=,n %%r25, %%r21, 0b		\n\t"
+	"nop					\n\t"
+	"stw	%%r28, %0			\n\t"
+	"stw	%%r21, %1			\n\t"
+	: "=m" (lws_ret), "=m" (lws_errno)
+        : "r" (mem), "r" (oldval), "r" (newval)
+	: _LWS_CLOBBER
+   );
+
+  if (lws_errno == -EFAULT || lws_errno == -ENOSYS)
+    ABORT_INSTRUCTION;
+
+  return lws_ret;
+}
+# define atomic_compare_and_exchange_val_acq(mem, newval, oldval)	\
+   ((__typeof__(oldval))						\
+    __atomic_compare_and_exchange_val_acq ((int)mem, (int)newval, (int)oldval))
 
 # define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) 	\
   ({									\
-     int ret;								\
+     __typeof__(oldval) ret;						\
      ret = atomic_compare_and_exchange_val_acq(mem, newval, oldval);	\
      /* Return 1 if it was already acquired.  */			\
-     (ret != (int)oldval);						\
+     (ret != oldval);						\
    })
 #else
 # error __ASSUME_LWS_CAS is required to build glibc.