Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/pa/linux-atomic.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | 855418dad1a3 |
children |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Linux-specific atomic operations for PA Linux. | 1 /* Linux-specific atomic operations for PA Linux. |
2 Copyright (C) 2008, 2009 Free Software Foundation, Inc. | 2 Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. |
3 Based on code contributed by CodeSourcery for ARM EABI Linux. | 3 Based on code contributed by CodeSourcery for ARM EABI Linux. |
4 Modifications for PA Linux by Helge Deller <deller@gmx.de> | 4 Modifications for PA Linux by Helge Deller <deller@gmx.de> |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
90 { \ | 90 { \ |
91 int failure, tmp; \ | 91 int failure, tmp; \ |
92 \ | 92 \ |
93 do { \ | 93 do { \ |
94 tmp = *ptr; \ | 94 tmp = *ptr; \ |
95 failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr); \ | 95 failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ |
96 } while (failure != 0); \ | 96 } while (failure != 0); \ |
97 \ | 97 \ |
98 return tmp; \ | 98 return tmp; \ |
99 } | 99 } |
100 | 100 |
122 shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ | 122 shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ |
123 mask = MASK_##WIDTH << shift; \ | 123 mask = MASK_##WIDTH << shift; \ |
124 \ | 124 \ |
125 do { \ | 125 do { \ |
126 oldval = *wordptr; \ | 126 oldval = *wordptr; \ |
127 newval = ((PFX_OP ((oldval & mask) >> shift) \ | 127 newval = ((PFX_OP (((oldval & mask) >> shift) \ |
128 INF_OP (unsigned int) val) << shift) & mask; \ | 128 INF_OP (unsigned int) val)) << shift) & mask; \ |
129 newval |= oldval & ~mask; \ | 129 newval |= oldval & ~mask; \ |
130 failure = __kernel_cmpxchg (oldval, newval, wordptr); \ | 130 failure = __kernel_cmpxchg (oldval, newval, wordptr); \ |
131 } while (failure != 0); \ | 131 } while (failure != 0); \ |
132 \ | 132 \ |
133 return (RETURN & mask) >> shift; \ | 133 return (RETURN & mask) >> shift; \ |
134 } | 134 } |
135 | 135 |
136 SUBWORD_SYNC_OP (add, , +, short, 2, oldval) | 136 SUBWORD_SYNC_OP (add, , +, unsigned short, 2, oldval) |
137 SUBWORD_SYNC_OP (sub, , -, short, 2, oldval) | 137 SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, oldval) |
138 SUBWORD_SYNC_OP (or, , |, short, 2, oldval) | 138 SUBWORD_SYNC_OP (or, , |, unsigned short, 2, oldval) |
139 SUBWORD_SYNC_OP (and, , &, short, 2, oldval) | 139 SUBWORD_SYNC_OP (and, , &, unsigned short, 2, oldval) |
140 SUBWORD_SYNC_OP (xor, , ^, short, 2, oldval) | 140 SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, oldval) |
141 SUBWORD_SYNC_OP (nand, ~, &, short, 2, oldval) | 141 SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval) |
142 | 142 |
143 SUBWORD_SYNC_OP (add, , +, char, 1, oldval) | 143 SUBWORD_SYNC_OP (add, , +, unsigned char, 1, oldval) |
144 SUBWORD_SYNC_OP (sub, , -, char, 1, oldval) | 144 SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, oldval) |
145 SUBWORD_SYNC_OP (or, , |, char, 1, oldval) | 145 SUBWORD_SYNC_OP (or, , |, unsigned char, 1, oldval) |
146 SUBWORD_SYNC_OP (and, , &, char, 1, oldval) | 146 SUBWORD_SYNC_OP (and, , &, unsigned char, 1, oldval) |
147 SUBWORD_SYNC_OP (xor, , ^, char, 1, oldval) | 147 SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, oldval) |
148 SUBWORD_SYNC_OP (nand, ~, &, char, 1, oldval) | 148 SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, oldval) |
149 | 149 |
150 #define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \ | 150 #define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \ |
151 int HIDDEN \ | 151 int HIDDEN \ |
152 __sync_##OP##_and_fetch_4 (int *ptr, int val) \ | 152 __sync_##OP##_and_fetch_4 (int *ptr, int val) \ |
153 { \ | 153 { \ |
154 int tmp, failure; \ | 154 int tmp, failure; \ |
155 \ | 155 \ |
156 do { \ | 156 do { \ |
157 tmp = *ptr; \ | 157 tmp = *ptr; \ |
158 failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr); \ | 158 failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ |
159 } while (failure != 0); \ | 159 } while (failure != 0); \ |
160 \ | 160 \ |
161 return PFX_OP tmp INF_OP val; \ | 161 return PFX_OP (tmp INF_OP val); \ |
162 } | 162 } |
163 | 163 |
164 OP_AND_FETCH_WORD (add, , +) | 164 OP_AND_FETCH_WORD (add, , +) |
165 OP_AND_FETCH_WORD (sub, , -) | 165 OP_AND_FETCH_WORD (sub, , -) |
166 OP_AND_FETCH_WORD (or, , |) | 166 OP_AND_FETCH_WORD (or, , |) |
167 OP_AND_FETCH_WORD (and, , &) | 167 OP_AND_FETCH_WORD (and, , &) |
168 OP_AND_FETCH_WORD (xor, , ^) | 168 OP_AND_FETCH_WORD (xor, , ^) |
169 OP_AND_FETCH_WORD (nand, ~, &) | 169 OP_AND_FETCH_WORD (nand, ~, &) |
170 | 170 |
171 SUBWORD_SYNC_OP (add, , +, short, 2, newval) | 171 SUBWORD_SYNC_OP (add, , +, unsigned short, 2, newval) |
172 SUBWORD_SYNC_OP (sub, , -, short, 2, newval) | 172 SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, newval) |
173 SUBWORD_SYNC_OP (or, , |, short, 2, newval) | 173 SUBWORD_SYNC_OP (or, , |, unsigned short, 2, newval) |
174 SUBWORD_SYNC_OP (and, , &, short, 2, newval) | 174 SUBWORD_SYNC_OP (and, , &, unsigned short, 2, newval) |
175 SUBWORD_SYNC_OP (xor, , ^, short, 2, newval) | 175 SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, newval) |
176 SUBWORD_SYNC_OP (nand, ~, &, short, 2, newval) | 176 SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval) |
177 | 177 |
178 SUBWORD_SYNC_OP (add, , +, char, 1, newval) | 178 SUBWORD_SYNC_OP (add, , +, unsigned char, 1, newval) |
179 SUBWORD_SYNC_OP (sub, , -, char, 1, newval) | 179 SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, newval) |
180 SUBWORD_SYNC_OP (or, , |, char, 1, newval) | 180 SUBWORD_SYNC_OP (or, , |, unsigned char, 1, newval) |
181 SUBWORD_SYNC_OP (and, , &, char, 1, newval) | 181 SUBWORD_SYNC_OP (and, , &, unsigned char, 1, newval) |
182 SUBWORD_SYNC_OP (xor, , ^, char, 1, newval) | 182 SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, newval) |
183 SUBWORD_SYNC_OP (nand, ~, &, char, 1, newval) | 183 SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, newval) |
184 | 184 |
185 int HIDDEN | 185 int HIDDEN |
186 __sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval) | 186 __sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval) |
187 { | 187 { |
188 int actual_oldval, fail; | 188 int actual_oldval, fail; |
189 | 189 |
190 while (1) | 190 while (1) |
191 { | 191 { |
192 actual_oldval = *ptr; | 192 actual_oldval = *ptr; |
193 | 193 |
194 if (oldval != actual_oldval) | 194 if (__builtin_expect (oldval != actual_oldval, 0)) |
195 return actual_oldval; | 195 return actual_oldval; |
196 | 196 |
197 fail = __kernel_cmpxchg (actual_oldval, newval, ptr); | 197 fail = __kernel_cmpxchg (actual_oldval, newval, ptr); |
198 | 198 |
199 if (!fail) | 199 if (__builtin_expect (!fail, 1)) |
200 return oldval; | 200 return actual_oldval; |
201 } | 201 } |
202 } | 202 } |
203 | 203 |
204 #define SUBWORD_VAL_CAS(TYPE, WIDTH) \ | 204 #define SUBWORD_VAL_CAS(TYPE, WIDTH) \ |
205 TYPE HIDDEN \ | 205 TYPE HIDDEN \ |
214 \ | 214 \ |
215 while (1) \ | 215 while (1) \ |
216 { \ | 216 { \ |
217 actual_oldval = *wordptr; \ | 217 actual_oldval = *wordptr; \ |
218 \ | 218 \ |
219 if (((actual_oldval & mask) >> shift) != (unsigned int) oldval) \ | 219 if (__builtin_expect (((actual_oldval & mask) >> shift) \ |
220 return (actual_oldval & mask) >> shift; \ | 220 != (unsigned int) oldval, 0)) \ |
221 return (actual_oldval & mask) >> shift; \ | |
221 \ | 222 \ |
222 actual_newval = (actual_oldval & ~mask) \ | 223 actual_newval = (actual_oldval & ~mask) \ |
223 | (((unsigned int) newval << shift) & mask); \ | 224 | (((unsigned int) newval << shift) & mask); \ |
224 \ | 225 \ |
225 fail = __kernel_cmpxchg (actual_oldval, actual_newval, \ | 226 fail = __kernel_cmpxchg (actual_oldval, actual_newval, \ |
226 wordptr); \ | 227 wordptr); \ |
227 \ | 228 \ |
228 if (!fail) \ | 229 if (__builtin_expect (!fail, 1)) \ |
229 return oldval; \ | 230 return (actual_oldval & mask) >> shift; \ |
230 } \ | 231 } \ |
231 } | 232 } |
232 | 233 |
233 SUBWORD_VAL_CAS (short, 2) | 234 SUBWORD_VAL_CAS (unsigned short, 2) |
234 SUBWORD_VAL_CAS (char, 1) | 235 SUBWORD_VAL_CAS (unsigned char, 1) |
235 | 236 |
236 typedef unsigned char bool; | 237 typedef unsigned char bool; |
237 | 238 |
238 bool HIDDEN | 239 bool HIDDEN |
239 __sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval) | 240 __sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval) |
250 TYPE actual_oldval \ | 251 TYPE actual_oldval \ |
251 = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \ | 252 = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \ |
252 return (oldval == actual_oldval); \ | 253 return (oldval == actual_oldval); \ |
253 } | 254 } |
254 | 255 |
255 SUBWORD_BOOL_CAS (short, 2) | 256 SUBWORD_BOOL_CAS (unsigned short, 2) |
256 SUBWORD_BOOL_CAS (char, 1) | 257 SUBWORD_BOOL_CAS (unsigned char, 1) |
257 | 258 |
258 int HIDDEN | 259 int HIDDEN |
259 __sync_lock_test_and_set_4 (int *ptr, int val) | 260 __sync_lock_test_and_set_4 (int *ptr, int val) |
260 { | 261 { |
261 int failure, oldval; | 262 int failure, oldval; |
287 } while (failure != 0); \ | 288 } while (failure != 0); \ |
288 \ | 289 \ |
289 return (oldval & mask) >> shift; \ | 290 return (oldval & mask) >> shift; \ |
290 } | 291 } |
291 | 292 |
292 SUBWORD_TEST_AND_SET (short, 2) | 293 SUBWORD_TEST_AND_SET (unsigned short, 2) |
293 SUBWORD_TEST_AND_SET (char, 1) | 294 SUBWORD_TEST_AND_SET (unsigned char, 1) |
294 | 295 |
295 #define SYNC_LOCK_RELEASE(TYPE, WIDTH) \ | 296 #define SYNC_LOCK_RELEASE(TYPE, WIDTH) \ |
296 void HIDDEN \ | 297 void HIDDEN \ |
297 __sync_lock_release_##WIDTH (TYPE *ptr) \ | 298 __sync_lock_release_##WIDTH (TYPE *ptr) \ |
298 { \ | 299 { \ |