Implement char and/or/xor and short CAS for msftc ARM and X86[_64]
authorIvan Maidanski <ivmai@mail.ru>
Sat, 21 Jan 2017 06:55:44 +0000 (09:55 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 23 Jan 2017 08:04:21 +0000 (11:04 +0300)
* src/atomic_ops/sysdeps/msftc/common32_defs.h [_MSC_VER>1400
&& !_M_ARM] (_InterlockedAnd8, _InterlockedCompareExchange16,
_InterlockedOr8, _InterlockedXor8): Declare intrinsic.
* src/atomic_ops/sysdeps/msftc/x86_64.h [_MSC_VER>1400]
(_InterlockedAnd8, _InterlockedCompareExchange16, _InterlockedOr8,
_InterlockedXor8): Likewise.
* src/atomic_ops/sysdeps/msftc/common32_defs.h [_MSC_VER>1400
&& !_M_ARM] (AO_char_and_full, AO_char_or_full, AO_char_xor_full,
AO_short_fetch_compare_and_swap_full): Implement (using intrinsic).
* src/atomic_ops/sysdeps/msftc/x86_64.h [_MSC_VER>1400]
(AO_char_and_full, AO_char_or_full, AO_char_xor_full,
AO_short_fetch_compare_and_swap_full): Likewise.

src/atomic_ops/sysdeps/msftc/common32_defs.h
src/atomic_ops/sysdeps/msftc/x86_64.h

index ab57e45..de55fef 100644 (file)
@@ -116,3 +116,43 @@ AO_fetch_and_sub1_full(volatile AO_t *p)
   }
 # define AO_HAVE_fetch_compare_and_swap_full
 #endif /* AO_ASSUME_WINDOWS98 */
+
+#if (_MSC_VER > 1400) && !defined(_M_ARM)
+
+# pragma intrinsic (_InterlockedAnd8)
+# pragma intrinsic (_InterlockedCompareExchange16)
+# pragma intrinsic (_InterlockedOr8)
+# pragma intrinsic (_InterlockedXor8)
+
+  AO_INLINE void
+  AO_char_and_full(volatile unsigned char *p, unsigned char value)
+  {
+    _InterlockedAnd8((char volatile *)p, value);
+  }
+# define AO_HAVE_char_and_full
+
+  AO_INLINE void
+  AO_char_or_full(volatile unsigned char *p, unsigned char value)
+  {
+    _InterlockedOr8((char volatile *)p, value);
+  }
+# define AO_HAVE_char_or_full
+
+  AO_INLINE void
+  AO_char_xor_full(volatile unsigned char *p, unsigned char value)
+  {
+    _InterlockedXor8((char volatile *)p, value);
+  }
+# define AO_HAVE_char_xor_full
+
+  AO_INLINE unsigned short
+  AO_short_fetch_compare_and_swap_full(volatile unsigned short *addr,
+                                       unsigned short old_val,
+                                       unsigned short new_val)
+  {
+    return _InterlockedCompareExchange16((short volatile *)addr,
+                                         new_val, old_val);
+  }
+# define AO_HAVE_short_fetch_compare_and_swap_full
+
+#endif /* _MSC_VER > 1400 */
index ed6eb0c..86fa2b7 100644 (file)
@@ -114,6 +114,45 @@ AO_int_fetch_and_add_full(volatile unsigned int *p, unsigned int incr)
 # define AO_HAVE_int_fetch_and_sub1_full
 #endif /* !AO_PREFER_GENERALIZED */
 
+#if _MSC_VER > 1400
+# pragma intrinsic (_InterlockedAnd8)
+# pragma intrinsic (_InterlockedCompareExchange16)
+# pragma intrinsic (_InterlockedOr8)
+# pragma intrinsic (_InterlockedXor8)
+
+  AO_INLINE void
+  AO_char_and_full(volatile unsigned char *p, unsigned char value)
+  {
+    _InterlockedAnd8((char volatile *)p, value);
+  }
+# define AO_HAVE_char_and_full
+
+  AO_INLINE void
+  AO_char_or_full(volatile unsigned char *p, unsigned char value)
+  {
+    _InterlockedOr8((char volatile *)p, value);
+  }
+# define AO_HAVE_char_or_full
+
+  AO_INLINE void
+  AO_char_xor_full(volatile unsigned char *p, unsigned char value)
+  {
+    _InterlockedXor8((char volatile *)p, value);
+  }
+# define AO_HAVE_char_xor_full
+
+  AO_INLINE unsigned short
+  AO_short_fetch_compare_and_swap_full(volatile unsigned short *addr,
+                                       unsigned short old_val,
+                                       unsigned short new_val)
+  {
+    return _InterlockedCompareExchange16((short volatile *)addr,
+                                         new_val, old_val);
+  }
+# define AO_HAVE_short_fetch_compare_and_swap_full
+
+#endif /* _MSC_VER > 1400 */
+
 #ifdef AO_ASM_X64_AVAILABLE
 
   AO_INLINE unsigned char