TMS320C28x Optimizing C/C++ Compiler v15.9.0.STS User's Guide
SPRU514 - REVISED SEPTEMBER, 2015

2 Using the C/C++ Compiler

The compiler translates your source program into machine language object code that the TMS320C28x can execute. Source code must be compiled, assembled, and linked to create an executable object file. All of these steps are executed at once by using the compiler.

2.1 About the Compiler

The compiler lets you compile, optimize, assemble, and optionally link in one step. The compiler performs the following steps on one or more source modules:

  • The compiler accepts C/C++ source code and assembly code. It produces object code.
  • You can compile C, C++, and assembly files in a single command. The compiler uses the filename extensions to distinguish between different file types. See Section 2.3.9 for more information.

  • The linker combines object files to create a static executable or dynamic object file. The link step is optional, so you can compile and assemble many modules independently and link them later. See Section 4 for information about linking the files.

NOTE

Invoking the Linker

By default, the compiler does not invoke the linker. You can invoke the linker by using the --run_linker (-z)compiler option. See Section 4.1.1 for details.

For a complete description of the assembler and the linker, see the TMS320C28x Assembly Language Tools User's Guide.

2.2 Invoking the C/C++ Compiler

To invoke the compiler, enter:

cl2000 [options] [filenames] [--run_linker [link_options] object files]]
cl2000 Command that runs the compiler and the assembler.
options Options that affect the way the compiler processes input files. The options are listed in Table 2-7 through Table 2-29.
filenames One or more C/C++ source files and assembly language source files.
--run_linker (-z) Option that invokes the linker. The --run_linker option's short form is -z. See Section 4 for more information.
link_options Options that control the linking process.
object files Names of the object files for the linking process.

The arguments to the compiler are of three types:

  • Compiler options
  • Link options
  • Filenames

The --run_linker option indicates linking is to be performed. If the --run_linker option is used, any compiler options must precede the --run_linker option, and all link options must follow the --run_linker option.

Source code filenames must be placed before the --run_linker option. Additional object file filenames can be placed after the --run_linker option.

For example, if you want to compile two files named symtab.c and file.c, assemble a third file named seek.asm, and link to create an executable program called myprogram.out, you will enter:

cl2000 symtab.c file.c seek.asm --run_linker --library=lnk.cmd --output_file=myprogram.out

2.3 Changing the Compiler's Behavior with Options

Options control the operation of the compiler. This section provides a description of option conventions and an option summary table. It also provides detailed descriptions of the most frequently used options, including options used for type-checking and assembling.

For a help screen summary of the options, enter cl2000 with no parameters on the command line.

The following apply to the compiler options:

  • There are typically two ways of specifying a given option. The "long form" uses a two hyphen prefix and is usually a more descriptive name. The "short form" uses a single hyphen prefix and a combination of letters and numbers that are not always intuitive.
  • Options are usually case sensitive.
  • Individual options cannot be combined.
  • An option with a parameter should be specified with an equal sign before the parameter to clearly associate the parameter with the option. For example, the option to undefine a constant can be expressed as --undefine=name. Likewise, the option to specify the maximum amount of optimization can be expressed as -O=3. You can also specify a parameter directly after certain options, for example -O3 is the same as -O=3. No space is allowed between the option and the optional parameter, so -O 3 is not accepted.
  • Files and options except the --run_linker option can occur in any order. The --run_linker option must follow all compiler options and precede any linker options.

You can define default options for the compiler by using the C2000_C_OPTION environment variable. For a detailed description of the environment variable, see Section 2.4.1.

Table 2-7 through Table 2-29 summarize all options (including link options). Use the references in the tables for more complete descriptions of the options.

Table 2-1 Processor Options

Option Alias Effect Section
--silicon_version=28 -v28 Specifies TMS320C28x architecture. The default (and only value accepted) is 28. This option is no longer required. Section 2.3.4
--unified_memory -mt Generates code for the unified memory model. Section 2.3.4
--cla_support[=cla0|cla1] Specifies TMS320C28x CLA accelerator support Type 0 or Type 1. Default is cla0. Section 2.3.4
--float_support={fpu32|softlib|fpu64} Specifies use of TMS320C28x 32- or 64-bit hardware floating-point support. The default is softlib. Section 2.3.4
--tmu_support[=tmu0] Enables support for the Trigonometric Math Unit (TMU). Using this option also enables FPU32 support (as with --float_support=fpu32). If this option is used but no value is specified, the default is tmu0. Section 2.3.4
--vcu_support[=vcu0|vcu2] Specifies C28x VCU coprocessor support Type 0 or Type 2. Default is vcu0. Section 2.3.4

Table 2-2 Optimization Options(1)

Option Alias Effect Section
--opt_level=off Disables all optimization (default). Section 3.1
--opt_level=n -On Level 0 (-O0) optimizes register usage only.
Level 1 (-O1) uses Level 0 optimizations and optimizes locally.
Level 2 (-O2) uses Level 1 optimizations and optimizes globally.
Level 3 (-O3) uses Level 2 optimizations and optimizes the file. ()
Level 4 (-O4) uses Level 3 optimizations and performs link-time optimization. ()
Section 3.1 , Section 3.2, Section 3.4
--opt_for_space=n -ms Controls code size on four levels (0, 1, 2, and 3). Section 3.10
--fp_mode={relaxed|strict} Enables or disables relaxed floating-point mode. Section 2.3.3
(1) Note: Machine-specific options (see Table 2-12) can also affect optimization.

Table 2-3 Advanced Optimization Options(1)

Option Alias Effect Section
--auto_inline=[size] -oi Sets automatic inlining size (--opt_level=3 only). If size is not specified, the default is 1. Section 3.6
--call_assumptions=n -opn Level 0 (-op0) specifies that the module contains functions and variables that are called or modified from outside the source code provided to the compiler.
Level 1 (-op1) specifies that the module contains variables modified from outside the source code provided to the compiler but does not use functions called from outside the source code.
Level 2 (-op2) specifies that the module contains no functions or variables that are called or modified from outside the source code provided to the compiler (default).
Level 3 (-op3) specifies that the module contains functions that are called from outside the source code provided to the compiler but does not use variables modified from outside the source code.
Section 3.3.1
--gen_opt_info=n -onn Level 0 (-on0) disables the optimization information file.
Level 1 (-on2) produces an optimization information file.
Level 2 (-on2) produces a verbose optimization information file.
Section 3.2.2
--opt_for_speed[=n] -mf Controls the tradeoff between size and speed (0-5 range). If this option is specified without n, the default value is 4. If this option is not specified, the default setting is 2. Section 3.9
--optimizer_interlist -os Interlists optimizer comments with assembly statements. Section 3.7
--remove_hooks_when_inlining Removes entry/exit hooks for auto-inlined functions. Section 2.13
--single_inline Inlines functions that are only called once. Section 2.11
--aliased_variables -ma Notifies the compiler that addresses passed to functions may be modified by an alias in the called function. Section 3.5.2.2
(1) Note: Machine-specific options (see Table 2-12) can also affect optimization.

Table 2-4 Debug Options

Option Alias Effect Section
--symdebug:dwarf -g Default behavior. Enables symbolic debugging. The generation of debug information no longer impacts optimization. Therefore, generating debug information is enabled by default. If you explicitly use the -g option but do not specify an optimization level, no optimization is performed. Section 2.3.5
Section 3.8
--symdebug:coff Enables symbolic debugging using the alternate STABS debugging format. Section 2.3.5
Section 3.8
--symdebug:none Disables all symbolic debugging. Section 2.3.5
Section 3.8
--symdebug:profile_coff Enables profiling using the alternate STABS debugging format. Section 2.3.5
--symdebug:skeletal (Deprecated; has no effect.)
--optimize_with_debug -mn (Deprecated; has no effect.)

Table 2-5 Advanced Debug Options

Option Alias Effect Section
--symdebug:keep_all_types Keep unreferenced type information. Section 2.3.5

Table 2-6 Include Options

Option Alias Effect Section
--include_path=directory -I Adds the specified directory to the #include search path. Section 2.5.2.1
--preinclude=filename Includes filename at the beginning of compilation. Section 2.3.3

Table 2-7 Control Options

Option Alias Effect Section
--compile_only -c Disables linking (negates --run_linker). Section 4.1.3
--help -h Prints (on the standard output device) a description of the options understood by the compiler. Section 2.3.2
--run_linker -z Causes the linker to be invoked from the compiler command line. Section 2.3.2
--skip_assembler -n Compiles C/C++ source file, producing an assembly language output file. The assembler is not run and no object file is produced. Section 2.3.2

Table 2-8 Language Options

Option Alias Effect Section
--c89 Processes C files according to the ISO C89 standard. Section 6.13
--c99 Processes C files according to the ISO C99 standard. Section 6.13
--c++03 Processes C++ files according to the ISO C++03 standard. Section 6.13
--cla_default Processes both .c and .cla files as CLA files. Section 10.1
--cpp_default -fg Processes all source files with a C extension as C++ source files. Section 2.3.7
--embedded_cpp -pe Enables embedded C++ mode. Section 6.13.4
--exceptions Enables C++ exception handling. Section 6.6
--float_operations_allowed={none| all|32|64} Restricts the types of floating point operations allowed. Section 2.3.3
--gen_acp_raw -pl Generates a raw listing file (.rl). Section 2.10
--gen_acp_xref -px Generates a cross-reference listing file (.crl). Section 2.9
--keep_unneeded_statics Keeps unreferenced static variables. Section 2.3.3
--kr_compatible -pk Allows K&R compatibility. Applies only to C code, not to C++ code. The --strict_ansi option cannot be used with the --kr_compatible option. Section 6.13.2
--multibyte_chars -pc Accepts multibyte character sequences in comments, string literals and character constants. If you use multibyte characters in your source code, enable this option. --
--no_inlining -pi Disables definition-controlled inlining (but --opt_level=3 (or -O3) optimizations still perform automatic inlining). Section 2.11
--no_intrinsics -pn Disables intrinsic functions. No compiler-supplied intrinsic functions will be predefined. Intrinsic functions can be enabled or disabled in both strict and relaxed ANSI mode. The --no_intrinsics setting has no effect on the --strict_ansi setting, and vice versa. --
--program_level_compile -pm Combines source files to perform program-level optimization. Section 3.3
--relaxed_ansi -pr Enables relaxed mode; ignores strict ISO violations. This is on by default. To disable this mode, use the --strict_ansi option. Section 6.13.3
--rtti -rtti Enables C++ run-time type information (RTTI). –-
--strict_ansi -ps Enables strict ANSI/ISO mode (for C/C++, not for K&R C). In this mode, language extensions that conflict with ANSI/ISO C/C++ are disabled. In strict ANSI/ISO mode, most ANSI/ISO violations are reported as errors. Violations that are considered discretionary may be reported as warnings instead. Section 6.13.3

Table 2-9 Parser Preprocessing Options

Option Alias Effect Section
--preproc_dependency[=filename] -ppd Performs preprocessing only, but instead of writing preprocessed output, writes a list of dependency lines suitable for input to a standard make utility. Section 2.5.8
--preproc_includes[=filename] -ppi Performs preprocessing only, but instead of writing preprocessed output, writes a list of files included with the #include directive. Section 2.5.9
--preproc_macros[=filename] -ppm Performs preprocessing only. Writes list of predefined and user-defined macros to a file with the same name as the input but with a .pp extension. Section 2.5.10
--preproc_only -ppo Performs preprocessing only. Writes preprocessed output to a file with the same name as the input but with a .pp extension. Section 2.5.4
--preproc_with_comment -ppc Performs preprocessing only. Writes preprocessed output, keeping the comments, to a file with the same name as the input but with a .pp extension. Section 2.5.6
--preproc_with_compile -ppa Continues compilation after preprocessing with any of the -pp<x> options that normally disable compilation. Section 2.5.5
--preproc_with_line -ppl Performs preprocessing only. Writes preprocessed output with line-control information (#line directives) to a file with the same name as the input but with a .pp extension. Section 2.5.7

Table 2-10 Predefined Symbols Options

Option Alias Effect Section
--define=name[=def] -D Predefines name. Section 2.3.2
--undefine=name -U Undefines name. Section 2.3.2

Table 2-11 Diagnostic Message Options

Option Alias Effect Section
--advice:performance[=all,none] Provides advice on ways to improve performance. Default is all. Section 2.3.3
--compiler_revision Prints out the compiler release revision and exits. --
--diag_error=num -pdse Categorizes the diagnostic identified by num as an error. Section 2.7.1
--diag_remark=num -pdsr Categorizes the diagnostic identified by num as a remark. Section 2.7.1
--diag_suppress=num -pds Suppresses the diagnostic identified by num. Section 2.7.1
--diag_warning=num -pdsw Categorizes the diagnostic identified by num as a warning. Section 2.7.1
--diag_wrap={on|off} Wrap diagnostic messages (default is on).
--display_error_number -pden Displays a diagnostic's identifiers along with its text. Section 2.7.1
--emit_warnings_as_errors -pdew Treat warnings as errors. Section 2.7.1
--issue_remarks -pdr Issues remarks (non-serious warnings). Section 2.7.1
--no_warnings -pdw Suppresses diagnostic warnings (errors are still issued). Section 2.7.1
--quiet -q Suppresses progress messages (quiet). --
--set_error_limit=num -pdel Sets the error limit to num. The compiler abandons compiling after this number of errors. (The default is 100.) Section 2.7.1
--super_quiet -qq Super quiet mode. --
--tool_version -version Displays version number for each tool. --
--verbose Display banner and function progress information. --
--verbose_diagnostics -pdv Provides verbose diagnostic messages that display the original source with line-wrap. Section 2.7.1
--write_diagnostics_file -pdf Generates a diagnostic message information file. Compiler only option. Section 2.7.1

Table 2-12 Run-Time Model Options

Option Alias Effect Section
--asm_code_fill=value Specifies assembler fill value for code sections. Default is zero. Section 2.3.4
--asm_data_fill=value Specifies fill value for data sections. Default is NOP instructions. Section 2.3.4
--c2xlp_src_compatible -m20 Accepts C2xLP assembly instructions. Section 2.3.4
--disable_dp_load_opt -md Disables DP load optimizations. Section 2.3.4
--fp_reassoc={on|off} Enables or disables the reassociation of floating-point arithmetic. Section 2.3.3
--gen_func_subsections={on|off} -mo Puts each function in a separate subsection in the object file. Section 4.2.1
--no_rpt -mi Disables generation of RPT instructions. Section 2.3.4
--profile:power Enables power profiling. Section 2.3.5
Section 3.8.1
--protect_volatile -mv Enables volatile reference protection. Section 2.3.4
--ramfunc={on|off} If set to on, specifies that all functions should be placed in the .TI.ramfunc section, which is placed in RAM. Section 2.3.4
--rpt_threshold=k Generates RPT loops that iterate k times or less. (k is a constant between 0 and 256.) Section 2.3.4
--sat_reassoc={on|off} Enables or disables the reassociation of saturating arithmetic. Default is --sat_reassoc=off. Section 2.3.3

Table 2-13 Entry/Exit Hook Options

Option Alias Effect Section
--entry_hook[=name] Enables entry hooks. Section 2.13
--entry_parm={none|name|
    address}
Specifies the parameters to the function to the --entry_hook option. Section 2.13
--exit_hook[=name] Enables exit hooks. Section 2.13
--exit_parm={none|name|address} Specifies the parameters to the function to the --exit_hook option. Section 2.13

Table 2-14 Library Function Assumptions Options

Option Alias Effect Section
--printf_support={nofloat|full|
    minimal}
Enables support for smaller, limited versions of the printf function family (sprintf, fprintf, etc.) and the scanf function family (sscanf, fscanf, etc.) run-time-support functions. Section 2.3.3
--std_lib_func_defined -ol1 or -oL1 Informs the optimizer that your file declares a standard library function. Section 3.2.1
--std_lib_func_not_defined -ol2 or -oL2 Informs the optimizer that your file does not declare or alter library functions. Overrides the -ol0 and -ol1 options (default). Section 3.2.1
--std_lib_func_redefined -ol0 or -oL0 Informs the optimizer that your file alters a standard library function. Section 3.2.1

Table 2-15 Assembler Options

Option Alias Effect Section
--keep_asm -k Keeps the assembly language (.asm) file. Section 2.3.11
--asm_listing -al Generates an assembly listing file. Section 2.3.11
--c_src_interlist -ss Interlists C source and assembly statements. Section 2.12
Section 3.7
--src_interlist -s Interlists optimizer comments (if available) and assembly source statements; otherwise interlists C and assembly source statements. Section 2.3.2
--absolute_listing -aa Enables absolute listing. Section 2.3.11
--asm_define=name[=def] -ad Sets the name symbol. Section 2.3.11
--asm_dependency -apd Performs preprocessing; lists only assembly dependencies. Section 2.3.11
--asm_includes -api Performs preprocessing; lists only included #include files. Section 2.3.11
--asm_remarks -mw Enables additional assembly-time checking. Section 2.3.11
--asm_undefine=name -au Undefines the predefined constant name. Section 2.3.11
--cdebug_asm_data -mg Produces C-type symbolic debugging for assembly variables. Section 2.3.11
--copy_file=filename -ahc Copies the specified file for the assembly module. Section 2.3.11
--cross_reference -ax Generates the cross-reference file. Section 2.3.11
--flash_prefetch_warn Assembler warnings for F281X BF flash prefetch issue. Section 2.3.11
--include_file=filename -ahi Includes the specified file for the assembly module. Section 2.3.11
--no_const_clink Stops generation of .clink directives for const global arrays. Section 2.3.3
--output_all_syms -as Puts labels in the symbol table. Section 2.3.11
--preproc_asm -mx Preprocesses assembly source, expands assembly macros. Section 2.3.11
--syms_ignore_case -ac Makes case insignificant in assembly source files. Section 2.3.11

Table 2-16 File Type Specifier Options

Option Alias Effect Section
--asm_file=filename -fa Identifies filename as an assembly source file regardless of its extension. By default, the compiler and assembler treat .asm files as assembly source files. Section 2.3.7
--c_file=filename -fc Identifies filename as a C source file regardless of its extension. By default, the compiler treats .c files as C source files. Section 2.3.7
--cpp_file=filename -fp Identifies filename as a C++ file, regardless of its extension. By default, the compiler treats .C, .cpp, .cc and .cxx files as a C++ files. Section 2.3.7
--obj_file=filename -fo Identifies filename as an object code file regardless of its extension. By default, the compiler and linker treat .obj files as object code files. Section 2.3.7

Table 2-17 Directory Specifier Options

Option Alias Effect Section
--abs_directory=directory -fb Specifies an absolute listing file directory. By default, the compiler uses the .obj directory. Section 2.3.10
--asm_directory=directory -fs Specifies an assembly file directory. By default, the compiler uses the current directory. Section 2.3.10
--list_directory=directory -ff Specifies an assembly listing file and cross-reference listing file directory By default, the compiler uses the .obj directory. Section 2.3.10
--obj_directory=directory -fr Specifies an object file directory. By default, the compiler uses the current directory. Section 2.3.10
--output_file=filename -fe Specifies a compilation output file name; can override --obj_directory. Section 2.3.10
--pp_directory=dir Specifies a preprocessor file directory. By default, the compiler uses the current directory. Section 2.3.10
--temp_directory=directory -ft Specifies a temporary file directory. By default, the compiler uses the current directory. Section 2.3.10

Table 2-18 Default File Extensions Options

Option Alias Effect Section
--asm_extension=[.]extension -ea Sets a default extension for assembly source files.

Section 2.3.9
--c_extension=[.]extension -ec Sets a default extension for C source files. Section 2.3.9
--cpp_extension=[.]extension -ep Sets a default extension for C++ source files. Section 2.3.9
--listing_extension=[.]extension -es Sets a default extension for listing files. Section 2.3.9
--obj_extension=[.]extension -eo Sets a default extension for object files. Section 2.3.9

Table 2-19 Command Files Options

Option Alias Effect Section
--cmd_file=filename -@ Interprets contents of a file as an extension to the command line. Multiple -@ instances can be used. Section 2.3.2

Table 2-20 MISRA-C:2004 Options

Option Alias Effect Section
--check_misra[={all|required|
    advisory|none|rulespec}]
Enables checking of the specified MISRA-C:2004 rules. Default is all. Section 2.3.3
--misra_advisory={error|warning|
    remark|suppress}
Sets the diagnostic severity for advisory MISRA-C:2004 rules. Section 2.3.3
--misra_required={error|warning|
    remark|suppress}
Sets the diagnostic severity for required MISRA-C:2004 rules. Section 2.3.3

2.3.1 Linker Options

The following tables list the linker options. See Section 4 of this document and the TMS320C28x Assembly Language Tools User's Guide for details on these options.

Table 2-21 Linker Basic Options

Option Alias Description
--run_linker -z Enables linking.
--output_file=file -o Names the executable output file. The default filename is a.out file.
--map_file=file -m Produces a map or listing of the input and output sections, including holes, and places the listing in filename .
--stack_size=size [-]-stack Sets C system stack size to sizewords and defines a global symbol that specifies the stack size. Default = 1K words.
--heap_size=size [-]-heap Sets heap size (for the dynamic memory allocation in C) to sizewords and defines a global symbol that specifies the heap size. Default = 1K words.
--warn_sections -w Displays a message when an undefined output section is created.

Table 2-22 File Search Path Options

Option Alias Description
--library=file -l Names an archive library or link command file as linker input.
--search_path=pathname -I Alters library-search algorithms to look in a directory named with pathname before looking in the default location. This option must appear before the --library option.
--priority -priority Satisfies unresolved references by the first library that contains a definition for that symbol.
--reread_libs -x Forces rereading of libraries, which resolves back references.
--disable_auto_rts Disables the automatic selection of a run-time-support library. See Section 4.3.1.1.

Table 2-23 Command File Preprocessing Options

Option Alias Description
--define=name=value Predefines name as a preprocessor macro.
--undefine=name Removes the preprocessor macro name.
--disable_pp Disables preprocessing for command files.

Table 2-24 Diagnostic Message Options

Option Alias Description
--diag_error=num Categorizes the diagnostic identified by num as an error.
--diag_remark=num Categorizes the diagnostic identified by num as a remark.
--diag_suppress=num Suppresses the diagnostic identified by num.
--diag_warning=num Categorizes the diagnostic identified by num as a warning.
--display_error_number Displays a diagnostic's identifiers along with its text.
--emit_warnings_as_errors -pdew Treat warnings as errors.
--issue_remarks Issues remarks (non-serious warnings).
--no_demangle Disables demangling of symbol names in diagnostic messages.
--no_warnings Suppresses diagnostic warnings (errors are still issued).
--set_error_limit=count Sets the error limit to count. The linker abandons linking after this number of errors. (The default is 100.)
--verbose_diagnostics Provides verbose diagnostic messages that display the original source with line-wrap.

Table 2-25 Linker Output Options

Option Alias Description
--absolute_exe -a Produces an absolute, executable object file. This is the default; if neither --absolute_exe nor --relocatable is specified, the linker acts as if --absolute_exe were specified.
--ecc:data_error Inject specified errors into the output file for testing.
--ecc:ecc_error Inject specified errors into the Error Correcting Code (ECC) for testing.
--mapfile_contents=attribute Controls the information that appears in the map file.
--relocatable -r Produces a nonexecutable, relocatable output object file.
--rom Creates a ROM object.
--run_abs -abs Produces an absolute listing file.
--xml_link_info=file Generates a well-formed XML file containing detailed information about the result of a link.

Table 2-26 Symbol Management Options

Option Alias Description
--entry_point=symbol -e Defines a global symbol that specifies the primary entry point for the executable object file.
--globalize=pattern Changes the symbol linkage to global for symbols that match pattern.
--hide=pattern Hides symbols that match the specified pattern.
--localize=pattern Make the symbols that match the specified pattern local.
--make_global=symbol -g Makes symbol global (overrides -h).
--make_static -h Makes all global symbols static.
--no_sym_merge -b Disables merge of symbolic debugging information in COFF object files.
--no_symtable -s Strips symbol table information and line number entries from the executable object file.
--scan_libraries -scanlibs Scans all libraries for duplicate symbol definitions.
--symbol_map=refname=defname Specifies a symbol mapping; references to the refname symbol are replaced with references to the defname symbol. The --symbol_map option is now supported when used with --opt_level=4.

--undef_sym=symbol -u Adds symbol to the symbol table as an unresolved symbol.
--unhide=pattern Excludes symbols that match the specified pattern from being hidden.

Table 2-27 Run-Time Environment Options

Option Alias Description
--arg_size=size --args Reserve size bytes for the argc/argv memory area.
--fill_value=value -f Sets default fill value for holes within output sections
--ram_model -cr Initializes variables at load time.
--rom_model -c Autoinitializes variables at run time.

Table 2-28 Link-Time Optimization Options(1)

Option Alias Description
--keep_asm Retain any post-link files (.pl) and .absolute listing files (.abs) generated by the −plink option. This allows you to view any changes the post-link optimizer makes. (Requires use of -plink)
--no_postlink_across_calls -nf Disable post-link optimizations across functions. (Requires use of -plink)
--plink_advice_only Annotates assembly code with comments if changes cannot be made safely due to pipeline considerations, such as when float support or VCU support is enabled. (Requires use of -plink)
--postlink_exclude -ex Exclude files from post-link pass. (Requires use of -plink)
--postlink_opt -plink Post-link optimizations (only after -z).
(1) See Section 5 for details.

Table 2-29 Miscellaneous Options

Option Alias Description
--disable_clink -j Disables conditional linking of COFF object files.
--linker_help [-]-help Displays information about syntax and available options.
--preferred_order=function Prioritizes placement of functions.
--strict_compatibility[=off|on] Performs more conservative and rigorous compatibility checking of input object files. Default is on.

2.3.2 Frequently Used Options

Following are detailed descriptions of options that you will probably use frequently:

--c_src_interlist Invokes the interlist feature, which interweaves original C/C++ source with compiler-generated assembly language. The interlisted C statements may appear to be out of sequence. You can use the interlist feature with the optimizer by combining the --optimizer_interlist and --c_src_interlist options. See Section 3.7. The --c_src_interlist option can have a negative performance and/or code size impact.
--cmd_file=filename Appends the contents of a file to the option set. You can use this option to avoid limitations on command line length or C style comments imposed by the host operating system. Use a # or ; at the beginning of a line in the command file to include comments. You can also include comments by delimiting them with /* and */. To specify options, surround hyphens with quotation marks. For example, "--"quiet.

You can use the --cmd_file option multiple times to specify multiple files. For instance, the following indicates that file3 should be compiled as source and file1 and file2 are --cmd_file files:

cl2000 --cmd_file=file1 --cmd_file=file2 file3
--compile_only Suppresses the linker and overrides the --run_linker option, which specifies linking. The --compile_only option's short form is -c. Use this option when you have --run_linker specified in the C2000_C_OPTION environment variable and you do not want to link. See Section 4.1.3.
--define=name[=def] Predefines the constant name for the preprocessor. This is equivalent to inserting #define name def at the top of each C source file. If the optional[=def] is omitted, the name is set to 1. The --define option's short form is -D.

If you want to define a quoted string and keep the quotation marks, do one of the following:

  • For Windows, use --define=name="\"string def\"". For example, --define=car="\"sedan\""
  • For UNIX, use --define=name='"string def"'. For example, --define=car='"sedan"'
  • For Code Composer Studio, enter the definition in a file and include that file with the --cmd_file option.
--help Displays the syntax for invoking the compiler and lists available options. If the --help option is followed by another option or phrase, detailed information about the option or phrase is displayed. For example, to see information about debugging options use --help debug.
--include_path=directory Adds directory to the list of directories that the compiler searches for #include files. The --include_path option's short form is -I. You can use this option several times to define several directories; be sure to separate the --include_path options with spaces. If you do not specify a directory name, the preprocessor ignores the --include_path option. See Section 2.5.2.1.
--keep_asm Retains the assembly language output from the compiler or assembly optimizer. Normally, the compiler deletes the output assembly language file after assembly is complete. The --keep_asm option's short form is -k.
--quiet Suppresses banners and progress information from all the tools. Only source filenames and error messages are output. The --quiet option's short form is -q.
--run_linker Runs the linker on the specified object files. The --run_linker option and its parameters follow all other options on the command line. All arguments that follow --run_linker are passed to the linker. The --run_linker option's short form is -z. See Section 4.1.
--skip_assembler Compiles only. The specified source files are compiled but not assembled or linked. The --skip_assembler option's short form is -n. This option overrides --run_linker. The output is assembly language output from the compiler.
--src_interlist Invokes the interlist feature, which interweaves optimizer comments or C/C++ source with assembly source. If the optimizer is invoked (--opt_level=n option), optimizer comments are interlisted with the assembly language output of the compiler, which may rearrange code significantly. If the optimizer is not invoked, C/C++ source statements are interlisted with the assembly language output of the compiler, which allows you to inspect the code generated for each C/C++ statement. The --src_interlist option implies the --keep_asm option. The --src_interlist option's short form is -s.
--tool_version Prints the version number for each tool in the compiler. No compiling occurs.
--undefine=name Undefines the predefined constant name. This option overrides any --define options for the specified constant. The --undefine option's short form is -U.
--verbose Displays progress information and toolset version while compiling. Resets the --quiet option.

2.3.3 Miscellaneous Useful Options

Following are detailed descriptions of miscellaneous options:

--advice:performance[=all|none] When Trigonometric Math Unit (TMU) support is enabled (--tmu_support) and --fp_mode=strict, advice will be generated if the compiler encounters function calls that could be replaced with TMU hardware instructions under --fp_mode=relaxed. These include floating point division, sqrt, sin, cos, atan, and atan2.
--check_misra={all|required|
    advisory|none|rulespec}
Displays the specified amount or type of MISRA-C documentation. The rulespec parameter is a comma-separated list of specifiers. See Section 6.3 for details.
--float_operations_allowed= {none|all|32|64} Restricts the type of floating point operations allowed in the application. The default is all. If set to none, 32, or 64, the application is checked for operations that will be performed at runtime. For example, if --float_operations_allowed=32 is specified on the command line, the compiler issues an error if a double precision operation will be generated. This can be used to ensure that double precision operations are not accidentally introduced into an application. The checks are performed after relaxed mode optimizations have been performed, so illegal operations that are completely removed result in no diagnostic messages.
--fp_mode={relaxed|strict} The default floating-point mode is strict. To enable relaxed floating-point mode use the --fp_mode=relaxed option. Relaxed floating-point mode causes double-precision floating-point computations and storage to be converted to integers where possible. This behavior does not conform with ISO, but it results in faster code, with some loss in accuracy. The following specific changes occur in relaxed mode:
  • Division by a constant is converted to inverse multiplication.
  • Certain C standard float functions--such as sqrt, sin, cos, atan, and atan2--are redirected to optimized inline functions where possible.
  • If the --tmu_support option is used to enable support for the Trigonometric Math Unit (TMU) and relaxed floating-point mode is enabled, RTS library calls are replaced with the corresponding TMU hardware instructions for the following floating-point operations: floating point division, sqrt, sin, cos, atan, and atan2. Note that there are algorithmic differences between the TMU hardware instructions and the library routines, so the results of operations may differ slightly.
--fp_reassoc={on|off} Enables or disables the reassociation of floating-point arithmetic. The default value is --fp_reassoc=on.

Because floating-point values are of limited precision, and because floating-point operations round, floating-point arithmetic is neither associative nor distributive. For instance, (1 + 3e100) - 3e100 is not equal to 1 + (3e100 - 3e100). If strictly following IEEE 754, the compiler cannot, in general, reassociate floating-point operations. Using --fp_reassoc=on allows the compiler to perform the algebraic reassociation, at the cost of a small amount of precision for some operations.

When --fp_reassoc=on, RPT MACF32 instructions may be generated. Because the RPT MACF32 instruction computes two partial sums and adds them together afterward to compute the entire accumulation, the result can vary in precision from a serial floating-point multiply accumulate loop.

--keep_unneeded_statics Prevents the compiler from deleting unreferenced static variables. The parser by default remarks about and then removes any unreferenced static variables. The --keep_unneeded_statics option keeps the parser from deleting unreferenced static variables and any static functions that are referenced by these variable definitions. Unreferenced static functions will still be removed.
--no_const_clink Tells the compiler to not generate .clink directives for const global arrays. By default, these arrays are placed in a .econst subsection and conditionally linked.
--misra_advisory={error|
    warning|remark|suppress}
Sets the diagnostic severity for advisory MISRA-C:2004 rules.
--misra_required={error|
    warning|remark|suppress}
Sets the diagnostic severity for required MISRA-C:2004 rules.
--preinclude=filename Includes the source code of filename at the beginning of the compilation. This can be used to establish standard macro definitions. The filename is searched for in the directories on the include search list. The files are processed in the order in which they were specified.
--printf_support={full|
    nofloat|minimal}
Enables support for smaller, limited versions of the printf function family (sprintf, fprintf, etc.) and the scanf function family (sscanf, fscanf, etc.) run-time-support functions. The valid values are:
  • full: Supports all format specifiers. This is the default.
  • nofloat: Excludes support for printing and scanning floating-point values. Supports all format specifiers except %a, %A, %f, %F, %g, %G, %e, and %E.
  • minimal: Supports the printing and scanning of integer, char, or string values without width or precision flags. Specifically, only the %%, %d, %o, %c, %s, and %x format specifiers are supported

There is no run-time error checking to detect if a format specifier is used for which support is not included. The --printf_support option precedes the --run_linker option, and must be used when performing the final link.

--sat_reassoc={on|off} Enables or disables the reassociation of saturating arithmetic.

2.3.4 Run-Time Model Options

These options are specific to the TMS320C28x toolset. See the referenced sections for more information. TMS320C28x-specific assembler options are listed in Section 2.3.11.

--asm_code_fill=value Specifies fill value to fill the holes in code sections created by the assembler. You can specify a 16-bit value in decimal, octal, or hexadecimal format.
--asm_data_fill=value Specifies fill value to fill the holes in data sections created by the assembler. You can specify a 16-bit value in decimal, octal, or hexadecimal format.
--c2xlp_src_compatible Accepts C2xLP assembly instructions and encodes them as equivalent C28x instructions.
--cla_support={cla0|cla1} Specifies TMS320C28x Control Law Accelerator (CLA) Type 0 or Type 1 support. This option is used to compile or assemble code written for the CLA. This option does not require any special library support when linking; the libraries used for C28x with/without FPU support should be sufficient.
--disable_dp_load_opt Disables the compiler from optimizing redundant loads of the DP register when using DP direct addressing.
--float_support={fpu32|fpu64} Specifies use of TMS320C28x 32- or 64-bit hardware floating-point support. Using --float_support=fpu32 specifies the C28x architecture with 32-bit hardware floating-point support. Using --float_support=fpu64 specifies the C28x architecture with 64-bit hardware floating-point support. If the --tmu_support option is used to enable support for the Trigonometric Math Unit, the --float_support option is automatically set to fpu32.
--no_rpt Prevents the compiler from generating repeat (RPT) instructions. By default, repeat instructions are generated for certain memcpy, division, and multiply-accumulate operations. However, repeat instructions are not interruptible.
--protect_volatile=num Enables volatile reference protection. Pipeline conflicts may occur between non-local variables that have been declared volatile. A conflict can occur between a write to one volatile variable that is followed by a read from a different volatile variable. The --protect_volatile option allows at least num instructions to be placed between the two volatile references to ensure the write occurs before the read. The num is optional. If no num is given, the default value is 2. For example, if --protect_volatile=4 is used, volatile writes and volatile reads are protected by at least 4 instructions.

The peripheral pipeline protection hardware protects all internal peripherals and XINTF zone 1. If you connect peripherals to Xintf zone 0, 2, 6, 7 then you may need to use the --protect_volatile option. Hardware protection or using this option is not required for memories.

--ramfunc={on|off} If set to on, specifies that all functions should be placed in the .TI.ramfunc section, which is placed in RAM. If set to off, only functions with the ramfunc function attribute are treated this way. See Section 6.14.2.

Newer TI linker command files support the --ramfunc option automatically by placing functions in the .TI.ramfunc section. If you have a linker command file that does not include a section specification for the .TI.ramfunc section, you can modify the linker command file to place this section in RAM. See the TMS320C28x Assembly Language Tools User's Guide for details on section placement.

Projects or files that were previously compiled without the --no_fast_branch option should use the --ramfunc=on option instead to generate fast branch instructions for all functions.

--rpt_threshold=k Generates RPT loops that iterate k times or less (k is a constant between 0 and 256). Multiple RPT’s may be generated for the same loop, if iteration count is more than k and if code size does not increase too much. Using this option when optimizing for code size disables RPT loop generation for loops whose iteration count can be greater than k.
--silicon_version=28 Generates code for the TMS320C28x architecture. The only value accepted is 28. This is the default, so this option is no longer required on command lines.
--unified_memory Use the --unified_memory (-mt) option if your memory map is configured as a single unified space; this allows the compiler to generate RPT PREAD instructions for most memcpy calls and structure assignments. This also allows MAC instructions to be generated. The --unified_memory option also allows more efficient data memory instructions to be used to access switch tables.
Even under unified memory, memory for some peripherals and some RAM associated with those peripherals is allocated only in data memory. If –unified_memory is enabled, you can prevent program memory address access to specific symbols by declaring those symbols as volatile.
--tmu_support[=tmu0] Enables support for the Trigonometric Math Unit (TMU). Using this option automatically enables FPU32 support (as with the --float_support=fpu32 option). When TMU support is enabled, intrinsics are available to perform trigonometric instructions on the TMU. In addition, in relaxed floating point mode, RTS library calls are replaced with the corresponding TMU hardware instructions for the following floating-point operations: floating point division, sqrt, sin, cos, atan, and atan2. Note that there are algorithmic differences between the TMU hardware instructions and the library routines, so the results of operations may differ slightly.
--vcu_support[=vcu0|vcu2] Specifies support for Type 0 or Type 2 of the Viterbi, Complex Math and CRC Unit (VCU). This option is useful only if the source is in assembly code, written for the VCU. The option is ignored for C/C++ code. This option does not need any special library support when linking; the libraries used for C28x with/without VCU support should be sufficient. Also note that there is no VCU Type 1.

2.3.5 Symbolic Debugging and Profiling Options

The following options are used to select symbolic debugging or profiling:

--profile:power Enables power profiling support by inserting NOPs into the frame code. These NOPs can then be instrumented by the power profiling tooling to track the power usage of functions. If the power profiling tool is not used, this option increases the cycle count of each function because of the NOPs. The --profile:power option also disables optimizations that cannot be handled by the power-profiler.
--symdebug:coff Enables symbolic debugging using the alternate STABS debugging format. This may be necessary to allow debugging with older debuggers or custom tools, which do not read the DWARF format.
--symdebug:dwarf (Default) Generates directives that are used by the C/C++ source-level debugger and enables assembly source debugging in the assembler. The --symdebug:dwarf option's short form is -g. See Section 3.8.

For more information on the DWARF debug format, see The DWARF Debugging Standard.

--symdebug:none Disables all symbolic debugging output. This option is not recommended; it prevents debugging and most performance analysis capabilities.
--symdebug:profile_coff Adds the necessary debug directives to the object file which are needed by the profiler to allow function level profiling with minimal impact on optimization (when used). Using --symdebug:coff may hinder some optimizations to ensure that debug ability is maintained, while this option will not hinder optimization.

You can set breakpoints and profile on function-level boundaries in Code Composer Studio, but you cannot single-step through code as with full debug ability.

--symdebug:skeletal Deprecated. Has no effect.

See Section 2.3.13 for a list of deprecated symbolic debugging options.

2.3.6 Specifying Filenames

The input files that you specify on the command line can be C source files, C++ source files, assembly source files, or object files. The compiler uses filename extensions to determine the file type.

Extension File Type
.asm, .abs, or .s* (extension begins with s) Assembly source
.c C source
.C Depends on operating system
.cpp, .cxx, .cc C++ source
.obj .o* .dll .so Object

NOTE

Case Sensitivity in Filename Extensions

Case sensitivity in filename extensions is determined by your operating system. If your operating system is not case sensitive, a file with a .C extension is interpreted as a C file. If your operating system is case sensitive, a file with a .C extension is interpreted as a C++ file.

For information about how you can alter the way that the compiler interprets individual filenames, see Section 2.3.7. For information about how you can alter the way that the compiler interprets and names the extensions of assembly source and object files, see Section 2.3.10.

You can use wildcard characters to compile or assemble multiple files. Wildcard specifications vary by system; use the appropriate form listed in your operating system manual. For example, to compile all of the files in a directory with the extension .cpp, enter the following:

cl2000 *.cpp

NOTE

No Default Extension for Source Files is Assumed

If you list a filename called example on the command line, the compiler assumes that the entire filename is example not example.c. No default extensions are added onto files that do not contain an extension.

2.3.7 Changing How the Compiler Interprets Filenames

You can use options to change how the compiler interprets your filenames. If the extensions that you use are different from those recognized by the compiler, you can use the filename options to specify the type of file. You can insert an optional space between the option and the filename. Select the appropriate option for the type of file you want to specify:

--asm_file=filename for an assembly language source file
--c_file=filename for a C source file
--cpp_file=filename for a C++ source file
--obj_file=filename for an object file

For example, if you have a C source file called file.s and an assembly language source file called assy, use the --asm_file and --c_file options to force the correct interpretation:

cl2000 --c_file=file.s --asm_file=assy

You cannot use the filename options with wildcard specifications.

2.3.8 Changing How the Compiler Processes C Files

The --cpp_default option causes the compiler to process C files as C++ files. By default, the compiler treats files with a .c extension as C files. See Section 2.3.9 for more information about filename extension conventions.

2.3.9 Changing How the Compiler Interprets and Names Extensions

You can use options to change how the compiler program interprets filename extensions and names the extensions of the files that it creates. The filename extension options must precede the filenames they apply to on the command line. You can use wildcard specifications with these options. An extension can be up to nine characters in length. Select the appropriate option for the type of extension you want to specify:

--asm_extension=new extension for an assembly language file
--c_extension=new extension for a C source file
--cpp_extension=new extension for a C++ source file
--listing_extension=new extension sets default extension for listing files
--obj_extension=new extension for an object file

The following example assembles the file fit.rrr and creates an object file named fit.o:

cl2000 --asm_extension=.rrr --obj_extension=.o fit.rrr

The period (.) in the extension is optional. You can also write the example above as:

cl2000 --asm_extension=rrr --obj_extension=o fit.rrr

2.3.10 Specifying Directories

By default, the compiler program places the object, assembly, and temporary files that it creates into the current directory. If you want the compiler program to place these files in different directories, use the following options:

--abs_directory=directory Specifies the destination directory for absolute listing files. The default is to use the same directory as the object file directory. For example: cl2000 --abs_directory=d:\abso_list
--asm_directory=directory Specifies a directory for assembly files. For example: cl2000 --asm_directory=d:\assembly
--list_directory=directory Specifies the destination directory for assembly listing files and cross-reference listing files. The default is to use the same directory as the object file directory. For example: cl2000 --list_directory=d:\listing
--obj_directory=directory Specifies a directory for object files. For example: cl2000 --obj_directory=d:\object
--output_file=filename Specifies a compilation output file name; can override --obj_directory . For example: cl2000 --output_file=transfer
--pp_directory=directory Specifies a preprocessor file directory for object files (default is .). For example: cl2000 --pp_directory=d:\preproc
--temp_directory=directory Specifies a directory for temporary intermediate files. For example: cl2000 --temp_directory=d:\temp

2.3.11 Assembler Options

Following are assembler options that you can use with the compiler. For more information, see the TMS320C28x Assembly Language Tools User's Guide.

--absolute_listing Generates a listing with absolute addresses rather than section-relative offsets.
--asm_define=name[=def] Predefines the constant name for the assembler; produces a .set directive for a constant or an .arg directive for a string. If the optional [=def] is omitted, the name is set to 1. If you want to define a quoted string and keep the quotation marks, do one of the following:

  • For Windows, use --asm_define=name="\"string def\"". For example: --asm_define=car="\"sedan\""
  • For UNIX, use --asm_define=name='"string def"'. For example: --asm_define=car='"sedan"'
  • For Code Composer Studio, enter the definition in a file and include that file with the --cmd_file option.
--asm_dependency Performs preprocessing for assembly files, but instead of writing preprocessed output, writes a list of dependency lines suitable for input to a standard make utility. The list is written to a file with the same name as the source file but with a .ppa extension.
--asm_includes Performs preprocessing for assembly files, but instead of writing preprocessed output, writes a list of files included with the #include directive. The list is written to a file with the same name as the source file but with a .ppa extension.
--asm_listing Produces an assembly listing file.
--asm_remarks Enables additional assembly-time checking. A warning is generated if an .ebss allocation size is greater than 64 words, or a 16-bit immediate operand value resides outside of the -32 768 to 65 535 range.
--asm_undefine=name Undefines the predefined constant name. This option overrides any --asm_define options for the specified name.
--cdebug_asm_data Produces C-type symbolic debugging for assembly variables defined in assembly source code using data directives. This support is for basic C types, structures, and arrays.
--copy_file=filename Copies the specified file for the assembly module; acts like a .copy directive. The file is inserted before source file statements. The copied file appears in the assembly listing files.
--cross_reference Produces a symbolic cross-reference in the listing file.
--flash_prefetch_warn Enables assembler warnings if a program data access instruction follows within 8 words of a BF or SBF instruction. As outlined in the TMS320C281X/TMS320F281X DSP Silicon Errata (SPRZ193) advisory on the "Flash and OTP Prefetch Buffer Overflow", the flash prefetch buffer may overflow if this instruction sequence is executed from flash or One-Time-Programmable (OTP) memory with the flash prefetch buffer enabled. Whether or not an overflow actually occurs depends on the instruction sequence, flash wait states, and CPU pipeline stalls. If an overflow occurs, it will result in execution of invalid opcodes. Instructions that use program memory addressing include MAC/XMAC, DMAC/XMACD, QMACL, IMACL, PREAD/XPREAD, and PWRITE/XPWRITE.
--include_file=filename Includes the specified file for the assembly module; acts like an .include directive. The file is included before source file statements. The included file does not appear in the assembly listing files.
--output_all_syms Puts labels in the symbol table. Label definitions are written to the symbol table for use with symbolic debugging.
--preproc_asm Expands macros in an assembly file and assembles the expanded file. Expanding macros helps you to debug the assembly file. The --preproc_asm option affects only the assembly file. When --preproc_asm is used, the compiler first invokes the assembler to generate the macro-expanded source .exp file. Then the .exp file is assembled to generate the object file. The debugger uses the .exp file for debugging. The .exp file is an intermediate file and any update to this file will be lost. You need to make any updates to the original assembly file.
--syms_ignore_case Makes letter case insignificant in assembly language source files. For example, --syms_ignore_case makes ABC and abc equivalent. If you do not use this option, case is significant.

2.3.12 Dynamic Linking

The C28x v?.? Code Generation Tools (CGT) support dynamic linking. For details on dynamic linking with the C28x CGT, see the TMS320C28x Assembly Language Tools User's Guide.

Table 2-30 provides a brief summary of the linker options that are related to support for the Dynamic Linking Model in the C28x CGT.

Table 2-30 Linker Options For Dynamic Linking

Option Description
--dynamic[=exe] Specifies that the result of a link will be a lightweight dynamic executable.
--dynamic= lib Specifies that the result of a link will be a dynamic library.
--export= symbol Specifies that symbol is exported by the ELF object that is generated for this link.
--fini= symbol Specifies the symbol name of the termination code for the output file currently being linked.
--import= symbol Specifies that symbol is imported by the ELF object that is generated for this link.
--init= symbol Specifies the symbol name of the initialization code for the output file currently being linked.
--rpath= dir Adds a directory to the beginning of the dynamic library search path.
--runpath= dir Adds a directory to the end of the dynamic library search path.
--soname= string Specifies shared object name to be used to identify this ELF object to the any downstream ELF object consumers.

2.3.13 Deprecated Options

Several compiler options have been deprecated. The compiler continues to accept these options, but they are not recommended for use. Future releases of the tools will not support these options. Table 2-31 lists the deprecated options that have been replaced by other options.

Table 2-31 Compiler Backwards-Compatibility Options Summary

Old Option Effect Option to Use Instead
-gcc Enabled support for GCC extensions. --relaxed_ansi
-gp Allowed function-level profiling of optimized code --symdebug:dwarf or -g
-gt Enabled symbolic debugging using the alternate STABS debugging format --symdebug:coff
-gw Enabled symbolic debugging using the DWARF debugging format --symdebug:dwarf or -g
--symdebug:skeletal Enabled minimal debugging. Now has no effect. --symdebug:none
--optimize_with_debug Enabled optimization with debugging. Now this is default behavior. Option has no effect.

Additionally, the --symdebug:profile_coff option has been added to enable function-level profiling of optimized code with symbolic debugging using the STABS debugging format (the --symdebug:coff or -gt option).

The --farheap and --large_memory_model options are deprecated.

The --no_fast_branch option is deprecated and no longer has any effect. Fast branching is generated only for functions that have the ramfunc attribute or the --ramfunc=on option is used. Projects or files previously compiled without the --no_fast_branch option should use the --ramfunc=on option instead to generate fast branch instructions for all functions.

The --opt_for_size option has been replaced by the --opt_for_space and --opt_for_speed options. The --disable_pcd and --out_as_uout options are now obsolete.

2.4 Controlling the Compiler Through Environment Variables

An environment variable is a system symbol that you define and assign a string to. Setting environment variables is useful when you want to run the compiler repeatedly without re-entering options, input filenames, or pathnames.

NOTE

C_OPTION and C_DIR -- The C_OPTION and C_DIR environment variables are deprecated. Use device-specific environment variables instead.

2.4.1 Setting Default Compiler Options (C2000_C_OPTION)

You might find it useful to set the compiler, assembler, and linker default options using the C2000_C_OPTION environment variable. If you do this, the compiler uses the default options and/or input filenames that you name C2000_C_OPTION every time you run the compiler.

Setting the default options with these environment variables is useful when you want to run the compiler repeatedly with the same set of options and/or input files. After the compiler reads the command line and the input filenames, it looks for the C2000_C_OPTION environment variable and processes it.

The table below shows how to set the C2000_C_OPTION environment variable. Select the command for your operating system:

Operating System Enter
UNIX (Bourne shell) C2000_C_OPTION="option1 [option2 . . .]"; export C2000_C_OPTION
Windows set C2000_C_OPTION=option1 [option2 . . .]

Environment variable options are specified in the same way and have the same meaning as they do on the command line. For example, if you want to always run quietly (the --quiet option), enable C/C++ source interlisting (the --src_interlist option), and link (the --run_linker option) for Windows, set up the C2000_C_OPTION environment variable as follows:

set C2000_C_OPTION=--quiet --src_interlist --run_linker

In the following examples, each time you run the compiler, it runs the linker. Any options following --run_linker on the command line or in C2000_C_OPTION are passed to the linker. Thus, you can use the C2000_C_OPTION environment variable to specify default compiler and linker options and then specify additional compiler and linker options on the command line. If you have set --run_linker in the environment variable and want to compile only, use the compiler --compile_only option. These additional examples assume C2000_C_OPTION is set as shown above:

cl2000 *c ; compiles and links cl2000 --compile_only *.c ; only compiles cl2000 *.c --run_linker lnk.cmd ; compiles and links using a command file cl2000 --compile_only *.c --run_linker lnk.cmd ; only compiles (--compile_only overrides --run_linker)

For details on compiler options, see Section 2.3. For details on linker options, see the Linker Description chapter in the TMS320C28x Assembly Language Tools User's Guide.

2.4.2 Naming One or More Alternate Directories (C2000_C_DIR)

The linker uses the C2000_C_DIR environment variable to name alternate directories that contain object libraries. The command syntaxes for assigning the environment variable are:

Operating System Enter
UNIX (Bourne shell) C2000_C_DIR="pathname1 ;pathname2 ;..."; export C2000_C_DIR
Windows set C2000_C_DIR=pathname1 ;pathname2 ;...

The pathnames are directories that contain input files. The pathnames must follow these constraints:

  • Pathnames must be separated with a semicolon.
  • Spaces or tabs at the beginning or end of a path are ignored. For example, the space before and after the semicolon in the following is ignored:
  • set C2000_C_DIR=c:\path\one\to\tools ; c:\path\two\to\tools
  • Spaces and tabs are allowed within paths to accommodate Windows directories that contain spaces. For example, the pathnames in the following are valid:
  • set C2000_C_DIR=c:\first path\to\tools;d:\second path\to\tools

The environment variable remains set until you reboot the system or reset the variable by entering:

Operating System Enter
UNIX (Bourne shell) unset C2000_C_DIR
Windows set C2000_C_DIR=

2.5 Controlling the Preprocessor

This section describes features that control the preprocessor, which is part of the parser. A general description of C preprocessing is in section A12 of K&R. The C/C++ compiler includes standard C/C++ preprocessing functions, which are built into the first pass of the compiler. The preprocessor handles:

  • Macro definitions and expansions
  • #include files
  • Conditional compilation
  • Various preprocessor directives, specified in the source file as lines beginning with the # character

The preprocessor produces self-explanatory error messages. The line number and the filename where the error occurred are printed along with a diagnostic message.

2.5.1 Predefined Macro Names

The compiler maintains and recognizes the predefined macro names listed in Table 2-32.

Table 2-32 Predefined C28x Macro Names

Macro Name Description
_ _DATE_ _(1) Expands to the compilation date in the form mmm dd yyyy
_ _FILE_ _(1) Expands to the current source filename
_ _LINE_ _(1) Expands to the current line number
_ _little_endian_ _ Always defined
_ _PTRDIFF_T_TYPE_ _ Set to the type of ptrdiff_t.
_ _SIZE_T_TYPE_ _ Set to the type of size_t.
_ _STDC_ _(1) Defined to indicate that compiler conforms to ISO C Standard. See Section 6.1 for exceptions to ISO C conformance.
_ _STDC_VERSION_ _ C standard macro
_ _TI_COMPILER_VERSION_ _ Defined to a 7-9 digit integer, depending on if X has 1, 2, or 3 digits. The number does not contain a decimal. For example, version 3.2.1 is represented as 3002001. The leading zeros are dropped to prevent the number being interpreted as an octal.
_ _TI_GNU_ATTRIBUTE_SUPPORT_ _ Defined if GCC extensions are enabled (the --gcc option is used); otherwise, it is undefined. (Deprecated)
_ _TI_STRICT_ANSI_MODE__ Defined if strict ANSI/ISO mode is enabled (the --strict_ansi option is used); otherwise, it is undefined.
_ _TI_STRICT_FP_MODE_ _ Defined to 1 if --fp_mode=strict is used (or implied); otherwise, it is undefined.
_ _TIME_ _(1) Expands to the compilation time in the form "hh:mm:ss"
_ _TMS320C2000_ _ Defined for C28x processor
_ _TMS320C28XX_ _ Defined if target is C28x
__TMS320C28XX_CLA__ Defined to 1 if any --cla_support option was used.
__TMS320C28XX_CLA0__ Defined to 1 if the --cla_support=cla0 option was used.
__TMS320C28XX_CLA1__ Defined to 1 if the --cla_support=cla1 option was used.
_ _TMS320C28XX_FPU32_ _ Expands to 1 (identifies the C28x processor with 32-bit hardware floating-point support).
_ _TMS320C28XX_FPU64_ _ Expands to 1 (identifies the C28x processor with 64-bit hardware floating-point support).
_ _TMS320C28XX_TMU_ _ Defined to 1 if the --tmu_support option was used to enable the Trigonometric Math Unit.
_ _WCHAR_T_TYPE_ _ Set to the type of wchar_t.
_INLINE Expands to 1 if optimization is used (--opt_level or -O option); undefined otherwise. Regardless of any optimization, always undefined when --no_inlining is used.
(1) Specified by the ISO standard

You can use the names listed in Table 2-32 in the same manner as any other defined name. For example,

printf ( "%s %s" , __TIME__ , __DATE__);

translates to a line such as:

printf ("%s %s" , "13:58:17", "Jan 14 1997");

2.5.2 The Search Path for #include Files

The #include preprocessor directive tells the compiler to read source statements from another file. When specifying the file, you can enclose the filename in double quotes or in angle brackets. The filename can be a complete pathname, partial path information, or a filename with no path information.

  • If you enclose the filename in double quotes (" "), the compiler searches for the file in the following directories in this order:
    1. The directory of the file that contains the #include directive and in the directories of any files that contain that file.
    2. Directories named with the --include_path option.
    3. Directories set with the C2000_C_DIR environment variable.
  • If you enclose the filename in angle brackets (< >), the compiler searches for the file in the following directories in this order:
    1. Directories named with the --include_path option.
    2. Directories set with the C2000_C_DIR environment variable.

See Section 2.5.2.1 for information on using the --include_path option. See Section 2.4.2 for more information on input file directories.

2.5.2.1 Adding a Directory to the #include File Search Path (--include_path Option)

The --include_path option names an alternate directory that contains #include files. The --include_path option's short form is -I. The format of the --include_path option is:

--include_path=directory1 [--include_path=directory2 ...]

There is no limit to the number of --include_path options per invocation of the compiler; each --include_path option names one directory. In C source, you can use the #include directive without specifying any directory information for the file; instead, you can specify the directory information with the --include_path option.

For example, assume that a file called source.c is in the current directory. The file source.c contains the following directive statement:

#include "alt.h"

Assume that the complete pathname for alt.h is:

UNIX /tools/files/alt.h
Windows c:\tools\files\alt.h

The table below shows how to invoke the compiler. Select the command for your operating system:

Operating System Enter
UNIX cl2000 --include_path=/tools/files source.c
Windows cl2000 --include_path=c:\tools\files source.c

NOTE

Specifying Path Information in Angle Brackets

If you specify the path information in angle brackets, the compiler applies that information relative to the path information specified with --include_path options and the C2000_C_DIR environment variable.

For example, if you set up C2000_C_DIR with the following command:

C2000_C_DIR "/usr/include;/usr/ucb"; export C2000_C_DIR

or invoke the compiler with the following command:

cl2000 --include_path=/usr/include file.c

and file.c contains this line:

#include <sys/proc.h>

the result is that the included file is in the following path:

/usr/include/sys/proc.h

2.5.3 Support for the #warning and #warn Directives

In strict ANSI mode, the TI preprocessor allows you to use the #warn directive to cause the preprocessor to issue a warning and continue preprocessing. The #warn directive is equivalent to the #warning directive supported by GCC, IAR, and other compilers.

If you use the --relaxed_ansi option (on by default), both the #warn and #warning preprocessor directives are supported.

2.5.4 Generating a Preprocessed Listing File (--preproc_only Option)

The --preproc_only option allows you to generate a preprocessed version of your source file with an extension of .pp. The compiler's preprocessing functions perform the following operations on the source file:

  • Each source line ending in a backslash (\) is joined with the following line.
  • Trigraph sequences are expanded.
  • Comments are removed.
  • #include files are copied into the file.
  • Macro definitions are processed.
  • All macros are expanded.
  • All other preprocessing directives, including #line directives and conditional compilation, are expanded.

The --preproc_only option is useful when creating a source file for a technical support case or to ask a question about your code. It allows you to reduce the test case to a single source file, because #include files are incorporated when the preprocessor runs.

2.5.5 Continuing Compilation After Preprocessing (--preproc_with_compile Option)

If you are preprocessing, the preprocessor performs preprocessing only; it does not compile your source code. To override this feature and continue to compile after your source code is preprocessed, use the --preproc_with_compile option along with the other preprocessing options. For example, use --preproc_with_compile with --preproc_only to perform preprocessing, write preprocessed output to a file with a .pp extension, and compile your source code.

2.5.6 Generating a Preprocessed Listing File with Comments (--preproc_with_comment Option)

The --preproc_with_comment option performs all of the preprocessing functions except removing comments and generates a preprocessed version of your source file with a .pp extension. Use the --preproc_with_comment option instead of the --preproc_only option if you want to keep the comments.

2.5.7 Generating Preprocessed Listing with Line-Control Details (--preproc_with_line Option)

By default, the preprocessed output file contains no preprocessor directives. To include the #line directives, use the --preproc_with_line option. The --preproc_with_line option performs preprocessing only and writes preprocessed output with line-control information (#line directives) to a file named as the source file but with a .pp extension.

2.5.8 Generating Preprocessed Output for a Make Utility (--preproc_dependency Option)

The --preproc_dependency option performs preprocessing only. Instead of writing preprocessed output, it writes a list of dependency lines suitable for input to a standard make utility. If you do not supply an optional filename, the list is written to a file with the same name as the source file but a .pp extension.

2.5.9 Generating a List of Files Included with #include (--preproc_includes Option)

The --preproc_includes option performs preprocessing only, but instead of writing preprocessed output, writes a list of files included with the #include directive. If you do not supply an optional filename, the list is written to a file with the same name as the source file but with a .pp extension.

2.5.10 Generating a List of Macros in a File (--preproc_macros Option)

The --preproc_macros option generates a list of all predefined and user-defined macros. If you do not supply an optional filename, the list is written to a file with the same name as the source file but with a .pp extension. Predefined macros are listed first and indicated by the comment /* Predefined */. User-defined macros are listed next and indicated by the source filename.

2.6 Passing Arguments to main()

Some programs pass arguments to main() via argc and argv. This presents special challenges in an embedded program that is not run from the command line. In general, argc and argv are made available to your program through the .args section. There are various ways to populate the contents of this section for use by your program.

To cause the linker to allocate an .args section of the appropriate size, use the --arg_size=size linker option. This option tells the linker to allocate an uninitialized section named .args, which can be used by the loader to pass arguments from the command line of the loader to the program. The size is the number of bytes to be allocated. When you use the --arg_size option, the linker defines the __c_args__ symbol to contain the address of the .args section.

It is the responsibility of the loader to populate the .args section. The loader and the target boot code can use the .args section and the __c_args__ symbol to determine whether and how to pass arguments from the host to the target program. The format of the arguments is an array of pointers to char on the target. Due to variations in loaders, it is not specified how the loader determines which arguments to pass to the target.

If you are using Code Composer Studio to run your application, you can use the Scripting Console tool to populate the .args section. To open this tool, choose View > Scripting Console from the CCS menus. You can use the loadProg command to load an object file and its associated symbol table into memory and pass an array of arguments to main(). These arguments are automatically written to the allocated .args section.

The loadProg syntax is as follows, where file is an executable file and args is an object array of arguments. Use JavaScript to declare the array of arguments before using this command.

loadProg(file, args)

The .args section is loaded with the following data for non-SYS/BIOS-based executables, where each element in the argv[] array contains a string corresponding to that argument:

Int argc; Char * argv[0]; Char * argv[1]; ... Char * argv[n];

For SYS/BIOS-based executables, the elements in the .args section are as follows:

Int argc; Char ** argv; /* points to argv[0] */ Char * envp; /* ignored by loadProg command */ Char * argv[0]; Char * argv[1]; ... Char * argv[n];

For more details, see the "Scripting Console" topic in the TI Processors Wiki.

2.7 Understanding Diagnostic Messages

One of the primary functions of the compiler and linker is to report diagnostic messages for the source program. A diagnostic message indicates that something may be wrong with the program. When the compiler or linker detects a suspect condition, it displays a message in the following format:

" file.c ", line n : diagnostic severity : diagnostic message

" file.c " The name of the file involved
linen: The line number where the diagnostic applies
diagnostic severity The diagnostic message severity (severity category descriptions follow)
diagnostic message The text that describes the problem

Diagnostic messages have a severity, as follows:

  • A fatal error indicates a problem so severe that the compilation cannot continue. Examples of such problems include command-line errors, internal errors, and missing include files. If multiple source files are being compiled, any source files after the current one will not be compiled.
  • An error indicates a violation of the syntax or semantic rules of the C/C++ language. Compilation may continue, but object code is not generated.
  • A warning indicates something that is likely to be a problem, but cannot be proven to be an error. For example, the compiler emits a warning for an unused variable. An unused variable does not affect program execution, but its existence suggests that you might have meant to use it. Compilation continues and object code is generated (if no errors are detected).
  • A remark is less serious than a warning. It may indicate something that is a potential problem in rare cases, or the remark may be strictly informational. Compilation continues and object code is generated (if no errors are detected). By default, remarks are not issued. Use the --issue_remarks compiler option to enable remarks.

Diagnostic messages are written to standard error with a form like the following example:

"test.c", line 5: error: a break statement may only be used within a loop or switch break; ^

By default, the source code line is not printed. Use the --verbose_diagnostics compiler option to display the source line and the error position. The above example makes use of this option.

The message identifies the file and line involved in the diagnostic, and the source line itself (with the position indicated by the ^ character) follows the message. If several diagnostic messages apply to one source line, each diagnostic has the form shown; the text of the source line is displayed several times, with an appropriate position indicated each time.

Long messages are wrapped to additional lines, when necessary.

You can use the --display_error_number command-line option to request that the diagnostic's numeric identifier be included in the diagnostic message. When displayed, the diagnostic identifier also indicates whether the diagnostic can have its severity overridden on the command line. If the severity can be overridden, the diagnostic identifier includes the suffix -D (for discretionary); otherwise, no suffix is present. For example:

"Test_name.c", line 7: error #64-D: declaration does not declare anything struct {}; ^ "Test_name.c", line 9: error #77: this declaration has no storage class or type specifier xxxxx; ^

Because errors are determined to be discretionary based on the severity in a specific context, an error can be discretionary in some cases and not in others. All warnings and remarks are discretionary.

For some messages, a list of entities (functions, local variables, source files, etc.) is useful; the entities are listed following the initial error message:

"test.c", line 4: error: more than one instance of overloaded function "f" matches the argument list: function "f(int)" function "f(float)" argument types are: (double) f(1.5); ^

In some cases, additional context information is provided. Specifically, the context information is useful when the front end issues a diagnostic while doing a template instantiation or while generating a constructor, destructor, or assignment operator function. For example:

"test.c", line 7: error: "A::A()" is inaccessible B x; ^ detected during implicit generation of "B::B()" at line 7

Without the context information, it is difficult to determine to what the error refers.

2.7.1 Controlling Diagnostic Messages

The C/C++ compiler provides diagnostic options to control compiler- and linker-generated diagnostic messages. The diagnostic options must be specified before the --run_linker option.

--diag_error=num Categorizes the diagnostic identified by num as an error. To determine the numeric identifier of a diagnostic message, use the --display_error_number option first in a separate compile. Then use --diag_error=num to recategorize the diagnostic as an error. You can only alter the severity of discretionary diagnostic messages.
--diag_remark=num Categorizes the diagnostic identified by num as a remark. To determine the numeric identifier of a diagnostic message, use the --display_error_number option first in a separate compile. Then use --diag_remark=num to recategorize the diagnostic as a remark. You can only alter the severity of discretionary diagnostic messages.
--diag_suppress=num Suppresses the diagnostic identified by num. To determine the numeric identifier of a diagnostic message, use the --display_error_number option first in a separate compile. Then use --diag_suppress=num to suppress the diagnostic. You can only suppress discretionary diagnostic messages.
--diag_warning=num Categorizes the diagnostic identified by num as a warning. To determine the numeric identifier of a diagnostic message, use the --display_error_number option first in a separate compile. Then use --diag_warning=num to recategorize the diagnostic as a warning. You can only alter the severity of discretionary diagnostic messages.
--display_error_number Displays a diagnostic's numeric identifier along with its text. Use this option in determining which arguments you need to supply to the diagnostic suppression options (--diag_suppress, --diag_error, --diag_remark, and --diag_warning). This option also indicates whether a diagnostic is discretionary. A discretionary diagnostic is one whose severity can be overridden. A discretionary diagnostic includes the suffix -D; otherwise, no suffix is present. See Section 2.7.
--emit_warnings_as_
     errors
Treats all warnings as errors. This option cannot be used with the --no_warnings option. The --diag_remark option takes precedence over this option. This option takes precedence over the --diag_warning option.
--issue_remarks Issues remarks (non-serious warnings), which are suppressed by default.
--no_warnings Suppresses diagnostic warnings (errors are still issued).
--set_error_limit=num Sets the error limit to num, which can be any decimal value. The compiler abandons compiling after this number of errors. (The default is 100.)
--verbose_diagnostics Provides verbose diagnostic messages that display the original source with line-wrap and indicate the position of the error in the source line.
--write_diagnostics_file Produces a diagnostic message information file with the same source file name with an .err extension. (The --write_diagnostics_file option is not supported by the linker.)

2.7.2 How You Can Use Diagnostic Suppression Options

The following example demonstrates how you can control diagnostic messages issued by the compiler. You control the linker diagnostic messages in a similar manner.

int one(); int I; int main() { switch (I){ case 1; return one (); break; default: return 0; break; } }

If you invoke the compiler with the --quiet option, this is the result:

"err.c", line 9: warning: statement is unreachable "err.c", line 12: warning: statement is unreachable

Because it is standard programming practice to include break statements at the end of each case arm to avoid the fall-through condition, these warnings can be ignored. Using the --display_error_number option, you can find out the diagnostic identifier for these warnings. Here is the result:

[err.c] "err.c", line 9: warning #111-D: statement is unreachable "err.c", line 12: warning #111-D: statement is unreachable

Next, you can use the diagnostic identifier of 111 as the argument to the --diag_remark option to treat this warning as a remark. This compilation now produces no diagnostic messages (because remarks are disabled by default).

NOTE

You can suppress any non-fatal errors, but be careful to make sure you only suppress diagnostic messages that you understand and are known not to affect the correctness of your program.

2.8 Other Messages

Other error messages that are unrelated to the source, such as incorrect command-line syntax or inability to find specified files, are usually fatal. They are identified by the symbol >> preceding the message.

2.9 Generating Cross-Reference Listing Information (--gen_acp_xref Option)

The --gen_acp_xref option generates a cross-reference listing file that contains reference information for each identifier in the source file. (The --gen_acp_xref option is separate from --cross_reference, which is an assembler rather than a compiler option.) The cross-reference listing file has the same name as the source file with a .crl extension.

The information in the cross-reference listing file is displayed in the following format:

sym-id name X filename line number column number

sym-id An integer uniquely assigned to each identifier
name The identifier name
X One of the following values:
D Definition
d Declaration (not a definition)
M Modification
A Address taken
U Used
C Changed (used and modified in a single operation)
R Any other kind of reference
E Error; reference is indeterminate
filename The source file
line number The line number in the source file
column number The column number in the source file

2.10 Generating a Raw Listing File (--gen_acp_raw Option)

The --gen_acp_raw option generates a raw listing file that can help you understand how the compiler is preprocessing your source file. Whereas the preprocessed listing file (generated with the --preproc_only, --preproc_with_comment, --preproc_with_line, and --preproc_dependency preprocessor options) shows a preprocessed version of your source file, a raw listing file provides a comparison between the original source line and the preprocessed output. The raw listing file has the same name as the corresponding source file with an .rl extension.

The raw listing file contains the following information:

  • Each original source line
  • Transitions into and out of include files
  • Diagnostic messages
  • Preprocessed source line if nontrivial processing was performed (comment removal is considered trivial; other preprocessing is nontrivial)

Each source line in the raw listing file begins with one of the identifiers listed in Table 2-33.

Table 2-33 Raw Listing File Identifiers

Identifier Definition
N Normal line of source
X Expanded line of source. It appears immediately following the normal line of source if nontrivial preprocessing occurs.
S Skipped source line (false #if clause)
L Change in source position, given in the following format:

L line number filename key

Where line number is the line number in the source file. The key is present only when the change is due to entry/exit of an include file. Possible values of key are:
1 = entry into an include file

2 = exit from an include file

The --gen_acp_raw option also includes diagnostic identifiers as defined in Table 2-34.

Table 2-34 Raw Listing File Diagnostic Identifiers

Diagnostic Identifier Definition
E Error
F Fatal
R Remark
W Warning

Diagnostic raw listing information is displayed in the following format:

Sfilenameline numbercolumn numberdiagnostic
S One of the identifiers in Table 2-34 that indicates the severity of the diagnostic
filename The source file
line number The line number in the source file
column number The column number in the source file
diagnostic The message text for the diagnostic

Diagnostic messages after the end of file are indicated as the last line of the file with a column number of 0. When diagnostic message text requires more than one line, each subsequent line contains the same file, line, and column information but uses a lowercase version of the diagnostic identifier. For more information about diagnostic messages, see Section 2.7.

2.11 Using Inline Function Expansion

When an inline function is called, a copy of the C/C++ source code for the function is inserted at the point of the call. This is known as inline function expansion, commonly called function inlining or just inlining. Inline function expansion can speed up execution by eliminating function call overhead. This is particularly beneficial for very small functions that are called frequently. Function inlining involves a tradeoff between execution speed and code size, because the code is duplicated at each function call site. Large functions that are called frequently are poor candidates for inlining.

Function inlining is triggered by the following situations:

  • The use of built-in intrinsic operations. Intrinsic operations look like function calls, and are inlined automatically, even though no function body exists.
  • Use of the inline keyword or the equivalent __inline keyword. Functions declared with the inline keyword may be inlined by the compiler if you set --opt_level=3 or greater. The inline keyword is a suggestion from the programmer to the compiler. Even if your optimization level is high, inlining is still optional for the compiler. The compiler decides whether to inline a function based on the length of the function, the number of times it is called, your --opt_for_speed setting, your --opt_for_space setting, and any contents of the function that disqualify it from inlining (see Section 2.11.4). Functions can be inlined at --opt_level=3 if the function body is visible in the same module or if -pm is also used and the function is visible in one of the modules being compiled. Functions may be inlined at link time if the file containing the definition and the call site were both compiled with --opt_level=4.
  • Use of static inline functions. Functions defined as both static and inline are more likely to be inlined.
  • When --opt_level=3 or greater is used, the compiler may automatically inline eligible functions even if they are not declared as inline functions. The same list of decision factors listed for functions explicitly defined with the inline keyword is used. For more about automatic function inlining, see Section 3.6
  • Definition-controlled inlining with the unguarded inline keyword
  • Definition-controlled inlining with the guarded inline keyword
  • The pragma FUNC_ALWAYS_INLINE forces a function to be inlined (where it is legal to do so) unless --opt_level=off. That is, the pragma FUNC_ALWAYS_INLINE forces function inlining even if --opt_level=0 or --opt_level=1.

NOTE

Function Inlining Can Greatly Increase Code Size

Function inlining increases code size, especially inlining a function that is called in a number of places. Function inlining is optimal for functions that are called only from a small number of places and for small functions.

The semantics of the inline keyword in C code follow the C99 standard. The semantics of the inline keyword in C++ code follow the C++ standard.

The inline keyword is supported in all C++ modes, in relaxed ANSI mode for all C standards, and in strict ANSI mode for C99. It is disabled in strict ANSI mode for C89, because it is a language extension that could conflict with a strictly conforming program. If you want to define inline functions while in strict ANSI C89 mode, use the alternate keyword _ _inline.

Compiler options that affect inlining are: --opt_level, --no_inlining, --auto_inline, -remove_hooks_when_inlining, --single_inline, --opt_for_space, and -opt_for_speed.

For example, if you use the --single_inline option, the compiler inlines all functions that are called exactly once. In most cases, single inlining will reduce the code size by a small amount.

NOTE

Using the --no_inlining Option with Level 3 Optimizations

The --no_inlining option turns off prioritizing inlining for functions declared with the inline keyword. If you use --no_inlining with --opt_level=3 , automatic inlining is still performed.

2.11.1 Inlining Intrinsic Operators

The compiler has built-in function-like operations called intrinsics. Intrinsic operations look like function calls, and can be implemented very efficiently with the target's instruction set.

There are many intrinsic operators for the C28x. All of them are automatically inlined by the compiler. The inlining happens automatically whether or not you use the optimizer. Intrinsic inlining can be disabled with the --no_intrinsics compiler option.

For details about intrinsics, and a list of the intrinsics, see Section 7.5.6.

2.11.2 Unguarded Definition-Controlled Inlining

The inline keyword specifies that a function is expanded inline at the point at which it is called rather than by using standard calling procedures. The compiler performs inline expansion of functions declared with the inline keyword.

You must invoke the optimizer with any --opt_level option (--opt_level=0, --opt_level=1, --opt_level=2, or --opt_level=3) to turn on definition-controlled inlining. Automatic inlining is also turned on when using --opt_level=3.

The --no_inlining option turns off definition-controlled inlining. This option is useful when you need a certain level of optimization but do not want definition-controlled inlining.

Example 2-1 shows usage of the inline keyword, where the function call is replaced by the code in the called function.

Example 2-1 Using the Inline Keyword

inline float volume_sphere(float r) { return 4.0/3.0 * PI * r * r * r; } int foo(...) { ... volume = volume_sphere(radius); ... }

2.11.3 Guarded Inlining and the _INLINE Preprocessor Symbol

When declaring a function in a header file as static inline, you must follow additional procedures to avoid a potential code size increase when inlining is turned off with --no_inlining or the optimizer is not run.

To prevent a static inline function in a header file from causing an increase in code size when inlining gets turned off, use the following procedure. This allows external-linkage when inlining is turned off; thus, only one function definition will exist throughout the object files.

  • Prototype a static inline version of the function. Then, prototype an alternative, nonstatic, externally-linked version of the function. Conditionally preprocess these two prototypes with the _INLINE preprocessor symbol, as shown in Example 2-2.
  • Create an identical version of the function definition in a .c or .cpp file, as shown in Example 2-3.

In the following examples there are two definitions of the strlen function. The first (Example 2-2), in the header file, is an inline definition. This definition is enabled and the prototype is declared as static inline only if _INLINE is true (_INLINE is automatically defined for you when the optimizer is used and --no_inlining is not specified).

The second definition (see Example 2-3) for the library, ensures that the callable version of strlen exists when inlining is disabled. Since this is not an inline function, the _INLINE preprocessor symbol is undefined (#undef) before string.h is included to generate a noninline version of strlen's prototype.

Example 2-2 Header File string.h

/*****************************************************************************/ /* string.h vx.xx */ /* Copyright (c) 1993-2006 Texas Instruments Incorporated */ /* Excerpted ... */ /*****************************************************************************/ #ifdef _INLINE #define _IDECL static inline #else #define _IDECL extern _CODE_ACCESS #endif _IDECL size_t strlen(const char *_string); #ifdef _INLINE /****************************************************************************/ /* strlen */ /****************************************************************************/ static inline size_t strlen(const char *string) { size_t n = (size_t)-1; const char *s = string - 1; do n++; while (*++s); return n } #endif

Example 2-3 Library Definition File

/****************************************************************************/ /* strlen */ /****************************************************************************/ #undef _INLINE #include <string>_CODE_ACCESS size_t strlen(cont char * string) { size_t n = (size_t)-1; const char *s = string - 1; do n++; while (*++s); return n; }

2.11.4 Inlining Restrictions

The compiler makes decisions about which functions to inline based on the factors mentioned in Section 2.11. In addition, there are several restrictions that can disqualify a function from being inlined by automatic inlining or inline keyword-based inlining. The FUNC_ALWAYS_INLINE pragma overrides these disqualifications, so you should be aware of situations that can cause problems if you are using the FUNC_ALWAYS_INLINE pragma.

  • Is not defined in the current compilation unit and you are not using -O4 optimization
  • Never returns
  • Is a recursive or nonleaf function that exceeds the depth limit
  • Has a variable-length argument list
  • Has a different number of arguments than the call site
  • Has an argument whose type is incompatible with the corresponding call site argument
  • Has a class, struct, or union parameter
  • Contains a volatile local variable or argument
  • Contains local static variables but is not a static inline function.
  • Is not declared inline and contains an asm() statement that is not a comment
  • Is the main() function
  • Is an interrupt function
  • Is not declared inline and returns void but its return value is needed.
  • Is not declared inline and will require too much stack space for local array or structure variables.

Furthermore, inlining should be used for small functions or functions that are called in a few places (though the compiler does not enforce this).

NOTE

Excessive Inlining Can Degrade Performance

Excessive inlining can make the compiler dramatically slower and degrade the performance of generated code.

2.12 Using Interlist

The compiler tools include a feature that interlists C/C++ source statements into the assembly language output of the compiler. The interlist feature enables you to inspect the assembly code generated for each C statement. The interlist behaves differently, depending on whether or not the optimizer is used, and depending on which options you specify.

The easiest way to invoke the interlist feature is to use the --c_src_interlist option. To compile and run the interlist on a program called function.c, enter:

cl2000 --c_src_interlist function

The --c_src_interlist option prevents the compiler from deleting the interlisted assembly language output file. The output assembly file, function.asm, is assembled normally.

When you invoke the interlist feature without the optimizer, the interlist runs as a separate pass between the code generator and the assembler. It reads both the assembly and C/C++ source files, merges them, and writes the C/C++ statements into the assembly file as comments.

Using the --c_src_interlist option can cause performance and/or code size degradation.

Example 2-4 shows a typical interlisted assembly file.

For more information about using the interlist feature with the optimizer, see Section 3.7.

Example 2-4 An Interlisted Assembly Language File

;---------------------------------------------------------------------- ; 1 | int main() ;---------------------------------------------------------------------- ;*************************************************************** ;* FNAME: _main FR SIZE: 0 * ;* * ;* FUNCTION ENVIRONMENT * ;* * ;* FUNCTION PROPERTIES * ;* 0 Parameter, 0 Auto, 0 SOE * ;*************************************************************** _main: ;---------------------------------------------------------------------- ; 3 | printf("Hello World\n"); ;---------------------------------------------------------------------- MOVL XAR4,#SL1 ; |3| LCR #_printf ; |3| ; call occurs [#_printf] ; |3| ;---------------------------------------------------------------------- ; 4 | return 0; ;---------------------------------------------------------------------- ;*************************************************************** ;* STRINGS * ;*************************************************************** .sect ".econst"SL1: .string "Hello World",10,0 ;*************************************************************** ;* UNDEFINED EXTERNAL REFERENCES * ;*************************************************************** .global _printf

2.13 Enabling Entry Hook and Exit Hook Functions

An entry hook is a routine that is called upon entry to each function in the program. An exit hook is a routine that is called upon exit of each function. Applications for hooks include debugging, trace, profiling, and stack overflow checking.

Entry and exit hooks are enabled using the following options:

--entry_hook[=name] Enables entry hooks. If specified, the hook function is called name. Otherwise, the default entry hook function name is __entry_hook.
--entry_parm{=name|
    address|none}
Specify the parameters to the hook function. The name parameter specifies that the name of the calling function is passed to the hook function as an argument. In this case the signature for the hook function is: void hook(const char *name);

The address parameter specifies that the address of the calling function is passed to the hook function. In this case the signature for the hook function is: void hook(void (*addr)());

The none parameter specifies that the hook is called with no parameters. This is the default. In this case the signature for the hook function is: void hook(void);

--exit_hook[=name] Enables exit hooks. If specified, the hook function is called name. Otherwise, the default exit hook function name is __exit_hook.
--exit_parm{=name|
    address|none}
Specify the parameters to the hook function. The name parameter specifies that the name of the calling function is passed to the hook function as an argument. In this case the signature for the hook function is: void hook(const char *name);

The address parameter specifies that the address of the calling function is passed to the hook function. In this case the signature for the hook function is: void hook(void (*addr)());

The none parameter specifies that the hook is called with no parameters. This is the default. In this case the signature for the hook function is: void hook(void);

The presence of the hook options creates an implicit declaration of the hook function with the given signature. If a declaration or definition of the hook function appears in the compilation unit compiled with the options, it must agree with the signatures listed above.

In C++, the hooks are declared extern "C". Thus you can define them in C (or assembly) without being concerned with name mangling.

Hooks can be declared inline, in which case the compiler tries to inline them using the same criteria as other inline functions.

Entry hooks and exit hooks are independent. You can enable one but not the other, or both. The same function can be used as both the entry and exit hook.

You must take care to avoid recursive calls to hook functions. The hook function should not call any function which itself has hook calls inserted. To help prevent this, hooks are not generated for inline functions, or for the hook functions themselves.

You can use the --remove_hooks_when_inlining option to remove entry/exit hooks for functions that are auto-inlined by the optimizer.

See Section 6.9.15 for information about the NO_HOOKS pragma.

Submit Documentation Feedback

Copyright© 2015, Texas Instruments Incorporated. An IMPORTANT NOTICE for this document addresses availability, warranty, changes, use in safety-critical applications, intellectual property matters and other important disclaimers.