aboutsummaryrefslogtreecommitdiffstats
path: root/erts/include
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2016-02-22 19:20:35 +0100
committerRickard Green <[email protected]>2016-02-22 19:20:35 +0100
commit3ac4a18199b9f35224624851b01a0d3cb6e8e0e1 (patch)
tree777ddb16e86fb75123607cc73ce750992427edcf /erts/include
parentd14f2d178d8abcaebd5b14e25ca8ac9a71775271 (diff)
parenteb59e961ae05048ea30362aafb7f91db26ceb939 (diff)
downloadotp-3ac4a18199b9f35224624851b01a0d3cb6e8e0e1.tar.gz
otp-3ac4a18199b9f35224624851b01a0d3cb6e8e0e1.tar.bz2
otp-3ac4a18199b9f35224624851b01a0d3cb6e8e0e1.zip
Merge branch 'rickard/dw-cmpxchg-clang/OTP-13336' into maint
* rickard/dw-cmpxchg-clang/OTP-13336: Improve cmpxchg8b/cmpxchg16b inline asm
Diffstat (limited to 'erts/include')
-rw-r--r--erts/include/internal/i386/ethr_dw_atomic.h57
1 files changed, 37 insertions, 20 deletions
diff --git a/erts/include/internal/i386/ethr_dw_atomic.h b/erts/include/internal/i386/ethr_dw_atomic.h
index 79de5d80da..5444a6345c 100644
--- a/erts/include/internal/i386/ethr_dw_atomic.h
+++ b/erts/include/internal/i386/ethr_dw_atomic.h
@@ -157,36 +157,53 @@ ethr_native_dw_atomic_cmpxchg_mb(ethr_native_dw_atomic_t *var,
ETHR_DW_DBG_ALIGNED__(p);
+#if ETHR_NO_CLOBBER_EBX__ && ETHR_CMPXCHG8B_REGISTER_SHORTAGE
+ /*
+ * gcc wont let us use ebx as input and we
+ * get a register shortage
+ */
+
__asm__ __volatile__(
-#if ETHR_NO_CLOBBER_EBX__
"pushl %%ebx\n\t"
-# if ETHR_CMPXCHG8B_REGISTER_SHORTAGE
"movl (%7), %%ebx\n\t"
"movl 4(%7), %%ecx\n\t"
-# else
- "movl %8, %%ebx\n\t"
-# endif
-#endif
- "lock; cmpxchg" ETHR_DW_CMPXCHG_SFX__ " %0\n\t"
+ "lock; cmpxchg8b %0\n\t"
"setz %3\n\t"
-#if ETHR_NO_CLOBBER_EBX__
"popl %%ebx\n\t"
-#endif
: "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd)
- : "m"(*p), "1"(xchg[1]), "2"(xchg[0]),
-#if ETHR_NO_CLOBBER_EBX__
-# if ETHR_CMPXCHG8B_REGISTER_SHORTAGE
- "3"(new)
-# else
- "3"(new[1]),
- "r"(new[0])
-# endif
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "r"(new)
+ : "cc", "memory");
+
+#elif ETHR_NO_CLOBBER_EBX__
+ /*
+ * gcc wont let us use ebx as input
+ */
+
+ __asm__ __volatile__(
+ "pushl %%ebx\n\t"
+ "movl %8, %%ebx\n\t"
+ "lock; cmpxchg8b %0\n\t"
+ "setz %3\n\t"
+ "popl %%ebx\n\t"
+ : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=q"(xchgd)
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "c"(new[1]), "r"(new[0])
+ : "cc", "memory");
+
#else
- "3"(new[1]),
- "b"(new[0])
-#endif
+ /*
+ * gcc lets us place values in the registers where
+ * we want them
+ */
+
+ __asm__ __volatile__(
+ "lock; cmpxchg" ETHR_DW_CMPXCHG_SFX__ " %0\n\t"
+ "setz %3\n\t"
+ : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=q"(xchgd)
+ : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "c"(new[1]), "b"(new[0])
: "cc", "memory");
+#endif
+
return (int) xchgd;
}