9.6. TI ARM CLANG Usage and Migration Guidelines

This section has additional useful information related to TI ARM Clang compiler/toolchain and porting existing code within PDK. It also compares some key points & configurations in TI ARM Clang (current compiler) and TI ARM CGT (older compiler) and the guidelines for migrating to TI ARM Clang from TI ARM CGT.

  1. TI ARM CLANG: Intoduction

  2. TI ARM CLANG: List of Suppressed Warnings

  3. TI ARM CLANG: Migration Guidelines

  4. TI ARM CLANG: Migration Care Abouts

  5. TI ARM CLANG: References

9.6.1. TI ARM CLANG: Intoduction

The TI Arm® code generation tools support development of applications for TI Arm-based platforms featuring TI Arm Cortex-M and Cortex-R series devices. There are now two Arm C/C++ compiler toolchains available from TI:

  • TI Arm Clang C/C++ Compiler Tools (tiarmclang)

  • TI Arm C/C++ Compiler Tools (armcl)

9.6.1.1. Introduction to TI ARM CLANG

The tiarmclang compiler is based on the open source LLVM compiler infrastructure and its Clang front-end. tiarmclang uses the TI Linker and C runtime for stability and reduced code size.

../_images/TiClangBlockDiagram.png

Benefits of tiarmclang include:

  • Excellent C/C++ standards support

  • Source-based code coverage

  • Support for migration from armcl

  • Improved code size over armcl/gcc

  • Ease of use with fast compiles and expressive diagnostic messages

  • GCC compatibility

  • Comprehensive documentation: Getting Started Guide, Migration Guide and Compiler Tools User Manual

  • Compiler Qualification Kit to assist qualifying the compiler to functional safety standards such as ISO 26262 and IEC 61508.

As a part of this migration activity, we are moving away from ‘armcl’ compiler tool chain and will be using ‘tiarmclang’ going forward. This will need some changes in CSL-FL, Drives, Sample Application and Linker Command File. The intent of this page is look at all the changes needed.

9.6.2. TI ARM CLANG: List of Suppressed Warnings

This section talks about list of suppressed warnings (reported as errors as warnings are treated as errors through ‘-Werror’ option). Most of these warninigs are not reported by TI ARM CGT compiler.

Reported Warning

Description

-Wno-unused-command-line-argument

If one of the option provided in the command is not used

-Wno-gnu-variable-sized-type-not-at-end

Variable sized member of the structure is not the last member of the structure

-Wno-unused-function

Warning about unused function

-Wno-address-of-packed-member

Taking the address of a packed member is dangerous since the reduced alignment of the pointee is lost. This can lead to memory alignment faults in some architectures if the pointer value is dereferenced

-Wno-bitfield-constant-conversion

Implicit truncation from ‘int’ to bit-field changes value from 64 to 0

-Wno-excess-initializers

Excess braces are available while initializing structure elements

-Wno-extern-initializer

Extern variable is initialized/re-initialized

9.6.3. TI ARM CLANG: Migration Guidelines

This sections talks about changes needed for migrating code base from TI ARM CGT to TI ARM Clang. armcl options has to be replaced by tiarmclang option as shown in following sections/tables. These changes mainly falls into two categories and are as follows:

9.6.3.1. Build Changes

9.6.3.1.1. Compiler/Assembler Options

`armcl` options (older)

`tiarmclang` options (new)

TI pre-defined macro symbols, pragmas, and intrinsic

Not Supported

–silicon_version=<processor ID> (-mv<processor ID>)

-mcpu=<processor variant> -march=<architecture ID>

–code_state=16/32

-mthumb/-marm

–float_support=<float hardware ID>

-mfloat-abi=<soft hard> -mfpu=<float hardware ID>

–endian=little (-me) –endian=big (default)

-mlittle-endian (default) -mbig-endian

–opt_level=<off/0/1/2/3/4> (-O<off/0/1/2/3/4>

-O<0/1/2/3/fast/s/z/g>

–opt_for_speed=<0/1/2/3/4/5> (-mf=<0/1/2/3/4/5>)

-Oz -Os -O3 -Ofast

–obj_directory=<dir> (-fr)

-c -save-temps

–temp_directory=<dir> (-ft)

Not Supported

–asm_file=<file> (-fa=<file>)

-x assembler/-x assembler-with-cpp/-x ti-asm

–c_file=<file> (-fc=<file>)

-x c

–obj_file=<file> (-fo=<file>)

Not Supported

–entry_hook=<func>/–exit_hook=<func>

-finstrument_functions

–entry_parm=<none/name/address>/–exit_parm=<none/name/address>/–remove_hooks_when_inlining

Not Supported

–define=<name>[=<value>] (-D=<name>[=<value>])

-D<name>[=<value>]

9.6.3.1.2. Linker Options

`armcl` options (older)

`tiarmclang` options (new)

-run_linker

Not needed as will be automatically invoked by compiler by default

-z

-Xlinker <linker option> -Wl,<comma-separated list of linker options>

-m map_filename

-m=map_filename

-o output_filename

–output_file=output_filename

Note

  • For all the linker related options, use either

    • prepend each linker option with “-Xlinker ” (there is a space between ‘-Xlinker’ keyword and actual command line option) OR

    • group all command line options together with each separated with “,” and then prepend this full set with “-Wl,”

  • First option is used in PDK build infrastructure.

9.6.3.2. Source File/Code Changes

Here are few and quick changes needed (following list mostly contains armcl options with corresponding counterparts in tiarmclang, this should be mostly ‘find and replace’ in the source code):

9.6.3.2.1. Macros

`armcl` options (older)

`tiarmclang` options (new)

__TI_ARM_V4__ /___TI_ARM_V5__ /___TI_ARM_V7A8__

Not Supported (tiarmclang does not support this arm architecture or processor variant)

__16bis__

defined(__thumb__)

__32bis__

!defined(__thumb__)

__TI_EABI_SUPPORT__

defined(__ELF__)

__TI_ARM_V6__

(__ARM_ARCH == 6)

__TI_ARM_V6M0__

(__ARM_ARCH == 6) && (__ARM_ARCH_PROFILE == ‘M’)

__TI_ARM_V7__

(__ARM_ARCH == 7)

__TI_ARM_V7M3__

(__ARM_ARCH == 7) && (__ARM_ARCH_PROFILE == ‘M’) && !defined(__ARM_FEATURE_SIMD32)

__TI_ARM_V7M4__

(__ARM_ARCH == 7) && (__ARM_ARCH_PROFILE == ‘M’) && defined(__ARM_FEATURE_SIMD32)

__TI_ARM_V7R4__

(__ARM_ARCH == 7) && (__ARM_ARCH_PROFILE == ‘R’) && !defined(__ARM_FEATURE_IDIV)

__TI_ARM_V7R5__

(__ARM_ARCH == 7) && (__ARM_ARCH_PROFILE == ‘R’) && defined(__ARM_FEATURE_IDIV)

__TI_VFP_SUPPORT__

defined(__ARM_FP)

__TI_VFPLIB_SUPPORT__

!defined(__ARM_FP)

__TI_VFPV3D16_SUPPORT__

defined(__ARM_FP) && (__ARM_FP == 12) && (__ARM_ARCH_PROFILE == ‘R’)

_TI_FPV4SPD16_SUPPORT__

defined(__ARM_FP) && (__ARM_FP == 6) && (__ARM_ARCH_PROFILE == ‘M’)

__big_endian__

defined(__ARM_BIG_ENDIAN)

__little_endian__

!defined(__ARM_BIG_ENDIAN)

9.6.3.2.2. Pragmas

`armcl` options (older)

`tiarmclang` options (new)

#pragma CODE_STATE (function, 32)

__attribute__((target(“arm”)))

#pragma INTERRUPT (function, IRQ)

__attribute__((interrupt(“IRQ”))) function

#pragma CODE_SECTION(func_name, “scn_name”)

__attribute__((section(“scn_name”)))

#pragma DATA_ALIGN(“sym_name”, alignment)

__attribute__((aligned(alignment)))

#pragma DATA_SECTION(sym_name, “scn_name”)

__attribute__((section(“scn_name”)))

#pragma FUNC_ALWAYS_INLINE(func_name)/#pragma FUNC_CANNOT_INLINE(func_name)

__attribute__((always_inline))/__attribute__((noinline))

#pragma LOCATION(address)

__attribute__((location(address)))

#pragma NOINIT(sym_name)

__attribute__((noinit))

#pragma RETAIN(sym_name)

__attribute__((retain))/__attribute__((used))

#pragma #pragma WEAK(sym_name)

__attribute__((weak))

#pragma NO_HOOKS(func_name)/#pragma SWI_ALIAS(func_name, swi_number)

Not Supported

#pragma SET_CODE_SECTION(“scn_name”)/#pragma SET_DATA_SECTION(“scn_name”)

Not Supported directly - Use “__attribute__((section(“scn_name”)))” for each following function/variable

#pragma diag_suppress 179

#pragma clang diagnostic warning “-Wunused”

9.6.4. TI ARM CLANG: Migration Care Abouts

Tip

  • This section does not talk about all the changes required, it only talks about most commonly used options. Please refer to `TI Arm Clang Compiler Tools User’s Guide` mentioned in References section.

9.6.4.1. Structure Initialization

  • Failing to initialize the structure instance may cause unexpected application failures

  • Clang tool-chain does not allow initializing only a few members of structure (and rest being set to 0) using below method:

    struct DemoStruct_t
    {
        uint32_t memberA;
        /**< Member A */
        uint32_t memberB;
        /**< Member B */
        uint32_t memberC;
        /**< Member C */
    };
    
    /* Initializing Member A of the structure */
    DemoStruct_t demoStructInst = {22U};
    
  • User can either initialize all members of the structure by enclosing them into pair of curly parenthesis (”{ }”) OR initialize particular member of structure like “.<member_name>=<initialization_value>;” Here are few examples to do the same:

    • Example 1:

    struct DemoStruct_t
    {
        uint32_t memberA;
        /**< Member A */
        uint32_t memberB;
        /**< Member B */
        uint32_t memberC;
        /**< Member C */
    };
    
    DemoStruct_t demoStructInst[2] =
    {
        /* Initialize all 3 members of the structure */
        {
            .memberA = 22U;
            .memberB = 44U;
            .memberC = 88U;
        },
        /* Initialize only needed 2 members of the structure */
        {
            .memberA = 22U;
            .memberC = 88U;
        },
    };
    
    • Example 2:

    struct DemoStruct_t
    {
        uint32_t memberA;
        /**< Member A */
        uint32_t memberB;
        /**< Member B */
        uint32_t memberC;
        /**< Member C */
    };
    
    /* This will initialize all members to '0' */
    DemoStruct_t demoStructInst = {0U};
    
    demoStructInst.memberA = 22U;
    

9.6.4.2. Linker Command File Changes

  • Add `’.rodata’` section in the linker command file and assign/allot it to same section as ‘.const’ sections.

9.6.4.3. Other Key Care Abouts

  • For armcl Intrinsics, the ‘arm_acle.h’ Header file needs to be included

  • Non-ACLE armcl Compiler Intrinsics are not supported in tiarmclang

  • Accessing armcl Compiler Intrinsics via the ‘ti_compatibility.h’ Header File

9.6.5. Migration to v2.1.3 from v1.3.0

9.6.5.1. Code Changes

  • If a variable is set and not used then Clang v2.1.3 reports an error. See the below example for reference

    void sample()
    {
        uint64_t x = 0x0029;
        uint64_t y;
        y = func(x);
    }
    
  • Clang v2.1.3 warns of inline assembly that will not be inlined by compiler and also mandates gcc style syntax. See the below example for reference

    # If you have the following lines in assembly files
    __asm volatile ( "dsb" ::: "memory" );
    # Then change it to below lines
    __asm__ __volatile__ ("dsb  sy"   "\n\t": : : "memory");
    

9.6.5.2. Linker File Changes

  • Wild cards are not supported in the output section in linker files. See the below example for reference

    # If you have the following line in liker file
    .const.devgroup* : {} align(4)    > DDR
    # Then change it to below line
    .const.devgroup : {*(.const.devgroup*)} align(4)    > DDR
    

9.6.5.3. Compiler Flag Changes

  • Use link time optimization flag(-flto) while compiling as well as linking

  • Link time optimization flag(-flto) is used only for release builds

  • Use -Os optimization flag for release build

  • Use -O1 optimization flag for debug build which is same with the previous compiler i.e v1.3.0

9.6.6. TI ARM CLANG: References