]> granicus.if.org Git - libatomic_ops/commitdiff
2008-02-11 Hans Boehm <Hans.Boehm@hp.com> gc7_1
authorhboehm <hboehm>
Tue, 12 Feb 2008 00:18:53 +0000 (00:18 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 25 Jul 2011 12:03:24 +0000 (16:03 +0400)
   (Really Ian Wienand & Debian maintainers)
* src/atomic_ops/sysdeps/gcc/x86.h
(AO_compare_double_and_swap_double_full): Correctly account for
ebx usage with PIC.

ChangeLog
src/atomic_ops/sysdeps/gcc/x86.h

index 46039a51be512868726b00d637712f93bd0ed1d3..e68ab4cb11efa41a85f05eb1b96e208443b24a65 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-02-11 Hans Boehm <Hans.Boehm@hp.com>
+          (Really Ian Wienand & Debian maintainers)
+       * src/atomic_ops/sysdeps/gcc/x86.h
+       (AO_compare_double_and_swap_double_full): Correctly account for
+       ebx usage with PIC.
+
 2008-01-09 Hans Boehm <Hans.Boehm@hp.com>
        * src/atomic_ops/sysdeps/standard_ao_double_t.h: Let
        double_ptr_storage default to long long; define everywhere.
index 0b344a7ed48da05668bb77050eb95e67f43030ec..96fd2cb66dd2c77bf43e4784cf50b00610360441 100644 (file)
@@ -141,14 +141,27 @@ AO_compare_double_and_swap_double_full(volatile AO_double_t *addr,
                                       AO_t new_val1, AO_t new_val2) 
 {
   char result;
-  register AO_t nv1 asm("%ebx") = new_val1;
-       /* The above hack seems to avoid a gcc error complaining        */
-       /* that ebx is unavailable.                                     */
-
-  __asm__ __volatile__("lock; cmpxchg8b %0; setz %1"
+  #if __PIC__
+  /* If PIC is turned on, we can't use %ebx as it is reserved for the
+     GOT poiner.  We can save and restore %ebx because GCC won't be
+     using it for anything else (such as any of the m operands) */
+  __asm__ __volatile__("pushl %%ebx;"   /* save ebx used for PIC GOT ptr */
+                      "movl %6,%%ebx;" /* move new_val2 to %ebx */
+                      "lock; cmpxchg8b %0; setz %1;"
+                      "pop %%ebx;"     /* restore %ebx */
+                      : "=m"(*addr), "=q"(result)
+                      : "m"(*addr), "d" (old_val2), "a" (old_val1),
+                        "c" (new_val2), "m" (new_val1) : "memory");
+  #else
+  /* We can't just do the same thing in non-PIC mode, because GCC
+   * might be using %ebx as the memory operand.  We could have ifdef'd
+   * in a clobber, but there's no point doing the push/pop if we don't
+   * have to. */
+  __asm__ __volatile__("lock; cmpxchg8b %0; setz %1;"
                       : "=m"(*addr), "=q"(result)
-                      : "m"(*addr), "a" (old_val1), "d" (old_val2),
-                        "b" (nv1), "c" (new_val2) : "memory");
+                      : "m"(*addr), "d" (old_val2), "a" (old_val1),
+                        "c" (new_val2), "b" (new_val1) : "memory");
+  #endif
   return (int) result;
 }