2. Using the tiarmclang Compiler and Linker

2.1. Using the Compiler and Linker

Both the TI Arm Clang (tiarmclang) Compiler Tools’ compiler and linker can be invoked from the tiarmclang command-line. The following subsections describe the basics of how to manage the compile and link steps of building an application from the tiarmclang command-line.

2.1.1. Invoking the Compiler and Linker

2.1.1.2. Compile-Only

You can avoid invoking the linker by specifying the -c option on the tiarmclang command-line.

tiarmclang -c [options] [source file names]

The following example will generate object files file1.o and file2.o from the C files file1.c and file2.c, respectively:

tiarmclang -c -mcpu=cortex-m0 file1.c file2.c

Using the -S option will cause the compiler to generate assembly files from the C or C++ source files that are specified on the command-line. When -S is specified on the command-line, compilation will stop after the assembly files are emitted, preventing the compiler from generating an object file or invoking the linker.

tiarmclang -S [options] [source file names]

The following example will generate assembly files, file1.s and file2.s, each containing GNU-syntax Arm assembly language directives and instructions:

tiarmclang -S -mcpu=cortex-m0 file1.c file2.c

2.2. Compiler and Linker Options

2.2.1. Useful Compiler Options

The commonly used options listed in the subsections below are available on the tiarmclang compiler command-line.

2.2.1.1. Processor Options

  • -mcpu - select the target processor version …

    The tiarmclang compiler supports the following Arm Cortex-M processor variants which support 16-bit and T32 THUMB instructions (as indicated):

    • -mcpu=cortex-m0 - 16-bit THUMB

    • -mcpu=cortex-m0plus - 16-bit THUMB

    • -mcpu=cortex-m3 - T32 THUMB

    • -mcpu=cortex-m4 - T32 THUMB

    The tiarmclang compiler also supports Arm Cortex-R type processor variants, Cortex-R4 and Cortex-R5, which can execute ARM and T32 THUMB instructions. By default, the tiarmclang compiler will assume ARM instruction mode, but the user can instruct the compiler to assume the use of T32 THUMB instructions for a givn copmilation by specifying the -mthumb option.

    • -mcpu=cortex-r4 - ARM (default) and/or T32 THUMB

    • -mcpu=cortex-r5 - ARM (default) and/or T32 THUMB

If an -mcpu option is not specified on the tiarmclang command-line, then the compiler will assume a default of -mcpu=cortex-m4.

2.2.1.2. Instruction Mode Options

The Cortex-M type Arm processors only support execution of THUMB mode instructions, so -mthumb is selected by default when using the -mcpu=cortex-m0, -mcpu=cortex-m0plus, -mcpu=cortex-m3, or -mcpu=cortex-m4 processor options.

  • -mthumb - select THUMB mode instructions (16-bit THUMB or T32 THUMB depending on which processor variant is selected) for current compilation; default for Cortex-M type architectures

Cortex-R type Arm processors can execute both ARM and T32 THUMB mode instructions. When either the -mcpu=cortex-r4 or -mcpu=cortex-r5 processor option is specified on the command-line, the tiarmclang compiler will assume ARM instruction mode by default. This can be overridden for a given compilation by specifying the -mthumb option in combination with -mcpu=cortex-r4 or -mcpu=cortex-r5 to cause the compiler to generate T32 THUMB instructions.

  • -marm - select ARM mode instructions for current compilation; default for Cortex-R type processors

2.2.1.3. Endianness

All of the Arm Cortex-M type processor variants supported by the tiarmclang compiler are little-endian. The Arm Cortex-R type processor variants supported by the tiarmclang compiler may be big-endian or little-endian. The following options can be used to select the endian-ness to be assumed for a given compilation:

  • -mlittle-endian - select little-endian; default

  • -mbig-endian - select big-endian; only applicable for Cortex-R

2.2.1.4. Floating-Point Support Options

Some Arm processor variants can be used in conjunction with floating-point hardware processors to perform floating-point operations more efficiently. To enable this support, the user must specify the -mfloat-abi=hard option in combination with the appropriate -mfpu option depending on what Arm processor variant is in use.

  • -mfloat-abi= - select floating point ABI

    • hard - floating-point hardware is available; select appropriate hardware with -mfpu option

    • soft - unless -mfloat-abi=hard is selected, floating-point operations are emulated in software

  • -mfpu= - select floating-point hardware

    Only certain Arm processor variants can be used in conjunction with floating-point hardware processors. The cortex-m0, cortex-m0plus, and cortex-m3 Arm processor variants are not compatible with any floating-point hardware processor.

    • vfpv3-d16 - available in combination with -mcpu=cortex-r4 or -mcpu=cortex-r5

    • fpv4-sp-d16 - available in combination with -mcpu=cortex-m4

2.2.1.5. Include Options

The tiarmclang compiler utilizes the include file directory search path to locate a header file that is included by a C/C++ source file via an #include preprocessor directive. The tiarmclang compiler implicitly defines an initial include file directory search path to contain directories relative to the tools installation area where C/C++ standard header files can be found. These C/C++ standard header files are considered part of the tiarmclang compiler package and should be used in combination with linker and the runtime libraries that are included in the tiarmclang compiler tools installation.

  • -I<dir>

    The -I option provides the user with the capability to add their own directories to the include file directory path, allowing user-created header files to be easily accessible during compilation.

2.2.1.6. Predefined Symbol Options

In addition to the pre-defined macro symbols that the tiarmclang compiler will define depending on which processor options are selected, the user can also manage their own symbols at compile-time using the -D and -U options. These options are useful when the source code is configured to behave differently based on whether a compile-time symbol is defined and/or what value it has.

  • -D<name>[=<value>]

    A user-created pre-defined compile symbol can be defined and given a value using the -D option. In the following example, MySym will be defined and given a value 123 at compile-time. MySym will then be available for use during the compilation of the test.c source file.

tiarmclang -mcpu=cortex-m0 -DMySym=123 -c test.c
  • -U<name>

    The -U option can be used to cancel a previous definition of a specified <name> whether it was pre-defind implicltly by the compiler or with a prior -D option.

2.2.1.7. Optimization Options

To enable optimization passes in the tiarmclang compiler, select a level of optimization from among the following -O[0|1|2|3|fast|g|s|z] options. In general, the options below represent various levels of optimization with some options designed to favor smaller compiler generated code size over performance, while others favor performance at the cost of increased compiler generated code size.

Among the options listed below, -Oz is recommended as the optimization option to use if small compiler generated code size is a priority for an application. Use of -Oz will still retain performance gains from many of the -O2 level optimizations that are performed.

  • -O0 - no optimization

  • -O1 or -O - restricted optimizations, providing a good trade-off between code size and debug-ability

  • -O2 - most optimizations enabled; some optimizations that require significantly additional compile time are disabled

  • -O3 - all optimizations available at -O2 plus others that require additional compile time to perform

  • -Ofast - all optimizations available at -O3 plus additional aggressive optimizations with potential for additional performance gains, but also not guaranteed to be in strict compliance with language standards

  • -Og - restricted optimizations while preserving debug-ability

  • -Os - all optimizations available at -O2 plus additional optimizations that are designed to reduce code size while mitigating negative impacts on performance

  • -Oz - all optimizations available at -O2 plus additional optimizations to further reduce code size with the risk of sacrificing performance

Note

Optimization Option Recommendations:

  • The -Oz option is recommended for optimizing code size.

  • The -O3 option is recommended for optimizing performance, but it is likely to increase compiler generated code size.

2.2.1.8. Debug Options

The tiarmclang compiler will generate DWARF debug information when the -g or -gdwarf-3 option is selected.

  • -g or -gdwarf-3 - emit DWARF version 3 debug information

2.2.1.9. Control Options

Some tiarmclang compiler options can be used to halt compilation at different stages:

  • -c - stop compilation after emitting compiler-generated object files; do not call linker

  • -E - stop compilation after the pre-processing phase of the compiler; this option can be used in conjunction with several other options that provide further control over the pre-processor output:

    • -dD - print macro definitions in addition to normal preprocessor output

    • -dI - print include directives in addition to normal preprocessor output

    • -dM - print macro symbol definitions instead of normal preprocessor output

  • -S - stop compilations after emitting compiler-generated assembly files; do not call assembler or linker

2.2.1.10. Compiler Output Option

  • -o<file>

    The -o option names the output file that results from a tiarmclang command. If tiarmclang is used to compile and link an executable output file, then the -o option’s <file> argument names that output file. If no -o option is specified in a compile and link invocation of tiarmclang then the linker will produce an executable output file named a.out.

    If the compiler is used to process a single source file, then the -o option will name the output of the compilation. This is sometimes useful in case there is a need to name the output file from the compiler something other than what the compiler will produce by default. In the following example, the output object file from the compilation of C source file task_42.c is named task.o by the -o option, replacing the task_42.o that would normally be generated by the compiler:

tiarmclang -mcpu=cortex-m0 -c task_42.c -o task.o

2.2.2. Interpretation of Source Files

The tiarmclang compiler will interpret source files with a recognized file extension in a predictable manner. The recognized file extensions include:

  • .c - C source file

  • .C or .cpp - C++ source file

  • .s - GNU-syntax Arm assembly source file

  • .S - GNU-syntax Arm assembly source file to be preprocessed by the compiler

2.2.2.1. Controlling Source File Interpretation with the -x Option

The tiarmclang compiler also supports a -x option that permits a user to dictate how an input file is to be interpreted by the compiler. This can be used to override default file extension interpretations or to instruct the compiler how to interpret a file extension that is not automatically recognized by the compiler.

  • -x<language> - interpret subsequent input files on the command-line as <language> type files.

    The following <language> types are available to the -x option:

    • -x none - reset compiler to default file extension interpretation

    • -x c - interpret subsequent input files as C source files

    • -x c++ - interpret subsequent input files as C++ source files

    • -x assembler - interpret subsequent files as GNU-syntax Arm assembly source files

    • -x assembler-with-cpp - interpret subsequent files as GNU-syntax Arm assembly source files that will be preprocessed by the compiler

    • -x ti-asm - interpret subsequent source files as legacy TI-syntax assembly source files causing the compiler to invoke the legacy TI-syntax Arm assembler to process them. For more information about handling legacy TI-syntax Arm assembly source files, please see Invoking the TI-Syntax ARM Assembler from tiarmclang.

Note

The -x<language> option is positionally dependent. A given -x option on the tiarmclang command-line will be in effect until the end of the command-line or until a subsequent -x option is encountered on the command-line.

2.2.3. Linker Options

2.2.3.2. Basic Linker Options

Listed below are some of the basic options that are commonly used when invoking the linker. They can be specified on the command-line or inside of a linker command file. The tiarmclang tools’ linker is nearly identical to the linker in the legacy TI compiler toolchain. You can find more information about linker options in Linker Options.

  • --map_file=<file> or -m<file> - emit information about the result of a link into the specified map <file>

  • --output_file=<file> or -o<file> - emit linked output to specified <file>

  • --args_size=<size> or --args=<size> - reserve <size> bytes of space to store command-line arguments that are passed to the linked application

  • --heap_size=<size> or --heap=<size> - reserve <size> bytes of heap space to be used for dynamically allocated memory

  • --stack_size=<size> or --stack=<size> - reserve <size> bytes of stack space for the run-time execution of the linked application

2.2.3.3. Specifying Linker Options on the tiarmclang Command-Line

As noted in a few of the above examples, when invoking the linker from the tiarmclang command, options that are to be passed directly to the linker must be preceded with a -Wl, or -Xlinker prefix. In this example, the tiarmclang compiler will pass the link_test.cmd linker command file directly to the linker:

tiarmclang -mcpu=cortex-m0 file1.c file2.o -o test.out -Wl,link_test.cmd

2.3. Runtime Support

2.3.1. Predefined Macro Symbols

The tiarmclang compiler will pre-define compile-time macro symbols for use in source to help distinguish code written particularly for Arm, for a specific Arm processor variant, or to be compiled by the tiarmclang compiler (as opposed to other Arm compilers) from other source code.

The tiarmclang compiler complies with the Arm C Language Extensions (ACLE) in that it will pre-define appropriate ACLE macro symbols based on the processor options specified on the tiarmclang command-line. Consider the following tiarmclang command:

tiarmclang -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -c test.c

When the tiarmclang compiler is invoked with the above command, these are some of the ACLE pre-defined macro symbols that will be defined:

__ARM_ACLE             200  - indicates compliance with ACLE
                              specification 2.0
__ARM_ARCH             7    - identifies Arm architecture level
__ARM_ARCH_ISA_THUMB   2    - indicates Thumb instrution set present
__ARM_ARCH_PROFILE     'M'  - identifies a Cortex-M type Arm architecture
__ARM_FP               0x6  - indicates floating-point hardware is available
__ARM_FP16_FORMAT_IEEE 1    - indicates 16-bit floating-point, IEEE format
__ARM_PCS              1    - using Arm procedure call standard (PCS)
__ARM_PCS_VFP          1    - indicates floating-point arguments passed in
                              floating-point hardware registers

For a more complete list of pre-defined macro symbols that are defined by the tiarmclang compiler for a given compilation, the processor options can be combined with the -E -dM preprocessor option combination. This will instruct the compiler to run only the preprocessor pass of the compilation and emit the list of pre-defined macro symbols that are defined along with their values to stdout.

For more information about ACLE pre-defined macro symbols, please see the Arm C Language Extensions - Release ACLE Q2 2018 specification.

In addition to the ACLE pre-defined macro symbols, the tiarmclang compiler will also pre-define several TI-specific pre-defined macro symbols that can be used to distinguish the use of the tiarmclang compiler from other Arm compilers. These include:

__ti__            1     - identify compiler vendor as TI
__ti_major__      1     - identify major version number
__ti_minor__      0     - identify minor version number
__ti_patchlevel__ 0     - identify patch version number
__ti_version__    10000 - (__ti_major__*10000)+(__ti_minor__*100)+__ti_patchlevel

2.3.2. Header Files

The header files that are provided with the installation of the tiarmclang compiler tools must be used when using functions from any of the runtime libraries that are provided with the tools installation. These include the C and C++ standard header files as well as additional header files such as arm_acle.h that help the compiler to support the Arm C Language Extensions. The tiarmclang compiler will implicitly define the initial include file directory search path so that these header files are accessible during a compilation.

2.3.3. Runtime Libraries

When linking an application containing object files that were generated by the tiarmclang compiler, the appropriate tiarmclang runtime libraries must be included in the link so that references to functions and data objects that are defined in the runtime libraries can be properly resolved at link time.

When the tiarmclang command is used to invoke the linker, the compiler will implicitly define the initial object file directory search path to contain directories relative to the tools installation area where runtime libraries can be found. The tiarmclang compiler will also implicitly add the following --start-group/--end-group option list to the linker invocation:

--start-group -llibc++.a -llibc++abi.a -llibc.a -llibsys.a
-llibsysbm.a -llibclang_rt.builtins.a -llibclang_rt.profile.a --end-group

This option list will instruct the linker to search among the list of specified runtime libraries for definitions of unresolved symbol references. When a definition of a function or data object that resolves a previously unresolved reference is encountered, the section containing the definition will be pulled into the link from the runtime library where it is defined. If new unresolved symbol references are introduced while this process is in progress, the libraries will be re-read until no further needed definitions can be found among the --start_group/--end_group list of runtime libraries.

There are currently eight different runtime library configurations supported in the tiarmclang compiler toolchain. An application built using the tiarmclang compiler tools must use a combination of target options that is compatible with one of the following configurations:

2.3.3.1. Cortex-M Configurations

  • armv6m-ti-none-eabi: (cortex-m0 or cortex-m0plus), little-endian

  • armv7m-ti-none-eabi: cortex-m3, little-endian

  • armv7em-ti-none-eabi: cortex-m4, little-endian

  • armv7em-ti-none-eabihf: cortex-m4, fpv4-sp-d16 fpu, little-endian

2.3.3.2. Cortex-R Configurations

Note

The Cortex-R runtime libraries included with the tiarmclang toolchain are built in ARM mode, but are compatible with Cortex-R object files that have been built with THUMB mode T32 instructions.

  • armv7r-ti-none-eabi: (cortex-r4 or cortex-r5), ARM mode, little-endian

  • armv7r-ti-none-eabihf: (cortex-r4 or cortex-r5), ARM mode, vfpv3-d16, little-endian

  • armv7reb-ti-none-eabi: (cortex-r4 or cortex-r5), ARM mode, big-endian

  • armv7reb-ti-none-eabhf: (cortex-r4 or cortex-r5), ARM mode, vfpv3-d16, big-endian

Note

If you are building an application with target options that are not compatible with any of the below configurations, you will encounter a link-time error in which the linker is unable to locate a compatible version of a runtime library in order to successfully complete the link. If this happens, and the configuration is valid for a TI device, please report the issue on the TI E2E™ design community and select the device being used.

For the compile options used in each of these configurations, refer to Arm Cortex Processor Variants Supported by tiarmclang.