Readme for C2000 Code Generation Tools v25.11.0.LTS
Table of Contents
- LTS Release
- Compiler Downloads and Documentation
- TI E2E Community
- Defect Tracking Database
- What’s New - Features Added in 25.11.0.LTS Release:
- EABI is now enabled by default
- Performance improvements C28
- LFU improvements
- Hex utility warning for --binary without --image
- Enabled support for attribute((constructor(priority))
- Include Linker Command Line in Linker-Generated XML Link Information File
- Linker Command File Size-Based align(power2) Operator
- Resolved defects
- Known defects (dynamic)
LTS Release
The C2000 CGT v25.11.x.LTS release is an LTS release.
Definitions
Short-Term Support (STS) release: All STS branches will be made reactive upon creation. A patch release for this branch will only be created for production stop issues and will only contain fixes for the production stop issues. For all other issues, users are advised to wait for the next STS branch, which may also contain new features. STS releases will occur approximately every 3 months up until the first LTS release in a release stream.
Long-Term Support (LTS) release: The LTS branch will be active upon creation. The branch will be active for at least 2 years. Production stop defects will be addressed within 2 weeks of being reported. Critical defects will be addressed within 90 days. Defect repairs are proactively applied to each release stream. The LTS release is intended for customers to lock down on tools.
Compiler Downloads and Documentation
Documentation for the “TI C2000 Optimizing Compiler User’s Guide” and the “TI C2000 Assembly Language User’s Guide” is available online at:
https://www.ti.com/tool/C2000-CGT
TI E2E Community
Questions concerning TI Code Generation Tools can be posted to the TI E2E Community forums at:
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 Development Tools bug database at:
What’s New - Features Added in 25.11.0.LTS Release:
EABI is now enabled by default
The default ABI is now EABI with –abi=eabi instead of –abi=coffabi.
For more details about COFF vs EABI, please see below:
https://software-dl.ti.com/ccs/esd/documents/C2000_c28x_migration_from_coff_to_eabi.html
Performance improvements C28
Improvements in modulo/division operations for 32-bit integers
The existing support for optimizations for modulo/division operations for 16-bit integers has been extended for 32-bit integers. The optimization requires --opt_level=0 or higher and --opt_for_speed=3 (-mf3) or higher.
For example, below expression:
if (int32_var % 3)
generates below call to an RTS library routine with -o0 -mf2:
MOVB ACC,#3
MOVL *-SP[2],ACC
MOVL ACC,XAR0
FFC XAR7,#L$MOD
TEST ACC
B $C$L3,EQ
and will instead be optimized to below with -o0 -mf3:
MOV T,#31
MOVL XAR4,XAR2
ASRL ACC,T
MOVL XAR7,ACC
MOV AL,#43691
MOV AH,#10922
MOVL XT,ACC
IMPYL P,XT,XAR4
SPM #1
QMPYL ACC,XT,XAR4
MOV T,#31
ASR64 ACC:P,T
SUBUL P,XAR7
MOVL ACC,P
ADDL ACC,P << PM
MOVL XT,ACC
MOVL ACC,XAR4
SUBL ACC,XT
B $C$L3,EQ
Improvements in use of MIN/MAX and CMP instructions to avoid branches:
Extended the current C28 support for optimizing if/else to MAX/MIN instructions for float to also optimize for integers. This optimization applies to both variable and constant values for min and max.
if (sum > max) sum = max;
if (sum < min) sum = min;
NOTE: ternary operator was already optimized for both floats and integers.
Improvements were also implemented to optimize the following saturation idioms for floats and integers, eliminating the redundant else branches:"
if (sum > max) sum = max;
else if (sum < min) sum = min;
Or this case:
if (sum > max) out = max;
else if (sum < min) out = min;
else out = sum;
Note: This optimization works by default for constant max/min values. However, for variable min/max, the optimization is only performed when the –sat_var_opt option is set to “on”:
--sat_var_opt=on,off
Crucial Note: Users must explicitly enable (opt-in) this variable min/max optimization because it alters the C code’s behavior if the variable min’s value exceeds the variable max’s value.
New C28 saturation intrinsics:
int = __add_sat(int, int); 16bit addition with saturation
int = __sub_sat(int, int); 16bit subtraction with saturation
long = __addl_sat(long, long); 32bit addition with saturation
long = __subl_sat(long, long); 32bit subtraction with saturation
long = __satlow16_fast(long); faster implementation of __satlow16(long)
See Compiler User Guide spru514 pdf Table 7-6 for more details on each of above.
LFU improvements
Option –lfu_default has new setting “all”
Option –lfu_default has new setting “all” in addition to “preserve” and “none” where “all” specifies to treat: existing variables without attribute(preserve) as lfu-“preserve” and new variables without attribute(update) as lfu-“update”.
New default behavior:
when no option is specified, default is "all" instead of only "preserve"
--lfu_default no argument means default-"all"
--lfu_default=all do both default-"preserve" and default-"update"
--lfu_default=preserve only default-"preserve" (no default-"update")
--lfu_default=none do not do any default-"preserve" or default-"update"
Warning for LFU attributes with const globals/statics
The following warnings are now emitted when lfu attributes update or preserve are used with const global/static variables:
warning #30025-D: Const variable "gvar_const" has attribute(preserve) and
will be placed into section .TI.bound at the same address as the reference
executable which may not be what was intended for const data.
warning #30025-D: Const variable "svar_arr_const" has attribute(update) and
will be placed into section .TI.update which may not be what was intended for
const data.
Warning for linker command files for .TI.update section
The following warnings are now emitted when an LFU link includes a linker command file that does not have an explicit entry for output section .TI.update, or if the .TI.update section has type=NOINIT:
Warning #10504-D: ".TI.update" section used for __attribute__((update))
requires an explicit SECTIONS specification entry for ".TI.update" to
ensure expected lfu warm start behavior.
warning #10505-D: ".TI.update" section cannot be type=NOINIT for lfu use
with __attribute__(update).
Warning for LFU attribute(update) for existing variables
The following warning is now emitted when a variable with attribute(update) was found to be in the reference executable:
warning #30024-D: Variable "gvar" with attribute update already has an
entry in the reference executable's symbol table. It will be placed in
the .TI.update section instead of preserving at the same address as in
the reference executable.
Warning for LFU attribute(preserve) with a new variable
The following warning is now emitted when lfu attribute(preserve) is used on a variable that was not in the reference executable:
warning #30023-D: Variable "gvar" with attribute(preserve) has no entry
in the the reference executable's symbol table and therefore cannot be
preserved. Remove attribute(preserve).
Hex utility warning for --binary without --image
Below warning is now emitted when the hex utility tool is used with output format –binary and does not also include –image or a ROM directive which are required in order to preserve any holes in memory. const global/static variables:
warning: Output format option --binary requires --image and a ROMS directive to avoid ignoring holes in memory.
Enabled support for attribute((constructor(priority))
The optional priority input to the constructor attribute is now supported.
__attribute__((constructor(102))) void func() { ...
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:
%> cl2000 hello.c -z -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>TMS320C2000 Linker Unix v25.11.0P25317 (a0196512 - Nov 13 2025)</banner>
<copyright>Copyright (c) 1996-2018 Texas Instruments Incorporated</copyright>
<command_line>lnk2000 --tm_feedback=/tmp/TIJepouSAsB -c --buffer_diagnostics --float_support=softlib hello.obj --ecc=off --library=lnk.cmd --xml_link_info=hello.xml --map_file=hello.map</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.
Resolved defects
Resolved defects in v25.11.0.LTS:
| ID | Summary |
|---|---|
| CODEGEN-14346 | Cannot use char16_t for 16-bit wide string literals |
| CODEGEN-14324 | Compiler fails with INTERNAL ERROR: opt2000 experienced a segmentation fault |
| CODEGEN-14244 | The compiler returns a successful exit code to the OS despite missing cmd options file |
| CODEGEN-14240 | C28 silicon bug workaround: FastIntDiv or DIVF64 instruction preceded by certain FPU 2p operations |
| CODEGEN-13621 | Compiler generates illegal parallel instruction that causes assembler to issue a valid error |
| CODEGEN-13606 | CLA code using a variable named “t” and EABI generates assembler error |
| CODEGEN-13346 | C28 intrinsic, __iexp2(float), uses TMU1 instruction IEXP2F32 which has accuracy issues when base/exponent are outside specified ranges |
| CODEGEN-13324 | symbol table entry for the compiled file should indicate source file name but instead has either a temp file name or the file's assembly file name |
| CODEGEN-13283 | LFU: when compiler uses assembly temp file name, lfu preserve fails for static variables. |
| CODEGEN-13239 | CLA nested 32-bit floating point conversion intrinsics generates compiler INTERNAL ERROR: no match for ANDB |
| CODEGEN-12829 | LFU: lfu compile emits false error for a default-preserved const variable with size change in lfu build even though const variables are no longer default preserved. |
| CODEGEN-12778 | Multiplication assignment operation, int32 *= (uint16_t)int16, incorrectly loses the cast to uint16_t during optimization |
| CODEGEN-12762 | assignment to a bit field mistakenly overwrites entire bit field structure |
| CODEGEN-12673 | C28 saturation optimization for if/ternary max check generates incorrect results for values above max limit for fpu64 with volatile variable |
| CODEGEN-12663 | Compiler may generate incorrect code for ternary max idiom with integers |
| CODEGEN-12562 | Compiler incorrectly optimizes implicit cast to pointer expression (int32)(uint16+constant) to within expression ((int32)uint16+constant) |
| CODEGEN-12560 | C2000 compiler ignores retain attribute/pragma for CLA functions |
| CODEGEN-12534 | C28 math.h exp2f/expf with –tmu_support=tmu1 and –fp_mode=relaxed generates incorrect results for negative inputs |
| CODEGEN-12500 | Optimizer incorrectly distributes a float type into an unsigned integer expression of smaller size |
| CODEGEN-12362 | lfu: for variables with lfu attribute(preserve), the linker incorrectly combines sections with initialized variables with sections for variables that have attribute(persistent). |
| CODEGEN-12361 | LFU: location attribute/pragma is ignored with attribute(preserve), and attribute(update) is ignored when used with location attr/pragma |
| CODEGEN-12282 | Missing warning for C89 with integer literal too large for long |
| CODEGEN-12270 | An inlined cast from int32_t to float32_t may get an incorrect optimization |
| CODEGEN-12260 | C2000 MOVDL instruction tries to simultaneously access two memory locations across DP boundary |
| CODEGEN-12112 | attribute constructor does not support optional priority input but silently accepts it |
| CODEGEN-12108 | LFU: attribute((update)) does not work for CLA and will not generate warm_init records |
| CODEGEN-11909 | Documentation needs to state that building C++ files with –abi=eabi forces runtime type identification (RTTI) to be included |
| CODEGEN-11693 | LFU: diagnostic #10098-D should not be emitted for lfu preserve variables |
| CODEGEN-11691 | LFU: DATA_SECTION attribute/pragma is ignored for lfu builds with variables also marked as attribute(update) |
| CODEGEN-11690 | LFU: for lfu builds, the linker incorrectly generates .cinit records for lfu “preserve” variables that are placed in output sections with type=NOINIT via DATA_SECTION pragma or section attribute |
| CODEGEN-11639 | Functions with constructor attribute are incorrectly discarded |
| CODEGEN-11523 | When using –opt_level=3, for a loop, compiler may emit assignment to member of a struct in the wrong place |
| CODEGEN-11515 | Compiler hangs on compile-time access of non-zero indices |
| CODEGEN-11329 | LFU build with multiple object files with the same global-static variable name that are lfu-preserved may generate linker errors |
| CODEGEN-11328 | ELF symbol table entry for uninitialized static variable incorrectly shows size of 0 |
| CODEGEN-11240 | align of C28 CRC/COPY/CINIT tables is 64bits (updated to 32bits) |
| CODEGEN-11223 | Compiler fails with internal error “Bad kind: TYPE::type_pointed_to” |
| CODEGEN-11218 | lfu should not combine .TI.bound output sections if the combined section would span memory range boundaries |
| CODEGEN-11206 | Use of offsetof causes Optimizer to terminate abnormally |
| CODEGEN-11025 | LFU: const variables should not default preserve and instead should require attribute |
| CODEGEN-10848 | Compiler places dynamically initialized const variables for instance of a class in the .const section instead of .data:variable_name |
| CODEGEN-10691 | assembler/linker incorrectly handles REL relocations if user specifies a CODE_SECTION that starts with ‘a’ |
| CODEGEN-10306 | For EABI cinit copy “compression”, the linker incorrectly sets the number of bytes to copy for smaller copy initialization sizes |
| CODEGEN-10285 | bitfield assign incorrectly shifting before extending for uint64_var.bf=int32_var |
| CODEGEN-10116 | C2000 long-long compares using MINL/MINCUL used invalid indirect-postinc addressing mode |
| CODEGEN-10101 | Option –fp_single_precision_constant errors on unsuffixed double precision float constants that are out of range of single precision float |
| CODEGEN-9407 | Flexible array of structs does not correctly initialize last element with implicitly initialized struct members. |
| CODEGEN-8789 | std::is_trivially_destructible<array of non-trivially destructible> should return false |
| CODEGEN-8528 | Assembler incorrectly issues the warning: Register write access is in the delay slot of a write of the same register |
| CODEGEN-8177 | Change documentation of –symbol_map |
Known defects (dynamic)
The following link will lead to an updated list of known defects in this release: