]> sourceware.org Git - glibc.git/commitdiff
hppa: Fix reload error with atomic code [BZ #18787]
authorJohn David Anglin <dave.anglin@bell.net>
Fri, 7 Aug 2015 17:37:35 +0000 (13:37 -0400)
committerMike Frysinger <vapier@gentoo.org>
Sat, 8 Aug 2015 05:11:44 +0000 (01:11 -0400)
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.

ChangeLog
NEWS
sysdeps/unix/sysv/linux/hppa/bits/atomic.h

index c2c0881f4e8ab6fba491695f28293b9348b19a13..414bd4e44f0f3d9ea6afbc7cc17925771926c4b0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/NEWS b/NEWS
index bb4a4c24c601e5139e172aa7cd0b7917941029e4..2beb28c8f0d5ad999bbcc9509bdaada33ac623c8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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.
 \f
 Version 2.22
 
index abde83e2f91593b0c2d9a8040fab0cda95df736b..6e73504fee0d542d692000e5ea52e11bdeba3e7f 100644 (file)
@@ -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)     \
This page took 0.115184 seconds and 5 git commands to generate.