LCOV - code coverage report
Current view: top level - zephyr/toolchain/iar - iccarm.h Coverage Total Hit
Test: new.info Lines: 33.3 % 3 1
Test Date: 2025-10-20 12:20:01

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

Generated by: LCOV version 2.0-1