1 /* 2 * Copyright (c) 2010-2014,2017 Wind River Systems, Inc. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ 8 #define ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ 9 10 #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ 11 #error Please do not include toolchain-specific headers directly, use <zephyr/toolchain.h> instead 12 #endif 13 14 /** 15 * @file 16 * @brief GCC toolchain abstraction 17 * 18 * Macros to abstract compiler capabilities for GCC toolchain. 19 */ 20 21 #define TOOLCHAIN_GCC_VERSION \ 22 ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + __GNUC_PATCHLEVEL__) 23 24 /* GCC supports #pragma diagnostics since 4.6.0 */ 25 #if !defined(TOOLCHAIN_HAS_PRAGMA_DIAG) && (TOOLCHAIN_GCC_VERSION >= 40600) 26 #define TOOLCHAIN_HAS_PRAGMA_DIAG 1 27 #endif 28 29 #if !defined(TOOLCHAIN_HAS_C_GENERIC) && (TOOLCHAIN_GCC_VERSION >= 40900) 30 #define TOOLCHAIN_HAS_C_GENERIC 1 31 #endif 32 33 #if !defined(TOOLCHAIN_HAS_C_AUTO_TYPE) && (TOOLCHAIN_GCC_VERSION >= 40900) 34 #define TOOLCHAIN_HAS_C_AUTO_TYPE 1 35 #endif 36 37 #define TOOLCHAIN_HAS_ZLA 1 38 39 /* 40 * Older versions of GCC do not define __BYTE_ORDER__, so it must be manually 41 * detected and defined using arch-specific definitions. 42 */ 43 44 #ifndef _LINKER 45 46 #ifndef __ORDER_BIG_ENDIAN__ 47 #define __ORDER_BIG_ENDIAN__ (1) 48 #endif 49 50 #ifndef __ORDER_LITTLE_ENDIAN__ 51 #define __ORDER_LITTLE_ENDIAN__ (2) 52 #endif 53 54 #ifndef __BYTE_ORDER__ 55 #if defined(__BIG_ENDIAN__) || defined(__ARMEB__) || \ 56 defined(__THUMBEB__) || defined(__AARCH64EB__) || \ 57 defined(__MIPSEB__) || defined(__TC32EB__) 58 59 #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ 60 61 #elif defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ 62 defined(__THUMBEL__) || defined(__AARCH64EL__) || \ 63 defined(__MIPSEL__) || defined(__TC32EL__) 64 65 #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ 66 67 #else 68 #error "__BYTE_ORDER__ is not defined and cannot be automatically resolved" 69 #endif 70 #endif 71 72 73 #undef BUILD_ASSERT /* clear out common version */ 74 /* C++11 has static_assert built in */ 75 #if defined(__cplusplus) && (__cplusplus >= 201103L) 76 #define BUILD_ASSERT(EXPR, MSG...) static_assert(EXPR, "" MSG) 77 78 /* 79 * GCC 4.6 and higher have the C11 _Static_assert built in and its 80 * output is easier to understand than the common BUILD_ASSERT macros. 81 * Don't use this in C++98 mode though (which we can hit, as 82 * static_assert() is not available) 83 */ 84 #elif !defined(__cplusplus) && \ 85 (((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))) || \ 86 (__STDC_VERSION__) >= 201100) 87 #define BUILD_ASSERT(EXPR, MSG...) _Static_assert((EXPR), "" MSG) 88 #else 89 #define BUILD_ASSERT(EXPR, MSG...) 90 #endif 91 92 #ifdef __cplusplus 93 #define ZRESTRICT __restrict 94 #else 95 #define ZRESTRICT restrict 96 #endif 97 98 #include <zephyr/toolchain/common.h> 99 #include <stdbool.h> 100 101 #define ALIAS_OF(of) __attribute__((alias(#of))) 102 103 #define FUNC_ALIAS(real_func, new_alias, return_type) \ 104 return_type new_alias() ALIAS_OF(real_func) 105 106 #if TOOLCHAIN_GCC_VERSION < 40500 107 #define __builtin_unreachable() __builtin_trap() 108 #endif 109 110 #if defined(CONFIG_ARCH_POSIX) && !defined(_ASMLANGUAGE) 111 #include <zephyr/arch/posix/posix_trace.h> 112 113 /*let's not segfault if this were to happen for some reason*/ 114 #define CODE_UNREACHABLE \ 115 {\ 116 posix_print_error_and_exit("CODE_UNREACHABLE reached from %s:%d\n",\ 117 __FILE__, __LINE__);\ 118 __builtin_unreachable(); \ 119 } 120 #else 121 #define CODE_UNREACHABLE __builtin_unreachable() 122 #endif 123 #define FUNC_NORETURN __attribute__((__noreturn__)) 124 125 /* The GNU assembler for Cortex-M3 uses # for immediate values, not 126 * comments, so the @nobits# trick does not work. 127 */ 128 #if defined(CONFIG_ARM) || defined(CONFIG_ARM64) 129 #define _NODATA_SECTION(segment) __attribute__((section(#segment))) 130 #else 131 #define _NODATA_SECTION(segment) \ 132 __attribute__((section(#segment ",\"wa\",@nobits#"))) 133 #endif 134 135 /* Unaligned access */ 136 #define UNALIGNED_GET(g) \ 137 __extension__ ({ \ 138 struct __attribute__((__packed__)) { \ 139 __typeof__(*(g)) __v; \ 140 } *__g = (__typeof__(__g)) (g); \ 141 __g->__v; \ 142 }) 143 144 145 #if (__GNUC__ >= 7) && (defined(CONFIG_ARM) || defined(CONFIG_ARM64)) 146 147 /* Version of UNALIGNED_PUT() which issues a compiler_barrier() after 148 * the store. It is required to workaround an apparent optimization 149 * bug in GCC for ARM Cortex-M3 and higher targets, when multiple 150 * byte, half-word and word stores (strb, strh, str instructions), 151 * which support unaligned access, can be coalesced into store double 152 * (strd) instruction, which doesn't support unaligned access (the 153 * compilers in question do this optimization ignoring __packed__ 154 * attribute). 155 */ 156 #define UNALIGNED_PUT(v, p) \ 157 do { \ 158 struct __attribute__((__packed__)) { \ 159 __typeof__(*p) __v; \ 160 } *__p = (__typeof__(__p)) (p); \ 161 __p->__v = (v); \ 162 compiler_barrier(); \ 163 } while (false) 164 165 #else 166 167 #define UNALIGNED_PUT(v, p) \ 168 do { \ 169 struct __attribute__((__packed__)) { \ 170 __typeof__(*p) __v; \ 171 } *__p = (__typeof__(__p)) (p); \ 172 __p->__v = (v); \ 173 } while (false) 174 175 #endif 176 177 /* Double indirection to ensure section names are expanded before 178 * stringification 179 */ 180 #define __GENERIC_SECTION(segment) __attribute__((section(STRINGIFY(segment)))) 181 #define Z_GENERIC_SECTION(segment) __GENERIC_SECTION(segment) 182 183 #define __GENERIC_DOT_SECTION(segment) \ 184 __attribute__((section("." STRINGIFY(segment)))) 185 #define Z_GENERIC_DOT_SECTION(segment) __GENERIC_DOT_SECTION(segment) 186 187 #define ___in_section(a, b, c) \ 188 __attribute__((section("." Z_STRINGIFY(a) \ 189 "." Z_STRINGIFY(b) \ 190 "." Z_STRINGIFY(c)))) 191 #define __in_section(a, b, c) ___in_section(a, b, c) 192 193 #ifndef __in_section_unique 194 #define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__) 195 #endif 196 197 #ifndef __in_section_unique_named 198 #define __in_section_unique_named(seg, name) \ 199 ___in_section(seg, __FILE__, name) 200 #endif 201 202 /* When using XIP, using '__ramfunc' places a function into RAM instead 203 * of FLASH. Make sure '__ramfunc' is defined only when 204 * CONFIG_ARCH_HAS_RAMFUNC_SUPPORT is defined, so that the compiler can 205 * report an error if '__ramfunc' is used but the architecture does not 206 * support it. 207 */ 208 #if !defined(CONFIG_XIP) 209 #define __ramfunc 210 #elif defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) 211 #if defined(CONFIG_ARM) 212 #define __ramfunc __attribute__((noinline)) \ 213 __attribute__((long_call, section(".ramfunc"))) 214 #else 215 #define __ramfunc __attribute__((noinline)) \ 216 __attribute__((section(".ramfunc"))) 217 #endif 218 #endif /* !CONFIG_XIP */ 219 220 #ifndef __fallthrough 221 #if __GNUC__ >= 7 222 #define __fallthrough __attribute__((fallthrough)) 223 #else 224 #define __fallthrough 225 #endif /* __GNUC__ >= 7 */ 226 #endif 227 228 #ifndef __packed 229 #define __packed __attribute__((__packed__)) 230 #endif 231 232 #ifndef __aligned 233 #define __aligned(x) __attribute__((__aligned__(x))) 234 #endif 235 236 #ifndef __noinline 237 #define __noinline __attribute__((noinline)) 238 #endif 239 240 #define __may_alias __attribute__((__may_alias__)) 241 242 #ifndef __printf_like 243 #ifdef CONFIG_ENFORCE_ZEPHYR_STDINT 244 #define __printf_like(f, a) __attribute__((format (printf, f, a))) 245 #else 246 /* 247 * The Zephyr stdint convention enforces int32_t = int, int64_t = long long, 248 * and intptr_t = long so that short string format length modifiers can be 249 * used universally across ILP32 and LP64 architectures. Without that it 250 * is possible for ILP32 toolchains to have int32_t = long and intptr_t = int 251 * clashing with the Zephyr convention and generating pointless warnings 252 * as they're still the same size. Inhibit the format argument type 253 * validation in that case and let the other configs do it. 254 */ 255 #define __printf_like(f, a) 256 #endif 257 #endif 258 259 #define __used __attribute__((__used__)) 260 #define __unused __attribute__((__unused__)) 261 #define __maybe_unused __attribute__((__unused__)) 262 263 #ifndef __deprecated 264 #define __deprecated __attribute__((deprecated)) 265 /* When adding this, remember to follow the instructions in 266 * https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html#deprecated 267 */ 268 #endif 269 270 #ifndef __attribute_const__ 271 #define __attribute_const__ __attribute__((__const__)) 272 #endif 273 274 #ifndef __must_check 275 #define __must_check __attribute__((warn_unused_result)) 276 #endif 277 278 #define ARG_UNUSED(x) (void)(x) 279 280 #define likely(x) (__builtin_expect((bool)!!(x), true) != 0L) 281 #define unlikely(x) (__builtin_expect((bool)!!(x), false) != 0L) 282 #define POPCOUNT(x) __builtin_popcount(x) 283 284 #ifndef __no_optimization 285 #define __no_optimization __attribute__((optimize("-O0"))) 286 #endif 287 288 #ifndef __weak 289 #define __weak __attribute__((__weak__)) 290 #endif 291 292 #ifndef __attribute_nonnull 293 #define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) 294 #endif 295 296 /* Builtins with availability that depend on the compiler version. */ 297 #if __GNUC__ >= 5 298 #define HAS_BUILTIN___builtin_add_overflow 1 299 #define HAS_BUILTIN___builtin_sub_overflow 1 300 #define HAS_BUILTIN___builtin_mul_overflow 1 301 #define HAS_BUILTIN___builtin_div_overflow 1 302 #endif 303 #if __GNUC__ >= 4 304 #define HAS_BUILTIN___builtin_clz 1 305 #define HAS_BUILTIN___builtin_clzl 1 306 #define HAS_BUILTIN___builtin_clzll 1 307 #define HAS_BUILTIN___builtin_ctz 1 308 #define HAS_BUILTIN___builtin_ctzl 1 309 #define HAS_BUILTIN___builtin_ctzll 1 310 #endif 311 312 /* 313 * Be *very* careful with these. You cannot filter out __DEPRECATED_MACRO with 314 * -wno-deprecated, which has implications for -Werror. 315 */ 316 317 /* 318 * Expands to nothing and generates a warning. Used like 319 * 320 * #define FOO __WARN("Please use BAR instead") ... 321 * 322 * The warning points to the location where the macro is expanded. 323 */ 324 #define __WARN(msg) __WARN1(GCC warning msg) 325 #define __WARN1(s) _Pragma(#s) 326 327 /* Generic message */ 328 #ifndef __DEPRECATED_MACRO 329 #define __DEPRECATED_MACRO __WARN("Macro is deprecated") 330 /* When adding this, remember to follow the instructions in 331 * https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html#deprecated 332 */ 333 #endif 334 335 /* These macros allow having ARM asm functions callable from thumb */ 336 337 #if defined(_ASMLANGUAGE) 338 339 #if defined(CONFIG_ARM) 340 341 #if defined(CONFIG_ASSEMBLER_ISA_THUMB2) 342 343 #define FUNC_CODE() .thumb; 344 #define FUNC_INSTR(a) 345 346 #else 347 348 #define FUNC_CODE() .code 32; 349 #define FUNC_INSTR(a) 350 351 #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */ 352 353 #else 354 355 #define FUNC_CODE() 356 #define FUNC_INSTR(a) 357 358 #endif /* CONFIG_ARM */ 359 360 #endif /* _ASMLANGUAGE */ 361 362 /* 363 * These macros are used to declare assembly language symbols that need 364 * to be typed properly(func or data) to be visible to the OMF tool. 365 * So that the build tool could mark them as an entry point to be linked 366 * correctly. This is an elfism. Use #if 0 for a.out. 367 */ 368 369 #if defined(_ASMLANGUAGE) 370 371 #if defined(CONFIG_ARM) || defined(CONFIG_NIOS2) || defined(CONFIG_RISCV) \ 372 || defined(CONFIG_XTENSA) || defined(CONFIG_ARM64) \ 373 || defined(CONFIG_MIPS) 374 #define GTEXT(sym) .global sym; .type sym, %function 375 #define GDATA(sym) .global sym; .type sym, %object 376 #define WTEXT(sym) .weak sym; .type sym, %function 377 #define WDATA(sym) .weak sym; .type sym, %object 378 #elif defined(CONFIG_ARC) 379 /* 380 * Need to use assembly macros because ';' is interpreted as the start of 381 * a single line comment in the ARC assembler. 382 */ 383 384 .macro glbl_text symbol 385 .globl \symbol 386 .type \symbol, %function 387 .endm 388 389 .macro glbl_data symbol 390 .globl \symbol 391 .type \symbol, %object 392 .endm 393 394 .macro weak_data symbol 395 .weak \symbol 396 .type \symbol, %object 397 .endm 398 399 #define GTEXT(sym) glbl_text sym 400 #define GDATA(sym) glbl_data sym 401 #define WDATA(sym) weak_data sym 402 403 #else /* !CONFIG_ARM && !CONFIG_ARC */ 404 #define GTEXT(sym) .globl sym; .type sym, @function 405 #define GDATA(sym) .globl sym; .type sym, @object 406 #endif 407 408 /* 409 * These macros specify the section in which a given function or variable 410 * resides. 411 * 412 * - SECTION_FUNC allows only one function to reside in a sub-section 413 * - SECTION_SUBSEC_FUNC allows multiple functions to reside in a sub-section 414 * This ensures that garbage collection only discards the section 415 * if all functions in the sub-section are not referenced. 416 */ 417 418 #if defined(CONFIG_ARC) 419 /* 420 * Need to use assembly macros because ';' is interpreted as the start of 421 * a single line comment in the ARC assembler. 422 * 423 * Also, '\()' is needed in the .section directive of these macros for 424 * correct substitution of the 'section' variable. 425 */ 426 427 .macro section_var section, symbol 428 .section .\section\().\symbol 429 \symbol : 430 .endm 431 432 .macro section_func section, symbol 433 .section .\section\().\symbol, "ax" 434 FUNC_CODE() 435 PERFOPT_ALIGN 436 \symbol : 437 FUNC_INSTR(\symbol) 438 .endm 439 440 .macro section_subsec_func section, subsection, symbol 441 .section .\section\().\subsection, "ax" 442 PERFOPT_ALIGN 443 \symbol : 444 .endm 445 446 #define SECTION_VAR(sect, sym) section_var sect, sym 447 #define SECTION_FUNC(sect, sym) section_func sect, sym 448 #define SECTION_SUBSEC_FUNC(sect, subsec, sym) \ 449 section_subsec_func sect, subsec, sym 450 #else /* !CONFIG_ARC */ 451 452 #define SECTION_VAR(sect, sym) .section .sect.sym; sym: 453 #define SECTION_FUNC(sect, sym) \ 454 .section .sect.sym, "ax"; \ 455 FUNC_CODE() \ 456 PERFOPT_ALIGN; sym : \ 457 FUNC_INSTR(sym) 458 #define SECTION_SUBSEC_FUNC(sect, subsec, sym) \ 459 .section .sect.subsec, "ax"; PERFOPT_ALIGN; sym : 460 461 #endif /* CONFIG_ARC */ 462 463 #endif /* _ASMLANGUAGE */ 464 465 #if defined(_ASMLANGUAGE) 466 #if defined(CONFIG_ARM) 467 #if defined(CONFIG_ASSEMBLER_ISA_THUMB2) 468 /* '.syntax unified' is a gcc-ism used in thumb-2 asm files */ 469 #define _ASM_FILE_PROLOGUE .text; .syntax unified; .thumb 470 #else 471 #define _ASM_FILE_PROLOGUE .text; .code 32 472 #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */ 473 #elif defined(CONFIG_ARM64) 474 #define _ASM_FILE_PROLOGUE .text 475 #endif /* CONFIG_ARM64 || CONFIG_ARM */ 476 #endif /* _ASMLANGUAGE */ 477 478 /* 479 * These macros generate absolute symbols for GCC 480 */ 481 482 /* create an extern reference to the absolute symbol */ 483 484 #define GEN_OFFSET_EXTERN(name) extern const char name[] 485 486 #define GEN_ABS_SYM_BEGIN(name) \ 487 EXTERN_C void name(void); \ 488 void name(void) \ 489 { 490 491 #define GEN_ABS_SYM_END } 492 493 /* 494 * Note that GEN_ABSOLUTE_SYM(), depending on the architecture 495 * and toolchain, may restrict the range of values permitted 496 * for assignment to the named symbol. 497 * 498 * For example, on x86, "value" is interpreted as signed 499 * 32-bit integer. Passing in an unsigned 32-bit integer 500 * with MSB set would result in a negative integer. 501 * Moreover, GCC would error out if an integer larger 502 * than 2^32-1 is passed as "value". 503 */ 504 505 /* 506 * GEN_ABSOLUTE_SYM_KCONFIG() is outputted by the build system 507 * to generate named symbol/value pairs for kconfigs. 508 */ 509 510 #if defined(CONFIG_ARM) 511 512 /* 513 * GNU/ARM backend does not have a proper operand modifier which does not 514 * produces prefix # followed by value, such as %0 for PowerPC, Intel, and 515 * MIPS. The workaround performed here is using %B0 which converts 516 * the value to ~(value). Thus "n"(~(value)) is set in operand constraint 517 * to output (value) in the ARM specific GEN_OFFSET macro. 518 */ 519 520 #define GEN_ABSOLUTE_SYM(name, value) \ 521 __asm__(".globl\t" #name "\n\t.equ\t" #name \ 522 ",%B0" \ 523 "\n\t.type\t" #name ",%%object" : : "n"(~(value))) 524 525 #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ 526 __asm__(".globl\t" #name \ 527 "\n\t.equ\t" #name "," #value \ 528 "\n\t.type\t" #name ",%object") 529 530 #elif defined(CONFIG_X86) 531 532 #define GEN_ABSOLUTE_SYM(name, value) \ 533 __asm__(".globl\t" #name "\n\t.equ\t" #name \ 534 ",%c0" \ 535 "\n\t.type\t" #name ",@object" : : "n"(value)) 536 537 #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ 538 __asm__(".globl\t" #name \ 539 "\n\t.equ\t" #name "," #value \ 540 "\n\t.type\t" #name ",@object") 541 542 #elif defined(CONFIG_ARC) || defined(CONFIG_ARM64) 543 544 #define GEN_ABSOLUTE_SYM(name, value) \ 545 __asm__(".globl\t" #name "\n\t.equ\t" #name \ 546 ",%c0" \ 547 "\n\t.type\t" #name ",@object" : : "n"(value)) 548 549 #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ 550 __asm__(".globl\t" #name \ 551 "\n\t.equ\t" #name "," #value \ 552 "\n\t.type\t" #name ",@object") 553 554 #elif defined(CONFIG_NIOS2) || defined(CONFIG_RISCV) || \ 555 defined(CONFIG_XTENSA) || defined(CONFIG_MIPS) 556 557 /* No special prefixes necessary for constants in this arch AFAICT */ 558 #define GEN_ABSOLUTE_SYM(name, value) \ 559 __asm__(".globl\t" #name "\n\t.equ\t" #name \ 560 ",%0" \ 561 "\n\t.type\t" #name ",%%object" : : "n"(value)) 562 563 #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ 564 __asm__(".globl\t" #name \ 565 "\n\t.equ\t" #name "," #value \ 566 "\n\t.type\t" #name ",%object") 567 568 #elif defined(CONFIG_ARCH_POSIX) 569 #define GEN_ABSOLUTE_SYM(name, value) \ 570 __asm__(".globl\t" #name "\n\t.equ\t" #name \ 571 ",%c0" \ 572 "\n\t.type\t" #name ",@object" : : "n"(value)) 573 574 #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ 575 __asm__(".globl\t" #name \ 576 "\n\t.equ\t" #name "," #value \ 577 "\n\t.type\t" #name ",@object") 578 579 #elif defined(CONFIG_SPARC) 580 #define GEN_ABSOLUTE_SYM(name, value) \ 581 __asm__(".global\t" #name "\n\t.equ\t" #name \ 582 ",%0" \ 583 "\n\t.type\t" #name ",#object" : : "n"(value)) 584 585 #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ 586 __asm__(".globl\t" #name \ 587 "\n\t.equ\t" #name "," #value \ 588 "\n\t.type\t" #name ",#object") 589 590 #else 591 #error processor architecture not supported 592 #endif 593 594 #define compiler_barrier() do { \ 595 __asm__ __volatile__ ("" ::: "memory"); \ 596 } while (false) 597 598 /** @brief Return larger value of two provided expressions. 599 * 600 * Macro ensures that expressions are evaluated only once. 601 * 602 * @note Macro has limited usage compared to the standard macro as it cannot be 603 * used: 604 * - to generate constant integer, e.g. __aligned(Z_MAX(4,5)) 605 * - static variable, e.g. array like static uint8_t array[Z_MAX(...)]; 606 */ 607 #define Z_MAX(a, b) ({ \ 608 /* random suffix to avoid naming conflict */ \ 609 __typeof__(a) _value_a_ = (a); \ 610 __typeof__(b) _value_b_ = (b); \ 611 (_value_a_ > _value_b_) ? _value_a_ : _value_b_; \ 612 }) 613 614 /** @brief Return smaller value of two provided expressions. 615 * 616 * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for 617 * macro limitations. 618 */ 619 #define Z_MIN(a, b) ({ \ 620 /* random suffix to avoid naming conflict */ \ 621 __typeof__(a) _value_a_ = (a); \ 622 __typeof__(b) _value_b_ = (b); \ 623 (_value_a_ < _value_b_) ? _value_a_ : _value_b_; \ 624 }) 625 626 /** @brief Return a value clamped to a given range. 627 * 628 * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for 629 * macro limitations. 630 */ 631 #define Z_CLAMP(val, low, high) ({ \ 632 /* random suffix to avoid naming conflict */ \ 633 __typeof__(val) _value_val_ = (val); \ 634 __typeof__(low) _value_low_ = (low); \ 635 __typeof__(high) _value_high_ = (high); \ 636 (_value_val_ < _value_low_) ? _value_low_ : \ 637 (_value_val_ > _value_high_) ? _value_high_ : \ 638 _value_val_; \ 639 }) 640 641 /** 642 * @brief Calculate power of two ceiling for some nonzero value 643 * 644 * @param x Nonzero unsigned long value 645 * @return X rounded up to the next power of two 646 */ 647 #define Z_POW2_CEIL(x) \ 648 ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) - 1)))) 649 650 /** 651 * @brief Check whether or not a value is a power of 2 652 * 653 * @param x The value to check 654 * @return true if x is a power of 2, false otherwise 655 */ 656 #define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0)) 657 658 #if defined(CONFIG_ASAN) && defined(__clang__) 659 #define __noasan __attribute__((no_sanitize("address"))) 660 #else 661 #define __noasan /**/ 662 #endif 663 664 #if defined(CONFIG_UBSAN) 665 #define __noubsan __attribute__((no_sanitize("undefined"))) 666 #else 667 #define __noubsan 668 #endif 669 670 /** 671 * @brief Function attribute to disable stack protector. 672 * 673 * @note Only supported for GCC >= 11.0.0 or Clang >= 7. 674 */ 675 #if (TOOLCHAIN_GCC_VERSION >= 110000) || \ 676 (defined(TOOLCHAIN_CLANG_VERSION) && (TOOLCHAIN_CLANG_VERSION >= 70000)) 677 #define FUNC_NO_STACK_PROTECTOR __attribute__((no_stack_protector)) 678 #else 679 #define FUNC_NO_STACK_PROTECTOR 680 #endif 681 682 #define TOOLCHAIN_IGNORE_WSHADOW_BEGIN \ 683 _Pragma("GCC diagnostic push") \ 684 _Pragma("GCC diagnostic ignored \"-Wshadow\"") 685 686 #define TOOLCHAIN_IGNORE_WSHADOW_END \ 687 _Pragma("GCC diagnostic pop") 688 689 #endif /* !_LINKER */ 690 691 #define TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER "-Waddress-of-packed-member" 692 #define TOOLCHAIN_WARNING_ARRAY_BOUNDS "-Warray-bounds" 693 #define TOOLCHAIN_WARNING_ATTRIBUTES "-Wattributes" 694 #define TOOLCHAIN_WARNING_DELETE_NON_VIRTUAL_DTOR "-Wdelete-non-virtual-dtor" 695 #define TOOLCHAIN_WARNING_EXTRA "-Wextra" 696 #define TOOLCHAIN_WARNING_NONNULL "-Wnonnull" 697 #define TOOLCHAIN_WARNING_SHADOW "-Wshadow" 698 #define TOOLCHAIN_WARNING_UNUSED_LABEL "-Wunused-label" 699 #define TOOLCHAIN_WARNING_UNUSED_VARIABLE "-Wunused-variable" 700 701 /* GCC-specific warnings that aren't in clang. */ 702 #if defined(__GNUC__) && !defined(__clang__) 703 #define TOOLCHAIN_WARNING_POINTER_ARITH "-Wpointer-arith" 704 #endif 705 706 #define _TOOLCHAIN_DISABLE_WARNING(compiler, warning) \ 707 TOOLCHAIN_PRAGMA(compiler diagnostic push) \ 708 TOOLCHAIN_PRAGMA(compiler diagnostic ignored warning) 709 710 #define _TOOLCHAIN_ENABLE_WARNING(compiler, warning) TOOLCHAIN_PRAGMA(compiler diagnostic pop) 711 712 #define TOOLCHAIN_DISABLE_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(GCC, warning) 713 #define TOOLCHAIN_ENABLE_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(GCC, warning) 714 715 #if defined(__GNUC__) && !defined(__clang__) 716 #define TOOLCHAIN_DISABLE_GCC_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(GCC, warning) 717 #define TOOLCHAIN_ENABLE_GCC_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(GCC, warning) 718 #endif 719 720 #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ */ 721