fixup! riscv: Implement large addend for global address
[tinycc.git] / include / stdatomic.h
blob2d423d1a9b5e9ab91b47bd7d44ce06f66ab143c1
1 /* This file is derived from clang's stdatomic.h */
3 /*===---- stdatomic.h - Standard header for atomic types and operations -----===
5 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 * See https://llvm.org/LICENSE.txt for license information.
7 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9 *===-----------------------------------------------------------------------===
12 #ifndef _STDATOMIC_H
13 #define _STDATOMIC_H
15 #include <stddef.h>
16 #include <stdint.h>
17 #include <stdbool.h>
19 #define __ATOMIC_RELAXED 0
20 #define __ATOMIC_CONSUME 1
21 #define __ATOMIC_ACQUIRE 2
22 #define __ATOMIC_RELEASE 3
23 #define __ATOMIC_ACQ_REL 4
24 #define __ATOMIC_SEQ_CST 5
26 /* Memory ordering */
27 typedef enum {
28 memory_order_relaxed = __ATOMIC_RELAXED,
29 memory_order_consume = __ATOMIC_CONSUME,
30 memory_order_acquire = __ATOMIC_ACQUIRE,
31 memory_order_release = __ATOMIC_RELEASE,
32 memory_order_acq_rel = __ATOMIC_ACQ_REL,
33 memory_order_seq_cst = __ATOMIC_SEQ_CST,
34 } memory_order;
36 /* Atomic typedefs */
37 typedef _Atomic(_Bool) atomic_bool;
38 typedef _Atomic(char) atomic_char;
39 typedef _Atomic(signed char) atomic_schar;
40 typedef _Atomic(unsigned char) atomic_uchar;
41 typedef _Atomic(short) atomic_short;
42 typedef _Atomic(unsigned short) atomic_ushort;
43 typedef _Atomic(int) atomic_int;
44 typedef _Atomic(unsigned int) atomic_uint;
45 typedef _Atomic(long) atomic_long;
46 typedef _Atomic(unsigned long) atomic_ulong;
47 typedef _Atomic(long long) atomic_llong;
48 typedef _Atomic(unsigned long long) atomic_ullong;
49 typedef _Atomic(uint_least16_t) atomic_char16_t;
50 typedef _Atomic(uint_least32_t) atomic_char32_t;
51 typedef _Atomic(wchar_t) atomic_wchar_t;
52 typedef _Atomic(int_least8_t) atomic_int_least8_t;
53 typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
54 typedef _Atomic(int_least16_t) atomic_int_least16_t;
55 typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
56 typedef _Atomic(int_least32_t) atomic_int_least32_t;
57 typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
58 typedef _Atomic(int_least64_t) atomic_int_least64_t;
59 typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
60 typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
61 typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
62 typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
63 typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
64 typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
65 typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
66 typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
67 typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
68 typedef _Atomic(intptr_t) atomic_intptr_t;
69 typedef _Atomic(uintptr_t) atomic_uintptr_t;
70 typedef _Atomic(size_t) atomic_size_t;
71 typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
72 typedef _Atomic(intmax_t) atomic_intmax_t;
73 typedef _Atomic(uintmax_t) atomic_uintmax_t;
75 /* Atomic flag */
76 typedef struct {
77 atomic_bool value;
78 } atomic_flag;
80 #define ATOMIC_FLAG_INIT {0}
81 #define ATOMIC_VAR_INIT(value) (value)
83 #define atomic_flag_test_and_set_explicit(object, order) \
84 __atomic_test_and_set((void *)(&((object)->value)), order)
85 #define atomic_flag_test_and_set(object) \
86 atomic_flag_test_and_set_explicit(object, __ATOMIC_SEQ_CST)
88 #define atomic_flag_clear_explicit(object, order) \
89 __atomic_clear((bool *)(&((object)->value)), order)
90 #define atomic_flag_clear(object) \
91 atomic_flag_clear_explicit(object, __ATOMIC_SEQ_CST)
93 /* Generic routines */
94 #define atomic_init(object, desired) \
95 atomic_store_explicit(object, desired, __ATOMIC_RELAXED)
97 #define atomic_store_explicit(object, desired, order) \
98 ({ __typeof__ (object) ptr = (object); \
99 __typeof__ (*ptr) tmp = (desired); \
100 __atomic_store (ptr, &tmp, (order)); \
102 #define atomic_store(object, desired) \
103 atomic_store_explicit (object, desired, __ATOMIC_SEQ_CST)
105 #define atomic_load_explicit(object, order) \
106 ({ __typeof__ (object) ptr = (object); \
107 __typeof__ (*ptr) tmp; \
108 __atomic_load (ptr, &tmp, (order)); \
109 tmp; \
111 #define atomic_load(object) atomic_load_explicit (object, __ATOMIC_SEQ_CST)
113 #define atomic_exchange_explicit(object, desired, order) \
114 ({ __typeof__ (object) ptr = (object); \
115 __typeof__ (*ptr) val = (desired); \
116 __typeof__ (*ptr) tmp; \
117 __atomic_exchange (ptr, &val, &tmp, (order)); \
118 tmp; \
120 #define atomic_exchange(object, desired) \
121 atomic_exchange_explicit (object, desired, __ATOMIC_SEQ_CST)
123 #define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
124 ({ __typeof__ (object) ptr = (object); \
125 __typeof__ (*ptr) tmp = desired; \
126 __atomic_compare_exchange(ptr, expected, &tmp, 0, success, failure); \
128 #define atomic_compare_exchange_strong(object, expected, desired) \
129 atomic_compare_exchange_strong_explicit (object, expected, desired, \
130 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
132 #define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
133 ({ __typeof__ (object) ptr = (object); \
134 __typeof__ (*ptr) tmp = desired; \
135 __atomic_compare_exchange(ptr, expected, &tmp, 1, success, failure); \
137 #define atomic_compare_exchange_weak(object, expected, desired) \
138 atomic_compare_exchange_weak_explicit (object, expected, desired, \
139 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
141 #define atomic_fetch_add(object, operand) \
142 __atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
143 #define atomic_fetch_add_explicit __atomic_fetch_add
145 #define atomic_fetch_sub(object, operand) \
146 __atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
147 #define atomic_fetch_sub_explicit __atomic_fetch_sub
149 #define atomic_fetch_or(object, operand) \
150 __atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
151 #define atomic_fetch_or_explicit __atomic_fetch_or
153 #define atomic_fetch_xor(object, operand) \
154 __atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
155 #define atomic_fetch_xor_explicit __atomic_fetch_xor
157 #define atomic_fetch_and(object, operand) \
158 __atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
159 #define atomic_fetch_and_explicit __atomic_fetch_and
161 extern void atomic_thread_fence (memory_order);
162 extern void __atomic_thread_fence (memory_order);
163 #define atomic_thread_fence(order) __atomic_thread_fence (order)
164 extern void atomic_signal_fence (memory_order);
165 extern void __atomic_signal_fence (memory_order);
166 #define atomic_signal_fence(order) __atomic_signal_fence (order)
167 extern bool __atomic_is_lock_free(size_t size, void *ptr);
168 #define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ))
170 extern bool __atomic_test_and_set (void *, memory_order);
171 extern void __atomic_clear (bool *, memory_order);
173 #endif /* _STDATOMIC_H */