TI Arm Clang Compiler Tools - 4.0.0.LTS Release Notes
Table of Contents
- Introduction
- Long-Term Support Release
- Documentation
- TI E2E Community - Where to Get Help
- Defect Tracking Database
- New Features
- Interrupt VFP Register Save/Restore Function Attribute, interrupt_save_fp
- Suppress Floating Point Speculation with -ffp-exceptions Compiler Option
- Cortex-M Security Extensions (CMSE) Security Bulletin
- Include Linker Command Line in Linker-Generated XML Link Information File
- Linker Command File Size-Based align(power2) Operator
- Support for MSP M0/M0+ Math Accelerator (-mmathacl)
- Link-Time Optimization (LTO) Debug Aid
- Security: Control Flow Integrity (CFI)
- Security: Support for C11 Secure Functions in C Runtime Support Library
- Security: Linker Command File fill Operator
- Security: pad Function Attribute
- Basic Support for Cortex-R52
- Addition of tiarmclang-tidy Utility to Compiler Tools Installation
- Compile and Link Using Build Automation Tools
- Host Support / Dependencies
- Device Support
- Resolved Defects
- Known Defects
Introduction
Version 4.0.0.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, r5, and r52). 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 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 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.
New Features
Interrupt VFP Register Save/Restore Function Attribute, interrupt_save_fp
The tiarmclang compiler tools now support the interrupt_save_fp function attribute that not only preserves the FPU’s arithmetic registers (d0-d16 on fpv4-sp-d16, for example), but also the FPEXC and FPSCR registers. The standard interrupt attribute does not save/restore FPU registers.
Example
Consider an interrupt function defined as follows:
extern int do_something(void);
__attribute__((interrupt_save_fp))
int interrupt_fcn(void) {
return do_something();
}
The compiler generated code looks something like this:
%> tiarmclang -mcpu=cortex-r5 -S interrupt_ex.c
%> cat interrupt_ex.s
...
.section .text.interrupt_fcn,"ax",%progbits
.hidden interrupt_fcn @ -- Begin function interrupt_fcn
.globl interrupt_fcn
.p2align 4
.type interrupt_fcn,%function
.code 32 @ @interrupt_fcn
interrupt_fcn:
.fnstart
push {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
add r11, sp, #28
vmrs r4, fpscr
vmrs r5, fpexc
push {r4, r5}
vpush {d0, d1, d2, d3, d4, d5, d6, d7}
bfc sp, #0, #3
bl do_something
sub sp, r11, #100
vpop {d0, d1, d2, d3, d4, d5, d6, d7}
pop {r4, r5}
vmsr fpscr, r4
vmsr fpexc, r5
pop {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
subs pc, lr, #4
...
.section ".note.GNU-stack","",%progbits
.addrsig
.addrsig_sym do_something
...
Suppress Floating Point Speculation with -ffp-exceptions Compiler Option
When optimization is enabled at level -O1 or higher during compilation. The compiler may perform floating-point speculation optimizations. The -ffp-exception-behavior compiler option may be used to suppress floating-point floating-point speculation optimizations.
Specifically, the user can specify either maytrap or strict as the argument to the -ffp-exception-behavior option to disable floating-point speculation.
-ffp-exception-behavior Compiler Option
-ffp-exception-behavior=[maytrap|strict|ignore]
- maytrap - The compiler avoids transformations that may raise exceptions that would not have been raised by the original code. Constant folding performed by the compiler is exempt from this option.
- strict - The compiler ensures that all transformations strictly preserve the floating point exception semantics of the original code.
- ignore - The compiler assumes that the exception status flags will not be read and that floating point exceptions will be masked.
If no argument is specified for the –ffp-exception-behavior option, then the default argument is assumed to be ignore.
As a point of clarification about the option name to avoid confusion, the term “exception” in the -ffp-exception-behavior option name refers to floating-point hardware exceptions, not C++ software exceptions.
Floating-Point Speculation Example
Consider a floating-point divide operation that is guarded by an if statement in a C function:
__attribute__((noinline)) void cp_fpu_trace(float32 *f_Info)
{
float32 f_array[10] = {0};
float32 float1 = *f_Info;
if (float1 > CP_MIN)
{
f_array[1u] = (1.f / *f_Info);
}
else
{
f_array[1u] = CP_MAX;
}
*f_Info = f_array[1u];
}
In this code the if statement is intended to prevent the floating-point divide operation from performing a divide-by-zero that will trigger a hardware floating-point exception. However, if optimization is enabled to perform floating-point speculation, the compiler may generate code to perform the divide instruction prior to the compare instruction that carries out the intent of the if statement:
cp_fpu_trace:
vldr s0, [r0]
vmov.f32 s2, #1.000000e+00
vldr s4, .LCPI1_0 ; <- load of CP_MIN
vldr s6, .LCPI1_1 ; <- load of CP_MAX
vdiv.f32 s2, s2, s0 ; <- divide
vcmp.f32 s0, s4 ; <- compare
vmrs APSR_nzcv, fpscr
vmovgt.f32 s6, s2 ; <- conditional move:
; if (float1 > CP_MIN)
; s6 = result of divide
vstr s6, [r0]
bx lr
In this case, if the value loaded into s0 is zero, then the divide instruction will trigger a floating-point hardware exception before the compare instruction has a chance to prevent that from happening. As mentioned above, including the -ffp-exception-behavior=maytrap or -ffp-exception-behavior=strict option on the compiler command-line will prevent the compiler from performing floating-point speculation optimizations and generating code that will execute the divide instruction prior to the compare and conditional move instructions.
Cortex-M Security Extensions (CMSE) Security Bulletin
In April of 2024, Arm Limited published a Cortex-M Security Extensions (CMSE) Security Bulletin that identifies a potential software security issue in code that uses CMSE. The security vulnerability allows an attacker to pass out-of-range values to code executing in Secure state to cause incorrect operation in Secure state. Please see the above referenced Security Bulletin for more details about what conditions must be met for a program to be at risk of being affected.
This security vulnerability is present in compilers that are not compliant with version 1.4 of the Arm v8-M Security Extensions Requirements on Development Tools.
The TI Arm Clang Compiler Tools version 4.0.0.LTS is compliant with the above specification and does not have this security vulnerability. Even though the 4.0.0.LTS utilizes source code from the LLVM version 18 release, the 4.0.0.LTS compiler is built with code that brings it into compliance with the above specification.
Versions of the TI Arm Clang Compiler Tools that are affected by this security vulnerability include releases prior to and including version 3.2.2.LTS.
Include Linker Command Line in Linker-Generated XML Link Information File
If the –xml_link_info=file option is specified on the linker command line, then an XML representation of the link information will be generated into the specified file. This linker-generated XML link information file will now contain a string representation of the linker command line used to invoke the linker.
Example
If we compile and link a simple program as follows:
%> tiarmclang -mcpu=cortex-m4 hello.c -o hello.out -Wl,-llnk.cmd,--xml_link_info=hello.xml,-mhello.map
Then the “hello.xml” file will contain a command-line XML tag like the following:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<link_info>
<banner>TI ARM Clang Linker Unix v4.0.0.LTS</banner>
<copyright>Copyright (c) 1996-2018 Texas Instruments Incorporated</copyright>
<command_line>/path/to/installation/bin/tiarmlnk -I/path/to/installation/lib -I/path/to/definition/of/linker_command_file -o hello.out /tmp/hello-e87e3b.o -llnk.cmd --xml_link_info=hello.xml -mhello.map --start-group -llibc++.a -llibc++abi.a -llibc.a -llibsys.a -llibsysbm.a -llibclang_rt.builtins.a -llibclang_rt.profile.a --end-group</command_line>
...
</link_info>
Linker Command File Size-Based align(power2) Operator
The linker now supports a new variant of the align operator, align(power2), that can be applied to an output section specification to effect an alignment of the output section to the next power-of-2, such that the selected power-of-2 is greater than or equal to the size of the output section’s contents.
Example
Consider a simple function to be defined in a user-named section called “.myscn”:
#include <stdio.h>
__attribute__((section(".myscn")))
void myfcn(void) {
printf("hello\n");
}
The output section in which “.myscn” will be placed could be specified as follows:
SECTIONS
{
...
.myscn: { myfile.o(.myscn) } align(power2) > MEM
...
}
When the link is performed, the linker will use the size of the “.myscn” output section to determine the alignment to apply in order to determine where in the MEM region the output section is to be allocated. Let’s suppose that the “.myscn” output section contains not only the definition of myfcn(), but also a linker-generated 8-byte trampoline to enable myfcn() to reach printf() in the event that printf() is placed out of range from myfcn():
.myscn 0 000012c0 00000018
000012c0 00000010 tryme.o (.myscn)
000012d0 00000008 libc.a : printf.c.obj (.tramp.printf.1)
The content of the “.myscn” output section adds up to 24 bytes, and so the align(power2) operator will force the “.myscn” output section to be allocated to a 32-byte boundary within the MEM region.
Support for MSP M0/M0+ Math Accelerator (-mmathacl)
The tiarmclang compiler tools have been updated to support the latest version of the math accelerator that can be paired with the Arm Cortex-M0+ processor variant. To enable utilization of the math accelerator hardware, specify the -mmathacl compiler option in combination with the -mcpu=cortex-m0plus compiler option.
Link-Time Optimization (LTO) Debug Aid
If Link-Time Optimization (LTO) is enabled and a linker-generated map file is requested on the linker command line (–mapfile linker option), then the linker will generate additional information into the map file to help with debugging applications that are built with LTO.
For each function that is a candidate to be included in the link, the map file will include:
Function Definition Details
- demangled (and mangled, if applicable) name of function
- function symbol’s binding (local, global, or weak)
- pre-LTO recompile size of function
- post-LTO recompile size of function
- fun-time address of function symbol
List of Pre-LTO Recompile Symbol References
- demangled (and mangled, if applicable) name of referenced symbol
- type of referenced symbol (function, object, section)
- location in function body where symbol reference(s) occur(s)
List of Post-LTO Recompile Symbol References
- demangled (and mangled, if applicable) name of referenced symbol
- type of referenced symbol (function, object, section)
- location in function body where symbol reference(s) occur(s)
The intention behind this feature is to provide the developer with some sense of what the effect of the LTO recompile is on a given function.
Example
Consider a simple application with two source files:
debug_aid_1.c
extern void f1(void);
extern void f2(void);
extern void f3(void);
int main() {
f1();
f2();
f3();
return 0;
}
debug_aid_2.c
#include <stdio.h>
__attribute__((section(".one_section")))
void f1(void) {
printf("this is f1\n");
}
__attribute__((section(".one_section")))
void f2(void) {
printf("this is f2\n");
}
__attribute__((section(".one_section")))
void f3(void) {
printf("this is f3\n");
}
We’ll compile and link these files together with LTO enabled.
%> tiarmclang -mcpu=cortex-m4 -flto -Oz debug_aid_1.c debug_aid_2.c -o a.out -Wl,-llnk.cmd,-ma.map
Then look at a couple snippets of the map file:
%> cat a.map
...
PRE/POST-LTO FUNCTION SYMBOL REFERENCES
...
Function: f1
---------
Binding: global
Pre-LTO Size: 12
Post-LTO Size: 0
Run Address: 0x00000001
Pre-LTO Symbol References
-------------------------
Symbol: .rodata.str1.3318338828525585858.1
Type: section
Offset: 0x00000008
Symbol: puts
Type: function
Offset: 0x00000002
Function: f2
---------
Binding: global
Pre-LTO Size: 12
Post-LTO Size: 0
Run Address: 0x0000000d
Pre-LTO Symbol References
-------------------------
Symbol: .rodata.str1.15142827100918509680.1
Type: section
Offset: 0x00000014
Symbol: puts
Type: function
Offset: 0x0000000e
Function: f3
---------
Binding: global
Pre-LTO Size: 12
Post-LTO Size: 0
Run Address: 0x00000019
Pre-LTO Symbol References
-------------------------
Symbol: .rodata.str1.11035941194088382892.1
Type: section
Offset: 0x00000020
Symbol: puts
Type: function
Offset: 0x0000001a
...
Function: main
---------
Binding: local
Pre-LTO Size: 18
Post-LTO Size: 36
Run Address: 0x00000b15
Pre-LTO Symbol References
-------------------------
Symbol: f1
Type: function
Offset: 0x00000002
Symbol: f2
Type: function
Offset: 0x00000006
Symbol: f3
Type: function
Offset: 0x0000000a
Post-LTO Symbol References
--------------------------
Symbol: .rodata.str1.13341988216064122737.1
Type: section
Offset: 0x00000014
Symbol: .rodata.str1.16633329539669029678.1
Type: section
Offset: 0x0000001c
Symbol: .rodata.str1.403218229802607084.1
Type: section
Offset: 0x00000020
Symbol: puts
Type: function
Offset: 0x00000018
In the above snippets of the map file, we can see:
- the definitions of f1, f2, and f3 are removed from the application during the LTO recompile (since the Post-LTO Size of each is 0)
the definition of main has been transformed by the LTO recompile:
- f1, f2, f3 have been inlined into main
- instead of three separate references to puts, there is only one in the Post-LTO version of main
In fact, if we look at the disassembly of main from the linked application:
%> tiarmobjdump -d -S a.out
...
00000b14 <main>:
b14: b510 push {r4, lr}
b16: 4804 ldr r0, [pc, #0x10] @ 0xb28 <main+0x14>
b18: 4c04 ldr r4, [pc, #0x10] @ 0xb2c <main+0x18>
b1a: 47a0 blx r4
b1c: 4804 ldr r0, [pc, #0x10] @ 0xb30 <main+0x1c>
b1e: 47a0 blx r4
b20: 4804 ldr r0, [pc, #0x10] @ 0xb34 <main+0x20>
b22: 47a0 blx r4
b24: 2000 movs r0, #0x0
b26: bd10 pop {r4, pc}
b28: 34 0c 00 00 .word 0x00000c34
b2c: 99 0b 00 00 .word 0x00000b99
b30: 3f 0c 00 00 .word 0x00000c3f
b34: 4a 0c 00 00 .word 0x00000c4a
...
We can make some more detailed observations:
- each load of r0 corresponds to the loading of a string constant prior to each call to puts
- puts is now called indirectly 3 times; its address is loaded into r4 and then called via “blx r4”
Even though the size of main grows from 18 to 36 bytes due to the LTO recompile, the definitions of f1, f2, and f3 are removed from the link leaving us with a net savings of 18 bytes.
Security: Control Flow Integrity (CFI)
The tiarmclang compiler tools now support a number of Control Flow Integrity (CFI) schemes that are designed to abort a program when certain forms of undefined behavior are detected. This feature helps to defend against security attacks that seek to exploit the undefined behavior.
In general, the support for CFI in tiarmclang is adopted from the LLVM compiler sources. More information about the LLVM implementation and usage of CFI can be found here: Control Flow Integrity.
Security: Support for C11 Secure Functions in C Runtime Support Library
The C Runtime Support Library (libc.a) included with the tiarmclang compiler tools now provides implementations of the following “secure” functions:
gets_s
char *gets_s(char *_ptr, rsize_t _size);
Takes input from stdin, detects and reports the following constraint violations:
- storage buffer pointer (_ptr) is NULL
- specified _size is 0
- specified _size is > RSIZE_MAX
- input from stdin will be truncated
memcpy_s
errno_t memcpy_s(void *dest, rsize_t destsz, const void *src, rsize_t count);
Copy memory from src to dest. The following constraint violations will be detected and reported:
- src or dest pointer is NULL
- specified destsz > RSIZE_MAX
- specified count > RSIZE_MAX
- specified count > specified destsz
- src and dest buffers overlap
memmove_s
errno_t memmove_s(void *dest, rsize_t destsz, const void *src, rsize_t count);
Copy memory from src to dest. The following constraint violations will be detected and reported:
- src or dest pointer is NULL
- specified destsz > RSIZE_MAX
- specified count > RSIZE_MAX
- specified count > specified destsz
memset_s
errno_t memset_s(void *dest, rsize_t destsz, int ch, rsize_t count);
Write count instances of specified character ch to dest. The following constraint violations will be detected and reported:
- dest pointer is NULL
- specified destsz > RSIZE_MAX
- specified count > RSIZE_MAX
- specified count > specified destsz
strcat_s
errno_t strcat_s(char *dest, rsize_t destsz, const char *src);
Concatenate contents of src to the end of the dest buffer. The following constraint violations will be detected and reported:
- src or dest pointer is NULL
- specified destsz is 0 or > RSIZE_MAX
- no null terminator character is present in the first destsz bytes of the dest buffer
- the contents of src will be truncated
- src and dest buffers overlap
strcpy_s
errno_t strcpy_s(char *dest, rsize_t destsz, const char *src);
Copy contents of src buffer into dest buffer. The following constraint violations will be detected and reported:
- src or dest pointer is NULL
- specified destsz is 0 or > RSIZE_MAX
- the contents of src will be truncated
- src and dest buffers overlap
strncat_s
errno_t strncat_s(char *dest, rsize_t destsz, const char *src, rsize_t count);
Concatenate a maximum of count characters from the src buffer to the end of the dest bufer. The following constraint violations will be detected and reported:
- src or dest pointer is NULL
- specified destsz is 0 or > RSIZE_MAX
- specified count > RSIZE_MAX
- no null terminator character is present in the first destsz bytes of the dest buffer
- the contents of src will be truncated
- src and dest buffers overlap
strncpy_s
errno_t strncpy_s(char *dest, rsize_t destsz, const char *src, rsize_t count);
Copy a maximum of count characters from the src buffer into the dest buffer. The following constraint violations will be detected and reported:
- src or dest pointer is NULL
- specified destsz is 0 or > RSIZE_MAX
- specified count > RSIZE_MAX
- the contents of src will be truncated
- src and dest buffers overlap
In addition, the following C11 security-related function helpers are included in the C Runtime Support Library (libc.a):
constraint_handler_t
typedef void (*constraint_handler_t)(const char *, void *, errno_t);
Pointer to a proper constraint handler function.
The type definition provides the signature of a viable constraint violation handler function. If you decide to define and utilize your own constraint handler function, it must adhere to the above type specification with a void return type, and three arguments of type const char , void , and errno_t in that order.
set_constraint_handler_s
constraint_handler_t set_constraint_handler_s(constraint_handler_t handler);
Constraint handler registration helper function. To set up a custom constraint handler function to be called when a constraint violation is detected, set_constraint_handler_s must be called with a pointer to the constraint handler function that is to be called when a violation is detected.
Two example constraint handler function implementations are provided in the C Runtime Support Library:
- abort_handler_s - a contraint violation will cause the application to abort
- ignore_handler_s - a constraint violation will have no effect; it will go unreported
If set_constraint_handler_s is not called before the first constraint violation is detected, then ignore_handler_s is assumed to be the default constraint handler.
strnlen_s
size_t strnlen_s(const char *string, size_t maxLen);
A variation on the strlen() function. In this case, if the length of string is longer than the specified maxLen, then strnlen_s() will return maxLen instead of the actual length of string.
In all cases, the __STDC_WANT_LIB_EXT1__ compile-time symbol must be defined to 1 before attempting to call any of the C11 secure runtime support functions.
An attempt to call any of the above C11 secure runtime support functions when __STDC_WANT_LIB_EXT1__is left undefined or is defined to zero (0) when the C11 secure runtime support function remains undeclared, will result in the compiler emitting a warning about an attempt to call a function that is implicitly declared. If the declaration of the actual C11 secure runtime function does not match what the compiler creates as an implicit declaration, while the link with the standard C runtime library may work, the load and run of such a linked program is likely to fail.
Security: Linker Command File fill Operator
The linker now supports the specification of a fill operator that can be applied to an output section to indicate both a value to be encoded in gaps between the input section contents of an output section and an optional size (in bits) to be associated with the value. If the size argument is excluded from the fill operator specification, then the size associated with the specified value argument is 32-bits by default.
Example
Consider a simple application defined as follows:
#include <stdio.h>
void func(void);
int main() {
func();
return 0;
}
__attribute__((section(".text:func")))
void func(void) {
printf("Bring on the funk!\n");
}
and compiled and linked with a linker command file that contains a fill operator applied to the “.func” output section:
SECTIONS
{
...
/* fill() operator uses 16-bit fill width */
.func : { .+=0x0008; *(.text:func) } fill(0x1234,0x10) > MEM
...
}
In this case, an 8-byte gap was inserted at the front of the “.func” output section. The fill operator applied the “.func” output section indicates a value of 0x1234 with a size argument of 16 to instruct the linker to interpret the value as having a size of 16-bits. At link time, the 8-byte gap will then be encoded with four instances of the 16-bit value 0x1234 as shown in the following disassembly output:
%> tiarmclang -mcpu=cortex-m4 basic_fcn.c -o a.out -Wl,arm_llvm_16bit_fill.cmd,-ma.map
%> tiarmobjdump -d -S a.out
Disassembly of section .func:
18000020 <.func>:
18000020: 1234 asrs r4, r6, #0x8
18000022: 1234 asrs r4, r6, #0x8
18000024: 1234 asrs r4, r6, #0x8
18000026: 1234 asrs r4, r6, #0x8
18000028 <func>:
18000028: b580 push {r7, lr}
1800002a: f249 2084 movw r0, #0x9284
1800002e: f2c0 0000 movt r0, #0x0
18000032: f000 f801 bl 0x18000038 <$Tramp$TT$L$PI$printf> @ imm = #0x2
18000036: bd80 pop {r7, pc}
Security: pad Function Attribute
The pad attribute can be applied to a function to instruct the linker to insert at least 32-bits of padding both before and after the definition of a function that is defined in its own subsection. The fill() operator can then be applied to the output section where the function is placed to encode a specific value into the padding space that was inserted before and after the subsection where the function is defined.
Example
Consider a simple printf application:
#include <stdio.h>
__attribute__((pad))
int main() {
printf("I AM a padded function\n");
return 0;
}
If the application is compiled and linked with a linker command file that contains a fill operator with a special encoding value:
%> tiarmclang -mcpu=cortex-m4 -c hello_pad.c
%> tiarmclang -mcpu=cortex-m4 hello_pad.o -o a.out -Wl,smc_pad.cmd,-ma.map
where smc_pad.cmd constains:
SECTIONS
{
...
.main: { hello_pad.o(.text.main) } fill(0xdeee,16) > MEM
...
}
We can disassemble the application to see UDF instructions inserted before and after the definition of main:
%> tiarmobjdump -d -S a.out
...
Disassembly of section .main:
00010020 <.main>:
10020: deee udf #0xee
10022: deee udf #0xee
00010024 <main>:
10024: b580 push {r7, lr}
10026: b082 sub sp, #0x8
10028: 2000 movs r0, #0x0
1002a: 9000 str r0, [sp]
1002c: 9001 str r0, [sp, #0x4]
1002e: f241 2068 movw r0, #0x1268
10032: f2c0 0000 movt r0, #0x0
10036: f7f0 fe25 bl 0xc84 <printf> @ imm = #-0xf3b6
1003a: 9800 ldr r0, [sp]
1003c: b002 add sp, #0x8
1003e: bd80 pop {r7, pc}
10040: deee udf #0xee
10042: deee udf #0xee
Basic Support for Cortex-R52
The tiarmclang compiler tools now support generating code for the Arm Cortex-R52 processor variant. This can be enabled via the -mcpu=cortex-r52 compiler option. If the -mcpu=cortex-r52 option is specified, then the compiler will assume that support for the neon-fp-armv8 FPU is also enabled by default.
When the -mcpu=cortex-r52 option is specified, the default enabling of the neon-fp-armv8 FPU can be overridden by specifying the -mfloat-abi=soft or the -mfpu=none option on the compiler command line. This indicates that the compiler is to generate instructions to perform floating-point operations without using the FPU instruction set.
For more information about optionsets available for generating Cortex-R52 code with and without neon-fp-armv8 instructions, please see the Device Support section below.
Addition of tiarmclang-tidy Utility to Compiler Tools Installation
The tiarmclang compiler tools installation now includes a tiarmclang-tidy utility that can be used to assist a developer in finding and fixing typical programming errors such as style violations, interface misuse, or bugs that can be deduced via static analysis.
The tiarmclang-tidy utility is based on the LLVM clang-tidy source code. Further information about how to use the utility can be found in the LLVM user documentation for Clang-Tidy.
Compile and Link Using Build Automation Tools
You can use build systems to automate the command line compilation and linking steps. Supported build systems include GNU Make and CMake.
For example, the following CMakeLists.txt file contains the directives required to use CMake (version 3.29 or higher) to build a sample tiarmclang application:
cmake_minimum_required(VERSION 3.29) # Minimum version for tiarmclang support
#------------------------------------------------------------------------------
# Set up cross compiling with TI clang compiler
#------------------------------------------------------------------------------
set(CMAKE_SYSTEM_NAME Generic) # Inform cmake of cross-compiling
# find tiarmclang in execution path
find_program(CMAKE_C_COMPILER tiarmclang)
#------------------------------------------------------------------------------
# or set path to tiarmclang explicity
# set(CMAKE_C_COMPILER /Users/ti/ti-cgt-armllvm_4.0.0.LTS/bin/tiarmclang)
#------------------------------------------------------------------------------
project(DDREyeFirmware C)
add_executable(app
main.c
lib/uart_lib/src/uartConsole.c
lib/uart_lib/src/uartStdio.c
lib/uart_lib/src/uart.c
lib/jacinto7_ddrss_tools_lib/src/jacinto7_ddrss_tools_lib.c
lib/jacinto7_ddrss_tools_lib/src/mmr.c
lib/pattern_gen_lib/src/pattern_gen_lib.c)
add_compile_options(-mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16 -mlittle-endian -mthumb)
add_compile_options(-Oz -g)
add_compile_definitions(J784S4)
include_directories(lib/uart_lib/inc)
include_directories(lib/uart_lib/src)
include_directories(lib/jacinto7_ddrss_tools_lib/inc)
include_directories(lib/jacinto7_ddrss_tools_lib/src)
include_directories(lib/pattern_gen_lib/inc)
include_directories(lib/pattern_gen_lib/src)
add_link_options(LINKER:--ram_model)
add_link_options(LINKER:--warn_sections)
add_link_options(${CMAKE_SOURCE_DIR}/linker.cmd)
Host Support / Dependencies
The following host-specific versions of the 4.0.0.LTS tiarmclang compiler tools are available:
- Linux: Ubuntu, RHEL 7
- Windows: 7, 8, 10
- Mac: OSX
Device Support
The tiarmclang compiler tools support development of applications that are to be loaded and run on one of the following Arm Cortex processor and runtime environment configurations:
Cortex-M0:
Runtime Environment Configuration | Options |
---|---|
Cortex-M0 | “-mcpu=cortex-m0” |
exceptions on | “-mcpu=cortex-m0 -fexceptions” |
execute-only on | “-mcpu=cortex-m0 -mexecute-only” |
execute-only and exceptions on | “-mcpu=cortex-m0 -mexecute-only -fexceptions” |
Cortex-M0+:
Runtime Environment Configuration | Options |
---|---|
Cortex-M0+ | “-mcpu=cortex-m0plus” |
exceptions on | “-mcpu=cortex-m0plus -fexceptions” |
execute-only on | “-mcpu=cortex-m0plus -mexecute-only” |
execute-only on, exceptions on | “-mcpu=cortex-m0plus -mexecute-only -fexceptions” |
Cortex-M3:
Runtime Environment Configuration | Options |
---|---|
Cortex-M3 | “-mcpu=cortex-m3” |
exceptions on | “-mcpu=cortex-m3 -fexceptions” |
Cortex-M4:
Runtime Environment Configuration | Options |
---|---|
Cortex-M4 (FPv4SPD16 on by default) | “-mcpu=cortex-m4” |
FPv4SPD16 on | “-mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16” |
FPv4SPD16 on, exceptions on | “-mcpu=cortex-m4 -fexceptions” |
FPv4SPD16 on, exceptions on | “-mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fexceptions” |
FPv4SPD16 off | “-mcpu=cortex-m4 -mfloat-abi=soft” |
FPv4SPD16 off, exceptions on | “-mcpu=cortex-m4 -mfloat-abi=soft -fexceptions” |
Cortex-M33:
Runtime Environment Configuration | Options |
---|---|
Cortex-M33 (FPv5SPD16 on by default) | “-mcpu=cortex-m33” |
FPv5SPD16 on | “-mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16” |
FPv5SPD16 on, exceptions on | “-mcpu=cortex-m33 -fexceptions” |
FPv5SPD16 on, exceptions on | “-mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -fexceptions” |
FPv5SPD16 off | “-mcpu=cortex-m33 -mfloat-abi=soft” |
FPv5SPD16 off, exceptions on | “-mcpu=cortex-m33 -mfloat-abi=soft -fexceptions” |
CDE CP0 on, FPv5SPD16 on | “-mcpu=cortex-m33 -march=armv8.1-m.main+cdecp0” |
CDE CP0 on, FPv5SPD16 on | “-mcpu=cortex-m33 -march=thumbv81-m.main+cdecp0” |
CDE CP0 on, FPv5SPD16 on | “-mcpu=cortex-m33 -march=armv8.1-m.main+cdecp0 -mfloat-abi=hard -mfpu=fpv5-sp-d16” |
CDE CP0 on, FPv5SPD16 on | “-mcpu=cortex-m33 -mfloat-abi=hard -march=thumbv81-m.main+cdecp0 -mfpu=fpv5-sp-d16” |
CDE CP0 on, FPv5SPD16 on, exceptions on | “-mcpu=cortex-m33 -march=armv8.1-m.main+cdecp0 -fexceptions” |
CDE CP0 on, FPv5SPD16 on, exceptions on | “-mcpu=cortex-m33 -march=thumbv81-m.main+cdecp0 -fexceptions” |
CDE CP0 on, FPv5SPD16 on, exceptions on | “-mcpu=cortex-m33 -march=armv8.1-m.main+cdecp0 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -fexceptions” |
CDE CP0 on, FPv5SPD16 on, exceptions on | “-mcpu=cortex-m33 -march=thumbv81-m.main+cdecp0 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -fexceptions” |
CDE CP0 on, FPv5SPD16 off | “-mcpu=cortex-m33 -march=armv8.1-m.main+cdecp0 -mfloat-abi=soft” |
CDE CP0 on, FPv5SPD16 off | “-mcpu=cortex-m33 -march=thumbv81-m.main+cdecp0 -mfloat-abi=soft” |
CDE CP0 on, FPv5SPD16 off, exceptions on | “-mcpu=cortex-m33 -march=armv8.1-m.main+cdecp0 -mfloat-abi=soft -fexceptions” |
CDE CP0 on, FPv5SPD16 off, exceptions on | “-mcpu=cortex-m33 -march=thumbv81-m.main+cdecp0 -mfloat-abi=soft -fexceptions” |
Please Note:
- CDE CP0 refers to support for Custom Datapath Extension intrinsics on Coprocessor 0
One of the following -march options must be specified in the tiarmclang command to enable support for the CDE intrinsics on Coprocessor 0;
-march=armv8.1-m.main+cdecp0 -march=thumbv8.1-m.main+cdecp0
You should only enable CDE intrinsics on Coprorcessor 0 if the target device is known to have a coprocessor unit on board
Cortex-R4:
Runtime Environment Configuration | Options |
---|---|
Cortex-R4 (default Arm mode, VFPv3D16 off) | “-mcpu=cortex-r4” |
Arm mode, VFPv3D16 off | “-mcpu=cortex-r4 -mfloat-abi=soft” |
Arm mode, VFPv3D16 off, exceptions on | “-mcpu=cortex-r4 -fexceptions” |
Arm mode, VFPv3D16 off, exceptions on | “-mcpu=cortex-r4 -mfloat-abi=soft -fexceptions” |
Arm mode, VFPv3D16 on | “-mcpu=cortex-r4 -mfloat-abi=hard -mfpu=vfpv3-d16” |
Arm mode, VFPv3D16 on, exceptions on | “-mcpu=cortex-r4 -mfloat-abi=hard -mfpu=vfpv3-d16” |
Thumb mode, VFPv3D16 off | “-mcpu=cortex-r4 -mthumb” |
Thumb mode, VFPv3D16 off | “-mcpu=cortex-r4 -mthumb -mfloat-abi=soft” |
Thumb mode, VFPv3D16 off, exceptions on | “-mcpu=cortex-r4 -mthumb -fexceptions” |
Thumb mode, VFPv3D16 off, exceptions on | “-mcpu=cortex-r4 -mthumb -mfloat-abi=soft -fexceptions” |
Thumb mode, VFPv3D16 on | “-mcpu=cortex-r4 -mthumb -mfloat-abi=hard -mfpu=vfpv3-d16” |
Thumb mode, VFPv3D16 on, exceptions on | “-mcpu=cortex-r4 -mthumb -mfloat-abi=hard -mfpu=vfpv3-d16 -fexceptions” |
Cortex-R5:
Runtime Environment Configuration | Options |
---|---|
Cortex-R5 (default Arm mode, VFPv3D16 on) | “-mcpu=cortex-r5” |
Arm mode, VFPv3D16 on | “-mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16” |
Arm mode, VFPv3D16 on, exceptions on | “-mcpu=cortex-r5 -fexceptions” |
Arm mode, VFPv3D16 on, exceptions on | “-mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16 -fexceptions” |
Arm mode, VFPv3D16 off | “-mcpu=cortex-r5 -mfloat-abi=soft” |
Arm mode, VFPv3D16 off, exceptions on | “-mcpu=cortex-r5 -mfloat-abi=soft -fexceptions” |
Thumb mode, VFPv3D16 on | “-mcpu=cortex-r5 -mthumb” |
Thumb mode, VFPv3D16 on | “-mcpu=cortex-r5 -mthumb -mfloat-abi=hard -mfpu=vfpv3-d16” |
Thumb mode, VFPv3D16 on, exceptions on | “-mcpu=cortex-r5 -mthumb -fexceptions” |
Thumb mode, VFPv3D16 on, exceptions on | “-mcpu=cortex-r5 -mthumb -mfloat-abi=hard -mfpu=vfpv3-d16 -fexceptions” |
Thumb mode, VFPv3D16 off | “-mcpu=cortex-r5 -mthumb -mfloat-abi=soft” |
Thumb mode, VFPv3D16 off, exceptions on | “-mcpu=cortex-r5 -mthumb -mfloat-abi=soft -fexceptions” |
Cortex-R52:
Runtime Environment Configuration | Options |
---|---|
Cortex-R52 (default Arm mode, FPARMv8+NEON on) | “-mcpu=cortex-r52” |
Arm mode, FPARMv8+NEON on | “-mcpu=cortex-r52 -mfloat-abi=hard -mfpu=neon-fp-armv8” |
Arm mode, FPARMv8+NEON on, exceptions on | “-mcpu=cortex-r52 -fexceptions” |
Arm mode, FPARMv8+NEON on, exceptions on | “-mcpu=cortex-r52 -mfloat-abi=hard -mfpu=neon-fp-armv8 -fexceptions” |
Arm mode, FPARMv8+NEON off | “-mcpu=cortex-r52 -mfloat-abi=soft” |
Arm mode, FPARMv8+NEON off, exceptions on | “-mcpu=cortex-r52 -mfloat-abi=soft -fexceptions” |
Thumb mode, FPARMv8+NEON on | “-mcpu=cortex-r52 -mthumb” |
Thumb mode, FPARMv8+NEON on | “-mcpu=cortex-r52 -mthumb -mfloat-abi=hard -mfpu=neon-fp_armv8” |
Thumb mode, FPARMv8+NEON on, exceptions on | “-mcpu=cortex-r52 -mthumb -fexceptions” |
Thumb mode, FPARMv8+NEON on, exceptions on | “-mcpu=cortex-r52 -mthumb -mfloat-abi=hard -mfpu=neon-fp_armv8 -fexceptions” |
Thumb mode, FPARMv8+NEON off | “-mcpu=cortex-r52 -mthumb -mfloat-abi=soft” |
Thumb mode, FPARMv8+NEON off, exceptions on | “-mcpu=cortex-r52 -mthumb -mfloat-abi=soft -fexceptions” |
Resolved Defects
ID | Summary |
---|---|
CODEGEN-12625 | Assembler error when ISR built with interrupt_save_fp dumped and compiled as assembly. |
CODEGEN-12535 | tiarmclang ti_compatibility.h gets build errors with -mcpu=cortex-m33 |
CODEGEN-12533 | Using tiarmclang -S -flto does not create an assembly file |
CODEGEN-11890 | Using 32bit counters sometimes results in counter size mismatch around increment.step |
CODEGEN-11631 | tiarmcov should not include instrumented runtime data by default or report errors |
CODEGEN-11527 | Wrong source for main is referenced during source stepping |
CODEGEN-11466 | QKIT: tiarmclang 2.1.0.LTS QKIT has typo's for c17 and c++17 support |
CODEGEN-11433 | Use of _disable_interrupts intrinsic causes compiler to emit call to function _get_CPSR, which does not exist |
CODEGEN-11158 | Do not emit the diagnostic: warning: call to function without interrupt attribute could clobber interruptee's VFP registers; consider using the interrupt_save_fp attribute to prevent this behavior |
CODEGEN-11092 | QKIT ToolDefinition.pdf for tiarmclang 1.3.x.LTS and 2.1.x.LTS has inaccurate Tool Version information |
CODEGEN-10988 | tiarmclang documentation fails to clarify that #pragma pack never increases the default alignment |
CODEGEN-10691 | assembler/linker incorrectly handles REL relocations if user specifies a CODE_SECTION that starts with ‘a’ |
CODEGEN-10591 | Optimization of Logical NOT on condition yields incorrect MC/DC test vector tracking |
CODEGEN-10444 | Enabling Code Coverage and LTO results in missing profile data section |
CODEGEN-10383 | Document ‘#pragma clang section bss’ to be used for uninitialized variables |
CODEGEN-10251 | Initialization of array of structures is mistakenly filled with 0 |
CODEGEN-10229 | Crash can occur when loading symbols due to self-referencing DIE |
CODEGEN-10067 | LTO: linker should include undefined symbols that are referenced from a static function in the IR symbol table that is passed to the LTO recompile |
CODEGEN-10000 | LTO: Compiling a source file with cortex-r4/r5 with -mthumb and linking with ARM mode cortex-r4/r5 runtime libraries improperly resolves an R_ARM_CALL relocation |
CODEGEN-9997 | tiarmclang: LTO behaves differently than non-LTO with regards to how zero-initialized variables are defined |
CODEGEN-9850 | Unresolved reference to runtime library function when that function is referenced from asm statement |
CODEGEN-9838 | Update tiarmclang documentation to explain that C++ library does not support features related to threads and concurrency |
CODEGEN-9834 | Compiler ignores attribute((used)) |
CODEGEN-9779 | Function local static array allocated to .data section, and not .bss |
CODEGEN-9669 | TI Arm Clang mismatch between source code and debugger view with function subsections |
CODEGEN-9415 | Compiler inappropriately generates non-empty ARM.exidx sections |
CODEGEN-9092 | tiarmclang mistakenly documents support for -fpic position independent code |
CODEGEN-8914 | _enable_IRQ in ti_compatibility.h only supports Cortex-M devices |
CODEGEN-8899 | tiarmlnk generates cinit record for tiny .init_array section |
CODEGEN-8887 | Compiler does not support linking code that uses C++ exceptions |
CODEGEN-8639 | tiarmar.exe is denied permission to create an archive file on Windows 7 |
CODEGEN-8533 | Use of virtual functions causes many RTS print functions to be linked into the program |
CODEGEN-8471 | Hex utility, when splitting a section as required by the bootloader, ignores the section alignment for the second part of the split |
CODEGEN-8255 | tiarmclang: zero-initialized static and global variables are being defined in .bss |
CODEGEN-8216 | Code coverage symbols not defined when profile counter section manually placed |
CODEGEN-8177 | Change documentation of –symbol_map |
CODEGEN-6288 | tiarmclang: optimizer removes empty loops that don't have side effects |
Known Defects
The up-to-date known defects in v4.0.0.LTS can be found here (dynamically generated):
[known defects in v4.0.0.LTS](https://sir.ext.ti.com/jira/issues/?jql=issuetype%20%3D%20BUG%20AND%20resolution%20%3D%20Unresolved%20AND%20%22Found%20In%20Release%22%20~%20%22ARMCLANG_*.*.*.LTS%22%20ORDER%20BY%20id%20DESC
End of File