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.
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.
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: Compile Modes¶
ALL PDK examples or libraries are compiled/validated in thumb mode. PDK build infra allows experimental builds for arm mode which can be enabled by following the below instructions
Comment the CFLAGs for thumb mode i.e -mthumb -march=thumbv7r and uncomment CFLAGs for arm mode i.e -marm -march=armv7-r in pdk/packages/ti/build/makerules/rules_ti_cgt_arm.mk file
Do the clean build of application
9.6.3. 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.4. 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.4.1. Build Changes¶
9.6.4.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.4.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.4.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.4.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.4.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.5. 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.5.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.5.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.5.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.4. TI ARM CLANG: Migration to v2.1.3 from v1.3.0¶
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");
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
Compiler Flag Changes
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.5.5. TI ARM CLANG: Migration to v3.2.0 from v2.1.3¶
Code Changes
If a variable is set(even to 0) and not used then Clang v3.2.0 reports an error. See the below example for reference
void sample() { uint64_t x = 0x0029; uint64_t y = 0; func(x); /* y is not used anywhere else */ }