Line data Source code
1 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 0 : #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 0 : #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 : /*
178 : * Get the address of a structure member even if the member may not be properly
179 : * aligned. Note that accessing such an address must be done with care (for
180 : * example with UNALIGNED_GET/PUT) and cannot be in general de-referenced to
181 : * access the member directly, as that would cause a fault in architectures
182 : * which have alignment requirements.
183 : */
184 : #define UNALIGNED_MEMBER_ADDR(_p, _member) ((__typeof__(_p->_member) *) \
185 : (((intptr_t)(_p)) + offsetof(__typeof__(*_p), _member)))
186 :
187 : /* Double indirection to ensure section names are expanded before
188 : * stringification
189 : */
190 : #define __GENERIC_SECTION(segment) __attribute__((section(STRINGIFY(segment))))
191 : #define Z_GENERIC_SECTION(segment) __GENERIC_SECTION(segment)
192 :
193 : #define __GENERIC_DOT_SECTION(segment) \
194 : __attribute__((section("." STRINGIFY(segment))))
195 : #define Z_GENERIC_DOT_SECTION(segment) __GENERIC_DOT_SECTION(segment)
196 :
197 : #define ___in_section(a, b, c) \
198 : __attribute__((section("." Z_STRINGIFY(a) \
199 : "." Z_STRINGIFY(b) \
200 : "." Z_STRINGIFY(c))))
201 : #define __in_section(a, b, c) ___in_section(a, b, c)
202 :
203 : #ifndef __in_section_unique
204 : #define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__)
205 : #endif
206 :
207 : #ifndef __in_section_unique_named
208 : #define __in_section_unique_named(seg, name) \
209 : ___in_section(seg, __FILE__, name)
210 : #endif
211 :
212 : /* When using XIP, using '__ramfunc' places a function into RAM instead
213 : * of FLASH. Make sure '__ramfunc' is defined only when
214 : * CONFIG_ARCH_HAS_RAMFUNC_SUPPORT is defined, so that the compiler can
215 : * report an error if '__ramfunc' is used but the architecture does not
216 : * support it.
217 : */
218 : #if !defined(CONFIG_XIP)
219 : #define __ramfunc
220 : #elif defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
221 : #if defined(CONFIG_ARM)
222 : #if defined(__clang__)
223 : /* No long_call attribute for Clang.
224 : * Rely on linker to place required veneers.
225 : * https://github.com/llvm/llvm-project/issues/39969
226 : */
227 : #define __ramfunc __attribute__((noinline)) __attribute__((section(".ramfunc")))
228 : #else
229 : /* GCC version */
230 : #define __ramfunc __attribute__((noinline)) \
231 : __attribute__((long_call, section(".ramfunc")))
232 : #endif
233 : #else
234 : #define __ramfunc __attribute__((noinline)) \
235 : __attribute__((section(".ramfunc")))
236 : #endif
237 : #endif /* !CONFIG_XIP */
238 :
239 : #ifndef __fallthrough
240 : #if __GNUC__ >= 7
241 : #define __fallthrough __attribute__((fallthrough))
242 : #else
243 : #define __fallthrough
244 : #endif /* __GNUC__ >= 7 */
245 : #endif
246 :
247 : #ifndef __packed
248 : #define __packed __attribute__((__packed__))
249 : #endif
250 :
251 : #ifndef __aligned
252 : #define __aligned(x) __attribute__((__aligned__(x)))
253 : #endif
254 :
255 : #ifndef __noinline
256 : #define __noinline __attribute__((noinline))
257 : #endif
258 :
259 : #define __may_alias __attribute__((__may_alias__))
260 :
261 : #ifndef __printf_like
262 : #ifdef CONFIG_ENFORCE_ZEPHYR_STDINT
263 : #define __printf_like(f, a) __attribute__((format (printf, f, a)))
264 : #else
265 : /*
266 : * The Zephyr stdint convention enforces int32_t = int, int64_t = long long,
267 : * and intptr_t = long so that short string format length modifiers can be
268 : * used universally across ILP32 and LP64 architectures. Without that it
269 : * is possible for ILP32 toolchains to have int32_t = long and intptr_t = int
270 : * clashing with the Zephyr convention and generating pointless warnings
271 : * as they're still the same size. Inhibit the format argument type
272 : * validation in that case and let the other configs do it.
273 : */
274 : #define __printf_like(f, a)
275 : #endif
276 : #endif
277 :
278 : #define __used __attribute__((__used__))
279 : #define __unused __attribute__((__unused__))
280 : #define __maybe_unused __attribute__((__unused__))
281 :
282 : #ifndef __deprecated
283 : #define __deprecated __attribute__((deprecated))
284 : /* When adding this, remember to follow the instructions in
285 : * https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html#deprecated
286 : */
287 : #endif
288 :
289 : #ifndef __attribute_const__
290 : #define __attribute_const__ __attribute__((__const__))
291 : #endif
292 :
293 : #ifndef __must_check
294 : #define __must_check __attribute__((warn_unused_result))
295 : #endif
296 :
297 : #define ARG_UNUSED(x) (void)(x)
298 :
299 : #define likely(x) (__builtin_expect((bool)!!(x), true) != 0L)
300 : #define unlikely(x) (__builtin_expect((bool)!!(x), false) != 0L)
301 : #define POPCOUNT(x) __builtin_popcount(x)
302 :
303 : #ifndef __no_optimization
304 : #define __no_optimization __attribute__((optimize("-O0")))
305 : #endif
306 :
307 : #ifndef __weak
308 : #define __weak __attribute__((__weak__))
309 : #endif
310 :
311 : #ifndef __attribute_nonnull
312 : #define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
313 : #endif
314 :
315 : /* Builtins with availability that depend on the compiler version. */
316 : #if __GNUC__ >= 5
317 : #define HAS_BUILTIN___builtin_add_overflow 1
318 : #define HAS_BUILTIN___builtin_sub_overflow 1
319 : #define HAS_BUILTIN___builtin_mul_overflow 1
320 : #define HAS_BUILTIN___builtin_div_overflow 1
321 : #endif
322 : #if __GNUC__ >= 4
323 : #define HAS_BUILTIN___builtin_clz 1
324 : #define HAS_BUILTIN___builtin_clzl 1
325 : #define HAS_BUILTIN___builtin_clzll 1
326 : #define HAS_BUILTIN___builtin_ctz 1
327 : #define HAS_BUILTIN___builtin_ctzl 1
328 : #define HAS_BUILTIN___builtin_ctzll 1
329 : #endif
330 :
331 : /*
332 : * Be *very* careful with these. You cannot filter out __DEPRECATED_MACRO with
333 : * -wno-deprecated, which has implications for -Werror.
334 : */
335 :
336 : /*
337 : * Expands to nothing and generates a warning. Used like
338 : *
339 : * #define FOO __WARN("Please use BAR instead") ...
340 : *
341 : * The warning points to the location where the macro is expanded.
342 : */
343 : #define __WARN(msg) __WARN1(GCC warning msg)
344 : #define __WARN1(s) _Pragma(#s)
345 :
346 : /* Generic message */
347 : #ifndef CONFIG_DEPRECATION_TEST
348 : #define __DEPRECATED_MACRO __WARN("Macro is deprecated")
349 : /* When adding this, remember to follow the instructions in
350 : * https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html#deprecated
351 : */
352 : #else
353 : #define __DEPRECATED_MACRO
354 : #endif
355 :
356 : /* These macros allow having ARM asm functions callable from thumb */
357 :
358 : #if defined(_ASMLANGUAGE)
359 :
360 : #if defined(CONFIG_ARM)
361 :
362 : #if defined(CONFIG_ASSEMBLER_ISA_THUMB2)
363 :
364 : #define FUNC_CODE() .thumb;
365 : #define FUNC_INSTR(a)
366 :
367 : #else
368 :
369 : #define FUNC_CODE() .code 32;
370 : #define FUNC_INSTR(a)
371 :
372 : #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */
373 :
374 : #else
375 :
376 : #define FUNC_CODE()
377 : #define FUNC_INSTR(a)
378 :
379 : #endif /* CONFIG_ARM */
380 :
381 : #endif /* _ASMLANGUAGE */
382 :
383 : /*
384 : * These macros are used to declare assembly language symbols that need
385 : * to be typed properly(func or data) to be visible to the OMF tool.
386 : * So that the build tool could mark them as an entry point to be linked
387 : * correctly. This is an elfism. Use #if 0 for a.out.
388 : */
389 :
390 : #if defined(_ASMLANGUAGE)
391 :
392 : #if defined(CONFIG_ARM) || defined(CONFIG_RISCV) \
393 : || defined(CONFIG_XTENSA) || defined(CONFIG_ARM64) \
394 : || defined(CONFIG_MIPS) || defined(CONFIG_RX)
395 : #define GTEXT(sym) .global sym; .type sym, %function
396 : #define GDATA(sym) .global sym; .type sym, %object
397 : #define WTEXT(sym) .weak sym; .type sym, %function
398 : #define WDATA(sym) .weak sym; .type sym, %object
399 : #elif defined(CONFIG_ARC)
400 : /*
401 : * Need to use assembly macros because ';' is interpreted as the start of
402 : * a single line comment in the ARC assembler.
403 : */
404 :
405 : .macro glbl_text symbol
406 : .globl \symbol
407 : .type \symbol, %function
408 : .endm
409 :
410 : .macro glbl_data symbol
411 : .globl \symbol
412 : .type \symbol, %object
413 : .endm
414 :
415 : .macro weak_data symbol
416 : .weak \symbol
417 : .type \symbol, %object
418 : .endm
419 :
420 : #define GTEXT(sym) glbl_text sym
421 : #define GDATA(sym) glbl_data sym
422 : #define WDATA(sym) weak_data sym
423 :
424 : #else /* !CONFIG_ARM && !CONFIG_ARC */
425 : #define GTEXT(sym) .globl sym; .type sym, @function
426 : #define GDATA(sym) .globl sym; .type sym, @object
427 : #endif
428 :
429 : /*
430 : * These macros specify the section in which a given function or variable
431 : * resides.
432 : *
433 : * - SECTION_FUNC allows only one function to reside in a sub-section
434 : * - SECTION_SUBSEC_FUNC allows multiple functions to reside in a sub-section
435 : * This ensures that garbage collection only discards the section
436 : * if all functions in the sub-section are not referenced.
437 : */
438 :
439 : #if defined(CONFIG_ARC)
440 : /*
441 : * Need to use assembly macros because ';' is interpreted as the start of
442 : * a single line comment in the ARC assembler.
443 : *
444 : * Also, '\()' is needed in the .section directive of these macros for
445 : * correct substitution of the 'section' variable.
446 : */
447 :
448 : .macro section_var section, symbol
449 : .section .\section\().\symbol
450 : \symbol :
451 : .endm
452 :
453 : .macro section_func section, symbol
454 : .section .\section\().\symbol, "ax"
455 : FUNC_CODE()
456 : PERFOPT_ALIGN
457 : \symbol :
458 : FUNC_INSTR(\symbol)
459 : .endm
460 :
461 : .macro section_subsec_func section, subsection, symbol
462 : .section .\section\().\subsection, "ax"
463 : PERFOPT_ALIGN
464 : \symbol :
465 : .endm
466 :
467 : #define SECTION_VAR(sect, sym) section_var sect, sym
468 : #define SECTION_FUNC(sect, sym) section_func sect, sym
469 : #define SECTION_SUBSEC_FUNC(sect, subsec, sym) \
470 : section_subsec_func sect, subsec, sym
471 : #else /* !CONFIG_ARC */
472 :
473 : #define SECTION_VAR(sect, sym) .section .sect.sym; sym:
474 : #define SECTION_FUNC(sect, sym) \
475 : .section .sect.sym, "ax"; \
476 : FUNC_CODE() \
477 : PERFOPT_ALIGN; sym : \
478 : FUNC_INSTR(sym)
479 : #define SECTION_SUBSEC_FUNC(sect, subsec, sym) \
480 : .section .sect.subsec, "ax"; PERFOPT_ALIGN; sym :
481 :
482 : #endif /* CONFIG_ARC */
483 :
484 : #endif /* _ASMLANGUAGE */
485 :
486 : #if defined(_ASMLANGUAGE)
487 : #if defined(CONFIG_ARM)
488 : #if defined(CONFIG_ASSEMBLER_ISA_THUMB2)
489 : /* '.syntax unified' is a gcc-ism used in thumb-2 asm files */
490 : #define _ASM_FILE_PROLOGUE .text; .syntax unified; .thumb
491 : #else
492 : #define _ASM_FILE_PROLOGUE .text; .code 32
493 : #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */
494 : #elif defined(CONFIG_ARM64)
495 : #define _ASM_FILE_PROLOGUE .text
496 : #endif /* CONFIG_ARM64 || CONFIG_ARM */
497 : #endif /* _ASMLANGUAGE */
498 :
499 : /*
500 : * These macros generate absolute symbols for GCC
501 : */
502 :
503 : /* create an extern reference to the absolute symbol */
504 :
505 : #define GEN_OFFSET_EXTERN(name) extern const char name[]
506 :
507 : #define GEN_ABS_SYM_BEGIN(name) \
508 : EXTERN_C void name(void); \
509 : void name(void) \
510 : {
511 :
512 : #define GEN_ABS_SYM_END }
513 :
514 : /*
515 : * Note that GEN_ABSOLUTE_SYM(), depending on the architecture
516 : * and toolchain, may restrict the range of values permitted
517 : * for assignment to the named symbol.
518 : *
519 : * For example, on x86, "value" is interpreted as signed
520 : * 32-bit integer. Passing in an unsigned 32-bit integer
521 : * with MSB set would result in a negative integer.
522 : * Moreover, GCC would error out if an integer larger
523 : * than 2^32-1 is passed as "value".
524 : */
525 :
526 : /*
527 : * GEN_ABSOLUTE_SYM_KCONFIG() is outputted by the build system
528 : * to generate named symbol/value pairs for kconfigs.
529 : */
530 :
531 : #if defined(CONFIG_ARM)
532 :
533 : /*
534 : * GNU/ARM backend does not have a proper operand modifier which does not
535 : * produces prefix # followed by value, such as %0 for PowerPC, Intel, and
536 : * MIPS. The workaround performed here is using %B0 which converts
537 : * the value to ~(value). Thus "n"(~(value)) is set in operand constraint
538 : * to output (value) in the ARM specific GEN_OFFSET macro.
539 : */
540 :
541 : #define GEN_ABSOLUTE_SYM(name, value) \
542 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
543 : ",%B0" \
544 : "\n\t.type\t" #name ",%%object" : : "n"(~(value)))
545 :
546 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
547 : __asm__(".globl\t" #name \
548 : "\n\t.equ\t" #name "," #value \
549 : "\n\t.type\t" #name ",%object")
550 :
551 : #elif defined(CONFIG_X86)
552 :
553 : #define GEN_ABSOLUTE_SYM(name, value) \
554 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
555 : ",%c0" \
556 : "\n\t.type\t" #name ",@object" : : "n"(value))
557 :
558 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
559 : __asm__(".globl\t" #name \
560 : "\n\t.equ\t" #name "," #value \
561 : "\n\t.type\t" #name ",@object")
562 :
563 : #elif defined(CONFIG_ARC) || defined(CONFIG_ARM64)
564 :
565 : #define GEN_ABSOLUTE_SYM(name, value) \
566 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
567 : ",%c0" \
568 : "\n\t.type\t" #name ",@object" : : "n"(value))
569 :
570 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
571 : __asm__(".globl\t" #name \
572 : "\n\t.equ\t" #name "," #value \
573 : "\n\t.type\t" #name ",@object")
574 :
575 : #elif defined(CONFIG_RISCV) || defined(CONFIG_XTENSA) || defined(CONFIG_MIPS)
576 :
577 : /* No special prefixes necessary for constants in this arch AFAICT */
578 : #define GEN_ABSOLUTE_SYM(name, value) \
579 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
580 : ",%0" \
581 : "\n\t.type\t" #name ",%%object" : : "n"(value))
582 :
583 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
584 : __asm__(".globl\t" #name \
585 : "\n\t.equ\t" #name "," #value \
586 : "\n\t.type\t" #name ",%object")
587 :
588 : #elif defined(CONFIG_ARCH_POSIX)
589 : #define GEN_ABSOLUTE_SYM(name, value) \
590 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
591 : ",%c0" \
592 : "\n\t.type\t" #name ",@object" : : "n"(value))
593 :
594 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
595 : __asm__(".globl\t" #name \
596 : "\n\t.equ\t" #name "," #value \
597 : "\n\t.type\t" #name ",@object")
598 :
599 : #elif defined(CONFIG_SPARC)
600 : #define GEN_ABSOLUTE_SYM(name, value) \
601 : __asm__(".global\t" #name "\n\t.equ\t" #name \
602 : ",%0" \
603 : "\n\t.type\t" #name ",#object" : : "n"(value))
604 :
605 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
606 : __asm__(".globl\t" #name \
607 : "\n\t.equ\t" #name "," #value \
608 : "\n\t.type\t" #name ",#object")
609 :
610 : #elif defined(CONFIG_RX)
611 : #define GEN_ABSOLUTE_SYM(name, value) \
612 : __asm__(".global\t" #name "\n\t.equ\t" #name \
613 : ",%c0" \
614 : "\n\t.type\t" #name ",%%object" : : "n"(value))
615 :
616 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
617 : __asm__(".global\t" #name \
618 : "\n\t.equ\t" #name "," #value \
619 : "\n\t.type\t" #name ",#object")
620 :
621 : #else
622 : #error processor architecture not supported
623 : #endif
624 :
625 : #define compiler_barrier() do { \
626 : __asm__ __volatile__ ("" ::: "memory"); \
627 : } while (false)
628 :
629 : /** @brief Return larger value of two provided expressions.
630 : *
631 : * Macro ensures that expressions are evaluated only once.
632 : *
633 : * @note Macro has limited usage compared to the standard macro as it cannot be
634 : * used:
635 : * - to generate constant integer, e.g. __aligned(Z_MAX(4,5))
636 : * - static variable, e.g. array like static uint8_t array[Z_MAX(...)];
637 : */
638 : #define Z_MAX(a, b) ({ \
639 : /* random suffix to avoid naming conflict */ \
640 : __typeof__(a) _value_a_ = (a); \
641 : __typeof__(b) _value_b_ = (b); \
642 : (_value_a_ > _value_b_) ? _value_a_ : _value_b_; \
643 : })
644 :
645 : /** @brief Return smaller value of two provided expressions.
646 : *
647 : * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for
648 : * macro limitations.
649 : */
650 : #define Z_MIN(a, b) ({ \
651 : /* random suffix to avoid naming conflict */ \
652 : __typeof__(a) _value_a_ = (a); \
653 : __typeof__(b) _value_b_ = (b); \
654 : (_value_a_ < _value_b_) ? _value_a_ : _value_b_; \
655 : })
656 :
657 : /** @brief Return a value clamped to a given range.
658 : *
659 : * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for
660 : * macro limitations.
661 : */
662 : #define Z_CLAMP(val, low, high) ({ \
663 : /* random suffix to avoid naming conflict */ \
664 : __typeof__(val) _value_val_ = (val); \
665 : __typeof__(low) _value_low_ = (low); \
666 : __typeof__(high) _value_high_ = (high); \
667 : (_value_val_ < _value_low_) ? _value_low_ : \
668 : (_value_val_ > _value_high_) ? _value_high_ : \
669 : _value_val_; \
670 : })
671 :
672 : /**
673 : * @brief Calculate power of two ceiling for some nonzero value
674 : *
675 : * @param x Nonzero unsigned long value
676 : * @return X rounded up to the next power of two
677 : */
678 : #define Z_POW2_CEIL(x) \
679 : ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) - 1))))
680 :
681 : /**
682 : * @brief Check whether or not a value is a power of 2
683 : *
684 : * @param x The value to check
685 : * @return true if x is a power of 2, false otherwise
686 : */
687 : #define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0))
688 :
689 : #if defined(CONFIG_ASAN) && defined(__clang__)
690 : #define __noasan __attribute__((no_sanitize("address")))
691 : #else
692 : #define __noasan /**/
693 : #endif
694 :
695 : #if defined(CONFIG_UBSAN)
696 : #define __noubsan __attribute__((no_sanitize("undefined")))
697 : #else
698 : #define __noubsan
699 : #endif
700 :
701 : /**
702 : * @brief Function attribute to disable stack protector.
703 : *
704 : * @note Only supported for GCC >= 11.0.0 or Clang >= 7.
705 : */
706 : #if (TOOLCHAIN_GCC_VERSION >= 110000) || \
707 : (defined(TOOLCHAIN_CLANG_VERSION) && (TOOLCHAIN_CLANG_VERSION >= 70000))
708 : #define FUNC_NO_STACK_PROTECTOR __attribute__((no_stack_protector))
709 : #else
710 : #define FUNC_NO_STACK_PROTECTOR
711 : #endif
712 :
713 : #endif /* !_LINKER */
714 :
715 0 : #define TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER "-Waddress-of-packed-member"
716 0 : #define TOOLCHAIN_WARNING_ARRAY_BOUNDS "-Warray-bounds"
717 0 : #define TOOLCHAIN_WARNING_ATTRIBUTES "-Wattributes"
718 0 : #define TOOLCHAIN_WARNING_DELETE_NON_VIRTUAL_DTOR "-Wdelete-non-virtual-dtor"
719 0 : #define TOOLCHAIN_WARNING_EXTRA "-Wextra"
720 0 : #define TOOLCHAIN_WARNING_NONNULL "-Wnonnull"
721 0 : #define TOOLCHAIN_WARNING_SHADOW "-Wshadow"
722 0 : #define TOOLCHAIN_WARNING_UNUSED_LABEL "-Wunused-label"
723 0 : #define TOOLCHAIN_WARNING_UNUSED_VARIABLE "-Wunused-variable"
724 :
725 : /* GCC-specific warnings that aren't in clang. */
726 : #if defined(__GNUC__) && !defined(__clang__)
727 : #define TOOLCHAIN_WARNING_POINTER_ARITH "-Wpointer-arith"
728 : #define TOOLCHAIN_WARNING_STRINGOP_OVERREAD "-Wstringop-overread"
729 : #endif
730 :
731 : #define _TOOLCHAIN_DISABLE_WARNING(compiler, warning) \
732 : TOOLCHAIN_PRAGMA(compiler diagnostic push) \
733 : TOOLCHAIN_PRAGMA(compiler diagnostic ignored warning)
734 :
735 : #define _TOOLCHAIN_ENABLE_WARNING(compiler, warning) TOOLCHAIN_PRAGMA(compiler diagnostic pop)
736 :
737 0 : #define TOOLCHAIN_DISABLE_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(GCC, warning)
738 0 : #define TOOLCHAIN_ENABLE_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(GCC, warning)
739 :
740 : #if defined(__GNUC__) && !defined(__clang__)
741 : #define TOOLCHAIN_DISABLE_GCC_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(GCC, warning)
742 : #define TOOLCHAIN_ENABLE_GCC_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(GCC, warning)
743 : #endif
744 :
745 : #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ */
|