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-09-05 16:43:28

            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              : #define FUNC_NO_STACK_PROTECTOR _Pragma("no_stack_protect")
     191              : 
     192              : #ifndef __attribute_const__
     193              : #if __VER__ > 0x09000000
     194              : #define __attribute_const__ __attribute__((const))
     195              : #else
     196              : #define __attribute_const__
     197              : #endif
     198              : #endif
     199              : 
     200              : #ifndef __must_check
     201              : /* #warning "The attribute __warn_unused_result is not supported in ICCARM". */
     202              : #define __must_check
     203              : /* #define __must_check __attribute__((warn_unused_result)) */
     204              : #endif
     205              : 
     206              : #define __PRAGMA(...) _Pragma(#__VA_ARGS__)
     207              : #define ARG_UNUSED(x) (void)(x)
     208              : 
     209              : #define likely(x)   (__builtin_expect((bool)!!(x), true) != 0L)
     210              : #define unlikely(x) (__builtin_expect((bool)!!(x), false) != 0L)
     211              : #define POPCOUNT(x) __builtin_popcount(x)
     212              : 
     213              : #ifndef __no_optimization
     214              : #define __no_optimization __PRAGMA(optimize = none)
     215              : #endif
     216              : 
     217              : #ifndef __attribute_nonnull
     218              :  #define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
     219              : #endif
     220              : 
     221              : /* __weak is an ICCARM built-in, but it doesn't work in all positions */
     222              : /* the Zephyr uses it so we replace it with an attribute((weak))      */
     223              : #define __weak __attribute__((__weak__))
     224              : 
     225              : /* Builtins */
     226              : 
     227              : #include <intrinsics.h>
     228              : 
     229              : /*
     230              :  * Be *very* careful with these. You cannot filter out __DEPRECATED_MACRO with
     231              :  * -wno-deprecated, which has implications for -Werror.
     232              :  */
     233              : 
     234              : 
     235              : /*
     236              :  * Expands to nothing and generates a warning. Used like
     237              :  *
     238              :  *   #define FOO __WARN("Please use BAR instead") ...
     239              :  *
     240              :  * The warning points to the location where the macro is expanded.
     241              :  */
     242              : #define __WARN(s) __PRAGMA(message = #s)
     243              : #define __WARN1(s) __PRAGMA(message = #s)
     244              : 
     245              : /* Generic message */
     246              : #ifndef CONFIG_DEPRECATION_TEST
     247              : #define __DEPRECATED_MACRO __WARN("Macro is deprecated")
     248              : #else
     249              : #define __DEPRECATED_MACRO
     250              : #endif
     251              : 
     252              : 
     253              : 
     254              : /* These macros allow having ARM asm functions callable from thumb */
     255              : 
     256              : #if defined(_ASMLANGUAGE)
     257              : 
     258              : #if defined(CONFIG_ASSEMBLER_ISA_THUMB2)
     259              : #define FUNC_CODE() .code 32
     260              : #define FUNC_INSTR(a)
     261              : /* '.syntax unified' is a gcc-ism used in thumb-2 asm files */
     262              : #define _ASM_FILE_PROLOGUE .text; .syntax unified; .thumb
     263              : #else
     264              : #define FUNC_CODE()
     265              : #define FUNC_INSTR(a)
     266              : #define _ASM_FILE_PROLOGUE .text; .code 32
     267              : #endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */
     268              : 
     269              : /*
     270              :  * These macros are used to declare assembly language symbols that need
     271              :  * to be typed properly(func or data) to be visible to the OMF tool.
     272              :  * So that the build tool could mark them as an entry point to be linked
     273              :  * correctly.  This is an elfism. Use #if 0 for a.out.
     274              :  */
     275              : 
     276              : /* This is not implemented yet for IAR */
     277              : #define GTEXT(sym)
     278              : #define GDATA(sym)
     279              : #define WTEXT(sym)
     280              : #define WDATA(sym)
     281              : 
     282              : #define SECTION_VAR(sect, sym)
     283              : #define SECTION_FUNC(sect, sym)
     284              : #define SECTION_SUBSEC_FUNC(sect, subsec, sym)
     285              : 
     286              : #endif /* _ASMLANGUAGE */
     287              : 
     288              : 
     289              : /*
     290              :  * These macros generate absolute symbols for IAR
     291              :  */
     292              : 
     293              : /* create an extern reference to the absolute symbol */
     294              : 
     295              : #define GEN_OFFSET_EXTERN(name) extern const char name[]
     296              : 
     297              : #define GEN_ABS_SYM_BEGIN(name) \
     298              :         EXTERN_C void name(void); \
     299              :         void name(void)         \
     300              :         {
     301              : 
     302              : #define GEN_ABS_SYM_END }
     303              : 
     304              : /*
     305              :  * Note that GEN_ABSOLUTE_SYM(), depending on the architecture
     306              :  * and toolchain, may restrict the range of values permitted
     307              :  * for assignment to the named symbol.
     308              :  */
     309              : #define GEN_ABSOLUTE_SYM(name, value) \
     310              :         __PRAGMA(public_equ = #name, (unsigned int)value)
     311              : 
     312              : /*
     313              :  * GEN_ABSOLUTE_SYM_KCONFIG() is outputted by the build system
     314              :  * to generate named symbol/value pairs for kconfigs.
     315              :  */
     316              : #define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \
     317              :         __PRAGMA(public_equ = #name, (unsigned int)value)
     318              : 
     319              : #define compiler_barrier() do { \
     320              :         __asm volatile("" ::: "memory"); \
     321              : } while (false)
     322              : 
     323              : /** @brief Return larger value of two provided expressions.
     324              :  *
     325              :  * Macro ensures that expressions are evaluated only once.
     326              :  *
     327              :  * @note Macro has limited usage compared to the standard macro as it cannot be
     328              :  *       used:
     329              :  *       - to generate constant integer, e.g. __aligned(Z_MAX(4,5))
     330              :  *       - static variable, e.g. array like static uint8_t array[Z_MAX(...)];
     331              :  */
     332              : #define Z_MAX(a, b) ({ \
     333              :                 /* random suffix to avoid naming conflict */ \
     334              :                 __typeof__(a) _value_a_ = (a); \
     335              :                 __typeof__(b) _value_b_ = (b); \
     336              :                 _value_a_ > _value_b_ ? _value_a_ : _value_b_; \
     337              :         })
     338              : 
     339              : /** @brief Return smaller value of two provided expressions.
     340              :  *
     341              :  * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for
     342              :  * macro limitations.
     343              :  */
     344              : #define Z_MIN(a, b) ({ \
     345              :                 /* random suffix to avoid naming conflict */ \
     346              :                 __typeof__(a) _value_a_ = (a); \
     347              :                 __typeof__(b) _value_b_ = (b); \
     348              :                 _value_a_ < _value_b_ ? _value_a_ : _value_b_; \
     349              :         })
     350              : 
     351              : /** @brief Return a value clamped to a given range.
     352              :  *
     353              :  * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for
     354              :  * macro limitations.
     355              :  */
     356              : #define Z_CLAMP(val, low, high) ({                                             \
     357              :                 /* random suffix to avoid naming conflict */                   \
     358              :                 __typeof__(val) _value_val_ = (val);                           \
     359              :                 __typeof__(low) _value_low_ = (low);                           \
     360              :                 __typeof__(high) _value_high_ = (high);                        \
     361              :                 (_value_val_ < _value_low_)  ? _value_low_ :                   \
     362              :                 (_value_val_ > _value_high_) ? _value_high_ :                  \
     363              :                                                _value_val_;                    \
     364              :         })
     365              : 
     366              : /**
     367              :  * @brief Calculate power of two ceiling for some nonzero value
     368              :  *
     369              :  * @param x Nonzero unsigned long value
     370              :  * @return X rounded up to the next power of two
     371              :  */
     372              : #define Z_POW2_CEIL(x) \
     373              :         ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) - 1))))
     374              : 
     375              : /**
     376              :  * @brief Check whether or not a value is a power of 2
     377              :  *
     378              :  * @param x The value to check
     379              :  * @return true if x is a power of 2, false otherwise
     380              :  */
     381              : #define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0))
     382              : 
     383              : #ifndef __INT8_C
     384              : #define __INT8_C(x)     x
     385              : #endif
     386              : 
     387              : #ifndef INT8_C
     388              : #define INT8_C(x)       __INT8_C(x)
     389              : #endif
     390              : 
     391              : #ifndef __UINT8_C
     392              : #define __UINT8_C(x)    x ## U
     393              : #endif
     394              : 
     395              : #ifndef UINT8_C
     396              : #define UINT8_C(x)      __UINT8_C(x)
     397              : #endif
     398              : 
     399              : #ifndef __INT16_C
     400              : #define __INT16_C(x)    x
     401              : #endif
     402              : 
     403              : #ifndef INT16_C
     404              : #define INT16_C(x)      __INT16_C(x)
     405              : #endif
     406              : 
     407              : #ifndef __UINT16_C
     408              : #define __UINT16_C(x)   x ## U
     409              : #endif
     410              : 
     411              : #ifndef UINT16_C
     412              : #define UINT16_C(x)     __UINT16_C(x)
     413              : #endif
     414              : 
     415              : #ifndef __INT32_C
     416              : #define __INT32_C(x)    x
     417              : #endif
     418              : 
     419              : #ifndef INT32_C
     420              : #define INT32_C(x)      __INT32_C(x)
     421              : #endif
     422              : 
     423              : #ifndef __UINT32_C
     424              : #define __UINT32_C(x)   x ## U
     425              : #endif
     426              : 
     427              : #ifndef UINT32_C
     428              : #define UINT32_C(x)     __UINT32_C(x)
     429              : #endif
     430              : 
     431              : #ifndef __INT64_C
     432              : #define __INT64_C(x)    x ## LL
     433              : #endif
     434              : 
     435              : #ifndef INT64_C
     436              : #define INT64_C(x)      __INT64_C(x)
     437              : #endif
     438              : 
     439              : #ifndef __UINT64_C
     440              : #define __UINT64_C(x)   x ## ULL
     441              : #endif
     442              : 
     443              : #ifndef UINT64_C
     444              : #define UINT64_C(x)     __UINT64_C(x)
     445              : #endif
     446              : 
     447              : /* Convenience macros */
     448              : #undef _GLUE_B
     449              : #undef _GLUE
     450              : #define _GLUE_B(x, y) x##y
     451              : #define _GLUE(x, y)   _GLUE_B(x, y)
     452              : 
     453              : #ifndef INTMAX_C
     454              : #define INTMAX_C(x)  _GLUE(x, __INTMAX_C_SUFFIX__)
     455              : #endif
     456              : 
     457              : #ifndef UINTMAX_C
     458              : #define UINTMAX_C(x) _GLUE(x, __UINTMAX_C_SUFFIX__)
     459              : #endif
     460              : 
     461              : #endif /* !_LINKER */
     462              : #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_ */
        

Generated by: LCOV version 2.0-1