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