This chapter contains the following sections:
How the Compiler Searches Include Files
EDE uses a makefile to build your entire project, from C source till the final ELF/DWARF object file which serves as input for the debugger.
Although in EDE you cannot run the compiler separately from the other tools, this chapter discusses the options that you can specify for the compiler.
On the command line it is possible to call the compiler separately from the other tools. However, it is recommended to use the control program cctc for command line invocations of the toolchain (see section 8.2, Control Program, in Chapter Using the Utilities). With the control program it is possible to call the entire toolchain with only one command line.
The compiler takes the following files for input and output:
Figure 5-1: C compiler
This chapter first describes the compilation process which consists of a frontend and a backend part. During compilation the code is optimized in several ways. The various optimizations are described in the second section. Third it is described how to call the compiler and how to use its options. An extensive list of all options and their descriptions is included in the section 4.1, Compiler Options, in Chapter 4, Tool Options, of the Reference Guide. Finally, a few important basic tasks are described.
During the compilation of a C program, the compiler ctc runs through a number of phases that are divided into two groups: frontend and backend.
The backend part is not called for each C statement, but starts after a complete C module or set of modules has been processed by the frontend (in memory). This allows better optimization.
The compiler requires only one pass over the input file which results in relative fast compilation.
1. The preprocessor phase:
The preprocessor includes files and substitutes macros by C source. It uses only string manipulations on the C source. The syntax for the preprocessor is independent of the C syntax but is also described in the ISO/IEC 9899:1999(E) standard.
2. The scanner phase:
The scanner converts the preprocessor output to a stream of tokens.
3. The parser phase:
The tokens are fed to a parser for the C grammar. The parser performs a syntactic and semantic analysis of the program, and generates an intermediate representation of the program. This code is called MIL (Medium level Intermediate Language).
4. The frontend optimization phase:
Target processor independent optimizations are performed by transforming the intermediate code.
5. Instruction selector phase:
This phase reads the MIL input and translates it into Low level Intermediate Language (LIL). The LIL objects correspond to a TriCore processor instruction, with an opcode, operands and information used within the compiler.
6. Peephole optimizer/instruction scheduler/software pipelining phase:
This phase replaces instruction sequences by equivalent but faster and/or shorter sequences, rearranges instructions and deletes unnecessary instructions.
7. Register allocator phase:
This phase chooses a physical register to use for each virtual register.
8. The backend optimization phase:
Performs target processor independent and dependent optimizations which operate on the Low level Intermediate Language.
9. The code generation/formatter phase:
This phase reads through the LIL operations to generate assembly language output.
The compiler has a number of optimizations which you can enable or disable. To enable or disable optimizations:
1. From the Project menu, select Project Options...
2. Expand the C Compiler entry and select Optimization.
3. Select an optimization level in the Optimization level box.
If you specify a certain optimization, all code in the module is subject to that optimization. Within the C source file you can overrule the compiler options for optimizations with #pragma optimize flag and #pragma endoptimize. Nesting is allowed:
#pragma optimize e /* Enable expression ... simplification */ ... C source ... ... #pragma optimize c /* Enable common expression ... elimination. Expression ... C source ... simplification still enabled */ ... #pragma endoptimize /* Disable common expression ... elimination */ #pragma endoptimize /* Disable expression ... simplification */
The compiler optimizes the code between the pragma pair as specified.
You can enable or disable the optimizations described below. The command line option for each optimization is given in brackets.
See also option
-O (--optimize)
in section 4.1,
Compiler Options, of Chapter Tool Options of the TriCore
Reference Guide.
Common subexpression elimination (CSE) (option -Oc/-OC)
The compiler detects repeated use of the same (sub-)expression. Such a "common" expression is replaced by a variable that is initialized with the value of the expression to avoid recomputation. This method is called common subexpression elimination (CSE).
Expression simplification (option -Oe/ -OE)
Multiplication by 0 or 1 and additions or subtractions of 0 are removed. Such useless expressions may be introduced by macros or by the compiler itself (for example, array subscription).
Constant propagation (option -Op/- OP)
A variable with a known constant value is replaced by that value.
Function Inlining (option -Oi/-OI)
Small functions that are not too often called, are inlined. This reduces execution speed at the cost of code size.
Control flow simplification (option -Of/-OF)
A number of techniques to simplify the flow of the program by removing unnecessary code and reducing the number of jumps. For example:
Switch optimization:
A number of optimizations of a switch statement are performed, such as removing redundant case labels or even removing an entire switch.
Jump chaining:
A (conditional) jump to a label which is immediately followed by an unconditional jump may be replaced by a jump to the destination label of the second jump. This optimization speeds up execution.
Conditional
jump reversal:
A conditional jump over an unconditional jump is transformed into
one conditional jump with the jump condition reversed. This reduces both the code size and the execution time.
Dead code
elimination:
Code that is never reached, is removed. The compiler generates a warning messages because this may indicate a coding error.
Subscript strength reduction (option -Os/-OS)
An array of pointer subscripted with a loop iterator variable (or a simple linear function of the iterator variable), is replaced by the dereference of a pointer that is updated whenever the iterator is updated.
Loop transformations (option -Ol/- OL)
Temporarily transform a loop with the entry point at the bottom, to a loop with the entry point at the top. This enables constant propagation in the initial loop test and code motion of loop invariant code by the CSE optimization.
Forward store (option -Oo/-OO)
A temporary variable is used to cache multiple assignments (stores) to the same non-automatic variable.
Coalescer (option - Oa/-OA)
The coalescer seeks for possibilities to reduce the number of moves (MOV instruction) by smart use of registers. This optimizes both speed as code size.
Peephole optimizations (option -Oy/ -OY)
The generated assembly code is improved by replacing instruction sequences by equivalent but faster and/or shorter sequences, or by deleting unnecessary instructions.
Instruction Scheduler (option -Ok/ -OK)
Instructions are rearranged with the following purposes:
Software pipelining (option -Ow/ -OW)
A number of techniques to optimize loops. For example, within a loop the most efficient order of instructions is chosen by the pipeline scheduler and it is examined what instructions can be executed parallel.
Use of SIMD instructions (option -Om/ -OM)
The iteration counts of loops are reduced where possible by taking advantage of the TriCore SIMD instructions. This optimizes speed, but may cause a slight increase in code size.
Generic assembly optimizations (option -Og/-OG)
A set of target independent optimizations that increase speed and decrease code size.
You can tell the compiler to focus on execution speed or code size during optimizations. You can do this by specifying a size/speed trade-off level from 0 (speed) to 4 (size). This trade-off does not turn optimization phases on or off. Instead, its level is a weight factor that is used in the different optimization phases to influence the heuristics. The higher the level, the more the compiler focuses on code size optimization.
To specify the size/speed trade-off optimization level:
1. From the Project menu, select Project Options...
2. Expand the C Compiler entry and select Optimization.
3. Select a Size/speed trade-off level.
See also option
-t (--tradeoff)
in section 4.1, Compiler Options, in Chapter Tool Options
of the TriCore Reference Guide.
EDE uses a makefile to build your entire project. This means that you cannot run the compiler only. If you compile a single C source file from within EDE, the file is also automatically assembled. However, you can set options specific for the compiler. After you have build your project, the output files of the compilation step are available in your project directory.
To compile your program, click either one of the following buttons:
Compiles and assembles the currently selected file. This results in a relocatable object file (.o).
Builds your entire project but looks whether there are already files available that are needed in the building process. If so, these files will not be generated again, which saves time.
Builds your entire project unconditionally. All steps necessary to obtain the final .elf file are performed.
To access the TriCore processor options:
1. From the Project menu, select Project Options...
2. Expand the Processor entry, fill in the Processor Definition page and optionally the Startup page and click OK to accept the processor options.
To specify the search path and include directories:
1. From the Project menu, select Directories...
2. Fill in the directory path settings and click OK.
To get access to the compiler options:
1. From the Project menu, select Project Options...
2. Expand the C Compiler entry, fill in the various pages and click OK to accept the compiler options.
The following processor options are available:
EDE options | Command line | ||||||||
Target | |||||||||
Target processor User defined TriCore 2 |
-Ccpu --is-tricore2 | ||||||||
FPU present | --fpu-present | ||||||||
Bypasses | |||||||||
CPU functional problem bypasses |
--silicon-bug= bug
Startup |
|
Automatically add cstart.asm to your project |
EDE only |
Bus Configuration |
|
Initialize bus configuration registers in startup code |
EDE only | |
Table 5-1: Processor options
The following project directories are available:
EDE options | Command line |
Directories | |
Executable files path Include files path Library files path | $PATH environment -Idir linker option -Ldir |
Table 5-2: Project directories
The following compiler options are available:
EDE options | Command line | ||||||||||||||||||||||||||||||||||||||||||||||
Preprocessing | |||||||||||||||||||||||||||||||||||||||||||||||
Store the C compiler preprocess output (file
.pre) Keep comments Strip #line source position info |
-Eflag -Ec -Ep | ||||||||||||||||||||||||||||||||||||||||||||||
Automatic inclusion of '.sfr' file | --no-tasking-sfr | ||||||||||||||||||||||||||||||||||||||||||||||
Define preprocessor macro | -Dmacro[=def ] | ||||||||||||||||||||||||||||||||||||||||||||||
Predefine the macro __TASKING__ to the value 1 (Undefine the macro __TASKING__) |
no option -U__TASKING__ | ||||||||||||||||||||||||||||||||||||||||||||||
Predefine the macro __CTC__ to compiler version (Undefine the macro __CTC__) |
no option -U__CTC__ | ||||||||||||||||||||||||||||||||||||||||||||||
Include an extra file at the beginning of the C source |
-Hfile
Language |
|
ISO C standard 90 or 99 (default: 99) |
-c{90|99} |
Language extensions | Allow language extension keywords Allow C++ style comments in C source
-Aflag | -Ak -Ap
Debug Information |
|
Generate symbolic debug information |
-g |
Optimization |
|
No optimization | Few optimizations Medium optimizations (default) Full optimization Custom optimization
-O0 | -O1 -O2 -O3 -Oflag
Size/speed trade-off (default: speed (0)) |
-t{0|1|2
|3|4} |
Allocation |
|
Threshold for __near allocation |
-Nthreshold |
Threshold for __a0 allocation |
-Zthreshold |
Warnings |
|
Report all warnings | Suppress all warnings Suppress specific warnings Treat warnings as errors
no option -w | -w -wnum[,num]... --warnings-as- errors
MISRA C |
|
MISRA C rules |
--misrac={all|nr
[-nr] ,...} |
Produce MISRA C report file |
linker option --misra-c-report |
Miscellaneous |
|
Merge C source code with assembly in output file (.src) |
-s |
Treat 'double' as 'float' |
-F |
Use hardware single precision floating point instructions |
--fpu-present |
Treat 'char' variables as unsigned instead of signed |
-u |
Call functions indirect |
--indirect |
Additional command line options |
options | |
Table 5-3: Compiler options
The following options are only available on the command line:
Description | Command line | ||||||||||||||||||||||
Display invocation syntax | -? | ||||||||||||||||||||||
Specify alignment (same as #pragma align n) |
--align=n
Make all addresses available for CSE |
--cse-all-addresses |
Show description of diagnostic(s) |
--diag=[fmt:]{all|nr,...} |
Redirect diagnostic messages to a file |
--error-file[=file] |
Read options from file |
-f file |
Maximum size increment inlining (in %) (default: 25) |
--inline-max-incr= value |
Maximum size for function to always inline | (default: 10)
--inline-max-size= value |
Always use 32-bit integers for enumeration |
--integer- | enumeration
Keep output file after errors |
-k |
Send output to standard output |
-n |
Specify name of output file |
-o file |
Display version header only |
-V | |
Table 5-4: Compiler options only available on the command line
The invocation syntax on the command
line is:
ctc [option]... [file]
ctc test.c
For a complete overview of all options
with extensive description, see section 4.1,
Compiler Options, of Chapter Tool Options of the TriCore Reference Guide.
Before you call the compiler, you need to tell the compiler for which target processor it needs to compile. Based on the CPU type, the compiler includes a special function register file. This is a regular include file which enables you to use virtual registers that are located in memory.
1. From the Project menu, select Project Options...
2. Expand the Processor entry and select Processor Definition.
3. In the Target processor list select the target processor.
4. Click OK to accept the new project settings.
1. From the Project menu, select Project Options...
2. Expand the Processor entry and select Processor Definition.
3. In the Target processor list, select one of the (user defined ...) entries.
4. Specify (part of) the name of the user defined SFR files.
5. (Optional) Specify if your user defined target processor has an FPU (Floating-Point Unit) and/or an MMU (Memory Management Unit).
6. Click OK to accept the new project settings.
The settings in EDE affect your whole project. If you
use the command line, you must specify the same options to the assembler when assembling the file, or you can use the control program.
ctc -Ctc2 test.c
Instead of using the -C option, you can also include the special function register file in the C source with the line:
#include "regtc2.sfr"
When you use include files, you can specify their location in several ways. The compiler searches the specified locations in the following order:
1. If the #include statement contains a pathname, the compiler looks for this file. If no path is specified, the compiler looks in the same directory as the source file. This is only possible for include files that are enclosed in "".
This first step is not done for include files enclosed
in <>.
2. When the compiler did not find the include file, it looks in the directories that are specified in the Directories dialog (-I option).
3. When the compiler did not find the include file (because it is not in the specified include directory or because no directory is specified), it looks which paths were set during installation. You can still change these paths.
See section 1.3.1
, Configuring the Windows Environment and environment variable CTCINC in section 1.3.2,
Configuring the Command Line Environment, in Chapter Software Installation.
4. When the compiler still did not find the include file, it finally tries the default include directory relative to the installation directory.
Compiling your files is the first step to get your application ready to run on a target. However, during development of your application you first may want to debug your application.
To create an object file that can be used for debugging, you must instruct the compiler to include symbolic debug information in the source file.
1. From the Project menu, select Project Options...
2. Expand the C Compiler entry and select Debug Information.
3. Enable the option Generate symbolic debug information.
4. Click OK to accept the new project settings.
ctc -g
Due to different compiler opimizations, it might be possible that certain debug information is optimized away. Therefore, it is best to specify No optimization (-O0) when you want to debug your application.
1. From the Project menu, select Project Options...
2. Expand the C Compiler entry and select Optimization.
3. In the Optimization level box, select No optimization.
The C programming language is a standard for high level language programming in embedded systems, yet it is considered somewhat unsuitable for programming safety-related applications. Through enhanced code checking and strict enforcement of best practice programming rules, TASKING MISRA C code checking helps you to produce more robust code.
MISRA C specifies a subset of the C programming language which is intended to be suitable for embedded automotive systems. It consists of a set of 127 rules, defined in the document "Guidelines for the Use of the C Language in Vehicle Based Software" published by "Motor Industry Research Association" (MISRA).
For a complete overview of all MISRA
C rules, see Chapter 9, MISRA C Rules, in the Reference Guide.
The MISRA C implementation in the compiler supports 117 of the 127 rules. Some MISRA C rules address documentation, run-time behavior, or other issues that cannot be checked by static source code inspection. Therefore, the following rules are not implemented: 2, 4, 6, 15, 41, 116, 117. In addition, the rules 23, 25 and 27 are not implemented in the compiler, because they cannot be checked without an application-wide overview.
During compilation of the code, violations of the enabled MISRA C rules are indicated with error messages and the build process is halted.
Note that not all MISRA C violations will be reported
when other errors are detected in the input source. For instance, when there
is a syntax error, all semantic checks will be skipped, including some
of the MISRA C checks. Also note that some checks cannot be performed when the optimizations are switched off.
To ensure compliance to the MISRA C rules throughout the entire project, the TASKING TriCore linker can generate a MISRA C Quality Assurance report. This report lists the various modules in the project with the respective MISRA C settings at the time of compilation. You can use this in your company's quality assurance system to provide proof that company rules for best practice programming have been applied in the particular project.
1. From the Project menu, select Project Options...
2. Expand the C Compiler entry and select MISRA C.
3. Select a MISRA C configuration. Select a predefined configuration for conformance with the required rules in the MISRA C guidelines.
4. (Optional) In the MISRA C Rules entry, specify the individual rules.
ctc --misrac={all | number [-number],...}
See compiler option --misrac
in section 4.1,
Compiler Options in Chapter Tool Options of the TriCore
Reference Guide.
See linker option --misra-c-report in section 4.3, Linker Options in Chapter Tool Options of the TriCore Reference Guide.
The csc compiler reports the following types of error messages:
After a fatal error the compiler immediately aborts compilation.
Errors are reported, but the compiler continues compilation. No output files are produced unless you have set the compiler option --keep-output-files (the resulting output file may be incomplete).
Warning messages do not result into an erroneous assembly output file. They are meant to draw your attention to assumptions of the compiler for a situation which may not be correct. You can control warnings in the C Compiler | Warnings page of the Project | Project Options... menu (compiler option -w).
Information messages are always preceded by an error message. Information messages give extra information about the error.
System errors occur when internal consistency checks fail and should never occur. When you still receive the system error message
S9##: internal consistency check failed - please report
please report the error number and as many details as possible about the context in which the error occurred. The following helps you to prepare an e-mail using EDE:
1. From the Help menu, select Technical Support -> Prepare Email...
2. Fill out the the form. State the error number and attach relevant files.
3. Click the Copy to Email client button to open your email application.
4. Finish the e-mail and send it.
1. In the Help menu, enable the option Show Help on Tool Errors.
2. In the Build tab of the Output window, double-click on an error or warning message.
ctc --diag=[format:]{all | number,...}
See compiler option --diag
in section 4.1,
Compiler Options in Chapter Tool Options of the TriCore
Reference Guide.