Skip to content

Commit

Permalink
hppa: Fix reload error with atomic code [BZ #18787]
Browse files Browse the repository at this point in the history
As noted in the bug, the asm operands need to be copied to register
variables to avoid operand reloads in the principal asm of the macro.
See the arm implementation for reference.  Otherwise we get:
../sysdeps/unix/sysv/linux/hppa/bits/atomic.h:68:6: error:
	can't find a register in class 'R1_REGS' while reloading 'asm'

Build tested on trunk with gcc-4.8.  Similar patch has been tested
with 2.19 on Debian hppa-unknown-linux-gnu.
  • Loading branch information
John David Anglin authored and Mike Frysinger committed Aug 8, 2015
1 parent 5d5de49 commit 74bc0c3
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 19 deletions.
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
2015-08-08 John David Anglin <danglin@gcc.gnu.org>

[BZ #18787]
* sysdeps/unix/sysv/linux/hppa/bits/atomic.h (_LWS_CLOBBER): Revise
clobber registers.
(atomic_compare_and_exchange_val_acq): Use register asms to assign
operand registers. Use register %r20 for EAGAIN and EDEADLOCK checks.
Cast return to __typeof (oldval).

2015-08-08 Mike Frysinger <vapier@gentoo.org>

* sysdeps/unix/sysv/linux/microblaze/sysdep.h: Wrap the whole file
Expand Down
2 changes: 1 addition & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using `glibc' in the "product" field.
Version 2.23

* The following bugs are resolved with this release:
16517, 16519, 18265, 18525, 18618, 18647, 18661.
16517, 16519, 18265, 18525, 18618, 18647, 18661, 18787.

Version 2.22

Expand Down
35 changes: 17 additions & 18 deletions sysdeps/unix/sysv/linux/hppa/bits/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,42 +56,41 @@ typedef uintmax_t uatomic_max_t;
#define _LWS "0xb0"
#define _LWS_CAS "0"
/* Note r31 is the link register. */
#define _LWS_CLOBBER "r1", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r28", "r31", "memory"
#define _LWS_CLOBBER "r1", "r23", "r22", "r20", "r31", "memory"
/* String constant for -EAGAIN. */
#define _ASM_EAGAIN "-11"
/* String constant for -EDEADLOCK. */
#define _ASM_EDEADLOCK "-45"

#if __ASSUME_LWS_CAS
/* The only basic operation needed is compare and exchange. */
/* The only basic operation needed is compare and exchange. The mem
pointer must be word aligned. */
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
({ \
volatile int lws_errno; \
__typeof__ (*mem) lws_ret; \
asm volatile( \
register long lws_errno asm("r21"); \
register unsigned long lws_ret asm("r28"); \
register unsigned long lws_mem asm("r26") = (unsigned long)(mem); \
register unsigned long lws_old asm("r25") = (unsigned long)(oldval);\
register unsigned long lws_new asm("r24") = (unsigned long)(newval);\
__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" \
"ldi " _ASM_EAGAIN ", %%r20 \n\t" \
"cmpb,=,n %%r20, %%r21, 0b \n\t" \
"nop \n\t" \
"ldi " _ASM_EDEADLOCK ", %%r25 \n\t" \
"cmpb,=,n %%r25, %%r21, 0b \n\t" \
"ldi " _ASM_EDEADLOCK ", %%r20 \n\t" \
"cmpb,=,n %%r20, %%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) \
: "=r" (lws_ret), "=r" (lws_errno) \
: "r" (lws_mem), "r" (lws_old), "r" (lws_new) \
: _LWS_CLOBBER \
); \
\
if(lws_errno == -EFAULT || lws_errno == -ENOSYS) \
if (lws_errno == -EFAULT || lws_errno == -ENOSYS) \
ABORT_INSTRUCTION; \
\
lws_ret; \
(__typeof (oldval)) lws_ret; \
})

# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
Expand Down

0 comments on commit 74bc0c3

Please sign in to comment.