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 __deprecated_version
290 : #define __deprecated_version(version) \
291 : __attribute__((deprecated("planned removal in v" #version)))
292 : #endif
293 :
294 : #ifndef __attribute_const__
295 : #define __attribute_const__ __attribute__((__const__))
296 : #endif
297 :
298 : #ifndef __must_check
299 : #define __must_check __attribute__((warn_unused_result))
300 : #endif
301 :
302 : #define ARG_UNUSED(x) (void)(x)
303 :
304 : #define likely(x) (__builtin_expect((bool)!!(x), true) != 0L)
305 : #define unlikely(x) (__builtin_expect((bool)!!(x), false) != 0L)
306 : #define POPCOUNT(x) __builtin_popcount(x)
307 :
308 : #ifndef __no_optimization
309 : #define __no_optimization __attribute__((optimize("-O0")))
310 : #endif
311 :
312 : #ifndef __weak
313 : #define __weak __attribute__((__weak__))
314 : #endif
315 :
316 : #ifndef __attribute_nonnull
317 : #define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
318 : #endif
319 :
320 : /* Builtins with availability that depend on the compiler version. */
321 : #if __GNUC__ >= 5
322 : #define HAS_BUILTIN___builtin_add_overflow 1
323 : #define HAS_BUILTIN___builtin_sub_overflow 1
324 : #define HAS_BUILTIN___builtin_mul_overflow 1
325 : #define HAS_BUILTIN___builtin_div_overflow 1
326 : #endif
327 : #if __GNUC__ >= 4
328 : #define HAS_BUILTIN___builtin_clz 1
329 : #define HAS_BUILTIN___builtin_clzl 1
330 : #define HAS_BUILTIN___builtin_clzll 1
331 : #define HAS_BUILTIN___builtin_ctz 1
332 : #define HAS_BUILTIN___builtin_ctzl 1
333 : #define HAS_BUILTIN___builtin_ctzll 1
334 : #endif
335 :
336 : /*
337 : * Be *very* careful with these. You cannot filter out __DEPRECATED_MACRO with
338 : * -wno-deprecated, which has implications for -Werror.
339 : */
340 :
341 : /*
342 : * Expands to nothing and generates a warning. Used like
343 : *
344 : * #define FOO __WARN("Please use BAR instead") ...
345 : *
346 : * The warning points to the location where the macro is expanded.
347 : */
348 : #define __WARN(msg) __WARN1(GCC warning msg)
349 : #define __WARN1(s) _Pragma(#s)
350 :
351 : /* Generic message */
352 : #ifndef CONFIG_DEPRECATION_TEST
353 : #define __DEPRECATED_MACRO __WARN("Macro is deprecated")
354 : /* When adding this, remember to follow the instructions in
355 : * https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html#deprecated
356 : */
357 : #else
358 : #define __DEPRECATED_MACRO
359 : #endif
360 :
361 : /* These macros allow having ARM asm functions callable from thumb */
362 :
363 : #if defined(_ASMLANGUAGE)
364 :
365 : #if defined(CONFIG_ARM)
366 :
367 : #if defined(CONFIG_ASSEMBLER_ISA_THUMB2)
368 :
369 : #define FUNC_CODE() .thumb;
370 : #define FUNC_INSTR(a)
371 :
372 : #else
373 :
374 : #define FUNC_CODE() .code 32;
375 : #define FUNC_INSTR(a)
376 :
377 : #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */
378 :
379 : #else
380 :
381 : #define FUNC_CODE()
382 : #define FUNC_INSTR(a)
383 :
384 : #endif /* CONFIG_ARM */
385 :
386 : #endif /* _ASMLANGUAGE */
387 :
388 : /*
389 : * These macros are used to declare assembly language symbols that need
390 : * to be typed properly(func or data) to be visible to the OMF tool.
391 : * So that the build tool could mark them as an entry point to be linked
392 : * correctly. This is an elfism. Use #if 0 for a.out.
393 : */
394 :
395 : #if defined(_ASMLANGUAGE)
396 :
397 : #if defined(CONFIG_ARM) || defined(CONFIG_RISCV) \
398 : || defined(CONFIG_XTENSA) || defined(CONFIG_ARM64) \
399 : || defined(CONFIG_MIPS) || defined(CONFIG_RX)
400 : #define GTEXT(sym) .global sym; .type sym, %function
401 : #define GDATA(sym) .global sym; .type sym, %object
402 : #define WTEXT(sym) .weak sym; .type sym, %function
403 : #define WDATA(sym) .weak sym; .type sym, %object
404 : #elif defined(CONFIG_ARC)
405 : /*
406 : * Need to use assembly macros because ';' is interpreted as the start of
407 : * a single line comment in the ARC assembler.
408 : */
409 :
410 : .macro glbl_text symbol
411 : .globl \symbol
412 : .type \symbol, %function
413 : .endm
414 :
415 : .macro glbl_data symbol
416 : .globl \symbol
417 : .type \symbol, %object
418 : .endm
419 :
420 : .macro weak_data symbol
421 : .weak \symbol
422 : .type \symbol, %object
423 : .endm
424 :
425 : #define GTEXT(sym) glbl_text sym
426 : #define GDATA(sym) glbl_data sym
427 : #define WDATA(sym) weak_data sym
428 :
429 : #else /* !CONFIG_ARM && !CONFIG_ARC */
430 : #define GTEXT(sym) .globl sym; .type sym, @function
431 : #define GDATA(sym) .globl sym; .type sym, @object
432 : #endif
433 :
434 : /*
435 : * These macros specify the section in which a given function or variable
436 : * resides.
437 : *
438 : * - SECTION_FUNC allows only one function to reside in a sub-section
439 : * - SECTION_SUBSEC_FUNC allows multiple functions to reside in a sub-section
440 : * This ensures that garbage collection only discards the section
441 : * if all functions in the sub-section are not referenced.
442 : */
443 :
444 : #if defined(CONFIG_ARC)
445 : /*
446 : * Need to use assembly macros because ';' is interpreted as the start of
447 : * a single line comment in the ARC assembler.
448 : *
449 : * Also, '\()' is needed in the .section directive of these macros for
450 : * correct substitution of the 'section' variable.
451 : */
452 :
453 : .macro section_var section, symbol
454 : .section .\section\().\symbol
455 : \symbol :
456 : .endm
457 :
458 : .macro section_func section, symbol
459 : .section .\section\().\symbol, "ax"
460 : FUNC_CODE()
461 : PERFOPT_ALIGN
462 : \symbol :
463 : FUNC_INSTR(\symbol)
464 : .endm
465 :
466 : .macro section_subsec_func section, subsection, symbol
467 : .section .\section\().\subsection, "ax"
468 : PERFOPT_ALIGN
469 : \symbol :
470 : .endm
471 :
472 : #define SECTION_VAR(sect, sym) section_var sect, sym
473 : #define SECTION_FUNC(sect, sym) section_func sect, sym
474 : #define SECTION_SUBSEC_FUNC(sect, subsec, sym) \
475 : section_subsec_func sect, subsec, sym
476 : #else /* !CONFIG_ARC */
477 :
478 : #define SECTION_VAR(sect, sym) .section .sect.sym; sym:
479 : #define SECTION_FUNC(sect, sym) \
480 : .section .sect.sym, "ax"; \
481 : FUNC_CODE() \
482 : PERFOPT_ALIGN; sym : \
483 : FUNC_INSTR(sym)
484 : #define SECTION_SUBSEC_FUNC(sect, subsec, sym) \
485 : .section .sect.subsec, "ax"; PERFOPT_ALIGN; sym :
486 :
487 : #endif /* CONFIG_ARC */
488 :
489 : #endif /* _ASMLANGUAGE */
490 :
491 : #if defined(_ASMLANGUAGE)
492 : #if defined(CONFIG_ARM)
493 : #if defined(CONFIG_ASSEMBLER_ISA_THUMB2)
494 : /* '.syntax unified' is a gcc-ism used in thumb-2 asm files */
495 : #define _ASM_FILE_PROLOGUE .text; .syntax unified; .thumb
496 : #else
497 : #define _ASM_FILE_PROLOGUE .text; .code 32
498 : #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */
499 : #elif defined(CONFIG_ARM64)
500 : #define _ASM_FILE_PROLOGUE .text
501 : #endif /* CONFIG_ARM64 || CONFIG_ARM */
502 : #endif /* _ASMLANGUAGE */
503 :
504 : /*
505 : * These macros generate absolute symbols for GCC
506 : */
507 :
508 : /* create an extern reference to the absolute symbol */
509 :
510 : #define GEN_OFFSET_EXTERN(name) extern const char name[]
511 :
512 : #define GEN_ABS_SYM_BEGIN(name) \
513 : EXTERN_C void name(void); \
514 : void name(void) \
515 : {
516 :
517 : #define GEN_ABS_SYM_END }
518 :
519 : /*
520 : * Note that GEN_ABSOLUTE_SYM(), depending on the architecture
521 : * and toolchain, may restrict the range of values permitted
522 : * for assignment to the named symbol.
523 : *
524 : * For example, on x86, "value" is interpreted as signed
525 : * 32-bit integer. Passing in an unsigned 32-bit integer
526 : * with MSB set would result in a negative integer.
527 : * Moreover, GCC would error out if an integer larger
528 : * than 2^32-1 is passed as "value".
529 : */
530 :
531 : /*
532 : * GEN_ABSOLUTE_SYM_KCONFIG() is outputted by the build system
533 : * to generate named symbol/value pairs for kconfigs.
534 : */
535 :
536 : #if defined(CONFIG_ARM)
537 :
538 : /*
539 : * GNU/ARM backend does not have a proper operand modifier which does not
540 : * produces prefix # followed by value, such as %0 for PowerPC, Intel, and
541 : * MIPS. The workaround performed here is using %B0 which converts
542 : * the value to ~(value). Thus "n"(~(value)) is set in operand constraint
543 : * to output (value) in the ARM specific GEN_OFFSET macro.
544 : */
545 :
546 : #define GEN_ABSOLUTE_SYM(name, value) \
547 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
548 : ",%B0" \
549 : "\n\t.type\t" #name ",%%object" : : "n"(~(value)))
550 :
551 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
552 : __asm__(".globl\t" #name \
553 : "\n\t.equ\t" #name "," #value \
554 : "\n\t.type\t" #name ",%object")
555 :
556 : #elif defined(CONFIG_X86)
557 :
558 : #define GEN_ABSOLUTE_SYM(name, value) \
559 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
560 : ",%c0" \
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_ARC) || defined(CONFIG_ARM64)
569 :
570 : #define GEN_ABSOLUTE_SYM(name, value) \
571 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
572 : ",%c0" \
573 : "\n\t.type\t" #name ",@object" : : "n"(value))
574 :
575 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
576 : __asm__(".globl\t" #name \
577 : "\n\t.equ\t" #name "," #value \
578 : "\n\t.type\t" #name ",@object")
579 :
580 : #elif defined(CONFIG_RISCV) || defined(CONFIG_XTENSA) || defined(CONFIG_MIPS)
581 :
582 : /* No special prefixes necessary for constants in this arch AFAICT */
583 : #define GEN_ABSOLUTE_SYM(name, value) \
584 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
585 : ",%0" \
586 : "\n\t.type\t" #name ",%%object" : : "n"(value))
587 :
588 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
589 : __asm__(".globl\t" #name \
590 : "\n\t.equ\t" #name "," #value \
591 : "\n\t.type\t" #name ",%object")
592 :
593 : #elif defined(CONFIG_ARCH_POSIX)
594 : #define GEN_ABSOLUTE_SYM(name, value) \
595 : __asm__(".globl\t" #name "\n\t.equ\t" #name \
596 : ",%c0" \
597 : "\n\t.type\t" #name ",@object" : : "n"(value))
598 :
599 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
600 : __asm__(".globl\t" #name \
601 : "\n\t.equ\t" #name "," #value \
602 : "\n\t.type\t" #name ",@object")
603 :
604 : #elif defined(CONFIG_SPARC)
605 : #define GEN_ABSOLUTE_SYM(name, value) \
606 : __asm__(".global\t" #name "\n\t.equ\t" #name \
607 : ",%0" \
608 : "\n\t.type\t" #name ",#object" : : "n"(value))
609 :
610 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
611 : __asm__(".globl\t" #name \
612 : "\n\t.equ\t" #name "," #value \
613 : "\n\t.type\t" #name ",#object")
614 :
615 : #elif defined(CONFIG_RX)
616 : #define GEN_ABSOLUTE_SYM(name, value) \
617 : __asm__(".global\t" #name "\n\t.equ\t" #name \
618 : ",%c0" \
619 : "\n\t.type\t" #name ",%%object" : : "n"(value))
620 :
621 : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
622 : __asm__(".global\t" #name \
623 : "\n\t.equ\t" #name "," #value \
624 : "\n\t.type\t" #name ",#object")
625 :
626 : #else
627 : #error processor architecture not supported
628 : #endif
629 :
630 : #define compiler_barrier() do { \
631 : __asm__ __volatile__ ("" ::: "memory"); \
632 : } while (false)
633 :
634 : /**
635 : * @brief Calculate power of two ceiling for some nonzero value
636 : *
637 : * @param x Nonzero unsigned long value
638 : * @return X rounded up to the next power of two
639 : */
640 : #define Z_POW2_CEIL(x) \
641 : ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) - 1))))
642 :
643 : /**
644 : * @brief Check whether or not a value is a power of 2
645 : *
646 : * @param x The value to check
647 : * @return true if x is a power of 2, false otherwise
648 : */
649 : #define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0))
650 :
651 : #if defined(CONFIG_ASAN) && defined(__clang__)
652 : #define __noasan __attribute__((no_sanitize("address")))
653 : #else
654 : #define __noasan /**/
655 : #endif
656 :
657 : #if defined(CONFIG_UBSAN)
658 : #define __noubsan __attribute__((no_sanitize("undefined")))
659 : #else
660 : #define __noubsan
661 : #endif
662 :
663 : /**
664 : * @brief Function attribute to disable stack protector.
665 : *
666 : * @note Only supported for GCC >= 11.0.0 or Clang >= 7.
667 : */
668 : #if (TOOLCHAIN_GCC_VERSION >= 110000) || \
669 : (defined(TOOLCHAIN_CLANG_VERSION) && (TOOLCHAIN_CLANG_VERSION >= 70000))
670 : #define FUNC_NO_STACK_PROTECTOR __attribute__((no_stack_protector))
671 : #else
672 : #define FUNC_NO_STACK_PROTECTOR
673 : #endif
674 :
675 : #if defined(CONFIG_INSTRUMENTATION)
676 : #define __no_instrumentation__ __attribute__((__no_instrument_function__))
677 : #else
678 : #define __no_instrumentation__ /**/
679 : #endif
680 :
681 : #endif /* !_LINKER */
682 :
683 0 : #define TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER "-Waddress-of-packed-member"
684 0 : #define TOOLCHAIN_WARNING_ARRAY_BOUNDS "-Warray-bounds"
685 0 : #define TOOLCHAIN_WARNING_ATTRIBUTES "-Wattributes"
686 0 : #define TOOLCHAIN_WARNING_DELETE_NON_VIRTUAL_DTOR "-Wdelete-non-virtual-dtor"
687 0 : #define TOOLCHAIN_WARNING_EXTRA "-Wextra"
688 0 : #define TOOLCHAIN_WARNING_NONNULL "-Wnonnull"
689 0 : #define TOOLCHAIN_WARNING_SHADOW "-Wshadow"
690 0 : #define TOOLCHAIN_WARNING_UNUSED_LABEL "-Wunused-label"
691 0 : #define TOOLCHAIN_WARNING_UNUSED_VARIABLE "-Wunused-variable"
692 0 : #define TOOLCHAIN_WARNING_CAST_QUAL "-Wcast-qual"
693 :
694 : /* GCC-specific warnings that aren't in clang. */
695 : #if defined(__GNUC__) && !defined(__clang__)
696 : #define TOOLCHAIN_WARNING_POINTER_ARITH "-Wpointer-arith"
697 : #define TOOLCHAIN_WARNING_STRINGOP_OVERREAD "-Wstringop-overread"
698 : #endif
699 :
700 : #define _TOOLCHAIN_DISABLE_WARNING(compiler, warning) \
701 : TOOLCHAIN_PRAGMA(compiler diagnostic push) \
702 : TOOLCHAIN_PRAGMA(compiler diagnostic ignored warning)
703 :
704 : #define _TOOLCHAIN_ENABLE_WARNING(compiler, warning) TOOLCHAIN_PRAGMA(compiler diagnostic pop)
705 :
706 0 : #define TOOLCHAIN_DISABLE_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(GCC, warning)
707 0 : #define TOOLCHAIN_ENABLE_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(GCC, warning)
708 :
709 : #if defined(__GNUC__) && !defined(__clang__)
710 : #define TOOLCHAIN_DISABLE_GCC_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(GCC, warning)
711 : #define TOOLCHAIN_ENABLE_GCC_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(GCC, warning)
712 : #endif
713 :
714 : #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ */
|