1 //
2 // Copyright (c) 2008-2013 Travis Geiselbrecht
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7 //
8 // Copyright 2016 The Fuchsia Authors. All rights reserved.
9 // Use of this source code is governed by a BSD-style license that can be
10 // found in the LICENSE file.
11 
12 #pragma once
13 
14 #ifndef __ASSEMBLY__
15 
16 #if __GNUC__ || __clang__
17 #define likely(x)       __builtin_expect(!!(x), 1)
18 #define unlikely(x)     __builtin_expect(!!(x), 0)
19 #define __UNUSED __attribute__((__unused__))
20 #define __USED __attribute__((__used__))
21 #define __PACKED __attribute__((packed))
22 #define __ALIGNED(x) __attribute__((aligned(x)))
23 #define __PRINTFLIKE(__fmt,__varargs) __attribute__((__format__ (__printf__, __fmt, __varargs)))
24 #define __SCANFLIKE(__fmt,__varargs) __attribute__((__format__ (__scanf__, __fmt, __varargs)))
25 #define __SECTION(x) __USED __attribute((section(x)))
26 #define __PURE __attribute((pure))
27 #define __CONST __attribute((const))
28 #define __NO_RETURN __attribute__((noreturn))
29 #define __MALLOC __attribute__((malloc))
30 #define __WEAK __attribute__((weak))
31 #define __GNU_INLINE __attribute__((gnu_inline))
32 #define __GET_CALLER(x) __builtin_return_address(0)
33 #define __GET_FRAME(x) __builtin_frame_address(0)
34 #define __NAKED __attribute__((naked))
35 #define __ISCONSTANT(x) __builtin_constant_p(x)
36 #define __NO_INLINE __attribute((noinline))
37 #define __SRAM __NO_INLINE __SECTION(".sram.text")
38 #define __CONSTRUCTOR __attribute__((constructor))
39 #define __DESTRUCTOR __attribute__((destructor))
40 #define __RESTRICT __restrict
41 
42 #define INCBIN(symname, sizename, filename, section)                    \
43     __asm__ (".section " section "; .balign 4; .globl "#symname);       \
44     __asm__ (""#symname ":\n.incbin \"" filename "\"");                 \
45     __asm__ (".balign 1; "#symname "_end:");                            \
46     __asm__ (".balign 4; .globl "#sizename);                            \
47     __asm__ (""#sizename ": .long "#symname "_end - "#symname);         \
48     __asm__ (".previous");                                              \
49     extern unsigned char symname[];                                     \
50     extern unsigned int sizename
51 
52 #define INCFILE(symname, sizename, filename) INCBIN(symname, sizename, filename, ".rodata")
53 
54 /* look for gcc 3.0 and above */
55 #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 0)
56 #define __ALWAYS_INLINE __attribute__((always_inline))
57 #else
58 #define __ALWAYS_INLINE
59 #endif
60 
61 /* look for gcc 3.1 and above */
62 #if !defined(__DEPRECATED) // seems to be built in in some versions of the compiler
63 #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
64 #define __DEPRECATED __attribute((deprecated))
65 #else
66 #define __DEPRECATED
67 #endif
68 #endif
69 
70 /* look for gcc 3.3 and above */
71 #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
72 /* the may_alias attribute was introduced in gcc 3.3; before that, there
73  * was no way to specify aliasiang rules on a type-by-type basis */
74 #define __MAY_ALIAS __attribute__((may_alias))
75 
76 /* nonnull was added in gcc 3.3 as well */
77 #define __NONNULL(x) __attribute((nonnull x))
78 #else
79 #define __MAY_ALIAS
80 #define __NONNULL(x)
81 #endif
82 
83 /* look for gcc 3.4 and above */
84 #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
85 #define __WARN_UNUSED_RESULT __attribute((warn_unused_result))
86 #else
87 #define __WARN_UNUSED_RESULT
88 #endif
89 
90 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
91 #define __EXTERNALLY_VISIBLE __attribute__((externally_visible))
92 #else
93 #define __EXTERNALLY_VISIBLE
94 #endif
95 
96 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
97 #define __UNREACHABLE __builtin_unreachable()
98 #else
99 #define __UNREACHABLE
100 #endif
101 
102 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
103 #ifdef __cplusplus
104 #define STATIC_ASSERT(e) static_assert(e, #e)
105 #else
106 #define STATIC_ASSERT(e) _Static_assert(e, #e)
107 #endif
108 #else
109 #define STATIC_ASSERT(e) extern char (*ct_assert(void)) [sizeof(char[1 - 2*!(e)])]
110 #endif
111 
112 /* compiler fence */
113 #define CF do { __asm__ volatile("" ::: "memory"); } while(0)
114 
115 #define __WEAK_ALIAS(x) __attribute__((weak, alias(x)))
116 #define __ALIAS(x) __attribute__((alias(x)))
117 
118 #define __EXPORT __attribute__ ((visibility("default")))
119 #define __LOCAL  __attribute__ ((visibility("hidden")))
120 
121 #define __THREAD __thread
122 
123 #define __offsetof(type, field) __builtin_offsetof(type, field)
124 
125 #if defined(__cplusplus) && __cplusplus >= 201703L
126 #define __FALLTHROUGH [[fallthrough]]
127 #elif defined(__cplusplus) && defined(__clang__)
128 #define __FALLTHROUGH [[clang::fallthrough]]
129 #elif __GNUC__ >= 7
130 #define __FALLTHROUGH __attribute__((__fallthrough__))
131 #else
132 #define __FALLTHROUGH do {} while (0)
133 #endif
134 
135 #ifndef __clang__
136 #define __LEAF_FN __attribute__((__leaf__))
137 #define __OPTIMIZE(x) __attribute__((optimize(x)))
138 #define __THREAD_ANNOTATION(x)
139 #define __has_feature(x) 0
140 #else
141 #define __LEAF_FN
142 #define __OPTIMIZE(x)
143 #define __THREAD_ANNOTATION(x) __attribute__((x))
144 #endif
145 
146 // Publicly exposed thread annotation macros. These have a long and ugly name to
147 // minimize the chance of collision with consumers of Zircon's public headers.
148 #define __TA_CAPABILITY(x) __THREAD_ANNOTATION(__capability__(x))
149 #define __TA_GUARDED(x) __THREAD_ANNOTATION(__guarded_by__(x))
150 #define __TA_ACQUIRE(...) __THREAD_ANNOTATION(__acquire_capability__(__VA_ARGS__))
151 #define __TA_TRY_ACQUIRE(...) __THREAD_ANNOTATION(__try_acquire_capability__(__VA_ARGS__))
152 #define __TA_ACQUIRED_BEFORE(...) __THREAD_ANNOTATION(__acquired_before__(__VA_ARGS__))
153 #define __TA_ACQUIRED_AFTER(...) __THREAD_ANNOTATION(__acquired_after__(__VA_ARGS__))
154 #define __TA_RELEASE(...) __THREAD_ANNOTATION(__release_capability__(__VA_ARGS__))
155 #define __TA_REQUIRES(...) __THREAD_ANNOTATION(__requires_capability__(__VA_ARGS__))
156 #define __TA_EXCLUDES(...) __THREAD_ANNOTATION(__locks_excluded__(__VA_ARGS__))
157 #define __TA_RETURN_CAPABILITY(x) __THREAD_ANNOTATION(__lock_returned__(x))
158 #define __TA_SCOPED_CAPABILITY __THREAD_ANNOTATION(__scoped_lockable__)
159 #define __TA_NO_THREAD_SAFETY_ANALYSIS __THREAD_ANNOTATION(__no_thread_safety_analysis__)
160 
161 #else
162 
163 #define likely(x)       (x)
164 #define unlikely(x)     (x)
165 #define __UNUSED
166 #define __PACKED
167 #define __ALIGNED(x)
168 #define __PRINTFLIKE(__fmt,__varargs)
169 #define __SCANFLIKE(__fmt,__varargs)
170 #define __SECTION(x)
171 #define __PURE
172 #define __CONST
173 #define __NONNULL(x)
174 #define __DEPRECATED
175 #define __WARN_UNUSED_RESULT
176 #define __ALWAYS_INLINE
177 #define __MAY_ALIAS
178 #define __NO_RETURN
179 #endif
180 
181 #endif
182 
183 /* TODO: add type check */
184 #if !defined(countof)
185 #define countof(a) (sizeof(a) / sizeof((a)[0]))
186 #endif
187 
188 /* CPP header guards */
189 #ifdef __cplusplus
190 #define __BEGIN_CDECLS  extern "C" {
191 #define __END_CDECLS    }
192 #else
193 #define __BEGIN_CDECLS
194 #define __END_CDECLS
195 #endif
196