Readme for C2000 Code Generation Tools v25.11.0.LTS

Table of Contents


LTS Release


The C2000 CGT v25.11.x.LTS release is an LTS release.

Definitions


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:

https://sir.ext.ti.com/


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() { ...

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:

Known defects – dynamic