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 : #define FUNC_NO_STACK_PROTECTOR _Pragma("no_stack_protect")
191 :
192 : #ifndef __attribute_const__
193 : #if __VER__ > 0x09000000
194 : #define __attribute_const__ __attribute__((const))
195 : #else
196 : #define __attribute_const__
197 : #endif
198 : #endif
199 :
200 : #ifndef __must_check
201 : /* #warning "The attribute __warn_unused_result is not supported in ICCARM". */
202 : #define __must_check
203 : /* #define __must_check __attribute__((warn_unused_result)) */
204 : #endif
205 :
206 : #define __PRAGMA(...) _Pragma(#__VA_ARGS__)
207 : #define ARG_UNUSED(x) (void)(x)
208 :
209 : #define likely(x) (__builtin_expect((bool)!!(x), true) != 0L)
210 : #define unlikely(x) (__builtin_expect((bool)!!(x), false) != 0L)
211 : #define POPCOUNT(x) __builtin_popcount(x)
212 :
213 : #ifndef __no_optimization
214 : #define __no_optimization __PRAGMA(optimize = none)
215 : #endif
216 :
217 : #ifndef __attribute_nonnull
218 : #define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
219 : #endif
220 :
221 : /* __weak is an ICCARM built-in, but it doesn't work in all positions */
222 : /* the Zephyr uses it so we replace it with an attribute((weak)) */
223 : #define __weak __attribute__((__weak__))
224 :
225 : /* Builtins */
226 :
227 : #include <intrinsics.h>
228 :
229 : /*
230 : * Be *very* careful with these. You cannot filter out __DEPRECATED_MACRO with
231 : * -wno-deprecated, which has implications for -Werror.
232 : */
233 :
234 :
235 : /*
236 : * Expands to nothing and generates a warning. Used like
237 : *
238 : * #define FOO __WARN("Please use BAR instead") ...
239 : *
240 : * The warning points to the location where the macro is expanded.
241 : */
242 : #define __WARN(s) __PRAGMA(message = #s)
243 : #define __WARN1(s) __PRAGMA(message = #s)
244 :
245 : /* Generic message */
246 : #ifndef CONFIG_DEPRECATION_TEST
247 : #define __DEPRECATED_MACRO __WARN("Macro is deprecated")
248 : #else
249 : #define __DEPRECATED_MACRO
250 : #endif
251 :
252 :
253 :
254 : /* These macros allow having ARM asm functions callable from thumb */
255 :
256 : #if defined(_ASMLANGUAGE)
257 :
258 : #if defined(CONFIG_ASSEMBLER_ISA_THUMB2)
259 : #define FUNC_CODE() .code 32
260 : #define FUNC_INSTR(a)
261 : /* '.syntax unified' is a gcc-ism used in thumb-2 asm files */
262 : #define _ASM_FILE_PROLOGUE .text; .syntax unified; .thumb
263 : #else
264 : #define FUNC_CODE()
265 : #define FUNC_INSTR(a)
266 : #define _ASM_FILE_PROLOGUE .text; .code 32
267 : #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */
268 :
269 : /*
270 : * These macros are used to declare assembly language symbols that need
271 : * to be typed properly(func or data) to be visible to the OMF tool.
272 : * So that the build tool could mark them as an entry point to be linked
273 : * correctly. This is an elfism. Use #if 0 for a.out.
274 : */
275 :
276 : /* This is not implemented yet for IAR */
277 : #define GTEXT(sym)
278 : #define GDATA(sym)
279 : #define WTEXT(sym)
280 : #define WDATA(sym)
281 :
282 : #define SECTION_VAR(sect, sym)
283 : #define SECTION_FUNC(sect, sym)
284 : #define SECTION_SUBSEC_FUNC(sect, subsec, sym)
285 :
286 : #endif /* _ASMLANGUAGE */
287 :
288 :
289 : /*
290 : * These macros generate absolute symbols for IAR
291 : */
292 :
293 : /* create an extern reference to the absolute symbol */
294 :
295 : #define GEN_OFFSET_EXTERN(name) extern const char name[]
296 :
297 : #define GEN_ABS_SYM_BEGIN(name) \
298 : EXTERN_C void name(void); \
299 : void name(void) \
300 : {
301 :
302 : #define GEN_ABS_SYM_END }
303 :
304 : /*
305 : * Note that GEN_ABSOLUTE_SYM(), depending on the architecture
306 : * and toolchain, may restrict the range of values permitted
307 : * for assignment to the named symbol.
308 : */
309 : #define GEN_ABSOLUTE_SYM(name, value) \
310 : __PRAGMA(public_equ = #name, (unsigned int)value)
311 :
312 : /*
313 : * GEN_ABSOLUTE_SYM_KCONFIG() is outputted by the build system
314 : * to generate named symbol/value pairs for kconfigs.
315 : */
316 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
317 : __PRAGMA(public_equ = #name, (unsigned int)value)
318 :
319 : #define compiler_barrier() do { \
320 : __asm volatile("" ::: "memory"); \
321 : } while (false)
322 :
323 : /** @brief Return larger value of two provided expressions.
324 : *
325 : * Macro ensures that expressions are evaluated only once.
326 : *
327 : * @note Macro has limited usage compared to the standard macro as it cannot be
328 : * used:
329 : * - to generate constant integer, e.g. __aligned(Z_MAX(4,5))
330 : * - static variable, e.g. array like static uint8_t array[Z_MAX(...)];
331 : */
332 : #define Z_MAX(a, b) ({ \
333 : /* random suffix to avoid naming conflict */ \
334 : __typeof__(a) _value_a_ = (a); \
335 : __typeof__(b) _value_b_ = (b); \
336 : _value_a_ > _value_b_ ? _value_a_ : _value_b_; \
337 : })
338 :
339 : /** @brief Return smaller value of two provided expressions.
340 : *
341 : * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for
342 : * macro limitations.
343 : */
344 : #define Z_MIN(a, b) ({ \
345 : /* random suffix to avoid naming conflict */ \
346 : __typeof__(a) _value_a_ = (a); \
347 : __typeof__(b) _value_b_ = (b); \
348 : _value_a_ < _value_b_ ? _value_a_ : _value_b_; \
349 : })
350 :
351 : /** @brief Return a value clamped to a given range.
352 : *
353 : * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for
354 : * macro limitations.
355 : */
356 : #define Z_CLAMP(val, low, high) ({ \
357 : /* random suffix to avoid naming conflict */ \
358 : __typeof__(val) _value_val_ = (val); \
359 : __typeof__(low) _value_low_ = (low); \
360 : __typeof__(high) _value_high_ = (high); \
361 : (_value_val_ < _value_low_) ? _value_low_ : \
362 : (_value_val_ > _value_high_) ? _value_high_ : \
363 : _value_val_; \
364 : })
365 :
366 : /**
367 : * @brief Calculate power of two ceiling for some nonzero value
368 : *
369 : * @param x Nonzero unsigned long value
370 : * @return X rounded up to the next power of two
371 : */
372 : #define Z_POW2_CEIL(x) \
373 : ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) - 1))))
374 :
375 : /**
376 : * @brief Check whether or not a value is a power of 2
377 : *
378 : * @param x The value to check
379 : * @return true if x is a power of 2, false otherwise
380 : */
381 : #define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0))
382 :
383 : #ifndef __INT8_C
384 : #define __INT8_C(x) x
385 : #endif
386 :
387 : #ifndef INT8_C
388 : #define INT8_C(x) __INT8_C(x)
389 : #endif
390 :
391 : #ifndef __UINT8_C
392 : #define __UINT8_C(x) x ## U
393 : #endif
394 :
395 : #ifndef UINT8_C
396 : #define UINT8_C(x) __UINT8_C(x)
397 : #endif
398 :
399 : #ifndef __INT16_C
400 : #define __INT16_C(x) x
401 : #endif
402 :
403 : #ifndef INT16_C
404 : #define INT16_C(x) __INT16_C(x)
405 : #endif
406 :
407 : #ifndef __UINT16_C
408 : #define __UINT16_C(x) x ## U
409 : #endif
410 :
411 : #ifndef UINT16_C
412 : #define UINT16_C(x) __UINT16_C(x)
413 : #endif
414 :
415 : #ifndef __INT32_C
416 : #define __INT32_C(x) x
417 : #endif
418 :
419 : #ifndef INT32_C
420 : #define INT32_C(x) __INT32_C(x)
421 : #endif
422 :
423 : #ifndef __UINT32_C
424 : #define __UINT32_C(x) x ## U
425 : #endif
426 :
427 : #ifndef UINT32_C
428 : #define UINT32_C(x) __UINT32_C(x)
429 : #endif
430 :
431 : #ifndef __INT64_C
432 : #define __INT64_C(x) x ## LL
433 : #endif
434 :
435 : #ifndef INT64_C
436 : #define INT64_C(x) __INT64_C(x)
437 : #endif
438 :
439 : #ifndef __UINT64_C
440 : #define __UINT64_C(x) x ## ULL
441 : #endif
442 :
443 : #ifndef UINT64_C
444 : #define UINT64_C(x) __UINT64_C(x)
445 : #endif
446 :
447 : /* Convenience macros */
448 : #undef _GLUE_B
449 : #undef _GLUE
450 : #define _GLUE_B(x, y) x##y
451 : #define _GLUE(x, y) _GLUE_B(x, y)
452 :
453 : #ifndef INTMAX_C
454 : #define INTMAX_C(x) _GLUE(x, __INTMAX_C_SUFFIX__)
455 : #endif
456 :
457 : #ifndef UINTMAX_C
458 : #define UINTMAX_C(x) _GLUE(x, __UINTMAX_C_SUFFIX__)
459 : #endif
460 :
461 : #endif /* !_LINKER */
462 : #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_ */
|