Lines 158-168
struct gcc_dcas_x86
Link Here
|
158 |
} |
158 |
} |
159 |
else |
159 |
else |
160 |
{ |
160 |
{ |
161 |
#if defined(__clang__) |
161 |
// Note that despite const qualification cmpxchg8b below may issue a store to the storage. The storage value |
162 |
// Clang cannot allocate eax:edx register pairs but it has sync intrinsics |
162 |
// will not change, but this prevents the storage to reside in read-only memory. |
163 |
value = __sync_val_compare_and_swap(&storage, (storage_type)0, (storage_type)0); |
163 |
|
164 |
#elif defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) |
164 |
#if defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) |
|
|
165 |
|
165 |
uint32_t value_bits[2]; |
166 |
uint32_t value_bits[2]; |
|
|
167 |
|
166 |
// We don't care for comparison result here; the previous value will be stored into value anyway. |
168 |
// We don't care for comparison result here; the previous value will be stored into value anyway. |
167 |
// Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. |
169 |
// Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. |
168 |
__asm__ __volatile__ |
170 |
__asm__ __volatile__ |
Lines 175-181
struct gcc_dcas_x86
Link Here
|
175 |
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" |
177 |
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" |
176 |
); |
178 |
); |
177 |
BOOST_ATOMIC_DETAIL_MEMCPY(&value, value_bits, sizeof(value)); |
179 |
BOOST_ATOMIC_DETAIL_MEMCPY(&value, value_bits, sizeof(value)); |
|
|
180 |
|
178 |
#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) |
181 |
#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) |
|
|
182 |
|
179 |
// We don't care for comparison result here; the previous value will be stored into value anyway. |
183 |
// We don't care for comparison result here; the previous value will be stored into value anyway. |
180 |
// Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. |
184 |
// Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. |
181 |
__asm__ __volatile__ |
185 |
__asm__ __volatile__ |
Lines 187-192
struct gcc_dcas_x86
Link Here
|
187 |
: [storage] "m" (storage) |
191 |
: [storage] "m" (storage) |
188 |
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" |
192 |
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" |
189 |
); |
193 |
); |
|
|
194 |
|
190 |
#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) |
195 |
#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) |
191 |
} |
196 |
} |
192 |
|
197 |
|
Lines 401-415
struct gcc_dcas_x86_64
Link Here
|
401 |
|
406 |
|
402 |
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT |
407 |
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT |
403 |
{ |
408 |
{ |
404 |
#if defined(__clang__) |
409 |
// Note that despite const qualification cmpxchg16b below may issue a store to the storage. The storage value |
|
|
410 |
// will not change, but this prevents the storage to reside in read-only memory. |
405 |
|
411 |
|
406 |
// Clang cannot allocate rax:rdx register pairs but it has sync intrinsics |
412 |
#if defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) |
407 |
storage_type value = storage_type(); |
|
|
408 |
return __sync_val_compare_and_swap(&storage, value, value); |
409 |
|
410 |
#elif defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) |
411 |
|
413 |
|
412 |
// Some compilers can't allocate rax:rdx register pair either and also don't support 128-bit __sync_val_compare_and_swap |
|
|
413 |
uint64_t value_bits[2]; |
414 |
uint64_t value_bits[2]; |
414 |
|
415 |
|
415 |
// We don't care for comparison result here; the previous value will be stored into value anyway. |
416 |
// We don't care for comparison result here; the previous value will be stored into value anyway. |