aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@bell.net>2014-08-10 09:39:25 -0400
committerMike Frysinger <vapier@gentoo.org>2015-08-05 06:44:54 -0400
commit6fef29c020d055f994cf7c4602b01a553b7a9860 (patch)
tree0b0dc645591c4a537776ba646cde11457825cab4
parent98b9c13e1abcf8d941d7934eed1a33527d6fd39b (diff)
downloadglibc-6fef29c020d055f994cf7c4602b01a553b7a9860.tar
glibc-6fef29c020d055f994cf7c4602b01a553b7a9860.tar.gz
glibc-6fef29c020d055f994cf7c4602b01a553b7a9860.tar.bz2
glibc-6fef29c020d055f994cf7c4602b01a553b7a9860.zip
hppa: fix build problems with atomic code
Specifically: ../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--sysdeps/unix/sysv/linux/hppa/bits/atomic.h60
1 files changed, 32 insertions, 28 deletions
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/atomic.h b/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
index abde83e2f9..b2294ba4b8 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
@@ -64,35 +64,39 @@ typedef uintmax_t uatomic_max_t;
#if __ASSUME_LWS_CAS
/* The only basic operation needed is compare and exchange. */
+static int __attribute__((noinline, unused))
+__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) \
- ({ \
- volatile int lws_errno; \
- __typeof__ (*mem) 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; \
- })
+ ((__typeof__(oldval)) \
+ __atomic_compare_and_exchange_val_acq ((int)mem, (int)newval, (int)oldval))
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
({ \