117 D result;
118
119 __asm__ __volatile__ (
120 strasm_lwsync
121 "1: ldarx %0, 0, %2 \n"
122 " add %0, %0, %1 \n"
123 " stdcx. %0, 0, %2 \n"
124 " bne- 1b \n"
125 strasm_isync
126 : /*%0*/"=&r" (result)
127 : /*%1*/"r" (add_value), /*%2*/"r" (dest)
128 : "cc", "memory" );
129
130 return result;
131 }
132
133 template<>
134 template<typename T>
135 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value,
136 T volatile* dest) const {
137 // Note that xchg_ptr doesn't necessarily do an acquire
138 // (see synchronizer.cpp).
139
140 T old_value;
141 const uint64_t zero = 0;
142
143 __asm__ __volatile__ (
144 /* lwsync */
145 strasm_lwsync
146 /* atomic loop */
147 "1: \n"
148 " lwarx %[old_value], %[dest], %[zero] \n"
149 " stwcx. %[exchange_value], %[dest], %[zero] \n"
150 " bne- 1b \n"
151 /* isync */
152 strasm_sync
153 /* exit */
154 "2: \n"
155 /* out */
156 : [old_value] "=&r" (old_value),
157 "=m" (*dest)
158 /* in */
159 : [dest] "b" (dest),
160 [zero] "r" (zero),
161 [exchange_value] "r" (exchange_value),
162 "m" (*dest)
163 /* clobber */
164 : "cc",
165 "memory"
166 );
167
168 return old_value;
169 }
170
171 template<>
172 template<typename T>
173 inline T Atomic::PlatformXchg<8>::operator()(T exchange_value,
174 T volatile* dest) const {
175 STATIC_ASSERT(8 == sizeof(T));
176 // Note that xchg_ptr doesn't necessarily do an acquire
177 // (see synchronizer.cpp).
178
179 T old_value;
180 const uint64_t zero = 0;
181
182 __asm__ __volatile__ (
183 /* lwsync */
184 strasm_lwsync
185 /* atomic loop */
186 "1: \n"
187 " ldarx %[old_value], %[dest], %[zero] \n"
188 " stdcx. %[exchange_value], %[dest], %[zero] \n"
189 " bne- 1b \n"
190 /* isync */
191 strasm_sync
192 /* exit */
193 "2: \n"
194 /* out */
195 : [old_value] "=&r" (old_value),
196 "=m" (*dest)
|
117 D result;
118
119 __asm__ __volatile__ (
120 strasm_lwsync
121 "1: ldarx %0, 0, %2 \n"
122 " add %0, %0, %1 \n"
123 " stdcx. %0, 0, %2 \n"
124 " bne- 1b \n"
125 strasm_isync
126 : /*%0*/"=&r" (result)
127 : /*%1*/"r" (add_value), /*%2*/"r" (dest)
128 : "cc", "memory" );
129
130 return result;
131 }
132
133 template<>
134 template<typename T>
135 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value,
136 T volatile* dest) const {
137 // Note that xchg doesn't necessarily do an acquire
138 // (see synchronizer.cpp).
139
140 T old_value;
141 const uint64_t zero = 0;
142
143 __asm__ __volatile__ (
144 /* lwsync */
145 strasm_lwsync
146 /* atomic loop */
147 "1: \n"
148 " lwarx %[old_value], %[dest], %[zero] \n"
149 " stwcx. %[exchange_value], %[dest], %[zero] \n"
150 " bne- 1b \n"
151 /* isync */
152 strasm_sync
153 /* exit */
154 "2: \n"
155 /* out */
156 : [old_value] "=&r" (old_value),
157 "=m" (*dest)
158 /* in */
159 : [dest] "b" (dest),
160 [zero] "r" (zero),
161 [exchange_value] "r" (exchange_value),
162 "m" (*dest)
163 /* clobber */
164 : "cc",
165 "memory"
166 );
167
168 return old_value;
169 }
170
171 template<>
172 template<typename T>
173 inline T Atomic::PlatformXchg<8>::operator()(T exchange_value,
174 T volatile* dest) const {
175 STATIC_ASSERT(8 == sizeof(T));
176 // Note that xchg doesn't necessarily do an acquire
177 // (see synchronizer.cpp).
178
179 T old_value;
180 const uint64_t zero = 0;
181
182 __asm__ __volatile__ (
183 /* lwsync */
184 strasm_lwsync
185 /* atomic loop */
186 "1: \n"
187 " ldarx %[old_value], %[dest], %[zero] \n"
188 " stdcx. %[exchange_value], %[dest], %[zero] \n"
189 " bne- 1b \n"
190 /* isync */
191 strasm_sync
192 /* exit */
193 "2: \n"
194 /* out */
195 : [old_value] "=&r" (old_value),
196 "=m" (*dest)
|