- Important information
- New features
- Known problems
- Program corrections
- User guide corrections
- Miscellaneous
- Release history
Important information
- Limitations of compiler support for Armv8.1-M
There are some limitations to the support for Armv8.1-M in this release, to be addressed in a future release:
- MVE: The Cortex-M vector extension can be utilized by means of intrinsic functions.
There is currently no support for auto-vectorization. The header filecannot be included from C++ code. Some optimizations of MVE code are missing, in particular when a VCMP instruction is followed by VPST they should be combined into a VPT instruction. - LOB: Limited matching of low-overhead loops.
A candidate loop must have a loop counter that is counted down by 1 until it reaches zero. The presence of an outer loop can lead to an inner loop not being matched. Other optimizations (most notably loop unrolling) can lead to a loop not being matched. - CMSE: The Armv8.1-M register FPCXT_NS is not restored by a non-secure entry function.
- _Float16: Some operations on _Float16 (such as plus and minus) are implemented by converting the input operands to float, using the corresponding instruction for float, and converting the result to _Float16.
- The conditional instructions from Armv8-A are not utilized (CSEL, CSET, CNEG).
- MVE: The Cortex-M vector extension can be utilized by means of intrinsic functions.
- Characteristics for the toolset in AARCH64 mode:
- The toolset, by default, supports generating code and data that is situated in one space that has a maximum size of 4 Gbytes. This is because static data will be accessed with an addressing mode that reaches +/- 4 Gbytes. Mechanisms exist to jump/call between such spaces.
- The produced code, by default, runs in execution state EL1.
Limitations:
- Big-endian code is not supported.
- Position-independent code is not supported.
- V8-A AARCH32 is not fully implemented. The 32-bit implementation is currently based on v7-A.
- Compiler MISRA C C:1998/C:2004 support is removed in version 9.10
The Compiler MISRA C is still available through the compiler command line but will be removed in a future release.
Refer to IAR C-STAT for full MISRA C support. - Changes in implementation of CMSIS intrinsics in version 8.20
The implementation of the CMSIS intrinsic interface is no longer based on IAR's intrinsics.h. As a consequence of that some intrinsics that was previously declared when the CMSIS header was included are no longer declared.
Examples of these intrinsics include __LDREX(), __STREX() and __enable_interrupt().
- Changed size of wchar_t in version 8.10 and later
Object files following the ARM ABI has a runtime attribute indicating the size of
wchar_t
.In EWARM version 7.80 and earlier, the size of
wchar_t
was 2 bytes wide and the runtime attribute was set accordingly.In EWARM version 8.10 and later,
wchar_t
is 4 bytes wide. -
If you have implemented the
time()
function, you must rename it into__time32()
. For more information see the Development guide. -
A special note on CMSIS integration:
If your application source code includes CMSIS header files explicitly, then you should not select Project>Options...>General Options>Library Configuration>Use CMSIS. Some of the Cortex-M application examples include CMSIS source files explicitly. Do not select the option Use CMSIS in these projects.
Deprecated features
-
--interwork
Future versions of the IAR C/C++ Compiler for ARM will assume
--interwork
when generating code for the ARMv4T architecture. There will be no option to generate non-interworking code for ARMv4T.
-
New features
Additional GNU C language extensions
pure
andconst
function attributes- GNU style statement expressions
- GNU style case ranges
- GNU style designated initializer ranges
- Binary literals with a
0b
prefix
Known problems
-
[EWARM-9298] In some cases, when using NEON intrinsics with vector parameters, the compiler might generate an internal error.
-
[EWARM-7413] In threaded applications, the linker option --manual_dynamic_initialization now also suppresses automatic initialization of the main thread's thread local variables, to avoid unnecessary dependence on the table driven initialization for applications that want entirely manual initialization.
-
[EWARM-6667, TPB-3086] The compiler can cluster variables that are initialized by copy and zero-initialized variables with static storage duration. When the total size of the variables initialized by copy is small compared to the total size of the zero-initialized variables, and if compressed initializers are not used, this can create a significant size overhead.
-
[EWARM-5239, EW25660] Passing a parameter of type va_list to a C++ function, where the caller is defined in one object file and the callee in another, will result in a linker error if one of the two objects is built with EWARM 7.20 (or newer) and the other is built with EWARM 7.10 (or older).
-
[EWARM-4824, EW24720] MISRA-C:2004 rule 9.1 will not find all used uninitialized local variables.
Program corrections
-
[EWARM-9398] When compiling for 64-bit Arm MCUs with a Neon co-processor, the scheduler sometimes reorders the instructions LD1 and ST1 relative to other memory operations on the same memory location.
-
[EWARM-9307, TPB-3568] In the C++ library, the general templated constructor and copy assignment operator of std::function accept basically any object, but according to C++ Library issue 2132, these functions should be excluded from consideration if the object is not callable. This can cause unwanted ambiguity when std::function objects are involved in overloading.
-
The size of a function with the __exception attribute is limited to 128 bytes. This limitation is unreasonable, because the code needed to save and restore registers in the presence of a function call is more than 128 bytes.
A warning is issued for an exception function with a size greater than 128 bytes, for example:
Warning[Ta161]: Exception function "Synchronous_Handler_A64" has size 292 bytes. Maximum size of a vector is 128 bytes
See also EWARM-8868 -
[EWARM-9305] The compiler can generate incorrect code for interrupt handlers that use Advanced SIMD/NEON instructions performing saturating arithmetic. In particular, the QC bit in the FPSR register is not guaranteed to be preserved across interrupts.
See also EWARM-8868 -
The compiler can generate incorrect code if a binary operator is applied to a scalar and a vector operand, in such a way that an implicit scalar-to-vector conversion occurs.
Example:
See also EWARM-9082, EWARM-9303uint32x2_t f(uint32x2_t v) { return v + 1; }
-
In C++, some uses of constexpr variables of structure type can result in an internal error ([PaType - MemoryAttribute]: no memory attribute set). For example:
struct CC { int base; }; constexpr CC D{ 0x1 }; CC fun() { return D; }
-
The intrinsic functions _get_SB and _set_SB for 32-bit Arm are documented, but they are not implemented. If they are used, the compiler issues a warning:
Warning[Pe223]: function "__get_SB" declared implicitly
If the compiler warning is ignored, the linker will issue an error:
Error[Li005]: no definition for "__get_SB"
-
[EWARM-9217, TPB-3559] On optimization level Medium and above, the compiler can generate different code for the same source on different invocations for code containing variables with static storage duration and nested control structures. The code is expected to be correct in all cases.
-
At High optimization level, an internal error (Access violation) is issued when the compiler fails to combine writes of zero to multiple consecutive addresses, due to an immediate offset being too large for the instruction used.
This happens with higher probability:
- with the option --no_unaligned_access (which limits the available immediate offsets)
- without the option --no_clustering (static clustering leads to larger offsets).
-
[EWARM-9178, TPB-3557] On optimization level High, the compiler can generate incorrect code when common subexpression elimination is turned off.
-
On optimization level High, the compiler can generate incorrect code when the same test is performed multiple times and the tested expression contains constants that can be simplified by simple algebraic rules. A triggering example is shown below. If this flaw is present, the compiler will erroneously deduce that the second test of 7-x != 4 is always true and the generated code will print exit 2 when x is 3.
void f(int x) { if (7 - x != 4) { printf("exit 1\n"); return; } if (7 - x != 4) { printf("exit 2\n"); return; } printf("exit 3\n"); return; }
-
When smart stack protection (--stack-protection) is enabled, the compiler will sometimes allocate separate stack locations for variables that can share locations. A triggering example is shown below. In this example, the analysis will incorrectly infer that the variables j1 and j2 are alive at the same time and cannot share the same location on the stack. Although the usage of the stack locations is not optimal, the generated code is still correct.
int ff(int *); int f(int i) { switch (i) { case 1: { int j1; i = ff(&j1); i += j1; break; } case 2: { int j2; i = ff(&j2); i += j2; break; } } return i; }
-
[EWARM-9105, TPB-3548] The compiler can generate incorrect code for functions with a stack parameter when the top-most loop has more than one entry point, for instance if the top-most loop is a DO loop and starts with an IF statement.
-
In some C++ cases involving defaulted member functions with exception support disabled, the compiler can emit spurious errors and warnings about incompatible exception specifications.
For example:class Other final { public: ~Other() {} }; class Base { public: virtual ~Base() = default; }; template <typename T> class Derived : public Base { public: // ***** Spurious error Pe766 here ~Derived() override = default; private: Other other; }; // ***** Spurious warning Pe768 here class Derived2 : public Derived<int> {};
-
[EWARM-9082] For 64-bit Arm, the 128-bit NEON vector types should be 16-bytes aligned, but this is not enforced. In some cases, this can lead to a linker error, in other cases to a hardware exception in runtime.
See also EWARM-9302, EWARM-9303 -
On optimization level High, the compiler can generate incorrect code when the destination of a pointer can be written both explicitly and by calls to memcpy or memmove. One triggering example is shown below.
void f(char *p, signed long v, char m) { char tmp[2] = { 4, 2 }; char r; switch (m) { case 1: { *p = ((char)(v)); } break; case 2: { *p = ((char)((v * 255) / 100)); r = ((char)((v * 255) % 100)); if ((r >= 50) && ((*p) < 255)) { (*p)++; } } break; case 3: { *p = ((char)(v)); } break; case 4: { memcpy(p, &tmp[0], 2); } break; case 5: { memcpy(p, &tmp[0], 2); } break; } }
-
[EWARM-8986, TPB-3539] The compiler produces a stack overflow error for source code that contains an expression that encompasses over 32,000 nested ?-: expressions.
-
[EWARM-8984, TPB-3537] In compiler platform 10.8, the --no_cse command line option disables common sub-expression elimination also for compiler-generated constants. This, in combination with the Embedded Workbench IDE adding --no_cse to the compiler command line also for optimization levels None and Low, can lead to larger and slower code than for earlier compiler platforms.
-
[EWARM-8965, TPB-3534] In C mode, a structure field can hide a typedef with the same name. For example:
typedef struct refPic { struct refPic *refPic; } refPic; typedef struct { refPic refPic[20]; refPic refPicList[20]; } picBuffer;
The declaration of the refPicList field is incorrectly rejected.
-
[EWARM-8893] When using 32-bit pointers (in 32-bit mode, and in 64-bit mode with ILP32), an internal error is issued when attempting to report "Error[Ta162]: Located address is too high" because of a variable located outside the 32-bit address space.
-
[EWARM-8868] The compiler can generate incorrect code for interrupt handlers that perform floating point/advanced SIMD operations and/or call one or more functions. The upper 8 bytes of the 16 byte SIMD registers will not be preserved across interrupts.
See also EWARM-8862, EWARM-9305, EWARM-9306 -
[EWARM-8862] The compiler can generate incorrect code for nested interrupt handlers. Register X16 is clobbered by the function entrance sequence for the interrupt handler.
See also EWARM-8868, EWARM-9304 -
[EWARM-8860] Object attributes set by the compiler make the linker issue "Warning[Lt010]: Inconsistent enum container size". This happens also when the underlying type of the enum is fixed (C++11), which is incorrect, because an enum with a fixed size does not contribute to inconsistencies regarding enum size.
-
Using alignas to set the alignment of a static data member with an in-class initializer results in a spurious error Pe1887 ("alignment attribute must also appear on definition").
Example:struct X { alignas(8) static constexpr short sh[2]{42, 17}; };
-
When compiling for Thumb2 instructions set at optimization level High, the instruction scheduler can move instructions across an IT block, even if the IT block contains an instruction with side effects.
In the following example, the if statement could be flattened to an IT block, and the assignment could be scheduled before the if statement:
if (((64 - 1u) < (levelState - 1u))) { __set_BASEPRI(64); } State->Level = levelState;
Instructions with side-effects that can be affected by this bug are generated from these intrinsic functions:
__set_BASEPRI
__set_PRIMASK
__set_CONTROL
__set_FAULTMASK
__set_BASEPRI
__set_interrupt_state
__set_MSP
__set_PSP
__set_FPSCR
__MCR
__MCR2
__TT
__TTT
__TTA
__TTAT
__arm_wsr
__arm_wsrp -
In C++ mode, compilation sometimes fails for constexpr objects with internal self-referencing.
Example:struct S { int i; constexpr S(): i{} {} }; struct X { constexpr X(): p(&u.i) {} // Note: p references inside u S u; int *p; }; struct Y: X { constexpr Y() {} }; constexpr Y y; // Error[Pe2807]: initialization is not constant
-
The warning Go029 can trigger erroneously for the first assignment to a field in a bitfield struct.
struct A { int x : 8; int y : 8; }; struct A f(int x, int y) { struct A id; id.x = x; // Triggers Go029 erroneously id.y = y; return id; }
-
In C++, the compiler can emit a spurious warning Pe940 ("missing return statement at end of non-void function") in a template context, if the immediately preceding statement is an if constexpr where the condition is false (that is, the else part is active), and the end of the else part is unreachable (for example, if the else part ends with a return statement).
Example:
template<int n> class Class { public: static long test(long x) { if constexpr(n < 0) { return 0; } else { return 1; } } // Warning[Pe940]: missing return statement at end of non-void function };
User guide corrections
- None.
Miscellaneous
-
Available workarounds for device erratas:
-
ARM Cortex-M3 errata 463764
Core might freeze forSLEEPONEXIT
single instructionISR
. More information is available on infocenter.arm.com.
Workaround generated for functions with attribute__irq
withiccarm --enable_hardware_workaround=arm463764
. Supported from EWARM 5.41. -
ARM Cortex-M3 errata 602117
LDRD
with base in list might result in incorrect base register when interrupted or faulted. From EWARM 5.20.3 the compiler/library avoids theLDRD
instruction with the base register in list. -
ARM Cortex-M3 errata 752419
ARM Cortex-M4 errata 752770
Interrupted loads toSP
can cause erroneous behaviour. From EWARM 6.21 the compiler/library does not generateLDR SP
instructions with writeback toRn
. Otherwise we allow the extra reads because the stack resides in RAM where multiple reads are acceptable. -
ARM Cortex-M4 errata 776924
VDIV or VSQRT instructions might not complete correctly when very short ISRs are used. IAR recommends the second workaround proposed by Arm: "Ensure that every interrupt service routine contains more than 2 instructions in addition to the exception return instruction." The background is that the compiler is unaware of interrupts since the Cortex-M architecture does not distinguish between ordinary functions and interrupt functions. -
ARM Cortex-M7 errata 833872
Flag setting instructions inside an IT block might cause incorrect execution of subsequent instructions. From EWARM 7.40, the compiler will the skip the IT transformation on this particular code pattern. -
ARM Cortex-M3 errata 838469
ARM Cortex-M4 errata 838869
Store immediate overlapping exception return operation might vector to incorrect interrupt. Follow the guidelines in the errata and implement the workaround proposed by ARM by using__DSB(void)
in applicable cases. -
Functional problem Core.1 in NXP device LPC2478: Incorrect update of the Abort Link register in Thumb state.
Workaround generated withiccarm --enable_hardware_workaround=NXP_Core.1
-
Functional problem in Stellaris devices: Non-word-aligned write to SRAM can cause an incorrect value to be loaded. More information is available on the Stellaris web site at www.ti.com/stellaris.
Workaround generated withiccarm --enable_hardware_workaround=LM3S_NWA_SRAM_Write
-
Functional problem in Freescale Semiconductors MC9328MX1 (i.MX1), masks 0L44N, 1L44N, and 2L44N:
TheLDM
instruction will in some cases not load the second register correctly. Workaround generated withiccarm --enable_hardware_workaround=920t-ldm2
NOTE: The libraries in the current EWARM version are not built with this workaround. Use EWARM 6.50.6 and linker option--enable_hardware_workaround=920t-ldm2
to use libraries built with this hardware workaround.
-
-
RTOS Threads and TLS
The inc\c\DLib_Threads.h header file contains support for locks and thread-local storage (TLS) variables. This is useful for implementing thread support. For more information, see the header file.
-
va_args
The implementation of
va_args
functions has changed in IAR Embedded Workbench for ARM 7.20.1. It is no longer possible to compile the output of the preprocessor from an earlier version of the compiler. The original source code must be preprocessed again, using IAR Embedded Workbench for ARM 7.20.1.
Release history
-
See release history.