119 }
120
121 template<>
122 template<typename T>
123 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value,
124 T volatile* dest,
125 T compare_value,
126 atomic_memory_order /* order */) const {
127 STATIC_ASSERT(8 == sizeof(T));
128 __asm__ __volatile__ ( "lock cmpxchgq %1,(%3)"
129 : "=a" (exchange_value)
130 : "r" (exchange_value), "a" (compare_value), "r" (dest)
131 : "cc", "memory");
132 return exchange_value;
133 }
134
135 #else // !AMD64
136
137 extern "C" {
138 // defined in bsd_x86.s
139 int64_t _Atomic_cmpxchg_long(int64_t, volatile int64_t*, int64_t, bool);
140 void _Atomic_move_long(const volatile int64_t* src, volatile int64_t* dst);
141 }
142
143 template<>
144 template<typename T>
145 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value,
146 T volatile* dest,
147 T compare_value,
148 atomic_memory_order /* order */) const {
149 STATIC_ASSERT(8 == sizeof(T));
150 return cmpxchg_using_helper<int64_t>(_Atomic_cmpxchg_long, exchange_value, dest, compare_value);
151 }
152
153 template<>
154 template<typename T>
155 inline T Atomic::PlatformLoad<8>::operator()(T const volatile* src) const {
156 STATIC_ASSERT(8 == sizeof(T));
157 volatile int64_t dest;
158 _Atomic_move_long(reinterpret_cast<const volatile int64_t*>(src), reinterpret_cast<volatile int64_t*>(&dest));
159 return PrimitiveConversions::cast<T>(dest);
|
119 }
120
121 template<>
122 template<typename T>
123 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value,
124 T volatile* dest,
125 T compare_value,
126 atomic_memory_order /* order */) const {
127 STATIC_ASSERT(8 == sizeof(T));
128 __asm__ __volatile__ ( "lock cmpxchgq %1,(%3)"
129 : "=a" (exchange_value)
130 : "r" (exchange_value), "a" (compare_value), "r" (dest)
131 : "cc", "memory");
132 return exchange_value;
133 }
134
135 #else // !AMD64
136
137 extern "C" {
138 // defined in bsd_x86.s
139 int64_t _Atomic_cmpxchg_long(int64_t, volatile int64_t*, int64_t);
140 void _Atomic_move_long(const volatile int64_t* src, volatile int64_t* dst);
141 }
142
143 template<>
144 template<typename T>
145 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value,
146 T volatile* dest,
147 T compare_value,
148 atomic_memory_order /* order */) const {
149 STATIC_ASSERT(8 == sizeof(T));
150 return cmpxchg_using_helper<int64_t>(_Atomic_cmpxchg_long, exchange_value, dest, compare_value);
151 }
152
153 template<>
154 template<typename T>
155 inline T Atomic::PlatformLoad<8>::operator()(T const volatile* src) const {
156 STATIC_ASSERT(8 == sizeof(T));
157 volatile int64_t dest;
158 _Atomic_move_long(reinterpret_cast<const volatile int64_t*>(src), reinterpret_cast<volatile int64_t*>(&dest));
159 return PrimitiveConversions::cast<T>(dest);
|