diff options
author | John David Anglin <dave.anglin@bell.net> | 2014-08-10 09:39:25 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2014-08-10 09:40:22 -0400 |
commit | 8e9c9f8f712392fc9c9c3abee93d2ac8bcac6c6e (patch) | |
tree | 322cc3bc3f6a616c6c4692db0c95d8e2a6af3071 | |
parent | fcf3bc5b09f1a97943999360921f9be730c2116d (diff) | |
download | glibc-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.h | 66 |
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. |