TI Arm Clang Compiler Tools - 1.3.1.LTS Release Notes

Table of Contents

Introduction

Version 1.3.1.LTS of the TI Arm Clang Compiler Tools, also known as the tiarmclang compiler, is derived from the open source LLVM/Clang source code base and the LLVM Compiler Infrastructure source base that can be found in GitHub (github.com).

The tiarmclang compiler can be used to compile and link C/C++ and assembly source files to build static executable application files that can be loaded and run on an Arm Cortex processor (m0, m0plus, m3, m4, m33, r4, and r5). Please see the Device Support section below for further information about which compiler options to use when building an application for a particular Arm Cortex processor configuration.

Long-Term Support Release

This is a Long-Term Support (LTS) patch release.

For definitions and explanations of STS, LTS, and the versioning number scheme, please see SDTO Compiler Version Numbers

Documentation

The TI Arm Clang Compiler Tools User’s Guide is now available online at the following URL:

Since the tiarmclang compiler is derived from the LLVM project’s Clang compiler source base, much of the generic Clang online documentation is also applicable to the tiarmclang compiler. The latest version of the generic Clang documentation can be found here:

TI E2E Community - Where to Get Help

Post compiler related questions to the TI E2E design community forum and select the TI device being used.

The following is the top-level webpage for all of TI’s Code Generation Tools.

If submitting a defect report, please attach a scaled-down test case with command-line options and the compiler version number to allow us to reproduce the issue easily.

Defect Tracking Database

Compiler defect reports can be tracked at the new Development Tools bug database, SIR. SIR is a JIRA-based view into all public tools defects. The old SDOWP tracking database will be retired.

A my.ti.com account is required to access this page. To find an issue in SIR, enter your defect id in the top right search box once logged in. Alternatively from the top red navigation bar, select “Issues” then “Search for Issues”.

To find an old SDOWP issue, place the SDOWP ID in the search box and use double quotes around the SDOWP ID.

What’s New

Prevent TI linker from allocating system heap when it isn’t required

In some cases, the TI linker would unnecessarily allocate a system heap in .sysmem when no routines required it.

Mitigate the cve-2021-35465 security vulneratbility

Recently a vulnerability issue was found in the implementation of VLLDM instruction in the Arm Cortex-M33. If the VLLDM instruction is abandoned due to an exception or interrupt when it is partially completed, it is possible for subsequent non-secure handler to access and modify the partial restored register values. This vulnerability is identified as CVE-2021-35465.

The mitigation sequence varies between v8-m and v8.1-m as follows:

   v8-m.main
   ---------
   mrs        r5, control
   tst        r5, #8       /* CONTROL_S.SFPA */
   it         ne
   .inst.w    0xeeb00a40   /* vmovne s0, s0 */
   1:
   vlldm      sp           /* Lazy restore of d0-d16 and FPSCR. */
    
   v8.1-m.main
   -----------
   vscclrm    {vpr}        /* Clear VPR. */
   vlldm      sp           /* Lazy restore of d0-d16 and FPSCR. */

More details on developer.arm.com/support/arm-security-updates/vlldm-instruction-security-vulnerability

Support for Function Outlining on Cortex-M0/M0+

The tiarmclang 1.3.0.LTS release supports function outlining code size optimizations for Arm Cortex-M0/M0+ processor variants.

Function outlining (aka “machine outlining”) is an optimization that saves code size by identifying recurring sequences of machine code and replacing each instance of the sequence with a call to a new function that executes the sequence of operations that the original machine code did. The compiler will effect this optimization only when it can determine that replacing each recurrence of a sequence with a call and adding a definition of a function containing the recurring sequence results in smaller code size overall.

The tiarmclang compiler also support an -moutline-inter-function option that instructs the compiler to employ the function outlining optimizations on an inter-function basis (across function boundaries). This mode of function outlining is more aggressive than the default mode of function outlining. It does not guarantee an overall code size reduction, but it is likely to be beneficial when all functions defined in a given compilation unit are included in the linked application.

This optimization is enabled for Cortex-M0/M0+ when the tiarmclang compiler is invoked with the -Oz option. The optimization can also be disabled under -Oz by specifying the -mno-outline option on the command-line.

Improvements to memset Function Inlining Optimizations

The tiarmclang compiler supports an -mllvm -arm-memset-max-stores=<n> option that allows you to control the criteria used by the compiler to decide whether or not to inline a call to the memset function.

If this option is not used, the compiler will inline the call to memset if the maximum number of stores employed by memset is <= 4 when optimizing for code size (-Os and -Oz options), and <= 8 otherwise.

If -mllvm -arm-memset-max-stores=<n> is specified on the tiarmclang command-line, then the integer value specified for <n> will override the default criteria (maximum number of stores limit) for inlining a memset call.

Consider an example with the following source code:

#include <string.h>

struct {
  int t1;
  int t2;
  int t3;
  int t4;
  short t5;
  long t6;
} my_struct_inline;

void func()
{
  memset(&my_struct_inline, 0, sizeof(my_struct_inline));
}

When compiled as follows:

%> tiarmclang -mcpu=cortex-m0plus -Oz -mllvm -arm-memset-max-stores=6 -S test.c

The compiler generated assembly code reveals that the call to memset has been inlined since the -mllvm -arm-memset-max-stores=6 option sets the maximum number of stores limit to 6 and the size of my_struct_inline is 24 bytes, so the memset call can be accomplished via 6 32-bit stores:

        .section        .text.func,"ax",%progbits
        .hidden func
        .globl  func
        .p2align        2
        .type   func,%function
        .code   16                              @ @func
        .thumb_func
func:
        ldr     r0, .LCPI0_0
        movs    r1, #0
        str     r1, [r0]
        str     r1, [r0, #4]
        str     r1, [r0, #8]
        str     r1, [r0, #12]
        str     r1, [r0, #16]
        str     r1, [r0, #20]
        bx      lr
        .p2align        2
.LCPI0_0:
        .long   my_struct_inline

        .hidden my_struct_inline                @ @my_struct_inline
        .type   my_struct_inline,%object
        .comm   my_struct_inline,24,4

The optimal value for the argument <n> to use with the -mllvm -arm-memset-max-stores=<n> option will vary depending on each particular use-case. Adjusting this value will only be beneficial if you are able to control the limit as needed.

Smaller Implementations of Runtime Support Integer Div/Mod Routines for Cortex-M0/M0+

Implementations of the following Cortex-M0/M0+ runtime support routines have been updated to provide a code size savings for applications that use them:

Support for fully_populate_jump_tables Function Attribute

The tiarmclang compiler supports the use of the fully_populate_jump_tables function attribute to disable switch statement optimizations that may cause the timing of a function to be inconsistent. This attribute can be useful for interrupt service routines that are time-sensitive.

Apply __attribute__((fully_populate_jump_tables)) to a function declaration to allow the function’s switch statements to use fully populated jump tables (if possible) with no minimum density up to a maximum range limit of 100 entries.

Note: this attribute may negatively impact code size depending on the size of the jump table.

Support for stpcpy / stpncpy in C Runtime Support Library

Suppport has been added for the stpcpy and stpncpy functions in the C runtime library:

Branch Coverage Added to Source-Based Code Coverage Support

In addition to function coverage, instantiation coverage, line coverage, and region coverage, the tiarmclang compiler implementation of Source-Based Code Coverage also includes branch coverage that allows users to measure “True/False” execution coverage of leaf-level Boolean expressions used in conditional statements. For more details about the tiarmclang compiler’s implementation of code coverage, see the “Source-Based Code Coverage with tiarmclang” section of the “tiarmclang Getting Started Guide.”

Updated C++ Name Demangler (tiarmdem) and Name (tiarmnm) Utilities

The previous TI-specific versions of the tiarmdem and tiarmnm utilities have been replaced by new versions that have been derived from the LLVM open source base. While the new versions of these utilities provide equivalent functionality compared to the previous versions, the command-line interface for the new versions is different from the previous versions.

C++ Name Demangler Utility (tiarmdem)

The C++ name demangler, tiarmdem, is a debugging aid that translates C++ mangled names to their original name found in the relevant C++ source code. The tiarmdem utility reads in input, looking for mangled names. All unmangled text is copied to output unaltered. All mangled names are demangled before being copied to output.

The syntax for invoking the C++ name demangler is:

  tiarmdem [options] <mangled names ...>

The C++ name demangler writes output to stdout. You can pipe the output to a file if desired.

Differences vs. Previous Version of C++ Name Demangler

Processing Text Input

Unlike the previous version of the C++ name demangler, the new version of tiarmdem will not process a text file specified as an argument to tiarmdem. Assuming that test.s is a compiler generated assembly file, you cannot specify test.s as an argument to tiarmdem. Instead, you can pipe the text file as input to the tiarmdem utility as follows:

  tiarmdem < test.s

or

  cat test.s | tiarmdem

Saving Output to a File

The previous version of the C++ name demangler supported an “--output-file” option that allowed you to write the output of the tiarmdem utility to a file. The new version of tiarmdem does not support a --output option. Instead, the output can be redirected to a file like so:

  cat test.s | tiarmdem > tiarmdemout

No ABI Option Needed

The previous version of the C++ name demangler required that an --abi=eabi option be specified in order to demangle C++ names that are generated by the tiarmclang compiler. The new version of tiarmdem assumes EABI and no ABI option is needed to process tiarmclang compiler generated C++ mangled names.

Name Utility (tiarmnm)

The name utility, tiarmnm, prints the list of symbol names defined and referenced in an object file, executable file, or object library. It also prints the symbol value and an indication of the symbol’s kind.

The syntax for invoking the name utility is:

  tiarmnm [options] <input files>

The output of the name utility is written to stdout. You can also elect to pipe the output to a file or as input to the C++ name demangler.

Symbol Kind Annotations

In the output from the tiarmnm utility, symbol names are annotated with an indication of their kind. The new version of the tiarmnm utility uses the following list of annotation characters to represent the different symbol kinds:

Differences vs. Previous Version of Name Utility

Thumb Function Symbols

In the previous version of the name utility, the value of a thumb function symbol would include a 1 in the least significant bit (the thumb mode bit), but the new version of tiarmnm will not report a 1 in the least significant bit position for thumb function symbol values.

Debug Symbol Names

The previous version of the name utility would include debug symbol names in the output. However, to include debug symbols in the output of the new versoin of tiarmnm, you must specify the tiarmnm’s --debug-syms option on the command-line.

Command-Line Options

Functionally Equivalent Option Mappings

Several of the options available in the previous version of the name utility now have functionally equivalent options with different syntax in the new version of the tiarmnm utility. Below is a list of option mappings where the old option symtax is specified first and the second option syntax pertains to the new version of the tiarmnm utility:

KEY: old option syntax -> new option syntax - description

Options No Longer Supported

The previous version of the name utility supported several command-line options that are no longer supported in the new version of the tiarmnm utility. These include:

Symbol Kind Annotations

The previous version of the name utility will annotate some symbols with kind information differently than the new version of the tiarmnm utility. One of the known differences is that the previous version of the name utility uses ‘d’ to annotate debug symbols, whereas the new version of tiarmnm uses ‘N’. There may be other differences. Please consult the above list of symbol kind annotations for the tiarmnm utility for more information.

Saving Output to a File

As indicated above, the previous version of the name utility supports a command-line option to write the output to a specified file, but the new version of the tiarmnm utility does not support such a command-line option. Instead, you can elect to pipe the output of tiarmnm to a file:

  tiarmnm test.o > tiarmnmout

or to the C++ name demangler utility, for example:

  tiarmnm test.o | tiarmdem > tiarmdemout

An Example

Consider the following source file (test.cpp):

  int g_my_num;
  namespace NS { int ns_my_num = 2; }
  int f() { return g_my_num + NS::ns_my_num; }
  int main() { return f(); }

If the above test.cpp is compiled:

  tiarmclang -mcpu=cortex-m4 -c test.cpp

We can then use the tiarmnm utility to write out the symbol names in test.o:

  %> tiarmnm test.o
  00000000 T _Z1fv
  00000000 D _ZN2NS9ns_my_numE
  00000000 B g_my_num
  00000000 T main

and we could pass the output of tiarmnm to tiarmdem to demangle the mangled names that are present in the tiarmnm output:

  %> tiarmnm test.o | tiarmdem
  00000000 T f()
  00000000 D NS::ns_my_num
  00000000 B g_my_num
  00000000 T main

Automatic Selection of Printf Support Implementation

The compiler tools will at link-time choose the smallest version of the underlying printf support function, __TI_printfi, used to support processing of format strings and format specifiers for the C RTS family of printf-like functions (printf, sprintf, fprintf, etc.).

There are three different versions of the __TI_printfi function available in the C RTS library, each providing a different level of support for processing format strings as the need dictates in a given application. The linker will choose one of these functions based on what format specifiers are used in the format strings. The three functions can then be characterized in terms of the format specifiers that they support:

If your application uses printf-type functions in the C RTS library, but it does not use format specifiers that require more involved code to support, then you may realize a code size savings if the linker is able to determine that it is safe to use a smaller version of __TI_printfi.

Automatic Selection of memcpy/memset Implementation

The compiler tools will at link-time choose versions of the C RTS memcpy and memset functions according to the optimization goals of a given application.

There are two different versions of each of the memcpy and memset functions available in the C RTS library. One version is designed for efficient performance in terms of run-time, and a second version is much smaller than the first, but relatively slow compared to the first especially if large blocks of data are to be handled by the memcpy or memset functions.

The selection of the memcpy and memset function implementations can be incluenced by the tiarmclang optimization option that is specified on the tiarmclang command-line. If the specified optimization option favors generating smaller code (as with the -Oz option), the linker will choose the smaller implementation of memcpy and memset. If the optimization option specified favors generating faster code (as with the -O3 option), the linker will choose the faster implementation of the memcpy and memset functions.

The selection of the memcpy and memset function implementations can also be controlled via the following linker options:

Use of these options will override any influence that the optimization option has on the link-time selection of the memcpy or memset implementation. If neither the –use_memcpy/–use_memset options nor an optimization option is specified for the build of an application, then the linker will select the smaller implementation of the memcpy and memset functions by default.

Stack Smashing Detection

The tiarmclang compiler tools provide stack protection functionality in the form of the -fstack-protector and -fstack-protector-all options:

How to enable Stack Smashing Detection

To enable stack smashing detection in your application, you need to provide definitions of:

  void __stack_chk_fail(void) {
    printf("__stack_chk_guard has been corrupted\n");
    exit(0);
  }
  unsigned long __stack_chk_guard = 0xbadeebad;

You can then compile a file containing both of these definitions to produce an object file that can be linked into an application that is instrumented for stack smashing detection.

The -fstack-protector or -fstack-protector-all option can then be specified on the compiler command-line to instrument your application code with the stack smashing detection mechanisms.

Here is a simple example to summarize and demonstrate …

The stack_check.c source file can then be compiled to generate stack_check.o:

  %> tiarmclang -mcpu=cortex-m4 -c stack_check.c

and the stack_smash.c source file is compiled and linked with stack smashing detection enabled via the use of the -fstack-protector-all option:

  %> tiarmclang -mcpu=cortex-m4 -fstack-protector-all stack_smash.c stack_check.o -o stack_smash.out -Xlinker -llnk.cmd

When loaded and run, the error message is emitted and the program exits when the stack check fails before returning from foo():

  %> load470 -q stack_smash.out
  ERROR: __stack_chk_guard has been corrupted

Support for noinit and persistent Attributes

The tiarmclang compiler supports the noinit and persistent attributes.

The noinit Attribute

Normally, global or local static variables are zero-initialized if not otherwise explicitly initialized. Some applications, however, make use of non-volatile memory that would make not initializing certain variables useful.

When the noinit attribute is applied to a global or static variable, the variable will keep its current value when a processor or platform is reset or loses power. It is not modified by default initialization on resumption of the program. Such a variable must not have an explicit initialization.

Consider a few examples:

// Error, use __attribute__((persistent)) instead
__attribute__((noinit)) int x = 5;

// Error, not global/static
void foo() { __attribute__((noinit)) int x; }

// Ok
__attribute__((noinit)) int x;
void foo() { __attribute__((noinit)) static int x; }

The noinit attribute may be used in conjunction with the location attribute to map variables to a specific memory location, like a memory-mapped register, but without generating unwanted writes.

The persistent Attribute

Normally, global or local static variables have their values reset when a program is restarted, either through loss-of-power or through a reset. Some applications, however, make use of non-volatile memory that would make not re-initializing certain variables useful.

When the persistent attribute is applied to a global or static variable, the variable is initialized to a known value on program start, but will keep its current value when a platform resets or loses power.

Consider a few examples:

// Error, use __attribute__((noinit)) instead
__attribute__((persistent)) int x;

// Error, not global/static
void foo() { __attribute__((persistent)) int x; }

// Ok
__attribute__((persistent)) int x = 5;
void foo() { __attribute__((persistent)) static int x = 5; }

If you are using non-volatile RAM, you can define a persistent variable with an initial value of zero loaded into RAM. The program can increment that variable over time as a counter, and that count will not disappear if the device loses power and restarts, because the memory is non-volatile and the boot routines do not initialize it back to zero.

For example:

__attribute__((persistent, location(0xC200))) int x = 0;

void main() {
  run_init();
  while (1) {
    run_actions(x);
    wait_cycles(1000000);
    x++;
  }
}

Updated ARM EABI Helper Functions in C Runtime Library

In previous releases of the tiarmclang compiler tools (prior to 1.0.0-alpha.2), the ARM EABI helper functions used by the C compiler to perform floating-point arithmetic were implemented in C. The implementation of these helper functions has since been replaced with smaller, more efficient implementations that are written in assembler language.

Applications that contain references to these helper functions are likely to realize a code size savings when built with the latest tiarmclang compiler release compared to builds with earlier versions of the tiarmclang compiler.

All Runtime Libraries are Built with Optimization (-Oz)

Some early analysis of tiarmclang code size gaps vs. armcl revealed that some of the runtime libraries provided with the tiarmclang compiler tools package were not being compiled with optimization turned on.

The applicable libraries include:

Since these libraries are now compiled with the -Oz option, applications that make use of functions in these libraries may realize some code size savings cersus earlier versions of the tiarmclang compiler tools.

Legacy TI-Syntax ARM Assembler Can Be Invoked from tiarmclang

The tiarmclang compiler can be instructed to process input files with its TI-syntax ARM assembler. The assembly language source files, written using legacy TI-syntax ARM assembly code, can be indicated to the tiarmclang compiler using the "-x language" option, where language is "ti-asm". This option applies to all subsequent input files, so be sure to reset the input file type if there are non-TI-syntax ARM assembly source files on the command line following the TI-syntax ARM assembly source files.

For example, in the following command:

    %> tiarmclang c-source1.c -x ti-asm ti-asm-source1.asm -x none c-source2.c

the "-x ti-asm" option indicates that the ti-asm-source1.asm file is to be processed by the TI-syntax ARM assembler, and the subsequent "-x none" option resets the input file type to a default state so that the tiarmclang compiler knows to process the c-source2.c input file as a C file.

While many important options that need to be passed to the TI-syntax ARM assembler, such as silicon version and FPU version, can be inferred from the compiler’s normal command line options, other options that you might need may be missing or need to be overridden. To support this, two new options, "-Wti-a" and "-Xti-assembler" are supported. These behave similarly to tiarmclang’s other "-W" and "-X" options. Please see -Xlinker flag and -Wl flag for examples of the "-X" and "-W" options that apply to the linker.

Some helpful options available for use are:

Remember that when passing one of the above options to the TI-syntax ARM assembler from the tiarmclang command line, to precede the option with the tiarmclang’s "-Xti-assembler" or "-Wti-a" option. In this example,

    %> tiarmclang ... -x ti-asm tia.asm -Xti-assembler \-\-define=MY_PREDEF_SYM=10 ...

the "--define=MY_PREDEF_SYM=10" option is passed to the TI-syntax ARM assembler when processing the TI-syntax ARM assembly source file, "tia.asm".

armcl -> tiarmclang Migration Aid Diagnostics

When migrating an ARM C/C++ application project from using the armcl compiler to using the tiarmlang compiler you may have instances of TI-specific pragmas, pre-defined macro symbols, or intrinsics that are supported by the armcl compiler, but not the tiarmclang compiler. To make your C/C++ source code more portable, we advise that you find these instances of TI-specific pragmas, pre-defined macro symbols, and instrinsics and convert them into their ACLE (ARM C Language Extensions) counterparts.

Please refer to the ARM C Language Extensions specification for details about ACLE.

To help with this process, the tiarmclang compiler will emit a diagnostic when it encounters the use of a legacy TI pre-defined macro symbol, pragma, or intrinsic and provide information about how that use can be safely transformed into a functionally equivalent ACLE alternative, if one exists. In cases where there is no functionally equivalent ACLE alternative to replace an instance of a legacy TI pre-defined macro symbol, pragma, or intrinsic, the tiarmclang compiler will emit a diagnostic to inform you about the presence of that legacy TI mechanism.

Let’s consider a couple of examples …

#pragma FUNC_CANNOT_INLINE

The tiarmclang compiler will emit the following diagnostic:

warning: pragma FUNC_CANNOT_INLINE is a legacy TI pragma and not supported in
clang compilers. use '__attribute__((noinline))' instead

However, the legacy TI pre-defined macro symbol __TI_ARM_V4__ does not have a viable ACLE alternative, so the following code:

#if defined(__TI_ARM_V4__)
 ...
#endif

will cause the tiarmclang compiler to emit the following diagnostic:

warning: '__TI_ARM_V4__' is a legacy TI macro and not supported in clang compilers

The migration aid warning diagnostics for use of legacy TI macro symbols, pragmas, and intrinsics are enabled by default in the tiarmclang compiler. If you wish to suppress any of the three migration aid diagnostic types, you can specify:

Support for Unsigned 32- and Signed 64-Bit POSIX time_t

The tiarmclang compiler defines time_t by default as a POSIX-compatible signed 64-bit value using the POSIX epoch of January 1, 1970. This is different from the TI proprietary ARM compiler (armcl), which defines time_t as an unsigned 32-bit value using a legacy TI-defined epoch of January 1, 1900. You do not need to take any special steps or define any macros to use the new implementation, just be sure to include time.h and use the standard C functions as you normally would. The standard C time functions will automatically map to 64-bit implementations.

AEABI portability mode

If you must link object files built with the tiarmclang compiler tools with object files built by other compiler vendors, you must use AEABI portability mode. The ARM standard (Section 5.20 of the "C Library ABI for the ARM® Architecture") specifies that you must define the _AEABI_PORTABILITY_LEVEL preprocessor macro as follows before #include’ing any standard header files, particularly <time.h>:

#define _AEABI_PORTABILITY_LEVEL 1

This definition enables full portability. For time.h, defining and setting this macro will force the compiler to use an unsigned 32-bit representation for time_t with POSIX epoch. All calls to the standard C time functions will refer to their 32-bit variants. In addition, the compiler will also ensure that the _AEABI_PORTABLE macro is defined, as required by the standard.

You may also interlink third party object code with the tiarmclang linker and runtime library, including calling the standard C time functions, requiring no special steps. You are responsible for ensuring that AEABI portability is used consistently throughout your application.

Other ways to leverage the unsigned 32-bit representation of time_t

You may also activate the unsigned 32-bit representation of time_t without activating AEABI portability mode. Instead of setting the _AEABI_PORTABILITY_LEVEL macro, simply set the macro __TI_TIME_USES_64=0.

As long as variables of type time_t aren’t used globally, you may freely link object files built using __TI_TIME_USES_64=0 with those that do not since the actual time functions in the RTS are not changed.

Concerns when migrating from ARMCL to TI ARM CLANG

Support for atexit() in Static Executable Use Cases

The tiarmclang compiler tools’ C runtime library provides support for using the atexit() function to register functions to be executed upon exit.

The implemented support for atexit() adheres to the Itanium C++ ABI - Construction and Destruction APIs for static executable use cases. It does not support dynamic linking and dynamic shared object use cases.

General Discussion of Implemented Functionality

First, some basic characteristics:

If atexit() is called to register a function during exit, perhaps even in the process of calling the already registered functions, then the newly registered function will be placed on the top of the function pointer stack. This situation may occur if atexit() is called as part of a destructor function.

In the TI proprietary ARM compiler tools (armcl), the maximum number of functions that could be registered via atexit() is 32. In the tiarmclang compiler tools, there is not a set limit for how many functions can be registered.

The atexit() implementation provided in the tiarmclang compiler tools does incur some overhead in terms of data space allocation to maintain the stack. Upon the first instance where a function is registered via atexit(), the C runtime library will allocate a data structure of 136 bytes to support up to 8 registered functions. If a program requires more than 8 registered functions, then an additional 136 bytes of memory will be allocated for every 8 functions registered via atexit().

Consider an example that demonstrates how to register a function to be called when the program exits:

#include <stdio.h>
#include <stdlib.h>

void foo() {
  printf("foo\n");
}

int main() {
  atexit(foo);
  return 0;
}

When run, the above program will write “foo” to stdout.

Standard atexit implementations require two function definitions: atexit() itself, and __cxa_atexit(). The atexit() function can be called explicitly as shown in the above example, but __cxa_atexit() can not. By default, the tiarmclang compiler will register global destructors via the __cxa_atexit() function. However, the tiarmclang compiler will use atexit() instead if the tiarmclang -fno-use-cxa-atexit option is specified on the command line.

Updated tiarmclang -help Display Output

The tiarmclang -help option output has been updated to provide information about options that are more commonly used in the development of applications for Arm Cortex processors. For more details about commonly used tiarmclang options, see the section entitled “Using the tiarmclang Compiler and Linker” in the tiarmclang Getting Started Guide

Testing and Validation

The tiarmclang toolchain is tested using a combination of commercial and in-house-developed test suites that test the correctness and robustness of the tiarmclang compiler tools. New testing continues to be added to the suite of TI proprietary custom tests (a.k.a. PHIL) to verify functionality and robustness of newly added features.

Our normal regression testing of the tiarmclang compiler tools includes:

Recently Fixed Issues

CODEGEN-8639 : tiarmar.exe is denied permission to create an archive file on Windows 7

When the tiarmclang 1.2.1.STS toolchain’s archiver, tiarmar.exe, is run on a Windows 7 machine, it is being denied permission to create an archive file.

This issue has been addressed in the tiarmclang 1.3.0.LTS release.

CODEGEN-6288 : tiarmclang optimizer removes empty loops that don’t have side effects

In tiarmclang releases prior to 1.2.1.STS, the optimizer would remove an empty while loop that contained no side effects. If a function contained only such a loop, then the optimizer would remove references to the function from other functions in the saem compilation unit even if the function were annotated with an optnone function attribute.

In tiarmclang releases starting with 1.2.1.STS, you can now mark a function containing an empty loop with no side effects with an optnone function attribute and references to the function will not be removed.

Alternatively, you can specify an asm() statement inside the body of the empty loop to create a side effect that will prevent the loop from being removed. For example:

  while (1) {
    __asm(" ");
  }

Host Support / Dependencies

The following host-specific versions of the 1.3.0.LTS tiarmclang compiler are available:

Device Support

The tiarmclang compiler supports development of applications that are to be loaded and run on one of the following Arm Cortex processor variants:

ARM Processor Variant Options
Cortex-M0 “-mcpu=cortex-m0”
Cortex-M0+ “-mcpu=cortex-m0plus”
Cortex-M3 “-mcpu=cortex-m3”
Cortex-M4 without FPv4SPD16 “-mcpu=cortex-m4 -mfloat-abi=soft”
Cortex-M4 with FPv4SPD16 “-mcpu=cortex-m0 -mfloat-abi=hard -mfpu=fpv4-sp-d16”
Cortex-M33 without FPv5SPD16 “-mcpu=cortex-m33 -mfloat-abi=soft”
Cortex-M33 with FPv5SPD16 “-mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16”
Cortex-R4 (Thumb) without VFPv3D16 “-mcpu=cortex-r4 -mthumb -mfloat-abi=soft”
Cortex-R4 (Thumb) with VFPv3D16 “-mcpu=cortex-r4 -mthumb -mfloat-abi=hard -mfpu=vfpv3-d16”
Cortex-R4 without VFPv3D16 “-mcpu=cortex-r4 -mfloat-abi=soft”
Cortex-R4 with VFPv3D16 “-mcpu=cortex-r4 -mfloat-abi=hard -mfpu=vfpv3-d16”
Cortex-R5 (Thumb) without VFPv3D16 “-mcpu=cortex-r5 -mthumb -mfloat-abi=soft”
Cortex-R5 (Thumb) with VFPv3D16 “-mcpu=cortex-r5 -mthumb -mfloat-abi=hard -mfpu=vfpv3-d16”
Cortex-R5 without VFPv3D16 “-mcpu=cortex-r5 -mfloat-abi=soft”
Cortex-R5 with VFPv3D16 “-mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16”

Resolved Defects

ID Summary
CODEGEN-9092 tiarmclang mistakenly documents support for -fpic position independent code
CODEGEN-8914 _enable_IRQ in ti_compatibility.h only supports Cortex-M devices

Known Defects

The up-to-date known defects in v1.3.1 can be found here (dynamically generated):

Known defects in v1.3.1

End Of File