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