x86asm: Add lzcnt/tzcnt support
[tinycc.git] / include / stdatomic.h
bloba8372eeb1ef6f69531b8a2a0b4ba652139f9be5c
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}
82 #define atomic_flag_test_and_set_explicit(object, order) \
83 __atomic_test_and_set((void *)(&((object)->value)), order)
84 #define atomic_flag_test_and_set(object) \
85 atomic_flag_test_and_set_explicit(object, __ATOMIC_SEQ_CST)
87 #define atomic_flag_clear_explicit(object, order) \
88 __atomic_clear((bool *)(&((object)->value)), order)
89 #define atomic_flag_clear(object) \
90 atomic_flag_clear_explicit(object, __ATOMIC_SEQ_CST)
92 /* Generic routines */
93 #define atomic_init(object, desired) \
94 atomic_store_explicit(object, desired, __ATOMIC_RELAXED)
96 #define atomic_store_explicit(object, desired, order) \
97 ({ __typeof__ (object) ptr = (object); \
98 __typeof__ (*ptr) tmp = (desired); \
99 __atomic_store (ptr, &tmp, (order)); \
101 #define atomic_store(object, desired) \
102 atomic_store_explicit (object, desired, __ATOMIC_SEQ_CST)
104 #define atomic_load_explicit(object, order) \
105 ({ __typeof__ (object) ptr = (object); \
106 __typeof__ (*ptr) tmp; \
107 __atomic_load (ptr, &tmp, (order)); \
108 tmp; \
110 #define atomic_load(object) atomic_load_explicit (object, __ATOMIC_SEQ_CST)
112 #define atomic_exchange_explicit(object, desired, order) \
113 ({ __typeof__ (object) ptr = (object); \
114 __typeof__ (*ptr) val = (desired); \
115 __typeof__ (*ptr) tmp; \
116 __atomic_exchange (ptr, &val, &tmp, (order)); \
117 tmp; \
119 #define atomic_exchange(object, desired) \
120 atomic_exchange_explicit (object, desired, __ATOMIC_SEQ_CST)
122 #define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
123 ({ __typeof__ (object) ptr = (object); \
124 __typeof__ (*ptr) tmp = desired; \
125 __atomic_compare_exchange(ptr, expected, &tmp, 0, success, failure); \
127 #define atomic_compare_exchange_strong(object, expected, desired) \
128 atomic_compare_exchange_strong_explicit (object, expected, desired, \
129 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
131 #define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
132 ({ __typeof__ (object) ptr = (object); \
133 __typeof__ (*ptr) tmp = desired; \
134 __atomic_compare_exchange(ptr, expected, &tmp, 1, success, failure); \
136 #define atomic_compare_exchange_weak(object, expected, desired) \
137 atomic_compare_exchange_weak_explicit (PTR, VAL, DES, \
138 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
140 #define atomic_fetch_add(object, operand) \
141 __atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
142 #define atomic_fetch_add_explicit __atomic_fetch_add
144 #define atomic_fetch_sub(object, operand) \
145 __atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
146 #define atomic_fetch_sub_explicit __atomic_fetch_sub
148 #define atomic_fetch_or(object, operand) \
149 __atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
150 #define atomic_fetch_or_explicit __atomic_fetch_or
152 #define atomic_fetch_xor(object, operand) \
153 __atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
154 #define atomic_fetch_xor_explicit __atomic_fetch_xor
156 #define atomic_fetch_and(object, operand) \
157 __atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
158 #define atomic_fetch_and_explicit __atomic_fetch_and
160 extern void atomic_thread_fence (memory_order);
161 extern void __atomic_thread_fence (memory_order);
162 #define atomic_thread_fence(order) __atomic_thread_fence (order)
163 extern void atomic_signal_fence (memory_order);
164 extern void __atomic_signal_fence (memory_order);
165 #define atomic_signal_fence(order) __atomic_signal_fence (order)
166 extern bool __atomic_is_lock_free(size_t size, void *ptr);
167 #define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ))
169 extern bool __atomic_test_and_set (void *, memory_order);
170 extern void __atomic_clear (bool *, memory_order);
172 #endif /* _STDATOMIC_H */