21
21
/* line options. */
22
22
/* We should perhaps test dynamically. */
24
#include "../aligned_atomic_load_store.h"
24
#include "../all_aligned_atomic_load_store.h"
26
26
/* Real X86 implementations, except for some old WinChips, appear */
27
27
/* to enforce ordering between memory operations, EXCEPT that a later */
55
57
/* Really only works for 486 and later */
57
AO_fetch_and_add_full (volatile AO_t *p, long incr)
59
AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
61
63
__asm__ __volatile__ ("lock; xaddq %0, %1" :
62
"+r" (result), "+m" (*p) : : "memory");
64
"=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
66
69
#define AO_HAVE_fetch_and_add_full
71
AO_INLINE unsigned char
72
AO_char_fetch_and_add_full (volatile unsigned char *p, unsigned char incr)
76
__asm__ __volatile__ ("lock; xaddb %0, %1" :
77
"=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
82
#define AO_HAVE_char_fetch_and_add_full
84
AO_INLINE unsigned short
85
AO_short_fetch_and_add_full (volatile unsigned short *p, unsigned short incr)
87
unsigned short result;
89
__asm__ __volatile__ ("lock; xaddw %0, %1" :
90
"=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
95
#define AO_HAVE_short_fetch_and_add_full
97
AO_INLINE unsigned short
98
AO_int_fetch_and_add_full (volatile unsigned int *p, unsigned int incr)
102
__asm__ __volatile__ ("lock; xaddl %0, %1" :
103
"=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
108
#define AO_HAVE_int_fetch_and_add_full
68
110
/* Really only works for 486 and later */
70
112
AO_or_full (volatile AO_t *p, AO_t incr)
72
114
__asm__ __volatile__ ("lock; orq %1, %0" :
73
"+m" (*p) : "r" (incr) : "memory");
115
"=m" (*p) : "r" (incr), "m" (*p) : "memory");
76
118
#define AO_HAVE_or_full
79
AO_test_and_set_full(volatile AO_t *addr)
120
AO_INLINE AO_TS_VAL_t
121
AO_test_and_set_full(volatile AO_TS_t *addr)
123
unsigned char oldval;
82
124
/* Note: the "xchg" instruction does not need a "lock" prefix */
83
__asm__ __volatile__("xchgq %0, %1"
84
: "=r"(oldval), "+m"(*(addr))
125
__asm__ __volatile__("xchgb %0, %1"
126
: "=r"(oldval), "=m"(*addr)
127
: "0"(0xff), "m"(*addr) : "memory");
128
return (AO_TS_VAL_t)oldval;
89
131
#define AO_HAVE_test_and_set_full
94
136
AO_t old, AO_t new_val)
97
__asm__ __volatile__("lock; cmpxchgq %2, %0; setz %1"
98
: "+m"(*(addr)), "=q"(result)
99
: "r" (new_val), "a"(old) : "memory");
139
__asm__ __volatile__("lock; cmpxchgq %3, %0; setz %1"
140
: "=m"(*addr), "=q"(result)
141
: "m"(*addr), "r" (new_val), "a"(old) : "memory");
100
142
return (int) result;
103
145
#define AO_HAVE_compare_and_swap_full
147
/* FIXME: The Intel version has a 16byte CAS instruction. */