Line data Source code
1 1 : /*
2 : * Copyright (c) 2025 IAR Systems AB
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_
8 : #define ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_
9 :
10 : /**
11 : * @file
12 : * @brief ICCARM toolchain abstraction
13 : *
14 : * Macros to abstract compiler capabilities for ICCARM toolchain.
15 : */
16 :
17 : /* ICCARM supports its own #pragma diag_{warning,default,error,warning}. */
18 : /* #define TOOLCHAIN_HAS_PRAGMA_DIAG 0 */
19 :
20 0 : #define TOOLCHAIN_HAS_C_GENERIC 1
21 :
22 0 : #define TOOLCHAIN_HAS_C_AUTO_TYPE 1
23 :
24 : /* #define TOOLCHAIN_HAS_ZLA 1 */
25 :
26 : /*
27 : * IAR do not define __BYTE_ORDER__, so it must be manually
28 : * detected and defined using arch-specific definitions.
29 : */
30 :
31 : #ifndef _LINKER
32 :
33 : #ifndef __ORDER_BIG_ENDIAN__
34 : #define __ORDER_BIG_ENDIAN__ (1)
35 : #endif /* __ORDER_BIG_ENDIAN__ */
36 :
37 : #ifndef __ORDER_LITTLE_ENDIAN__
38 : #define __ORDER_LITTLE_ENDIAN__ (2)
39 : #endif /* __ORDER_LITTLE_ENDIAN__ */
40 :
41 : #ifndef __ORDER_PDP_ENDIAN__
42 : #define __ORDER_PDP_ENDIAN__ (3)
43 : #endif /* __ORDER_PDP_ENDIAN__ */
44 :
45 : #ifndef __BYTE_ORDER__
46 :
47 : #if __LITTLE_ENDIAN__ == 1
48 : #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
49 : #else
50 : #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
51 : #endif /* __LITTLE_ENDIAN__ == 1 */
52 :
53 : #endif /* __BYTE_ORDER__ */
54 :
55 :
56 : #if defined(__cplusplus) && (__cplusplus >= 201103L)
57 : #define BUILD_ASSERT(EXPR, MSG...) static_assert(EXPR, "" MSG)
58 : #elif defined(__ICCARM__)
59 : #define BUILD_ASSERT(EXPR, MSG...) _Static_assert(EXPR, "" MSG)
60 : #endif
61 :
62 : /* Zephyr makes use of __ATOMIC_SEQ_CST */
63 : #ifdef __STDC_NO_ATOMICS__
64 : #ifndef __ATOMIC_SEQ_CST
65 : #define __MEMORY_ORDER_SEQ_CST__ 5
66 : #endif
67 : #endif
68 : #ifndef __ATOMIC_SEQ_CST
69 : #define __ATOMIC_SEQ_CST __MEMORY_ORDER_SEQ_CST__
70 : #endif
71 :
72 : /* By default, restrict is recognized in Standard C
73 : * __restrict is always recognized
74 : */
75 : #define ZRESTRICT __restrict
76 :
77 : #include <zephyr/toolchain/common.h>
78 : #include <stdbool.h>
79 :
80 : #define ALIAS_OF(of) __attribute__((alias(#of)))
81 :
82 : #define FUNC_ALIAS(real_func, new_alias, return_type) \
83 : return_type new_alias() ALIAS_OF(real_func)
84 :
85 : #define CODE_UNREACHABLE __builtin_unreachable()
86 : #define FUNC_NORETURN __attribute__((__noreturn__))
87 :
88 : #define _NODATA_SECTION(segment) __attribute__((section(#segment)))
89 :
90 : /* Unaligned access */
91 : #define UNALIGNED_GET(p) \
92 : __extension__ ({ \
93 : struct __attribute__((__packed__)) { \
94 : __typeof__(*(p)) __v; \
95 : } *__p = (__typeof__(__p)) (p); \
96 : __p->__v; \
97 : })
98 :
99 : #define UNALIGNED_PUT(v, p) \
100 : do { \
101 : struct __attribute__((__packed__)) { \
102 : __typeof__(*p) __v; \
103 : } *__p = (__typeof__(__p)) (p); \
104 : __p->__v = (v); \
105 : } while (false)
106 :
107 :
108 : /* Double indirection to ensure section names are expanded before
109 : * stringification
110 : */
111 : #define __GENERIC_SECTION(segment) __attribute__((section(STRINGIFY(segment))))
112 : #define Z_GENERIC_SECTION(segment) __GENERIC_SECTION(segment)
113 :
114 : #define __GENERIC_DOT_SECTION(segment) \
115 : __attribute__((section("." STRINGIFY(segment))))
116 : #define Z_GENERIC_DOT_SECTION(segment) __GENERIC_DOT_SECTION(segment)
117 :
118 : #define ___in_section(a, b, c) \
119 : __attribute__((section("." Z_STRINGIFY(a) \
120 : "." Z_STRINGIFY(b) \
121 : "." Z_STRINGIFY(c))))
122 : #define __in_section(a, b, c) ___in_section(a, b, c)
123 :
124 : #define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__)
125 :
126 : #define __in_section_unique_named(seg, name) \
127 : ___in_section(seg, __FILE__, name)
128 :
129 : /* When using XIP, using '__ramfunc' places a function into RAM instead
130 : * of FLASH. Make sure '__ramfunc' is defined only when
131 : * CONFIG_ARCH_HAS_RAMFUNC_SUPPORT is defined, so that the compiler can
132 : * report an error if '__ramfunc' is used but the architecture does not
133 : * support it.
134 : */
135 : #if !defined(CONFIG_XIP)
136 : #define __ramfunc
137 : #elif defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
138 : /* Use this instead of the IAR keyword __ramfunc to make sure it
139 : * ends up in the correct section.
140 : */
141 : #define __ramfunc __attribute__((noinline, section(".ramfunc")))
142 : #endif /* !CONFIG_XIP */
143 :
144 : #ifndef __fallthrough
145 : /* TG-WG: ICCARM does not support __fallthrough */
146 : #define __fallthrough [[fallthrough]]
147 : #endif
148 :
149 : #ifndef __packed
150 : #define __packed __attribute__((__packed__))
151 : #endif
152 :
153 : #ifndef __aligned
154 : #define __aligned(x) __attribute__((__aligned__(x)))
155 : #endif
156 :
157 : #ifndef __noinline
158 : #define __noinline __attribute__((noinline))
159 : #endif
160 :
161 : #if defined(__cplusplus)
162 : #define __alignof(x) alignof(x)
163 : #else
164 : #define __alignof(x) _Alignof(x)
165 : #endif
166 :
167 : #define __may_alias __attribute__((__may_alias__))
168 :
169 : #ifndef __printf_like
170 : /*
171 : * The Zephyr stdint convention enforces int32_t = int, int64_t = long long,
172 : * and intptr_t = long so that short string format length modifiers can be
173 : * used universally across ILP32 and LP64 architectures. Without that it
174 : * is possible for ILP32 toolchains to have int32_t = long and intptr_t = int
175 : * clashing with the Zephyr convention and generating pointless warnings
176 : * as they're still the same size. Inhibit the format argument type
177 : * validation in that case and let the other configs do it.
178 : */
179 : #define __printf_like(f, a)
180 : #endif
181 :
182 : #define __used __attribute__((__used__))
183 : #define __unused __attribute__((__unused__))
184 : #define __maybe_unused __attribute__((__unused__))
185 :
186 : #ifndef __deprecated
187 : #define __deprecated __attribute__((deprecated))
188 : #endif
189 :
190 : #ifndef __deprecated_version
191 : #define __deprecated_version(version) \
192 : __attribute__((deprecated("planned removal in v" #version)))
193 : #endif
194 :
195 : #define FUNC_NO_STACK_PROTECTOR _Pragma("no_stack_protect")
196 :
197 : #ifndef __attribute_const__
198 : #if __VER__ > 0x09000000
199 : #define __attribute_const__ __attribute__((const))
200 : #else
201 : #define __attribute_const__
202 : #endif
203 : #endif
204 :
205 : #ifndef __must_check
206 : /* #warning "The attribute __warn_unused_result is not supported in ICCARM". */
207 : #define __must_check
208 : /* #define __must_check __attribute__((warn_unused_result)) */
209 : #endif
210 :
211 : #define __PRAGMA(...) _Pragma(#__VA_ARGS__)
212 : #define ARG_UNUSED(x) (void)(x)
213 :
214 : #define likely(x) (__builtin_expect((bool)!!(x), true) != 0L)
215 : #define unlikely(x) (__builtin_expect((bool)!!(x), false) != 0L)
216 : #define POPCOUNT(x) __builtin_popcount(x)
217 :
218 : #ifndef __no_optimization
219 : #define __no_optimization __PRAGMA(optimize = none)
220 : #endif
221 :
222 : #ifndef __attribute_nonnull
223 : #define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
224 : #endif
225 :
226 : /* __weak is an ICCARM built-in, but it doesn't work in all positions */
227 : /* the Zephyr uses it so we replace it with an attribute((weak)) */
228 : #define __weak __attribute__((__weak__))
229 :
230 : /* Builtins */
231 :
232 : #include <intrinsics.h>
233 :
234 : /*
235 : * Be *very* careful with these. You cannot filter out __DEPRECATED_MACRO with
236 : * -wno-deprecated, which has implications for -Werror.
237 : */
238 :
239 :
240 : /*
241 : * Expands to nothing and generates a warning. Used like
242 : *
243 : * #define FOO __WARN("Please use BAR instead") ...
244 : *
245 : * The warning points to the location where the macro is expanded.
246 : */
247 : #define __WARN(s) __PRAGMA(message = #s)
248 : #define __WARN1(s) __PRAGMA(message = #s)
249 :
250 : /* Generic message */
251 : #ifndef CONFIG_DEPRECATION_TEST
252 : #define __DEPRECATED_MACRO __WARN("Macro is deprecated")
253 : #else
254 : #define __DEPRECATED_MACRO
255 : #endif
256 :
257 :
258 :
259 : /* These macros allow having ARM asm functions callable from thumb */
260 :
261 : #if defined(_ASMLANGUAGE)
262 :
263 : #if defined(CONFIG_ASSEMBLER_ISA_THUMB2)
264 : #define FUNC_CODE() .code 32
265 : #define FUNC_INSTR(a)
266 : /* '.syntax unified' is a gcc-ism used in thumb-2 asm files */
267 : #define _ASM_FILE_PROLOGUE .text; .syntax unified; .thumb
268 : #else
269 : #define FUNC_CODE()
270 : #define FUNC_INSTR(a)
271 : #define _ASM_FILE_PROLOGUE .text; .code 32
272 : #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */
273 :
274 : /*
275 : * These macros are used to declare assembly language symbols that need
276 : * to be typed properly(func or data) to be visible to the OMF tool.
277 : * So that the build tool could mark them as an entry point to be linked
278 : * correctly. This is an elfism. Use #if 0 for a.out.
279 : */
280 :
281 : /* This is not implemented yet for IAR */
282 : #define GTEXT(sym)
283 : #define GDATA(sym)
284 : #define WTEXT(sym)
285 : #define WDATA(sym)
286 :
287 : #define SECTION_VAR(sect, sym)
288 : #define SECTION_FUNC(sect, sym)
289 : #define SECTION_SUBSEC_FUNC(sect, subsec, sym)
290 :
291 : #endif /* _ASMLANGUAGE */
292 :
293 :
294 : /*
295 : * These macros generate absolute symbols for IAR
296 : */
297 :
298 : /* create an extern reference to the absolute symbol */
299 :
300 : #define GEN_OFFSET_EXTERN(name) extern const char name[]
301 :
302 : #define GEN_ABS_SYM_BEGIN(name) \
303 : EXTERN_C void name(void); \
304 : void name(void) \
305 : {
306 :
307 : #define GEN_ABS_SYM_END }
308 :
309 : /*
310 : * Note that GEN_ABSOLUTE_SYM(), depending on the architecture
311 : * and toolchain, may restrict the range of values permitted
312 : * for assignment to the named symbol.
313 : */
314 : #define GEN_ABSOLUTE_SYM(name, value) \
315 : __PRAGMA(public_equ = #name, (unsigned int)value)
316 :
317 : /*
318 : * GEN_ABSOLUTE_SYM_KCONFIG() is outputted by the build system
319 : * to generate named symbol/value pairs for kconfigs.
320 : */
321 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
322 : __PRAGMA(public_equ = #name, (unsigned int)value)
323 :
324 : #define compiler_barrier() do { \
325 : __asm volatile("" ::: "memory"); \
326 : } while (false)
327 :
328 : /**
329 : * @brief Calculate power of two ceiling for some nonzero value
330 : *
331 : * @param x Nonzero unsigned long value
332 : * @return X rounded up to the next power of two
333 : */
334 : #define Z_POW2_CEIL(x) \
335 : ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) - 1))))
336 :
337 : /**
338 : * @brief Check whether or not a value is a power of 2
339 : *
340 : * @param x The value to check
341 : * @return true if x is a power of 2, false otherwise
342 : */
343 : #define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0))
344 :
345 : #ifndef __INT8_C
346 : #define __INT8_C(x) x
347 : #endif
348 :
349 : #ifndef INT8_C
350 : #define INT8_C(x) __INT8_C(x)
351 : #endif
352 :
353 : #ifndef __UINT8_C
354 : #define __UINT8_C(x) x ## U
355 : #endif
356 :
357 : #ifndef UINT8_C
358 : #define UINT8_C(x) __UINT8_C(x)
359 : #endif
360 :
361 : #ifndef __INT16_C
362 : #define __INT16_C(x) x
363 : #endif
364 :
365 : #ifndef INT16_C
366 : #define INT16_C(x) __INT16_C(x)
367 : #endif
368 :
369 : #ifndef __UINT16_C
370 : #define __UINT16_C(x) x ## U
371 : #endif
372 :
373 : #ifndef UINT16_C
374 : #define UINT16_C(x) __UINT16_C(x)
375 : #endif
376 :
377 : #ifndef __INT32_C
378 : #define __INT32_C(x) x
379 : #endif
380 :
381 : #ifndef INT32_C
382 : #define INT32_C(x) __INT32_C(x)
383 : #endif
384 :
385 : #ifndef __UINT32_C
386 : #define __UINT32_C(x) x ## U
387 : #endif
388 :
389 : #ifndef UINT32_C
390 : #define UINT32_C(x) __UINT32_C(x)
391 : #endif
392 :
393 : #ifndef __INT64_C
394 : #define __INT64_C(x) x ## LL
395 : #endif
396 :
397 : #ifndef INT64_C
398 : #define INT64_C(x) __INT64_C(x)
399 : #endif
400 :
401 : #ifndef __UINT64_C
402 : #define __UINT64_C(x) x ## ULL
403 : #endif
404 :
405 : #ifndef UINT64_C
406 : #define UINT64_C(x) __UINT64_C(x)
407 : #endif
408 :
409 : /* Convenience macros */
410 : #undef _GLUE_B
411 : #undef _GLUE
412 : #define _GLUE_B(x, y) x##y
413 : #define _GLUE(x, y) _GLUE_B(x, y)
414 :
415 : #ifndef INTMAX_C
416 : #define INTMAX_C(x) _GLUE(x, __INTMAX_C_SUFFIX__)
417 : #endif
418 :
419 : #ifndef UINTMAX_C
420 : #define UINTMAX_C(x) _GLUE(x, __UINTMAX_C_SUFFIX__)
421 : #endif
422 :
423 : #endif /* !_LINKER */
424 : #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_ */
|