implemented Setup.hs to build boehm cpp libs and install them;
[hs-boehmgc.git] / gc-7.2 / libatomic_ops / src / atomic_ops / generalize.h
1 /*
2  * Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 /*
24  * Generalize atomic operations for atomic_ops.h.
25  * Should not be included directly.
26  *
27  * We make no attempt to define useless operations, such as
28  * AO_nop_acquire
29  * AO_nop_release
30  *
31  * We have also so far neglected to define some others, which
32  * do not appear likely to be useful, e.g. stores with acquire
33  * or read barriers.
34  *
35  * This file is sometimes included twice by atomic_ops.h.
36  * All definitions include explicit checks that we are not replacing
37  * an earlier definition.  In general, more desirable expansions
38  * appear earlier so that we are more likely to use them.
39  *
40  * We only make safe generalizations, except that by default we define
41  * the ...dd_acquire_read operations to be equivalent to those without
42  * a barrier.  On platforms for which this is unsafe, the platform-specific
43  * file must define AO_NO_DD_ORDERING.
44  */
45
46 #ifndef ATOMIC_OPS_H
47 # error Atomic_ops_generalize.h should not be included directly.
48 #endif
49
50 #if AO_CHAR_TS_T
51 # define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) \
52                                 AO_char_compare_and_swap_full(a,o,n)
53 # define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
54                                 AO_char_compare_and_swap_acquire(a,o,n)
55 # define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
56                                 AO_char_compare_and_swap_release(a,o,n)
57 # define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_char_compare_and_swap(a,o,n)
58 #endif
59
60 #if AO_AO_TS_T
61 # define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) AO_compare_and_swap_full(a,o,n)
62 # define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
63                                         AO_compare_and_swap_acquire(a,o,n)
64 # define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
65                                         AO_compare_and_swap_release(a,o,n)
66 # define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_compare_and_swap(a,o,n)
67 #endif
68
69 /* Generate test_and_set_full, if necessary and possible.       */
70 #if !defined(AO_HAVE_test_and_set) && !defined(AO_HAVE_test_and_set_release) \
71     && !defined(AO_HAVE_test_and_set_acquire) \
72     && !defined(AO_HAVE_test_and_set_read) \
73     && !defined(AO_HAVE_test_and_set_full)
74 # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_full)) \
75      || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_full))
76     AO_INLINE AO_TS_VAL_t
77     AO_test_and_set_full(volatile AO_TS_t *addr)
78     {
79       if (AO_TS_COMPARE_AND_SWAP_FULL(addr, AO_TS_CLEAR, AO_TS_SET))
80         return AO_TS_CLEAR;
81       else
82         return AO_TS_SET;
83     }
84 #   define AO_HAVE_test_and_set_full
85 # endif /* AO_HAVE_compare_and_swap_full */
86
87 # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_acquire)) \
88      || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_acquire))
89     AO_INLINE AO_TS_VAL_t
90     AO_test_and_set_acquire(volatile AO_TS_t *addr)
91     {
92       if (AO_TS_COMPARE_AND_SWAP_ACQUIRE(addr, AO_TS_CLEAR, AO_TS_SET))
93         return AO_TS_CLEAR;
94       else
95         return AO_TS_SET;
96     }
97 #   define AO_HAVE_test_and_set_acquire
98 # endif /* AO_HAVE_compare_and_swap_acquire */
99
100 # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_release)) \
101      || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_release))
102     AO_INLINE AO_TS_VAL_t
103     AO_test_and_set_release(volatile AO_TS_t *addr)
104     {
105       if (AO_TS_COMPARE_AND_SWAP_RELEASE(addr, AO_TS_CLEAR, AO_TS_SET))
106         return AO_TS_CLEAR;
107       else
108         return AO_TS_SET;
109     }
110 #   define AO_HAVE_test_and_set_release
111 # endif /* AO_HAVE_compare_and_swap_release */
112
113 # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap)) \
114      || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap))
115     AO_INLINE AO_TS_VAL_t
116     AO_test_and_set(volatile AO_TS_t *addr)
117     {
118       if (AO_TS_COMPARE_AND_SWAP(addr, AO_TS_CLEAR, AO_TS_SET))
119         return AO_TS_CLEAR;
120       else
121         return AO_TS_SET;
122     }
123 #   define AO_HAVE_test_and_set
124 # endif /* AO_HAVE_compare_and_swap */
125
126 # if defined(AO_HAVE_test_and_set) && defined(AO_HAVE_nop_full) \
127      && !defined(AO_HAVE_test_and_set_acquire)
128     AO_INLINE AO_TS_VAL_t
129     AO_test_and_set_acquire(volatile AO_TS_t *addr)
130     {
131       AO_TS_VAL_t result = AO_test_and_set(addr);
132       AO_nop_full();
133       return result;
134     }
135 #   define AO_HAVE_test_and_set_acquire
136 # endif
137 #endif /* No prior test and set */
138
139 /* Nop */
140 #if !defined(AO_HAVE_nop)
141   AO_INLINE void AO_nop(void) {}
142 # define AO_HAVE_nop
143 #endif
144
145 #if defined(AO_HAVE_test_and_set_full) && !defined(AO_HAVE_nop_full)
146   AO_INLINE void
147   AO_nop_full(void)
148   {
149     AO_TS_t dummy = AO_TS_INITIALIZER;
150     AO_test_and_set_full(&dummy);
151   }
152 # define AO_HAVE_nop_full
153 #endif
154
155 #if defined(AO_HAVE_nop_acquire)
156 # error AO_nop_acquire is useless: dont define.
157 #endif
158 #if defined(AO_HAVE_nop_release)
159 # error AO_nop_release is useless: dont define.
160 #endif
161
162 #if defined(AO_HAVE_nop_full) && !defined(AO_HAVE_nop_read)
163 # define AO_nop_read() AO_nop_full()
164 # define AO_HAVE_nop_read
165 #endif
166
167 #if defined(AO_HAVE_nop_full) && !defined(AO_HAVE_nop_write)
168 # define AO_nop_write() AO_nop_full()
169 # define AO_HAVE_nop_write
170 #endif
171
172 /* Load */
173 #if defined(AO_HAVE_load_full) && !defined(AO_HAVE_load_acquire)
174 # define AO_load_acquire(addr) AO_load_full(addr)
175 # define AO_HAVE_load_acquire
176 #endif
177
178 #if defined(AO_HAVE_load_acquire) && !defined(AO_HAVE_load)
179 # define AO_load(addr) AO_load_acquire(addr)
180 # define AO_HAVE_load
181 #endif
182
183 #if defined(AO_HAVE_load_full) && !defined(AO_HAVE_load_read)
184 # define AO_load_read(addr) AO_load_full(addr)
185 # define AO_HAVE_load_read
186 #endif
187
188 #if !defined(AO_HAVE_load_acquire_read) && defined(AO_HAVE_load_acquire)
189 # define AO_load_acquire_read(addr) AO_load_acquire(addr)
190 # define AO_HAVE_load_acquire_read
191 #endif
192
193 #if defined(AO_HAVE_load) && defined(AO_HAVE_nop_full) \
194     && !defined(AO_HAVE_load_acquire)
195   AO_INLINE AO_t
196   AO_load_acquire(const volatile AO_t *addr)
197   {
198     AO_t result = AO_load(addr);
199     /* Acquire barrier would be useless, since the load could be delayed */
200     /* beyond it.                                                        */
201     AO_nop_full();
202     return result;
203   }
204 # define AO_HAVE_load_acquire
205 #endif
206
207 #if defined(AO_HAVE_load) && defined(AO_HAVE_nop_read) \
208     && !defined(AO_HAVE_load_read)
209   AO_INLINE AO_t
210   AO_load_read(const volatile AO_t *addr)
211   {
212     AO_t result = AO_load(addr);
213     /* Acquire barrier would be useless, since the load could be delayed */
214     /* beyond it.                                                        */
215     AO_nop_read();
216     return result;
217   }
218 # define AO_HAVE_load_read
219 #endif
220
221 #if defined(AO_HAVE_load_acquire) && defined(AO_HAVE_nop_full) \
222     && !defined(AO_HAVE_load_full)
223 # define AO_load_full(addr) (AO_nop_full(), AO_load_acquire(addr))
224 # define AO_HAVE_load_full
225 #endif
226
227 #if !defined(AO_HAVE_load_acquire_read) && defined(AO_HAVE_load_read)
228 # define AO_load_acquire_read(addr) AO_load_read(addr)
229 # define AO_HAVE_load_acquire_read
230 #endif
231
232 #if defined(AO_HAVE_load_acquire_read) && !defined(AO_HAVE_load)
233 # define AO_load(addr) AO_load_acquire_read(addr)
234 # define AO_HAVE_load
235 #endif
236
237 #ifdef AO_NO_DD_ORDERING
238 # if defined(AO_HAVE_load_acquire_read)
239 #   define AO_load_dd_acquire_read(addr) AO_load_acquire_read(addr)
240 #   define AO_HAVE_load_dd_acquire_read
241 # endif
242 #else
243 # if defined(AO_HAVE_load)
244 #   define AO_load_dd_acquire_read(addr) AO_load(addr)
245 #   define AO_HAVE_load_dd_acquire_read
246 # endif
247 #endif
248
249 /* Store */
250 #if defined(AO_HAVE_store_full) && !defined(AO_HAVE_store_release)
251 # define AO_store_release(addr,val) AO_store_full(addr,val)
252 # define AO_HAVE_store_release
253 #endif
254
255 #if defined(AO_HAVE_store_release) && !defined(AO_HAVE_store)
256 # define AO_store(addr,val) AO_store_release(addr,val)
257 # define AO_HAVE_store
258 #endif
259
260 #if defined(AO_HAVE_store_full) && !defined(AO_HAVE_store_write)
261 # define AO_store_write(addr,val) AO_store_full(addr,val)
262 # define AO_HAVE_store_write
263 #endif
264
265 #if defined(AO_HAVE_store_release) && !defined(AO_HAVE_store_release_write)
266 # define AO_store_release_write(addr,val) AO_store_release(addr,val)
267 # define AO_HAVE_store_release_write
268 #endif
269
270 #if defined(AO_HAVE_store_write) && !defined(AO_HAVE_store)
271 # define AO_store(addr,val) AO_store_write(addr,val)
272 # define AO_HAVE_store
273 #endif
274
275 #if defined(AO_HAVE_store) && defined(AO_HAVE_nop_full) \
276     && !defined(AO_HAVE_store_release)
277 # define AO_store_release(addr,val) (AO_nop_full(), AO_store(addr,val))
278 # define AO_HAVE_store_release
279 #endif
280
281 #if defined(AO_HAVE_nop_write) && defined(AO_HAVE_store) \
282     && !defined(AO_HAVE_store_write)
283 # define AO_store_write(addr,val) (AO_nop_write(), AO_store(addr,val))
284 # define AO_HAVE_store_write
285 #endif
286
287 #if defined(AO_HAVE_store_write) && !defined(AO_HAVE_store_release_write)
288 # define AO_store_release_write(addr,val) AO_store_write(addr,val)
289 # define AO_HAVE_store_release_write
290 #endif
291
292 #if defined(AO_HAVE_store_release) && defined(AO_HAVE_nop_full) \
293     && !defined(AO_HAVE_store_full)
294 # define AO_store_full(addr,val) (AO_store_release(addr,val), AO_nop_full())
295 # define AO_HAVE_store_full
296 #endif
297
298 /* NEC LE-IT: Test and set */
299 #if defined(AO_HAVE_test_and_set) && defined(AO_HAVE_nop_full) \
300     && !defined(AO_HAVE_test_and_set_release)
301 # define AO_test_and_set_release(addr) (AO_nop_full(), AO_test_and_set(addr))
302 # define AO_HAVE_test_and_set_release
303 #endif
304
305 #if defined(AO_HAVE_test_and_set) && defined(AO_HAVE_nop_full) \
306     && !defined(AO_HAVE_test_and_set_acquire)
307   AO_INLINE AO_TS_VAL_t
308   AO_test_and_set_acquire(volatile AO_TS_t *addr)
309   {
310     AO_TS_VAL_t result = AO_test_and_set(addr);
311     AO_nop_full();
312     return result;
313   }
314 # define AO_HAVE_test_and_set_acquire
315 #endif
316
317 /* Fetch_and_add */
318 /* We first try to implement fetch_and_add variants in terms    */
319 /* of the corresponding compare_and_swap variants to minimize   */
320 /* adding barriers.                                             */
321 #if defined(AO_HAVE_compare_and_swap_full) \
322     && !defined(AO_HAVE_fetch_and_add_full)
323   AO_INLINE AO_t
324   AO_fetch_and_add_full(volatile AO_t *addr, AO_t incr)
325   {
326     AO_t old;
327     do
328       {
329         old = *addr;
330       }
331     while (!AO_compare_and_swap_full(addr, old, old+incr));
332     return old;
333   }
334 # define AO_HAVE_fetch_and_add_full
335 #endif
336
337 #if defined(AO_HAVE_compare_and_swap_acquire) \
338     && !defined(AO_HAVE_fetch_and_add_acquire)
339   AO_INLINE AO_t
340   AO_fetch_and_add_acquire(volatile AO_t *addr, AO_t incr)
341   {
342     AO_t old;
343     do
344       {
345         old = *addr;
346       }
347     while (!AO_compare_and_swap_acquire(addr, old, old+incr));
348     return old;
349   }
350 # define AO_HAVE_fetch_and_add_acquire
351 #endif
352
353 #if defined(AO_HAVE_compare_and_swap_release) \
354     && !defined(AO_HAVE_fetch_and_add_release)
355   AO_INLINE AO_t
356   AO_fetch_and_add_release(volatile AO_t *addr, AO_t incr)
357   {
358     AO_t old;
359     do
360       {
361         old = *addr;
362       }
363     while (!AO_compare_and_swap_release(addr, old, old+incr));
364     return old;
365   }
366 # define AO_HAVE_fetch_and_add_release
367 #endif
368
369 #if defined(AO_HAVE_compare_and_swap) && !defined(AO_HAVE_fetch_and_add)
370   AO_INLINE AO_t
371   AO_fetch_and_add(volatile AO_t *addr, AO_t incr)
372   {
373     AO_t old;
374     do
375       {
376         old = *addr;
377       }
378     while (!AO_compare_and_swap(addr, old, old+incr));
379     return old;
380   }
381 # define AO_HAVE_fetch_and_add
382 #endif
383
384 #if defined(AO_HAVE_fetch_and_add_full)
385 # if !defined(AO_HAVE_fetch_and_add_release)
386 #   define AO_fetch_and_add_release(addr,val) AO_fetch_and_add_full(addr,val)
387 #   define AO_HAVE_fetch_and_add_release
388 # endif
389 # if !defined(AO_HAVE_fetch_and_add_acquire)
390 #   define AO_fetch_and_add_acquire(addr,val) AO_fetch_and_add_full(addr,val)
391 #   define AO_HAVE_fetch_and_add_acquire
392 # endif
393 # if !defined(AO_HAVE_fetch_and_add_write)
394 #   define AO_fetch_and_add_write(addr,val) AO_fetch_and_add_full(addr,val)
395 #   define AO_HAVE_fetch_and_add_write
396 # endif
397 # if !defined(AO_HAVE_fetch_and_add_read)
398 #   define AO_fetch_and_add_read(addr,val) AO_fetch_and_add_full(addr,val)
399 #   define AO_HAVE_fetch_and_add_read
400 # endif
401 #endif /* AO_HAVE_fetch_and_add_full */
402
403 #if !defined(AO_HAVE_fetch_and_add) && defined(AO_HAVE_fetch_and_add_release)
404 # define AO_fetch_and_add(addr,val) AO_fetch_and_add_release(addr,val)
405 # define AO_HAVE_fetch_and_add
406 #endif
407 #if !defined(AO_HAVE_fetch_and_add) && defined(AO_HAVE_fetch_and_add_acquire)
408 # define AO_fetch_and_add(addr,val) AO_fetch_and_add_acquire(addr,val)
409 # define AO_HAVE_fetch_and_add
410 #endif
411 #if !defined(AO_HAVE_fetch_and_add) && defined(AO_HAVE_fetch_and_add_write)
412 # define AO_fetch_and_add(addr,val) AO_fetch_and_add_write(addr,val)
413 # define AO_HAVE_fetch_and_add
414 #endif
415 #if !defined(AO_HAVE_fetch_and_add) && defined(AO_HAVE_fetch_and_add_read)
416 # define AO_fetch_and_add(addr,val) AO_fetch_and_add_read(addr,val)
417 # define AO_HAVE_fetch_and_add
418 #endif
419
420 #if defined(AO_HAVE_fetch_and_add_acquire) && defined(AO_HAVE_nop_full) \
421     && !defined(AO_HAVE_fetch_and_add_full)
422 # define AO_fetch_and_add_full(addr,val) \
423                         (AO_nop_full(), AO_fetch_and_add_acquire(addr,val))
424 # define AO_HAVE_fetch_and_add_full
425 #endif
426
427 #if !defined(AO_HAVE_fetch_and_add_release_write) \
428     && defined(AO_HAVE_fetch_and_add_write)
429 # define AO_fetch_and_add_release_write(addr,val) \
430                                         AO_fetch_and_add_write(addr,val)
431 # define AO_HAVE_fetch_and_add_release_write
432 #endif
433 #if !defined(AO_HAVE_fetch_and_add_release_write) \
434     && defined(AO_HAVE_fetch_and_add_release)
435 # define AO_fetch_and_add_release_write(addr,val) \
436                                         AO_fetch_and_add_release(addr,val)
437 # define AO_HAVE_fetch_and_add_release_write
438 #endif
439 #if !defined(AO_HAVE_fetch_and_add_acquire_read) \
440     && defined(AO_HAVE_fetch_and_add_read)
441 # define AO_fetch_and_add_acquire_read(addr,val) \
442                                         AO_fetch_and_add_read(addr,val)
443 # define AO_HAVE_fetch_and_add_acquire_read
444 #endif
445 #if !defined(AO_HAVE_fetch_and_add_acquire_read) \
446     && defined(AO_HAVE_fetch_and_add_acquire)
447 # define AO_fetch_and_add_acquire_read(addr,val) \
448                                         AO_fetch_and_add_acquire(addr,val)
449 # define AO_HAVE_fetch_and_add_acquire_read
450 #endif
451
452 #ifdef AO_NO_DD_ORDERING
453 # if defined(AO_HAVE_fetch_and_add_acquire_read)
454 #   define AO_fetch_and_add_dd_acquire_read(addr,val) \
455                                 AO_fetch_and_add_acquire_read(addr,val)
456 #   define AO_HAVE_fetch_and_add_dd_acquire_read
457 # endif
458 #else
459 # if defined(AO_HAVE_fetch_and_add)
460 #   define AO_fetch_and_add_dd_acquire_read(addr,val) \
461                                         AO_fetch_and_add(addr,val)
462 #   define AO_HAVE_fetch_and_add_dd_acquire_read
463 # endif
464 #endif /* !AO_NO_DD_ORDERING */
465
466 /* Fetch_and_add1 */
467
468 #if defined(AO_HAVE_fetch_and_add_full) \
469     && !defined(AO_HAVE_fetch_and_add1_full)
470 # define AO_fetch_and_add1_full(addr) AO_fetch_and_add_full(addr,1)
471 # define AO_HAVE_fetch_and_add1_full
472 #endif
473 #if defined(AO_HAVE_fetch_and_add_release) \
474     && !defined(AO_HAVE_fetch_and_add1_release)
475 # define AO_fetch_and_add1_release(addr) AO_fetch_and_add_release(addr,1)
476 # define AO_HAVE_fetch_and_add1_release
477 #endif
478 #if defined(AO_HAVE_fetch_and_add_acquire) \
479     && !defined(AO_HAVE_fetch_and_add1_acquire)
480 # define AO_fetch_and_add1_acquire(addr) AO_fetch_and_add_acquire(addr,1)
481 # define AO_HAVE_fetch_and_add1_acquire
482 #endif
483 #if defined(AO_HAVE_fetch_and_add_write) \
484     && !defined(AO_HAVE_fetch_and_add1_write)
485 # define AO_fetch_and_add1_write(addr) AO_fetch_and_add_write(addr,1)
486 # define AO_HAVE_fetch_and_add1_write
487 #endif
488 #if defined(AO_HAVE_fetch_and_add_read) \
489     && !defined(AO_HAVE_fetch_and_add1_read)
490 # define AO_fetch_and_add1_read(addr) AO_fetch_and_add_read(addr,1)
491 # define AO_HAVE_fetch_and_add1_read
492 #endif
493 #if defined(AO_HAVE_fetch_and_add_release_write) \
494     && !defined(AO_HAVE_fetch_and_add1_release_write)
495 # define AO_fetch_and_add1_release_write(addr) \
496                                         AO_fetch_and_add_release_write(addr,1)
497 # define AO_HAVE_fetch_and_add1_release_write
498 #endif
499 #if defined(AO_HAVE_fetch_and_add_acquire_read) \
500     && !defined(AO_HAVE_fetch_and_add1_acquire_read)
501 # define AO_fetch_and_add1_acquire_read(addr) \
502                                         AO_fetch_and_add_acquire_read(addr,1)
503 # define AO_HAVE_fetch_and_add1_acquire_read
504 #endif
505 #if defined(AO_HAVE_fetch_and_add) && !defined(AO_HAVE_fetch_and_add1)
506 # define AO_fetch_and_add1(addr) AO_fetch_and_add(addr,1)
507 # define AO_HAVE_fetch_and_add1
508 #endif
509
510 #if defined(AO_HAVE_fetch_and_add1_full)
511 # if !defined(AO_HAVE_fetch_and_add1_release)
512 #   define AO_fetch_and_add1_release(addr) AO_fetch_and_add1_full(addr)
513 #   define AO_HAVE_fetch_and_add1_release
514 # endif
515 # if !defined(AO_HAVE_fetch_and_add1_acquire)
516 #   define AO_fetch_and_add1_acquire(addr) AO_fetch_and_add1_full(addr)
517 #   define AO_HAVE_fetch_and_add1_acquire
518 # endif
519 # if !defined(AO_HAVE_fetch_and_add1_write)
520 #   define AO_fetch_and_add1_write(addr) AO_fetch_and_add1_full(addr)
521 #   define AO_HAVE_fetch_and_add1_write
522 # endif
523 # if !defined(AO_HAVE_fetch_and_add1_read)
524 #   define AO_fetch_and_add1_read(addr) AO_fetch_and_add1_full(addr)
525 #   define AO_HAVE_fetch_and_add1_read
526 # endif
527 #endif /* AO_HAVE_fetch_and_add1_full */
528
529 #if !defined(AO_HAVE_fetch_and_add1) \
530     && defined(AO_HAVE_fetch_and_add1_release)
531 # define AO_fetch_and_add1(addr) AO_fetch_and_add1_release(addr)
532 # define AO_HAVE_fetch_and_add1
533 #endif
534 #if !defined(AO_HAVE_fetch_and_add1) \
535     && defined(AO_HAVE_fetch_and_add1_acquire)
536 # define AO_fetch_and_add1(addr) AO_fetch_and_add1_acquire(addr)
537 # define AO_HAVE_fetch_and_add1
538 #endif
539 #if !defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_add1_write)
540 # define AO_fetch_and_add1(addr) AO_fetch_and_add1_write(addr)
541 # define AO_HAVE_fetch_and_add1
542 #endif
543 #if !defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_add1_read)
544 # define AO_fetch_and_add1(addr) AO_fetch_and_add1_read(addr)
545 # define AO_HAVE_fetch_and_add1
546 #endif
547
548 #if defined(AO_HAVE_fetch_and_add1_acquire) && defined(AO_HAVE_nop_full) \
549     && !defined(AO_HAVE_fetch_and_add1_full)
550 # define AO_fetch_and_add1_full(addr) \
551                         (AO_nop_full(), AO_fetch_and_add1_acquire(addr))
552 # define AO_HAVE_fetch_and_add1_full
553 #endif
554
555 #if !defined(AO_HAVE_fetch_and_add1_release_write) \
556     && defined(AO_HAVE_fetch_and_add1_write)
557 # define AO_fetch_and_add1_release_write(addr) AO_fetch_and_add1_write(addr)
558 # define AO_HAVE_fetch_and_add1_release_write
559 #endif
560 #if !defined(AO_HAVE_fetch_and_add1_release_write) \
561     && defined(AO_HAVE_fetch_and_add1_release)
562 # define AO_fetch_and_add1_release_write(addr) AO_fetch_and_add1_release(addr)
563 # define AO_HAVE_fetch_and_add1_release_write
564 #endif
565 #if !defined(AO_HAVE_fetch_and_add1_acquire_read) \
566     && defined(AO_HAVE_fetch_and_add1_read)
567 # define AO_fetch_and_add1_acquire_read(addr) AO_fetch_and_add1_read(addr)
568 # define AO_HAVE_fetch_and_add1_acquire_read
569 #endif
570 #if !defined(AO_HAVE_fetch_and_add1_acquire_read) \
571     && defined(AO_HAVE_fetch_and_add1_acquire)
572 # define AO_fetch_and_add1_acquire_read(addr) AO_fetch_and_add1_acquire(addr)
573 # define AO_HAVE_fetch_and_add1_acquire_read
574 #endif
575
576 #ifdef AO_NO_DD_ORDERING
577 # if defined(AO_HAVE_fetch_and_add1_acquire_read)
578 #   define AO_fetch_and_add1_dd_acquire_read(addr) \
579                                         AO_fetch_and_add1_acquire_read(addr)
580 #   define AO_HAVE_fetch_and_add1_dd_acquire_read
581 # endif
582 #else
583 # if defined(AO_HAVE_fetch_and_add1)
584 #   define AO_fetch_and_add1_dd_acquire_read(addr) AO_fetch_and_add1(addr)
585 #   define AO_HAVE_fetch_and_add1_dd_acquire_read
586 # endif
587 #endif /* !AO_NO_DD_ORDERING */
588
589 /* Fetch_and_sub1 */
590 #if defined(AO_HAVE_fetch_and_add_full) \
591     && !defined(AO_HAVE_fetch_and_sub1_full)
592 # define AO_fetch_and_sub1_full(addr) AO_fetch_and_add_full(addr,(AO_t)(-1))
593 # define AO_HAVE_fetch_and_sub1_full
594 #endif
595 #if defined(AO_HAVE_fetch_and_add_release) \
596     && !defined(AO_HAVE_fetch_and_sub1_release)
597 # define AO_fetch_and_sub1_release(addr) \
598                                 AO_fetch_and_add_release(addr,(AO_t)(-1))
599 # define AO_HAVE_fetch_and_sub1_release
600 #endif
601 #if defined(AO_HAVE_fetch_and_add_acquire) \
602     && !defined(AO_HAVE_fetch_and_sub1_acquire)
603 # define AO_fetch_and_sub1_acquire(addr) \
604                                 AO_fetch_and_add_acquire(addr,(AO_t)(-1))
605 # define AO_HAVE_fetch_and_sub1_acquire
606 #endif
607 #if defined(AO_HAVE_fetch_and_add_write) \
608     && !defined(AO_HAVE_fetch_and_sub1_write)
609 # define AO_fetch_and_sub1_write(addr) AO_fetch_and_add_write(addr,(AO_t)(-1))
610 # define AO_HAVE_fetch_and_sub1_write
611 #endif
612 #if defined(AO_HAVE_fetch_and_add_read) \
613     && !defined(AO_HAVE_fetch_and_sub1_read)
614 # define AO_fetch_and_sub1_read(addr) AO_fetch_and_add_read(addr,(AO_t)(-1))
615 # define AO_HAVE_fetch_and_sub1_read
616 #endif
617 #if defined(AO_HAVE_fetch_and_add_release_write) \
618     && !defined(AO_HAVE_fetch_and_sub1_release_write)
619 # define AO_fetch_and_sub1_release_write(addr) \
620                         AO_fetch_and_add_release_write(addr,(AO_t)(-1))
621 # define AO_HAVE_fetch_and_sub1_release_write
622 #endif
623 #if defined(AO_HAVE_fetch_and_add_acquire_read) \
624     && !defined(AO_HAVE_fetch_and_sub1_acquire_read)
625 # define AO_fetch_and_sub1_acquire_read(addr) \
626                         AO_fetch_and_add_acquire_read(addr,(AO_t)(-1))
627 # define AO_HAVE_fetch_and_sub1_acquire_read
628 #endif
629 #if defined(AO_HAVE_fetch_and_add) && !defined(AO_HAVE_fetch_and_sub1)
630 # define AO_fetch_and_sub1(addr) AO_fetch_and_add(addr,(AO_t)(-1))
631 # define AO_HAVE_fetch_and_sub1
632 #endif
633
634 #if defined(AO_HAVE_fetch_and_sub1_full)
635 # if !defined(AO_HAVE_fetch_and_sub1_release)
636 #   define AO_fetch_and_sub1_release(addr) AO_fetch_and_sub1_full(addr)
637 #   define AO_HAVE_fetch_and_sub1_release
638 # endif
639 # if !defined(AO_HAVE_fetch_and_sub1_acquire)
640 #   define AO_fetch_and_sub1_acquire(addr) AO_fetch_and_sub1_full(addr)
641 #   define AO_HAVE_fetch_and_sub1_acquire
642 # endif
643 # if !defined(AO_HAVE_fetch_and_sub1_write)
644 #   define AO_fetch_and_sub1_write(addr) AO_fetch_and_sub1_full(addr)
645 #   define AO_HAVE_fetch_and_sub1_write
646 # endif
647 # if !defined(AO_HAVE_fetch_and_sub1_read)
648 #   define AO_fetch_and_sub1_read(addr) AO_fetch_and_sub1_full(addr)
649 #   define AO_HAVE_fetch_and_sub1_read
650 # endif
651 #endif /* AO_HAVE_fetch_and_sub1_full */
652
653 #if !defined(AO_HAVE_fetch_and_sub1) \
654     && defined(AO_HAVE_fetch_and_sub1_release)
655 # define AO_fetch_and_sub1(addr) AO_fetch_and_sub1_release(addr)
656 # define AO_HAVE_fetch_and_sub1
657 #endif
658 #if !defined(AO_HAVE_fetch_and_sub1) \
659     && defined(AO_HAVE_fetch_and_sub1_acquire)
660 # define AO_fetch_and_sub1(addr) AO_fetch_and_sub1_acquire(addr)
661 # define AO_HAVE_fetch_and_sub1
662 #endif
663 #if !defined(AO_HAVE_fetch_and_sub1) && defined(AO_HAVE_fetch_and_sub1_write)
664 # define AO_fetch_and_sub1(addr) AO_fetch_and_sub1_write(addr)
665 # define AO_HAVE_fetch_and_sub1
666 #endif
667 #if !defined(AO_HAVE_fetch_and_sub1) && defined(AO_HAVE_fetch_and_sub1_read)
668 # define AO_fetch_and_sub1(addr) AO_fetch_and_sub1_read(addr)
669 # define AO_HAVE_fetch_and_sub1
670 #endif
671
672 #if defined(AO_HAVE_fetch_and_sub1_acquire) && defined(AO_HAVE_nop_full) \
673     && !defined(AO_HAVE_fetch_and_sub1_full)
674 # define AO_fetch_and_sub1_full(addr) \
675                         (AO_nop_full(), AO_fetch_and_sub1_acquire(addr))
676 # define AO_HAVE_fetch_and_sub1_full
677 #endif
678
679 #if !defined(AO_HAVE_fetch_and_sub1_release_write) \
680     && defined(AO_HAVE_fetch_and_sub1_write)
681 # define AO_fetch_and_sub1_release_write(addr) AO_fetch_and_sub1_write(addr)
682 # define AO_HAVE_fetch_and_sub1_release_write
683 #endif
684 #if !defined(AO_HAVE_fetch_and_sub1_release_write) \
685     && defined(AO_HAVE_fetch_and_sub1_release)
686 # define AO_fetch_and_sub1_release_write(addr) AO_fetch_and_sub1_release(addr)
687 # define AO_HAVE_fetch_and_sub1_release_write
688 #endif
689 #if !defined(AO_HAVE_fetch_and_sub1_acquire_read) \
690     && defined(AO_HAVE_fetch_and_sub1_read)
691 # define AO_fetch_and_sub1_acquire_read(addr) AO_fetch_and_sub1_read(addr)
692 # define AO_HAVE_fetch_and_sub1_acquire_read
693 #endif
694 #if !defined(AO_HAVE_fetch_and_sub1_acquire_read) \
695     && defined(AO_HAVE_fetch_and_sub1_acquire)
696 # define AO_fetch_and_sub1_acquire_read(addr) AO_fetch_and_sub1_acquire(addr)
697 # define AO_HAVE_fetch_and_sub1_acquire_read
698 #endif
699
700 #ifdef AO_NO_DD_ORDERING
701 # if defined(AO_HAVE_fetch_and_sub1_acquire_read)
702 #   define AO_fetch_and_sub1_dd_acquire_read(addr) \
703                                         AO_fetch_and_sub1_acquire_read(addr)
704 #   define AO_HAVE_fetch_and_sub1_dd_acquire_read
705 # endif
706 #else
707 # if defined(AO_HAVE_fetch_and_sub1)
708 #   define AO_fetch_and_sub1_dd_acquire_read(addr) AO_fetch_and_sub1(addr)
709 #   define AO_HAVE_fetch_and_sub1_dd_acquire_read
710 # endif
711 #endif /* !AO_NO_DD_ORDERING */
712
713 /* Atomic or */
714 #if defined(AO_HAVE_compare_and_swap_full) && !defined(AO_HAVE_or_full)
715   AO_INLINE void
716   AO_or_full(volatile AO_t *addr, AO_t incr)
717   {
718     AO_t old;
719     do
720       {
721         old = *addr;
722       }
723     while (!AO_compare_and_swap_full(addr, old, old | incr));
724   }
725 # define AO_HAVE_or_full
726 #endif
727
728 #if defined(AO_HAVE_or_full)
729 # if !defined(AO_HAVE_or_release)
730 #   define AO_or_release(addr,val) AO_or_full(addr,val)
731 #   define AO_HAVE_or_release
732 # endif
733 # if !defined(AO_HAVE_or_acquire)
734 #   define AO_or_acquire(addr,val) AO_or_full(addr,val)
735 #   define AO_HAVE_or_acquire
736 # endif
737 # if !defined(AO_HAVE_or_write)
738 #   define AO_or_write(addr,val) AO_or_full(addr,val)
739 #   define AO_HAVE_or_write
740 # endif
741 # if !defined(AO_HAVE_or_read)
742 #   define AO_or_read(addr,val) AO_or_full(addr,val)
743 #   define AO_HAVE_or_read
744 # endif
745 #endif /* AO_HAVE_or_full */
746
747 #if !defined(AO_HAVE_or) && defined(AO_HAVE_or_release)
748 # define AO_or(addr,val) AO_or_release(addr,val)
749 # define AO_HAVE_or
750 #endif
751 #if !defined(AO_HAVE_or) && defined(AO_HAVE_or_acquire)
752 # define AO_or(addr,val) AO_or_acquire(addr,val)
753 # define AO_HAVE_or
754 #endif
755 #if !defined(AO_HAVE_or) && defined(AO_HAVE_or_write)
756 # define AO_or(addr,val) AO_or_write(addr,val)
757 # define AO_HAVE_or
758 #endif
759 #if !defined(AO_HAVE_or) && defined(AO_HAVE_or_read)
760 # define AO_or(addr,val) AO_or_read(addr,val)
761 # define AO_HAVE_or
762 #endif
763
764 #if defined(AO_HAVE_or_acquire) && defined(AO_HAVE_nop_full) \
765     && !defined(AO_HAVE_or_full)
766 # define AO_or_full(addr,val) (AO_nop_full(), AO_or_acquire(addr,val))
767 # define AO_HAVE_or_full
768 #endif
769
770 #if !defined(AO_HAVE_or_release_write) && defined(AO_HAVE_or_write)
771 # define AO_or_release_write(addr,val) AO_or_write(addr,val)
772 # define AO_HAVE_or_release_write
773 #endif
774 #if !defined(AO_HAVE_or_release_write) && defined(AO_HAVE_or_release)
775 # define AO_or_release_write(addr,val) AO_or_release(addr,val)
776 # define AO_HAVE_or_release_write
777 #endif
778 #if !defined(AO_HAVE_or_acquire_read) && defined(AO_HAVE_or_read)
779 # define AO_or_acquire_read(addr,val) AO_or_read(addr,val)
780 # define AO_HAVE_or_acquire_read
781 #endif
782 #if !defined(AO_HAVE_or_acquire_read) && defined(AO_HAVE_or_acquire)
783 # define AO_or_acquire_read(addr,val) AO_or_acquire(addr,val)
784 # define AO_HAVE_or_acquire_read
785 #endif
786
787 /* dd_aquire_read is meaningless.       */
788
789 /* Test_and_set */
790 #if defined(AO_HAVE_test_and_set_full)
791 # if !defined(AO_HAVE_test_and_set_release)
792 #   define AO_test_and_set_release(addr) AO_test_and_set_full(addr)
793 #   define AO_HAVE_test_and_set_release
794 # endif
795 # if !defined(AO_HAVE_test_and_set_acquire)
796 #   define AO_test_and_set_acquire(addr) AO_test_and_set_full(addr)
797 #   define AO_HAVE_test_and_set_acquire
798 # endif
799 # if !defined(AO_HAVE_test_and_set_write)
800 #   define AO_test_and_set_write(addr) AO_test_and_set_full(addr)
801 #   define AO_HAVE_test_and_set_write
802 # endif
803 # if !defined(AO_HAVE_test_and_set_read)
804 #   define AO_test_and_set_read(addr) AO_test_and_set_full(addr)
805 #   define AO_HAVE_test_and_set_read
806 # endif
807 #endif /* AO_HAVE_test_and_set_full */
808
809 #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_release)
810 # define AO_test_and_set(addr) AO_test_and_set_release(addr)
811 # define AO_HAVE_test_and_set
812 #endif
813 #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_acquire)
814 # define AO_test_and_set(addr) AO_test_and_set_acquire(addr)
815 # define AO_HAVE_test_and_set
816 #endif
817 #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_write)
818 # define AO_test_and_set(addr) AO_test_and_set_write(addr)
819 # define AO_HAVE_test_and_set
820 #endif
821 #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_read)
822 # define AO_test_and_set(addr) AO_test_and_set_read(addr)
823 # define AO_HAVE_test_and_set
824 #endif
825
826 #if defined(AO_HAVE_test_and_set_acquire) && defined(AO_HAVE_nop_full) \
827     && !defined(AO_HAVE_test_and_set_full)
828 # define AO_test_and_set_full(addr) \
829                         (AO_nop_full(), AO_test_and_set_acquire(addr))
830 # define AO_HAVE_test_and_set_full
831 #endif
832
833 #if !defined(AO_HAVE_test_and_set_release_write) \
834     && defined(AO_HAVE_test_and_set_write)
835 # define AO_test_and_set_release_write(addr) AO_test_and_set_write(addr)
836 # define AO_HAVE_test_and_set_release_write
837 #endif
838 #if !defined(AO_HAVE_test_and_set_release_write) \
839     && defined(AO_HAVE_test_and_set_release)
840 # define AO_test_and_set_release_write(addr) AO_test_and_set_release(addr)
841 # define AO_HAVE_test_and_set_release_write
842 #endif
843 #if !defined(AO_HAVE_test_and_set_acquire_read) \
844     && defined(AO_HAVE_test_and_set_read)
845 # define AO_test_and_set_acquire_read(addr) AO_test_and_set_read(addr)
846 # define AO_HAVE_test_and_set_acquire_read
847 #endif
848 #if !defined(AO_HAVE_test_and_set_acquire_read) \
849     && defined(AO_HAVE_test_and_set_acquire)
850 # define AO_test_and_set_acquire_read(addr) AO_test_and_set_acquire(addr)
851 # define AO_HAVE_test_and_set_acquire_read
852 #endif
853
854 #ifdef AO_NO_DD_ORDERING
855 # if defined(AO_HAVE_test_and_set_acquire_read)
856 #   define AO_test_and_set_dd_acquire_read(addr) \
857                                         AO_test_and_set_acquire_read(addr)
858 #   define AO_HAVE_test_and_set_dd_acquire_read
859 # endif
860 #else
861 # if defined(AO_HAVE_test_and_set)
862 #   define AO_test_and_set_dd_acquire_read(addr) AO_test_and_set(addr)
863 #   define AO_HAVE_test_and_set_dd_acquire_read
864 # endif
865 #endif /* !AO_NO_DD_ORDERING */
866
867 /* Compare_and_swap */
868 #if defined(AO_HAVE_compare_and_swap) && defined(AO_HAVE_nop_full) \
869     && !defined(AO_HAVE_compare_and_swap_acquire)
870   AO_INLINE int
871   AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val)
872   {
873     int result = AO_compare_and_swap(addr, old, new_val);
874     AO_nop_full();
875     return result;
876   }
877 # define AO_HAVE_compare_and_swap_acquire
878 #endif
879 #if defined(AO_HAVE_compare_and_swap) && defined(AO_HAVE_nop_full) \
880     && !defined(AO_HAVE_compare_and_swap_release)
881 # define AO_compare_and_swap_release(addr,old,new_val) \
882                         (AO_nop_full(), AO_compare_and_swap(addr,old,new_val))
883 # define AO_HAVE_compare_and_swap_release
884 #endif
885 #if defined(AO_HAVE_compare_and_swap_full)
886 # if !defined(AO_HAVE_compare_and_swap_release)
887 #   define AO_compare_and_swap_release(addr,old,new_val) \
888                                 AO_compare_and_swap_full(addr,old,new_val)
889 #   define AO_HAVE_compare_and_swap_release
890 # endif
891 # if !defined(AO_HAVE_compare_and_swap_acquire)
892 #   define AO_compare_and_swap_acquire(addr,old,new_val) \
893                                 AO_compare_and_swap_full(addr,old,new_val)
894 #   define AO_HAVE_compare_and_swap_acquire
895 # endif
896 # if !defined(AO_HAVE_compare_and_swap_write)
897 #   define AO_compare_and_swap_write(addr,old,new_val) \
898                                 AO_compare_and_swap_full(addr,old,new_val)
899 #   define AO_HAVE_compare_and_swap_write
900 # endif
901 # if !defined(AO_HAVE_compare_and_swap_read)
902 #   define AO_compare_and_swap_read(addr,old,new_val) \
903                                 AO_compare_and_swap_full(addr,old,new_val)
904 #   define AO_HAVE_compare_and_swap_read
905 # endif
906 #endif /* AO_HAVE_compare_and_swap_full */
907
908 #if !defined(AO_HAVE_compare_and_swap) \
909     && defined(AO_HAVE_compare_and_swap_release)
910 # define AO_compare_and_swap(addr,old,new_val) \
911                                 AO_compare_and_swap_release(addr,old,new_val)
912 # define AO_HAVE_compare_and_swap
913 #endif
914 #if !defined(AO_HAVE_compare_and_swap) \
915     && defined(AO_HAVE_compare_and_swap_acquire)
916 # define AO_compare_and_swap(addr,old,new_val) \
917                                 AO_compare_and_swap_acquire(addr,old,new_val)
918 # define AO_HAVE_compare_and_swap
919 #endif
920 #if !defined(AO_HAVE_compare_and_swap) \
921     && defined(AO_HAVE_compare_and_swap_write)
922 # define AO_compare_and_swap(addr,old,new_val) \
923                                 AO_compare_and_swap_write(addr,old,new_val)
924 # define AO_HAVE_compare_and_swap
925 #endif
926 #if !defined(AO_HAVE_compare_and_swap) \
927     && defined(AO_HAVE_compare_and_swap_read)
928 # define AO_compare_and_swap(addr,old,new_val) \
929                                 AO_compare_and_swap_read(addr,old,new_val)
930 # define AO_HAVE_compare_and_swap
931 #endif
932
933 #if defined(AO_HAVE_compare_and_swap_acquire) \
934     && defined(AO_HAVE_nop_full) && !defined(AO_HAVE_compare_and_swap_full)
935 # define AO_compare_and_swap_full(addr,old,new_val) \
936                 (AO_nop_full(), AO_compare_and_swap_acquire(addr,old,new_val))
937 # define AO_HAVE_compare_and_swap_full
938 #endif
939
940 #if !defined(AO_HAVE_compare_and_swap_release_write) \
941     && defined(AO_HAVE_compare_and_swap_write)
942 # define AO_compare_and_swap_release_write(addr,old,new_val) \
943                                 AO_compare_and_swap_write(addr,old,new_val)
944 # define AO_HAVE_compare_and_swap_release_write
945 #endif
946 #if !defined(AO_HAVE_compare_and_swap_release_write) \
947     && defined(AO_HAVE_compare_and_swap_release)
948 # define AO_compare_and_swap_release_write(addr,old,new_val) \
949                                 AO_compare_and_swap_release(addr,old,new_val)
950 # define AO_HAVE_compare_and_swap_release_write
951 #endif
952 #if !defined(AO_HAVE_compare_and_swap_acquire_read) \
953     && defined(AO_HAVE_compare_and_swap_read)
954 # define AO_compare_and_swap_acquire_read(addr,old,new_val) \
955                                 AO_compare_and_swap_read(addr,old,new_val)
956 # define AO_HAVE_compare_and_swap_acquire_read
957 #endif
958 #if !defined(AO_HAVE_compare_and_swap_acquire_read) \
959     && defined(AO_HAVE_compare_and_swap_acquire)
960 # define AO_compare_and_swap_acquire_read(addr,old,new_val) \
961                                 AO_compare_and_swap_acquire(addr,old,new_val)
962 # define AO_HAVE_compare_and_swap_acquire_read
963 #endif
964
965 #ifdef AO_NO_DD_ORDERING
966 # if defined(AO_HAVE_compare_and_swap_acquire_read)
967 #   define AO_compare_and_swap_dd_acquire_read(addr,old,new_val) \
968                         AO_compare_and_swap_acquire_read(addr,old,new_val)
969 #   define AO_HAVE_compare_and_swap_dd_acquire_read
970 # endif
971 #else
972 # if defined(AO_HAVE_compare_and_swap)
973 #   define AO_compare_and_swap_dd_acquire_read(addr,old,new_val) \
974                                 AO_compare_and_swap(addr,old,new_val)
975 #   define AO_HAVE_compare_and_swap_dd_acquire_read
976 # endif
977 #endif /* !AO_NO_DD_ORDERING */
978
979 #include "generalize-small.h"
980
981 /* Compare_double_and_swap_double */
982 #if defined(AO_HAVE_compare_double_and_swap_double) \
983     && defined(AO_HAVE_nop_full) \
984     && !defined(AO_HAVE_compare_double_and_swap_double_acquire)
985   AO_INLINE int
986   AO_compare_double_and_swap_double_acquire(volatile AO_double_t *addr,
987                                             AO_t o1, AO_t o2,
988                                             AO_t n1, AO_t n2)
989   {
990     int result = AO_compare_double_and_swap_double(addr, o1, o2, n1, n2);
991     AO_nop_full();
992     return result;
993   }
994 # define AO_HAVE_compare_double_and_swap_double_acquire
995 #endif
996 #if defined(AO_HAVE_compare_double_and_swap_double) \
997     && defined(AO_HAVE_nop_full) \
998     && !defined(AO_HAVE_compare_double_and_swap_double_release)
999 # define AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2) \
1000       (AO_nop_full(), AO_compare_double_and_swap_double(addr,o1,o2,n1,n2))
1001 # define AO_HAVE_compare_double_and_swap_double_release
1002 #endif
1003 #if defined(AO_HAVE_compare_double_and_swap_double_full)
1004 # if !defined(AO_HAVE_compare_double_and_swap_double_release)
1005 #   define AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2) \
1006                 AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2)
1007 #   define AO_HAVE_compare_double_and_swap_double_release
1008 # endif
1009 # if !defined(AO_HAVE_compare_double_and_swap_double_acquire)
1010 #   define AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2) \
1011                 AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2)
1012 #   define AO_HAVE_compare_double_and_swap_double_acquire
1013 # endif
1014 # if !defined(AO_HAVE_compare_double_and_swap_double_write)
1015 #   define AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2) \
1016                 AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2)
1017 #   define AO_HAVE_compare_double_and_swap_double_write
1018 # endif
1019 # if !defined(AO_HAVE_compare_double_and_swap_double_read)
1020 #   define AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2) \
1021                 AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2)
1022 #   define AO_HAVE_compare_double_and_swap_double_read
1023 # endif
1024 #endif /* AO_HAVE_compare_double_and_swap_double_full */
1025
1026 #if !defined(AO_HAVE_compare_double_and_swap_double) \
1027     && defined(AO_HAVE_compare_double_and_swap_double_release)
1028 # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \
1029                 AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2)
1030 # define AO_HAVE_compare_double_and_swap_double
1031 #endif
1032 #if !defined(AO_HAVE_compare_double_and_swap_double) \
1033     && defined(AO_HAVE_compare_double_and_swap_double_acquire)
1034 # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \
1035                 AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2)
1036 # define AO_HAVE_compare_double_and_swap_double
1037 #endif
1038 #if !defined(AO_HAVE_compare_double_and_swap_double) \
1039     && defined(AO_HAVE_compare_double_and_swap_double_write)
1040 # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \
1041                 AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2)
1042 # define AO_HAVE_compare_double_and_swap_double
1043 #endif
1044 #if !defined(AO_HAVE_compare_double_and_swap_double) \
1045     && defined(AO_HAVE_compare_double_and_swap_double_read)
1046 # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \
1047                 AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2)
1048 # define AO_HAVE_compare_double_and_swap_double
1049 #endif
1050
1051 #if defined(AO_HAVE_compare_double_and_swap_double_acquire) \
1052     && defined(AO_HAVE_nop_full) \
1053     && !defined(AO_HAVE_compare_double_and_swap_double_full)
1054 # define AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2) \
1055                 (AO_nop_full(), \
1056                  AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2))
1057 # define AO_HAVE_compare_double_and_swap_double_full
1058 #endif
1059
1060 #if !defined(AO_HAVE_compare_double_and_swap_double_release_write) \
1061     && defined(AO_HAVE_compare_double_and_swap_double_write)
1062 # define AO_compare_double_and_swap_double_release_write(addr,o1,o2,n1,n2) \
1063                 AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2)
1064 # define AO_HAVE_compare_double_and_swap_double_release_write
1065 #endif
1066 #if !defined(AO_HAVE_compare_double_and_swap_double_release_write) \
1067     && defined(AO_HAVE_compare_double_and_swap_double_release)
1068 # define AO_compare_double_and_swap_double_release_write(addr,o1,o2,n1,n2) \
1069                 AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2)
1070 # define AO_HAVE_compare_double_and_swap_double_release_write
1071 #endif
1072 #if !defined(AO_HAVE_compare_double_and_swap_double_acquire_read) \
1073     && defined(AO_HAVE_compare_double_and_swap_double_read)
1074 # define AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2) \
1075                 AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2)
1076 # define AO_HAVE_compare_double_and_swap_double_acquire_read
1077 #endif
1078 #if !defined(AO_HAVE_compare_double_and_swap_double_acquire_read) \
1079     && defined(AO_HAVE_compare_double_and_swap_double_acquire)
1080 # define AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2) \
1081                 AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2)
1082 # define AO_HAVE_compare_double_and_swap_double_acquire_read
1083 #endif
1084
1085 #ifdef AO_NO_DD_ORDERING
1086 # if defined(AO_HAVE_compare_double_and_swap_double_acquire_read)
1087 #   define AO_compare_double_and_swap_double_dd_acquire_read(addr,o1,o2,n1,n2) \
1088              AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2)
1089 #   define AO_HAVE_compare_double_and_swap_double_dd_acquire_read
1090 # endif
1091 #else
1092 # if defined(AO_HAVE_compare_double_and_swap_double)
1093 #   define AO_compare_double_and_swap_double_dd_acquire_read(addr,o1,o2,n1,n2) \
1094                         AO_compare_double_and_swap_double(addr,o1,o2,n1,n2)
1095 #   define AO_HAVE_compare_double_and_swap_double_dd_acquire_read
1096 # endif
1097 #endif /* !AO_NO_DD_ORDERING */
1098
1099 /* Compare_and_swap_double */
1100 #if defined(AO_HAVE_compare_and_swap_double) && defined(AO_HAVE_nop_full) \
1101     && !defined(AO_HAVE_compare_and_swap_double_acquire)
1102   AO_INLINE int
1103   AO_compare_and_swap_double_acquire(volatile AO_double_t *addr,
1104                                             AO_t o1,
1105                                             AO_t n1, AO_t n2)
1106   {
1107     int result = AO_compare_and_swap_double(addr, o1, n1, n2);
1108     AO_nop_full();
1109     return result;
1110   }
1111 # define AO_HAVE_compare_and_swap_double_acquire
1112 #endif
1113 #if defined(AO_HAVE_compare_and_swap_double) \
1114     && defined(AO_HAVE_nop_full) \
1115     && !defined(AO_HAVE_compare_and_swap_double_release)
1116 # define AO_compare_and_swap_double_release(addr,o1,n1,n2) \
1117                 (AO_nop_full(), AO_compare_and_swap_double(addr,o1,n1,n2))
1118 # define AO_HAVE_compare_and_swap_double_release
1119 #endif
1120 #if defined(AO_HAVE_compare_and_swap_double_full)
1121 # if !defined(AO_HAVE_compare_and_swap_double_release)
1122 #   define AO_compare_and_swap_double_release(addr,o1,n1,n2) \
1123                                 AO_compare_and_swap_double_full(addr,o1,n1,n2)
1124 #   define AO_HAVE_compare_and_swap_double_release
1125 # endif
1126 # if !defined(AO_HAVE_compare_and_swap_double_acquire)
1127 #   define AO_compare_and_swap_double_acquire(addr,o1,n1,n2) \
1128                                 AO_compare_and_swap_double_full(addr,o1,n1,n2)
1129 #   define AO_HAVE_compare_and_swap_double_acquire
1130 # endif
1131 # if !defined(AO_HAVE_compare_and_swap_double_write)
1132 #   define AO_compare_and_swap_double_write(addr,o1,n1,n2) \
1133                                 AO_compare_and_swap_double_full(addr,o1,n1,n2)
1134 #   define AO_HAVE_compare_and_swap_double_write
1135 # endif
1136 # if !defined(AO_HAVE_compare_and_swap_double_read)
1137 #   define AO_compare_and_swap_double_read(addr,o1,n1,n2) \
1138                                 AO_compare_and_swap_double_full(addr,o1,n1,n2)
1139 #   define AO_HAVE_compare_and_swap_double_read
1140 # endif
1141 #endif /* AO_HAVE_compare_and_swap_double_full */
1142
1143 #if !defined(AO_HAVE_compare_and_swap_double) \
1144     && defined(AO_HAVE_compare_and_swap_double_release)
1145 # define AO_compare_and_swap_double(addr,o1,n1,n2) \
1146                         AO_compare_and_swap_double_release(addr,o1,n1,n2)
1147 # define AO_HAVE_compare_and_swap_double
1148 #endif
1149 #if !defined(AO_HAVE_compare_and_swap_double) \
1150     && defined(AO_HAVE_compare_and_swap_double_acquire)
1151 # define AO_compare_and_swap_double(addr,o1,n1,n2) \
1152                         AO_compare_and_swap_double_acquire(addr,o1,n1,n2)
1153 # define AO_HAVE_compare_and_swap_double
1154 #endif
1155 #if !defined(AO_HAVE_compare_and_swap_double) \
1156     && defined(AO_HAVE_compare_and_swap_double_write)
1157 # define AO_compare_and_swap_double(addr,o1,n1,n2) \
1158                         AO_compare_and_swap_double_write(addr,o1,n1,n2)
1159 # define AO_HAVE_compare_and_swap_double
1160 #endif
1161 #if !defined(AO_HAVE_compare_and_swap_double) \
1162     && defined(AO_HAVE_compare_and_swap_double_read)
1163 # define AO_compare_and_swap_double(addr,o1,n1,n2) \
1164                         AO_compare_and_swap_double_read(addr,o1,n1,n2)
1165 # define AO_HAVE_compare_and_swap_double
1166 #endif
1167
1168 #if defined(AO_HAVE_compare_and_swap_double_acquire) \
1169     && defined(AO_HAVE_nop_full) \
1170     && !defined(AO_HAVE_compare_and_swap_double_full)
1171 # define AO_compare_and_swap_double_full(addr,o1,n1,n2) \
1172         (AO_nop_full(), AO_compare_and_swap_double_acquire(addr,o1,n1,n2))
1173 # define AO_HAVE_compare_and_swap_double_full
1174 #endif
1175
1176 #if !defined(AO_HAVE_compare_and_swap_double_release_write) \
1177     && defined(AO_HAVE_compare_and_swap_double_write)
1178 # define AO_compare_and_swap_double_release_write(addr,o1,n1,n2) \
1179                         AO_compare_and_swap_double_write(addr,o1,n1,n2)
1180 # define AO_HAVE_compare_and_swap_double_release_write
1181 #endif
1182 #if !defined(AO_HAVE_compare_and_swap_double_release_write) \
1183     && defined(AO_HAVE_compare_and_swap_double_release)
1184 # define AO_compare_and_swap_double_release_write(addr,o1,n1,n2) \
1185                         AO_compare_and_swap_double_release(addr,o1,n1,n2)
1186 # define AO_HAVE_compare_and_swap_double_release_write
1187 #endif
1188 #if !defined(AO_HAVE_compare_and_swap_double_acquire_read) \
1189     && defined(AO_HAVE_compare_and_swap_double_read)
1190 # define AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2) \
1191                         AO_compare_and_swap_double_read(addr,o1,n1,n2)
1192 # define AO_HAVE_compare_and_swap_double_acquire_read
1193 #endif
1194 #if !defined(AO_HAVE_compare_and_swap_double_acquire_read) \
1195     && defined(AO_HAVE_compare_and_swap_double_acquire)
1196 # define AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2) \
1197                         AO_compare_and_swap_double_acquire(addr,o1,n1,n2)
1198 # define AO_HAVE_compare_and_swap_double_acquire_read
1199 #endif
1200
1201 #ifdef AO_NO_DD_ORDERING
1202 # if defined(AO_HAVE_compare_and_swap_double_acquire_read)
1203 #   define AO_compare_and_swap_double_dd_acquire_read(addr,o1,n1,n2) \
1204                         AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2)
1205 #   define AO_HAVE_compare_and_swap_double_dd_acquire_read
1206 # endif
1207 #else
1208 # if defined(AO_HAVE_compare_and_swap_double)
1209 #   define AO_compare_and_swap_double_dd_acquire_read(addr,o1,n1,n2) \
1210                         AO_compare_and_swap_double(addr,o1,n1,n2)
1211 #   define AO_HAVE_compare_and_swap_double_dd_acquire_read
1212 # endif
1213 #endif
1214
1215 /* NEC LE-IT: Convenience functions for AO_double compare and swap which */
1216 /* types and reads easier in code                                        */
1217 #if defined(AO_HAVE_compare_double_and_swap_double_release) \
1218     && !defined(AO_HAVE_double_compare_and_swap_release)
1219   AO_INLINE int
1220   AO_double_compare_and_swap_release(volatile AO_double_t *addr,
1221                                      AO_double_t old_val, AO_double_t new_val)
1222   {
1223     return AO_compare_double_and_swap_double_release(addr,
1224                                           old_val.AO_val1, old_val.AO_val2,
1225                                           new_val.AO_val1, new_val.AO_val2);
1226   }
1227 # define AO_HAVE_double_compare_and_swap_release
1228 #endif
1229
1230 #if defined(AO_HAVE_compare_double_and_swap_double_acquire) \
1231     && !defined(AO_HAVE_double_compare_and_swap_acquire)
1232   AO_INLINE int
1233   AO_double_compare_and_swap_acquire(volatile AO_double_t *addr,
1234                                      AO_double_t old_val, AO_double_t new_val)
1235   {
1236     return AO_compare_double_and_swap_double_acquire(addr,
1237                                           old_val.AO_val1, old_val.AO_val2,
1238                                           new_val.AO_val1, new_val.AO_val2);
1239   }
1240 # define AO_HAVE_double_compare_and_swap_acquire
1241 #endif
1242
1243 #if defined(AO_HAVE_compare_double_and_swap_double_full) \
1244     && !defined(AO_HAVE_double_compare_and_swap_full)
1245   AO_INLINE int
1246   AO_double_compare_and_swap_full(volatile AO_double_t *addr,
1247                                   AO_double_t old_val, AO_double_t new_val)
1248   {
1249     return AO_compare_double_and_swap_double_full(addr,
1250                                           old_val.AO_val1, old_val.AO_val2,
1251                                           new_val.AO_val1, new_val.AO_val2);
1252   }
1253 # define AO_HAVE_double_compare_and_swap_full
1254 #endif