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) |