summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Schleifer <js@webkeks.org>2012-03-21 10:22:07 +0100
committerJonathan Schleifer <js@webkeks.org>2012-03-21 10:23:54 +0100
commit675755534b55cd76b66f4d2bf00879f512153401 (patch)
tree0841b0936a081a3c577814290d496c4e33235ac4
parent644cf66cc08243e9abb0dadcab8e2c784760abb6 (diff)
Fix of_atomic_{add,sub}_ptr on AMD64.0.6
-rw-r--r--src/atomic.h25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/atomic.h b/src/atomic.h
index 2b844a7f..59087b91 100644
--- a/src/atomic.h
+++ b/src/atomic.h
@@ -83,7 +83,7 @@ of_atomic_add_ptr(void* volatile *p, intptr_t i)
{
#if !defined(OF_THREADS)
return (*(char* volatile*)p += i);
-#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
+#elif defined(OF_X86_ASM)
__asm__ (
"lock\n\t"
"xaddl %0, %2\n\t"
@@ -93,6 +93,16 @@ of_atomic_add_ptr(void* volatile *p, intptr_t i)
);
return (void*)i;
+#elif defined(OF_AMD64_ASM)
+ __asm__ (
+ "lock\n\t"
+ "xaddq %0, %2\n\t"
+ "addq %1, %0"
+ : "+&r"(i)
+ : "r"(i), "m"(*p)
+ );
+
+ return (void*)i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
return __sync_add_and_fetch(p, i);
#elif defined(OF_HAVE_OSATOMIC)
@@ -165,7 +175,7 @@ of_atomic_sub_ptr(void* volatile *p, intptr_t i)
{
#if !defined(OF_THREADS)
return (*(char* volatile*)p -= i);
-#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
+#elif defined(OF_X86_ASM)
__asm__ (
"negl %0\n\t"
"lock\n\t"
@@ -176,6 +186,17 @@ of_atomic_sub_ptr(void* volatile *p, intptr_t i)
);
return (void*)i;
+#elif defined(OF_AMD64_ASM)
+ __asm__ (
+ "negq %0\n\t"
+ "lock\n\t"
+ "xaddq %0, %2\n\t"
+ "subq %1, %0"
+ : "+&r"(i)
+ : "r"(i), "m"(*p)
+ );
+
+ return (void*)i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
return __sync_sub_and_fetch(p, i);
#elif defined(OF_HAVE_OSATOMIC)