C166/ST10 v8.7: C Cross Compiler User's Manual
C166/ST10 v8.7: C Cross Compiler User's Manual
C166/ST10 v8.7
C Cross−Compiler
User’s Manual
A publication of
Altium BV
Documentation Department
http://www.tasking.com
http://www.altium.com
The information in this document has been carefully reviewed and is
believed to be accurate and reliable. However, Altium assumes no liabilities
for inaccuracies in this document. Furthermore, the delivery of this
information does not convey to the recipient any license to use or copy the
software or documentation, except as provided in an executed license
agreement covering the software and documentation.
CONTENTS
CONTENTS
Table of Contents V
OVERVIEW 2−1
2.1 Introduction to C C166/ST10 Cross−Compiler . . . . . . . . 2−3
2.2 General Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 2−4
2.2.1 Compiler Phases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2−4
2.2.2 Frontend Optimizations . . . . . . . . . . . . . . . . . . . . . . . . . . 2−6
2.3 Program Development Flow . . . . . . . . . . . . . . . . . . . . . . 2−9
2.4 Working With Projects in EDE . . . . . . . . . . . . . . . . . . . . . 2−13
2.5 Start EDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2−15
2.6 Using the Sample Projects . . . . . . . . . . . . . . . . . . . . . . . . 2−16
2.7 Create a New Project Space with a Project . . . . . . . . . . 2−17
2.8 Set Options for the Tools in the Toolchain . . . . . . . . . . 2−21
2.9 Build your Application . . . . . . . . . . . . . . . . . . . . . . . . . . . 2−23
2.10 How to Build Your Application on the Command Line 2−24
2.10.1 Using the Control Program . . . . . . . . . . . . . . . . . . . . . . . . 2−24
2.10.2 Using the Separate Programs . . . . . . . . . . . . . . . . . . . . . . 2−26
2.10.3 Using a Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2−29
2.11 Debugging your Application . . . . . . . . . . . . . . . . . . . . . . 2−30
2.12 Using DAvE Projects with EDE . . . . . . . . . . . . . . . . . . . . 2−31
• • • • • • • •
VI Table of Contents
• • • • • • • •
VIII Table of Contents
LIBRARIES 6−1
6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6−3
6.2 Small, Medium and Large I/O Formatters . . . . . . . . . . . 6−5
6.3 Single Precision Floating Point . . . . . . . . . . . . . . . . . . . . 6−6
6.4 CAN Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6−6
6.5 Header Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6−7
6.6 C Library Interface Description . . . . . . . . . . . . . . . . . . . . 6−10
6.7 CAN Library Interface Description . . . . . . . . . . . . . . . . . . 6−108
6.8 Creating your own C Library . . . . . . . . . . . . . . . . . . . . . . 6−111
CONTENTS
MISRA C A−1
INDEX
• • • • • • • •
X Table of Contents
CONTENTS
Manual Purpose and Structure XI
PURPOSE
This manual is aimed at users of the TASKING C166/ST10 C
Cross−Compiler. It assumes that you are familiar with the C language.
MANUAL STRUCTURE
Related Publications
Conventions Used In This Manual
Chapters
1. Software Installation
Describes the installation of the C Cross−Compiler for the C166/ST10.
2. Overview
Provides an overview of the TASKING C166/ST10 toolchain and gives
you some familiarity with the different parts of it and their relationship.
A sample session explains how to build a C166/ST10 application from
your C file.
3. Language Implementation
Concentrates on the approach of the C166/ST10 architecture and
describes the language implementation. The C language itself is not
described in this document. We recommend: "The C Programming
Language" (second edition) by B. Kernighan and D. Ritchie (1988,
Prentice Hall).
4. Compiler Use
Deals with control program and C compiler invocation, command line
options and pragmas.
5. Compiler Diagnostics
Describes the exit status and error/warning messages of the compiler.
6. Libraries
Contains the library functions supported by the compiler, and describes
their interface and ’header’ files.
• • • • • • • •
XII Manual Purpose and Structure
7. Run−time Environment
Describes the run−time environment for a C application. It deals with
items like assembly language interfacing, C startup code and
stack/heap size.
Appendices
A. MISRA C
Supported and unsupported MISRA C rules.
B. Debug Environment
Contains operation remarks when you want to use a debug
environment such as CrossView Pro with evaluation boards, Kontron
debugger, Hitex HiTOP or the pls fast−view66 debugger.
RELATED PUBLICATIONS
• The C Programming Language (second edition) by B. Kernighan and D.
Ritchie (1988, Prentice Hall)
• ANSI X3.159−1989 standard [ANSI]
• C166/ST10 Cross−Assembler, Linker/Locator, Utilities User’s Manual
[TASKING, MA019−000−00−00]
• C166/ST10 C++ Compiler User’s Manual [TASKING, MA019−012−00−00]
• C166/ST10 CrossView Pro Debugger User’s Manual
[TASKING, MA019−041−00−00]
• C16x User’s Manuals [Infineon Technologies]
• ST10 User’s Manuals [STMicroelectronics]
• ST10 Family Programming Manual [STMicroelectronics]
• XC16x/Super10 User’s Manuals
[Infineon Technologies / STMicroelectronics]
• • • • • • • •
XIV Manual Purpose and Structure
filename
For example
command [option]... filename
This line could be written in plain English as: execute the command
command with the optional options option and with the file filename.
Illustrations
The following illustrations are used in this manual:
This illustration indicates actions you can perform with the mouse.
• • • • • • • •
XVI Manual Purpose and Structure
MANUAL STRUCTURE
CHAPTER
SOFTWARE
INSTALLATION
1
1−2
INSTALLATION
1
CHAPTER
Chapter 1
Software Installation 1−3
1.1 INTRODUCTION
This chapter guides you through the procedures to install the software on
a Windows system or on a Solaris host.
The software for Windows has two faces: a graphical interface (Embedded
Development Environment) and a command line interface. The Solaris
software only has a command line interface.
You can find your serial number on the invoice, delivery note, or picking
slip delivered with the product.
• • • • • • • •
1−4 Chapter 1
Be sure you have read, write and execute permissions in the installation
directory. Otherwise, login as "root" or use the su command.
If you are a first time user, decide where you want to install the product.
By default it will be installed in /usr/local.
2. Insert the TASKING CD−ROM into the CD−ROM drive and mount the
CD−ROM on a directory, for example /cdrom. Make sure to use an ISO
9660 file system with Rock Ridge extensions enabled. See the UNIX
manual pages about mount for details.
First a question appears about where to install the software. The default
answer is /usr/local.
On some hosts the installation script asks if you want to install SW000098,
the Flexible License Manager (FLEXlm). If you do not already have FLEXlm
on your system, you must install it, otherwise the product will not work on
INSTALLATION
If the script detects that the software has been installed before, the
following messages appear on the screen:
*** WARNING ***
SWxxxxxx xxxx.xxxx already installed.
Do you want to REINSTALL? [y,n]
• • • • • • • •
1−6 Chapter 1
A dialog box appears in which you can select and add directories, remove
them again and change their order.
Environment Description
Variable
A166INC With this variable you specify one or more additional
directories in which the assembler a166 looks for
INSTALLATION
STDNAMES files.
C166INC With this variable you specify one or more additional
directories in which the C compiler c166 looks for
include files. The compiler first looks in these
directories, then always looks in the default
include directory relative to the installation
directory.
CC166BIN When this variable is set, the control program
cc166, prepends the directory specified by this
variable to the names of the tools invoked.
CC166OPT With this variable you specify options and/or
arguments to each invocation of the control program
cc166. The control program processes these
arguments before the command line arguments.
Software Installation 1−7
Environment Description
Variable
LINK166 With this variable you specify extra options and/or
arguments to each invocation of the link stage of
l166.
LM_LICENSE_FILE With this variable you specify the location of the
license data file. You only need to specify this
variable if the license file is not on its default location
(c:\flexlm for Windows,
/usr/local/flexlm/licenses for Solaris).
LOCATE166 With this variable you specify extra options and/or
arguments to each invocation of the locate stage of
l166.
M166INC With this variable you specify one or more additional
directories in which the macro preprocessor m166
looks for include files.
PATH With this variable you specify the directory in which
the executables reside. This allows you to call the
executables when you are not in the bin directory.
Usually your system already uses the PATH variable
for other purposes. To keep these settings, you
need to add (rather than replace) the path. Use a
semicolon (;) to separate pathnames.
TASKING_LIC_WAIT If you set this variable, the tool will wait for a license
to become available, if all licenses are taken. If you
have not set this variable, the tool aborts with an
error message. (Only useful with floating licenses)
TMPDIR With this variable you specify the location where
programs can create temporary files. Usually your
system already uses this variable. In this case you
do not need to change it.
• • • • • • • •
1−8 Chapter 1
6. Click on the OK button to accept the changes and close the dialogs.
Floating license
This license type manages the use of TASKING product licenses among
users at one site. This license type does not lock the software to one
specific PC or workstation but it requires a network. The software can then
be used on any computer in the network. The license specifies the
number of users who can use the software simultaneously. A system
allocating floating licenses is called a license server. A license manager
running on the license server keeps track of the number of users.
Trial mode
When you use the product without a valid license, the tools will run in
trial mode. This means you can use the toolset 15 days with full
functionality. When you run the toolset in trial mode, each tool will report
this. When you use a license that does not cover the full toolset, the tools
that are not covered by the license will run in trial mode.
When after you installed the license file, the tools that are covered by the
license still report that they are running in trial mode, this means that there
is a license error. If you want to force the termination of the trial mode to
get the FLEXlm error message you can set the environment variable
FORCE_NO_TRIAL to "yes".
• • • • • • • •
1−10 Chapter 1
Windows
1. Run the License Administrator during installation and follow the steps to
Request a license key from Altium by E−mail.
2. E−mail the license request to your local TASKING sales representative. The
license key will be sent to you by E−mail.
Solaris
1. If you need a floating license on Solaris, you must determine the host ID
and host name of the computer where you want to use the license
manager. Also decide how many users will be using the product. See
section 1.4.5, How to Determine the Host ID and section 1.4.6, How to
Determine the Host Name.
2. When you order a TASKING product, provide the host ID, host name and
number of users to your local TASKING sales representative. The license
key will be sent to you by E−mail.
If you do not have received your license key, read section 1.4.1, Obtaining
License Information, before continuing.
If you wish to install the license file in a different directory, see section
1.4.4, Modifying the License File Location.
If you already have a license file, add the license key information to the
existing license file. If the license file already contains any SERVER lines,
you must use another license file. See section 1.4.4, Modifying the License
File Location, for additional information.
The software product and license file are now properly installed.
For Windows, you can follow the same steps to import a license key or
create a license file manually, as explained in the previous section with the
installation of a node−locked license.
• • • • • • • •
1−12 Chapter 1
For Solaris, you have to insert the license key manually in the license file.
The default location of the license file license.dat is in directory
/usr/local/flexlm/licenses for Solaris.
If you wish to install the license file in a different directory, see section
1.4.4, Modifying the License File Location.
If you already have a license file, add the license key information to the
existing license file. If the license file already contains any SERVER lines,
make sure that the number of SERVER lines and their contents match,
otherwise you must use another license file. See section 1.4.4, Modifying
the License File Location, for additional information.
3. If you already have installed FLEXlm v8.4 or higher (for example as part of
another product) you can skip this step and continue with step 4.
Otherwise, install SW000098, the Flexible License Manager (FLEXlm), on
the license server where you want to use the license manager.
5. On the license server also add the license key to the license file. Follow
the same instructions as with "Add a license key to a local license file" in
step 2.
See the FLEXlm PDF manual delivered with SW000098, which is present
on each TASKING product CD, for more information.
Software Installation 1−13
If you want to use another name or directory for the license file, each user
must define the environment variable LM_LICENSE_FILE .
If you have more than one product using the FLEXlm license manager you
can specify multiple license files to the LM_LICENSE_FILE environment
variable by separating each pathname (lfpath) with a ’;’ (on Solaris ’:’):
Example Windows:
set LM_LICENSE_FILE=c:\flexlm\license.dat;c:\license.txt
Example Solaris:
setenv LM_LICENSE_FILE
/usr/local/flexlm/licenses/license.dat:/myprod/license.txt
If the license file is not available on these hosts, you must set
LM_LICENSE_FILE to port@host; where host is the host name of the
system which runs the FLEXlm license manager and port is the TCP/IP port
number on which the license manager listens.
To obtain the port number, look in the license file at host for a line starting
with "SERVER". The fourth field on this line specifies the TCP/IP port
number on which the license server listens. For example:
setenv LM_LICENSE_FILE 7594@elliot
See the FLEXlm PDF manual delivered with SW000098, which is present
on each TASKING product CD, for detailed information.
• • • • • • • •
1−14 Chapter 1
If you do not have the program licadmin you can download it from our
Web site at: http://www.tasking.com/support/flexlm/licadmin.zip . It is
also on every product CD that includes FLEXlm, in directory licensing.
Platform Method
Windows licadmin or:
Go to the Control Panel, open "System". In the "Computer
Name" tab look for "Full computer name".
INSTALLATION
Solaris hostname
OVERVIEW
2
2−2
OVERVIEW
2
CHAPTER
Chapter 2
Overview 2−3
The c166 is not a general C compiler adapted for use with the C166/ST10
architecture, but instead it is dedicated to the microcontroller architecture
of the C166/ST10 architecture. This means that you can access all special
features of the C166/ST10 architecture in C: 16K page architecture (with
full pointer support), bit−addressable memory, (extended) special function
registers (I/O ports), interrupt support, scalable vector tables, (local)
register banks and a number of built−in (intrinsic) functions to utilize
special C166/ST10 architecture instructions. And yet no compromise is
made to the ANSI standard. It is a fast, single pass, optimizing compiler
that generates extremely fast and compact code.
The c166 generates assembly source code using the Infineon assembly
language specification, and must be assembled with the TASKING
C166/ST10 Cross−Assembler. This manual uses a166 as the shorthand
notation for ’TASKING C166/ST10 Cross−Assembler’.
The object file generated by a166 can be linked with other objects and
libraries using the TASKING l166 linker/locator. This manual uses l166 as
the shorthand notation for ’TASKING l166 linker/locator’. With the link
stage of l166 you can link objects and libraries to one object. You can
locate assembler objects, linked objects and libraries to a complete
application by using the locate stage of l166.
• • • • • • • •
2−4 Chapter 2
The C166/ST10 toolchain also accepts C++ source files. C++ source files or
sources using C++ language features must be preprocessed by cp166. The
output generated by cp166 is C166/ST10 C, which can be translated with
the C compiler c166.
The C++ compiler is not part of the C compiler package. You can order it
separately from TASKING. The C++ compiler package includes the C
compiler as well.
With the TASKING cc166 control program you can invoke the various
components of the C166/ST10 toolchain with one call. This manual uses
cc166 as the shorthand notation for ’TASKING cc166 control program’.
You can debug the software written in C, C++ and/or assembly with the
TASKING CrossView Pro high−level language debugger. This manual uses
XVW166 as the shorthand notation for ’TASKING CrossView Pro high−level
language debugger’. A list of supported platforms and emulators is
available from TASKING.
You can also use other debugging environments supporting the IEEE−695
format (e.g. Kontron, Hitex, Krohn & Stiller, Lauterbach, etc.).
Target Processors:
All C16x/ST10 derivatives (such as C167, ST10x172). This is the default.
All ST10 derivatives with MAC support is enabled with the ’−xd’ option.
All C166S v1.0 derivatives support is enabled with the ’−x1’ option.
All XC16x/Super10 derivatives support is enabled with the ’−x2’ option.
All enhanced Super10 derivatives support is enabled with the ’−x22’
option.
This section describes the different phases of the compiler and the target
independent optimizations.
frontend:
The preprocessor 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.
backend:
The backend optimization phase:
• • • • • • • •
2−6 Chapter 2
This phase is only enabled for the ext2 architectures. It tries to reorder
the instructions in order to keep the pipeline from stalling as much as
possible. During this phase no instructions will be added or removed.
All phases (of both frontend and backend) are combined into one
program: c166. The compiler does not use any intermediate file for
communication between the different phases of compilation. The backend
part is not called for each C statement, but is started after a complete C
function has been processed by the frontend (in memory), thus allowing
more optimization. The compiler only requires one pass over the input
OVERVIEW
Constant folding
Expressions only involving constants are replaced by their result.
Overview 2−7
Expression rearrangement
Expressions are rearranged to allow more constant folding. E.g. 1+ (x−3)
is transformed into x + (1−3), which can be folded.
Expression simplification
Multiplication by 0 or 1 and additions or subtractions of 0 are removed.
Such useless expressions may be introduced by macros in C (#define), or
by the compiler itself.
Loop rotation
With for and while loops, the expression is evaluated once at the ’top’
and then at the ’bottom’ of the loop. This optimization does not save code,
but speeds up execution.
Switch optimization
A number of optimizations of a switch statement are performed, such as
the deletion of redundant case labels or even the deletion of the switch.
Jump chaining
A conditional or unconditional 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. These situations frequently occur
with nested control structures. This optimization does not save code, but
speeds up execution.
• • • • • • • •
2−8 Chapter 2
Register coloring
Optimize register allocation within a C function. The compiler tries to keep
as much local variables as possible in registers.
Constant/value propagation
A reference to a variable with a known contents is replaced by those
contents.
• • • • • • • •
2−10 Chapter 2
You can use the control program cc166 to build an absolute loadable file
starting with an input file of any stage. C++ source programs are compiled
by the C++ compiler. With a C source file as input, cc166 calls c166, a166
and l166 with the appropriate command line arguments.
The ihex166 program formats the a.out file into an Intel Hex format file.
You can load this output file into an EPROM programmer.
The srec166 program formats the a.out file into a Motorola S Format for
EPROM programmers.
The ar166 program is a librarian facility. You can use this program to
create and maintain object libraries.
For a full description of all available utilities, see chapter 12 Utilities in the
C166/ST10 Cross−Assembler, Linker/Locator, Utilities User’s Manual.
The name of the C166/ST10 CrossView Pro Debugger is xfw166. For more
information check the C166/ST10 CrossView Pro Debugger User’s Manual.
This manual uses xvw166 as the general executable name.
• • • • • • • •
2−12 Chapter 2
File extensions
The following table lists the file types used by the C166/ST10 toolchain.
Extension Description
Source files
.cc, .cxx, .cpp C++ source file, input for the C++ compiler, compiled to .ic
.ccm C++ source file containing intrinsics, input for the C++
compiler, compiled to .icm
.c C source file, input for the C compiler
.cmp C source file containing intrinsics, input for the C compiler
.asm Assembler source file, hand coded, or generated by C
compiler from .cmp or .icm
Generated source files
.ic C source file, generated by the C++ compiler, input for the C
compiler
.icm C source file containing intrinsics, generated by the C++
compiler, input for the C compiler
.src Assembler source file, generated by the C compiler
.sif Source information file for the global storage optimizer
.gso Global storage optimizer file
Object files
.obj IEEE−695 relocatable object file, generated by the assembler
.lno Linked object module
.lib Object library file
.out Absolute locator output file
.abs IEEE−695 absolute object file
.hex Intel Hex absolute object file
OVERVIEW
List files
.mpl Macro proprocessor list file
.lst Assembler list file
.lnl Linker map file
.map Locator map file
.mcr MISRA C report file
Overview 2−13
Extension Description
Error list files
.err Compiler error messages file
.mpe Macro preprocessor error messages file
.erl Assembler error messages file
.elk Linker error messages file
A project space holds a set of projects and must always contain at least one
project. Before you can create a project you have to setup a project space.
All information of a project space is saved in a project space file (.psp):
• a list of projects in the project space
• history information
Within a project space you can create projects. Projects are bound to a
target! You can create, add or edit files in the project which together form
your application. All information of a project is saved in a project file
(.pjt):
• the target for which the project is created
• a list of the source files in the project
• the options for the compiler, assembler, linker and debugger
• the default directories for the include files, libraries and executables
• the build options
• history information
When you build your project, EDE handles file dependencies and the
exact sequence of operations required to build your application. When
you push the Build button, EDE generates a makefile, including all
dependencies, and builds your application.
• • • • • • • •
2−14 Chapter 2
Start EDE
• Double−click on the EDE shortcut on your desktop.
− or −
Launch EDE via the program folder created by the installation program.
Select Start −> Programs −> TASKING toolchain −> EDE.
The EDE screen contains a menu bar, a toolbar with command buttons,
one or more windows (default, a window to edit source files, a project
window and an output window) and a status bar.
Project Options Compile Build Rebuild Debug On−line Manuals
Document Windows
Used to view and edit files.
Project Window
Contains several
tabs for viewing
information about
projects and other
files. Output Window
Contains several tabs to display
and manipulate results of EDE
operations. For example, to view
the results of builds or compiles.
• • • • • • • •
2−16 Chapter 2
A menu appears.
3. Read the file readme.txt for more information about the selected sample
project.
Once the files have been processed you can inspect the generated messages
in the Build tab of the Output window.
OVERVIEW
Overview 2−17
2. In the the Filename field, enter a name for your project space (for
example MyProjects). Click the Browse button to select a directory first
and enter a filename.
3. Check the directory and filename and click OK to create the .psp file in
the directory shown in the dialog.
• • • • • • • •
2−18 Chapter 2
• • • • • • • •
2−20 Chapter 2
A new empty file is created and added to the project. Repeat steps 6 and 7 if
you want to add more files.
8. Click OK.
The new project is now open. EDE loads the new file(s) in the editor in
separate document windows.
EDE automatically creates a makefile for the project (in this case
getstart.mak ). This file contains the rules to build your application.
EDE updates the makefile every time you modify your project.
void main(void)
{
printf("Hello World!\n");
}
4. In the Processor list select your target processor (for example, C167).
• • • • • • • •
2−22 Chapter 2
The Project Options dialog appears. Here you can specify options that are
valid for the entire project. To overrule the project options for the currently
active file instead, from the Project menu select Current File Options...
The C Compiler entry contains several pages where you can specify C
compiler settings.
3. For each page make your changes. If you have made all changes click OK.
The Cancel button closes the dialog without saving your changes. With
OVERVIEW
the Default... button you can restore the default project options (for the
current page, or all pages in the dialog).
4. Make your changes for all other entries (C++ Compiler, Assembler, Macro
Preprocessor, Linker/Locator, CrossView Pro) of the Project Options dialog
in a similar way as described above for the C compiler.
If available, the Options string field shows the command line options
that correspond to your graphical selections.
Overview 2−23
The file is compiled, assembled, linked and located. The resulting file is
getstart.abs .
The build process only builds files that are out−of−date. So, if you click
Make again in this example nothing is done, because all files are
up−to−date.
If you selected the file hello.c, this results in the compiled and assembled
file hello.obj.
• • • • • • • •
2−24 Chapter 2
1. In a text editor, write the file hello.c with the following contents:
#include <stdio.h>
void main(void)
{
printf("Hello World!\n");
}
The control program calls all tools in the toolchain. The −v option shows all
the individual steps. The resulting file is getstart.abs .
OVERVIEW
3. Compile, assemble, link and locate the modules using one call to the
control program cc166:
cc166 −g −ieee −o sieve.abs sieve.c
The −ieee option specifies that the output file must be formatted in the
IEEE Std. 695 format. The −o sieve.abs option specifies the output
filename to be sieve.abs. The result of the command are the files
sieve.abs which can be loaded and executed by CrossView Pro and
sieve.map containing the locate map of the application.
You can specify the −DMEASURE_TIME option if you want to build the
sieve benchmark program for time measurement. Note that this is done in
the makefile which can be processed by mk166.
Now you have created all the files necessary for debugging with
CrossView Pro with one call to the control program.
If you want to see how the control program calls the compiler, assembler,
link stage, locate stage and formatter, you can use the −v option or −v0
option. The −v0 option only displays the invocations without executing
them. The −v option also executes them:
cc166 −g −ieee −o sieve.abs sieve.c −v0
• • • • • • • •
2−26 Chapter 2
The −e option specifies to remove the output file if compiler errors occur.
The NOPR control suppresses the assembler list file generation. The TO
control has the same function as the −o option of the compiler, and
specifies the output filename.
As you can see, the tools use temporary files for intermediate results. If
you want to keep the intermediate files you can use the −tmp option. The
following command makes this clear.
cc166 −g −ieee −o sieve.abs sieve.c −v0 −tmp
As you can see, if you use the −tmp option, the assembly source files and
linker output file will be created in your current directory also.
Of course, you will get the same result if you invoke the tools separately
using the same calling scheme as the control program.
As you can see, the control program automatically calls each tool with the
correct options and controls.
The −s option puts the C source text as comments into the output
assembly source file sieve.src. The other options are the same as
explained by the invocation of the control program.
The suffix .src is default and may therefore be omitted. The assembler
produces a relocatable object file called sieve.obj and a list file called
sieve.lst.
The C startup code is delivered in each run−time library for the memory
model of the library and in assembly source code, because this file usually
must be adapted to the target environment. The library is delivered for all
memory models supported. In this case, we are using the small model,
because this is the default memory model of c166. See the next chapter
for detailed information on memory models.
The libraries are organized in two basic library sets: one set for the
C16x/ST10 architecture (subdirectory ext) and one set for the
XC16x/Super10 architectures (subdirectory ext2).
These two basic library sets are additionally organized in two variants: one
standard variant and one variant with all silicon bug workarounds enabled.
The subdirectories for this last variant are followed by the character ’p’
(subdirectories extp and ext2p).
All four library sets are also available for the User Stack Model. All
subdirectories for this extra variant are preceded with the character ’u’.
It depends on the hardware environment you are using, which library set
must be used. By default the compiler assumes the C16x/ST10 architecture
without any silicon bug workarounds enabled. Therefore, the library set in
the subdirectory ext is used.
PC:
l166 link sieve.obj ext\c166s.lib ext\rt166s.lib to
sieve.lno
• • • • • • • •
2−28 Chapter 2
UNIX:
l166 link sieve.obj ext/c166s.lib ext/rt166s.lib to
sieve.lno
By default the linker searches the lib directory for libraries. This way it
finds the c166s.lib and rt166s.lib libraries. The cstart.obj C
startup code is extracted from the rt166s.lib library because the
compiler generates a reference to this module when the main() function
is defined.
The result of this command is the linked task object module sieve.lno.
When you use the PRINT control the file sieve.lnl is created,
containing information about the linking stage: memory map, symbol
table, register map. However, this is slowing down the process of linking
and therefore turned off by default.
The result of this command is the absolute output file sieve.out and the
file sieve.map containing the locate map of the application. The nocc
control disables the checking on definition of class ranges, used to locate
all parts of the application in user defined memory ranges.
In order to load this application into the CrossView Pro debugger, the
output file must be formatted into IEEE Std. 695 format.
For building one example program, make the directory containing the
example the current working directory. Build the example by typing:
mk166
When the example has already been built before, only the parts which are
out of date are rebuilt.
For more information see also the readme.txt files in the subdirectories
of the examples.
When you want to re−translate the examples with other settings you
should first clean up the results of a previous translation. This can be done
by:
mk166 clean
You can also use this when you just want to clean up the example
directories.
• • • • • • • •
2−30 Chapter 2
See the CrossView Pro Debugger User’s Manual for more information.
OVERVIEW
Overview 2−31
1. Create a new (or open your existing) C166/ST10 EDE project (for example
"ede_project.pjt "). For more information on how to do this, see
section 2.7, Create a New Project Space with a Project.
3. Add the C startup code start.asm to your project: from the Project
menu, select Project Options..., expand the Application entry and select
Startup, enable the check box Generate system startup code and add
it to project and specify the name start.asm in the Startup code file
name field.
4. Click the Refresh DAvE imported project button in the EDE toolbar.
The EDE project is now fully setup to build the application you have created
using DAvE.
• • • • • • • •
2−32 Chapter 2
The C166/ST10 EDE only reflects those (E)SFR register settings which must
be configured when booting the CPU before the execution of the EINIT
(end of initialization) instruction. These registers are configured in the C
startup code. All other registers are configured from the C code which is
generated by DAvE.
3
3−2
LANGUAGE
3
CHAPTER
Chapter 3
Language Implementation 3−3
3.1 INTRODUCTION
The TASKING C C166/ST10 cross−compiler offers a new approach to
high−level language programming for the C166/ST10 family. It conforms to
the ANSI standard, but allows the user to control the I/O registers, bit
memory, interrupts and data page architecture of the C166/ST10 in C. This
chapter describes the language implementation in relation to the
C166/ST10 architecture.
_bit
You can use data type _bit for the type definition of scalars and for the
return type of functions.
_bitword
You can declare word variables in the bit−addressable area as fp. You can
access individual bits using the intrinsic functions _getbit() and
_putbit().
_sfrbit / _esfrbit
Data types for the declaration of specific, absolute bits in special function
registers or special absolute bits in the SFR address space.
_sfr / _esfr
Data types for the declaration of Special Function Registers.
_xsfr
Data type for the declaration of Special Function Registers not residing in
SFR memory but do reside in internal RAM. An example of these SFRs are
PEC source and destination pointers. The compiler will use a ’mem’
addressing mode for this data type whereas for an object of type _sfr a
’reg’ or ’mem’ addressing mode may be used.
_at
You can specify a variable to be at an absolute address.
• • • • • • • •
3−4 Chapter 3
_atbit
You can specify a variable to be at a bit offset within a _bitword or
bitaddressable _sfr variable.
_inline
Used for defining inline functions.
_usm / _nousm
With these function qualifiers you can force that a function is called using
the user stack model calling convention or using the generic CALL/RET
calling convention.
_bita
You can tell the compiler that a struct must be located in bitaddressable
memory by using the _bita memory qualifier.
memory−specific pointers
c166 allows you to define pointers which point to a specific target
memory. These types of pointers are very efficient and require only 2 or 4
bytes memory space.
special types
Apart from a memory category (extern, static, ...) you can specify a storage
type in each declaration. This way you obtain a memory
model−independent addressing of variables in several address ranges of
the C166/ST10 (_near, _xnear, _far, _huge, _shuge, _system,
_iram).
interrupt functions
LANGUAGE
You can specify interrupt functions directly through interrupt vectors in the
C language (_interrupt keyword). You may also specify the register
bank to be used (_using keyword).
intrinsic functions
A number of pre−declared functions can be used to generate inline
assembly code at the location of the intrinsic (built−in) function call. This
avoids the overhead which is normally used to do parameter passing and
context saving before executing the called function.
Language Implementation 3−5
The approach of data memory differs with the approach of code memory.
Code memory is accessed in segments of 64K using a 16−bit offset and an
8−bit segment number. Because there is no translation done on this 8−bit
segment number, code memory access is ’almost’ linear. However, data
memory is accessed within 16 KB pages. The 16−bit address is translated
into a 24−bit address via one of four data page pointers, specified with bit
14 and 15. So, the 24−bit address is made out of the 14−bit page offset and
the 10−bit contents of the selected DPP.
c166 has two methods of gaining greater control over how your program
uses memory. These methods can be used together. First you can specify
the ’memory model’ for the program. The compiler allows you to choose
from a number of different approaches. In section 3.2.1 Memory Models
more detailed information is present. Second, you can use one of the
keywords _near, _xnear, _system, _iram, _far, _huge and _shuge in
your program. Note that although these keywords are also used by other C
compilers (for the 8086 family), they are not part of the standard C
language. C is meant as a portable language.
Only a small part of the application will use language extensions. These
parts often deal with items such as:
− I/O, using the (extended) special function registers
− high execution speed needed
− high code density needed
− access to non−default memory required (e.g. far/huge/shuge data)
− bit type needed
• • • • • • • •
3−6 Chapter 3
− C interrupt functions
DPP registers always contain their startup values thus allowing linear 64K
access of data. This results in relatively high code density and execution
speed. On interrupt the C166/ST10 does not have to save the CS register
and an extra port (Port 4) is available, because address lines A16 − A23 are
not used. The usage of the _far, _huge and _shuge keywords is not
allowed. The tiny memory model is meant for very small (even
single−chip) applications.
Language Implementation 3−7
Map example
256K
64K
normal data
code
0
• • • • • • • •
3−8 Chapter 3
The compiler does not assume the CSP register to contain something valid.
Each call results in a far inter−segment code access, unless the _near
keyword is used explicitly in the function prototype. We therefore
recommend using the _near keyword with static functions when using
the small or large model, since static functions are always in the same
code section as their caller functions. This model allows code access in all
segments up to 16M.
The small memory model supports 64K of ’normal user data’ via fixed DPP
values, specified at locate time. This results in high code density and
execution speed. Note that the ROM data of an application (e.g. strings,
floating point constants, jump tables, etc.) must also be allocated in this
area of 64K of ’normal user data’. There are three memory configurations
possible for this 64K of ’normal user data’:
I (default)
The four DPP registers are assumed to contain their system startup value
(0−3), providing one linear data area of 64K in the first segment
(0−0FFFFh).
II Addresses Linear
DPP3 contains page number 3, allowing access to SYSTEM (extended) SFR
registers and bitaddressable memory. DPP0 − DPP2 provide a linear data
area of 48K anywhere in memory. You must specify the
’base−page−number’ of this area at locate time via the ADDRESSES(
LANGUAGE
III SND
DPP3 contains page number 3, allowing access to SYSTEM (extended) SFR
registers and bitaddressable memory. DPP0, DPP1 and DPP2 contain the
page number of a data area of 16K anywhere in memory. These page
numbers are specified at locate time via the SND locator control. When
you use this configuration, the size of a single ’normal data’ object is
limited to 16K.
Language Implementation 3−9
In variant I and II, the paging principle is not really used, so the size of a
single ’normal data’ object (e.g. array) can be greater than 16K (one page).
If you use the small memory model (default of c166), the compiler uses
the section type ’LDAT’ for normal user data. This means that a non−paged
section (unless SND is used of course) must be allocated by the locator in
either:
If you need more than 64K of data (or if you need a huge data object),
you can use the _far/_huge keywords in the declaration of these
variables.
’normal data’ sections can contain both RAM data and ROM data.
• • • • • • • •
3−10 Chapter 3
code
page 10 DPP2
page 9 normal data DPP1
code page 8 DPP0
code
64K 64K
page 3 DPP3 page 3 normal data DPP3
page 2 normal data DPP2
page 1 DPP1 code
page 0 code DPP0
0 0
code
code
64K
page 3 normal data DPP3
code
ROM data (e.g. strings, floating point constants, jump tables, etc.) is also
present in LDAT sections and thus needs some space in the 64K of ’normal
user data’. We recommend using page 3 for (external) ROM, allowing this
ROM data (and code sections) to be allocated in this page and yet use
DPP3 for SYSTEM (SFR) access. This means that the other three pages can
be used for (external) RAM.
• • • • • • • •
3−12 Chapter 3
In the small model far/huge/shuge data access causes the compiler to emit
code which, temporarily, overrules DPP0 with the page number of the far
data. The DPP0 register is restored afterwards. DPP2 is sometimes used for
far/near copy actions. During a task switch (interrupt) DPP0 and DPP2 are
preserved and the correct page number is assigned to these DPP registers
before activating the C code of this task, because a far access might be
interrupted. The compiler also uses the special prefix instructions, which
are treated by the processor as a prefix for a number of so−called ’atomic
instructions’: thus uninterruptable.
Far/huge/shuge data access produces extra code and results into slow
execution. Therefore accessing far/huge/shuge data must be an exception
within the application. The majority of the execution time of the
application should be dealing with normal data, otherwise it is better to
use the large model, allowing more efficient usage of far/huge/shuge data.
LDAT and PDAT section types are not allowed in segmented data mode.
The only section type allowed in a DGROUP is the DATA type (not
HDAT).
Language Implementation 3−13
Map example
256K
huge data /
shuge data
normal data
near data
normal data
user stack
64K xnear data
code
• • • • • • • •
3−14 Chapter 3
Map example
256K
huge data /
shuge data
code
near data
normal data
user stack
xnear data
code
• • • • • • • •
3−16 Chapter 3
Map example
16M
normal data /
shuge data
code
near data
far data
user stack
xnear data
code
• • • • • • • •
3−18 Chapter 3
3.2.1.6 _MODEL
c166 introduces the predefined preprocessor symbol _MODEL. The value
of this symbol represents the memory model selected. This can be very
helpful in making conditional C code in one source module, used for
different applications in different memory models. See also section 3.21,
Portable C Code, explaining the include file c166.h.
Language Implementation 3−19
Example:
#if _MODEL == ’m’ || _MODEL == ’l’ /* medium or
large model */
...
#endif
Strings, floating point constants and jump tables are allocated in ROM and
can never be in the default data sections.
• • • • • • • •
3−20 Chapter 3
The default data sections are member of a special DGROUP group which
is (of course) limited to 16K. It is possible to have a DGROUP area (of
max 16K) per task. DPP2 is ASSUMED to contain the page number of this
group, which is assigned at system startup. During a context switch
(interrupt) DPP2, and the scratch register DPP0, are saved, assigned new
values and restored afterwards. However, you can also share the default
data group area with the default data groups of each task (interrupt).
The threshold value is user definable via the −T option. The default value
is 256 for non−initialized static/public RAM data. The major advantage of
this approach is that better performance is achieved with existing C source
code. However, addresses of these variables are still treated ’far’, ’huge’ or
’shuge’ (4 bytes), for usage with (default) pointers.
System forces allocation in the system data group. The system data group
C166_SGROUP is always located in the system page (page 3). It also
allows better pointer arithmetic, because a pointer to system (2 bytes
instead of 4 bytes) is supported. Public/external references are supported,
assuming DPP3 is used with an external system variable. Of course a
system address can be converted to a far, huge or shuge address.
Language Implementation 3−21
C166_DGROUP sections
If the cumulated size of all C166_DGROUP sections of a task exceeds 16K,
there are five possibilities to solve it (to be tried in this order):
• • • • • • • •
3−22 Chapter 3
If you use this option, it is your own responsibility to declare ’extern near’
variables within the same group! Therefore the compiler emits warnings
for ’extern near’ declarations if you use the −G option.
Be sure that functions called by this module do NOT use their own default
data. Some C library functions might use default data too!
for particular items (either data or code) without changing the addressing
conventions for the program as a whole.
The _near, _xnear, _far, _huge and _shuge keywords are not allowed
with automatics and parameters (unless used as a target of a pointer of
course).
The following explains how the usage of these keywords affects the
addressing of code, data or pointers to code or data in all models:
Language Implementation 3−23
tiny model
In this model all normal data is implicitly _near, because the processor
does not run in segmented mode. A linear 16 bit (64K) data area is
achieved. The _far, _huge and _shuge keywords are not possible (and
not allowed).
small model
In this model all normal data is implicitly _near. Address arithmetic is
performed on 16 bit addresses (linear address space assumed). Therefore
objects may be greater than 16K, unless the SND locator control is used,
which introduces gaps in the address space of normal data. Besides 64K of
normal data (including ROM data), far data is supported. Far data may be
anywhere in memory, not assumed to be in the linear data area. You can
reference far data using a 24 bit address. Address arithmetic is performed
on 14 bit (page offset only). Therefore, individual data items (e.g. arrays)
cannot exceed 16K (page) and cannot cross page boundaries if declared
_far. If you use far objects greater than 16K, you must declare them
_huge or _shuge. Huge data may be anywhere in memory and you can
also reference it using a 24 bit address. However, address arithmetic is
done using the complete address (24 bit). Shuge data may also be
anywhere in memory and you can also reference it using a 24 bit address.
However, address arithmetic is done using a 16 bit address.
medium model
In this model ’near data’ means data allocated into a special page for fast
access. See section 3.2.1.7, Efficiency in Large Data Models
(Medium/Large/Huge) for more details on the ’default data group’. Address
arithmetic on near and far data is always 14 bit. As in the small model,
huge and shuge data access is supported.
This model also supports ’xnear’ data. This data is allocated together with
the user stack in DPP1. The access to this memory space is just as fast as
to ’near’ data. Address arithmetic on _xnear data is done in 14 bits. See
section 3.2.1.7, Efficiency in Large Data Models (Medium/Large/Huge) for
more details on the ’C166_XGROUP’ data group.
• • • • • • • •
3−24 Chapter 3
All function calls are assumed to be in the same (first) segment of 64K.
However, an inter−segment call is supported via a huge function (the
keyword _huge must be present in the function prototype). The _huge
function may not call any standard C library function, run−time library or
any normal _near function in another segment. You cannot apply the
_far keyword to functions.
large/huge model
In these models ’near data’ means data allocated into a special page for
fast access. See section 3.2.1.7, Efficiency in Large Data Models
(Medium/Large/Huge) for more details on the ’default data group’. Address
arithmetic on near and far data is always 14 bit. As in the small and
medium models, huge and shuge data access is supported.
Without any of the _near, _xnear, _far, _huge and _shuge keywords,
the default data access is _far paged data for the large model and _huge
for the huge model.
These models also support ’xnear’ data. This data is allocated together with
the user stack in DPP1. The access to this memory space is just as fast as
to ’near’ data. Address arithmetic on _xnear data is done in 14 bits. See
section 3.2.1.7, Efficiency in Large Data Models (Medium/Large/Huge) for
more details on the ’C166_XGROUP’ data group.
All function calls are assumed to be _huge (in another code segment of
64K), unless you use the _near keyword in the function prototype. In fact
you could declare (and define) all static functions as near functions,
because they are always allocated in the same code section as the
functions they are called by.
think of the _far keyword and the item to its right as being a
single unit. In this case, p is a pointer to a far char, and therefore
contains a 24 bit far address.
Language Implementation 3−25
p is a far pointer when you use the medium or large model, a huge
pointer in the huge model otherwise a near pointer. The storage
type of p itself is near in tiny and small model, and, depending on
the threshold value, probably also near in medium, large and huge
model.
• You cannot apply the _far keyword to functions.
The _system, _iram and _bita keywords are not allowed with
automatics, functions and constants unless used as a target of a pointer.
• • • • • • • •
3−26 Chapter 3
_system
Objects declared with the keyword _system are allocated in system data
sections (see paragraph 3.2.3, Section Allocation). The system data sections
are member of the special group C166_SGROUP which is limited to the
size of the SYSTEM page (16K−SFRs). DPP3 is ASSUMED to contain the
page number of this group which is equal to the SYSTEM page number
(page 3) and is assigned at system startup.
_iram
Objects declared with the keyword _iram are allocated in
IRAMADDRESSABLE data sections (see paragraph 3.2.3, Section
Allocation). The locator places IRAMADDRESSABLE sections in the internal
RAM of the C166/ST10.
The _iram sections are limited to 2048 bytes internal RAM. By default the
_iram section size is limited by the compiler to 2048 bytes. But you can
always set your own _iram sections size limit with the −m mem=size
compiler option (e.g. −mIR=512). See for more information section 4.3,
Detailed Description of the Compiler Options.
_bita
When using bit fields in structures that are located in bitaddressable
memory the compiler can take advantage of the bit and bit field
instructions of the processor. You can tell the compiler that a struct must
be located in bitaddressable memory by using the _bita memory
qualifier.
LANGUAGE
Example:
_bita struct {
unsigned bf1:1;
unsigned pit:2;
unsigned bf2:1;
} s;
The compiler will allocate the struct in a bitaddressable section. For nested
structures and unions _bita can only be applied to the outer level. When
_bita is used for structure members the compiler ignores this.
Language Implementation 3−27
Example:
struct m {
int m1:2;
int m2:3;
} mm;
struct n {
_bita struct m n1; // _bita ignored
struct m n2;
} nn;
Even with the _bita keyword structures will be word aligned. Also the
structure members are aligned as they would be without the _bita
qualifier; i.e., byte addressable members (signed/unsigned char) are
byte aligned and word addressable members (such as int and pointers)
are word aligned.
w |= 0x4000;
if (w & (1 << 10))
{
w &= 0xFFEF;
}
For non−static local variables the _bita keyword is not allowed. Most
local variables will be placed in registers automatically, making them
bitaddressable anyway. See also the pragmas autobita and autobitastruct
in section 4.5, Pragmas.
• • • • • • • •
3−28 Chapter 3
When using plain user stack model, special libraries are needed to support
this feature. These user stack model libraries are an integral part of this
product. If −Pd was specified at the command line, all calls to the library
use the regular CALL/RET calling convention.
This behavior can also be forced for user defined functions using either
the _usm or _nousm function qualifiers. If _usm is specified at the
function definition, the function is called using user stack model calling
conventions. If _nousm is specified, the function is called using the
generic CALL/RET calling method, even if −P was specified on the
command line.
There are two valid reasons to use this option (and libraries):
• Real−time Operation Systems
When using a real−time kernel, it is often not allowed to use the
system stack area (in fact change SP), because this area is reserved for
the kernel. Therefore, the −P option can be used, when using a kernel.
Please refer to the documentation supplied with the kernel to verify if
this option must be used.
Language Implementation 3−29
• Heavy recursion
When the system stack area is getting too small and it is not possible to
implement a circular system stack approach (using SOV/SUN exception
handlers), the −P option can be used. In this case the compiler uses the
user stack instead of the system stack. You must link the application
with the user stack model libraries.
Using −P does not mean that you have to use a kernel. You can run the
application as a standalone application, without any kernel.
• • • • • • • •
3−30 Chapter 3
In the C166/ST10 compiler the code generator does not have to know if
internal or external RAM is accessed, because the same code can be
generated. Execution speed is in fact a matter of allocating sections in
internal memory instead of external memory. The allocation of sections is
done by the locator stage of l166, and can be manipulated by specifying a
memory range for each ’class’ of sections.
c166 allows you to control the class, align type and combine type of a
section with a command line option (e.g. −RclNB=NEARRAM changes the
class of non−initialized near data to ’NEARRAM’ for this module). The
disadvantage of this method is that the changed attributes are used for the
complete C module.
Naming convention
c166 uses a naming convention for the generated sections. In general the
following modifications are applied to a filename:
− whitespace and dots are converted to underscores
− filenames are converted to uppercase.
− if a filename starts with a digit, the first digit is replaced by an
underscore.
Everything after (and including) the last dot is stripped from the filename.
Thus, the filename: "long file.name.c" will result in the following
string to be used as a basis for the section name (in the text below
referred to as "module"):
"LONG_FILE_NAME"
module_number_mem
where,
c166 uses the following table for its defaults (e.g. compiling mod.c):
• • • • • • • •
3−32 Chapter 3
1 See also section 3.2.5, Constant Romdata Section Allocation, for small model only.
2 CNEARROM when tiny/small model is used.
When using the medium or large model, near data, xnear data or system
data always remain a member of the default data group or system data
group. So for these memory areas, it is not possible to change all section
attributes.
module_IR_mem
module_ID_mem
module_ER_mem
module_ED_mem
where,
c166 uses the following table for its defaults (near data):
Example:
File mod.c contains the following initialized romdata:
#pragma eramdata
int i = 1; /* default near data */
#pragma iramdata
_far int j = 2;
• • • • • • • •
3−34 Chapter 3
III Specials
The following special section names exist:
You can only change the section attributes of non−initialized data sections,
normal sections and romdata sections (category I), using the mem code
listed in the table.
You can tell the compiler to use other class names, combine types and
align types instead of the defaults listed above by means of the following
pragmas. Each pragma, has an equivalent command line option that can
be used if the complete module must use the changed attributes.
#pragma class mem=name /* use name as class for
section of area mem */
#pragma combine mem=ctype /* use ctype as combine type
for section of area mem */
#pragma align mem=atype /* use atype as align type
for section of area mem */
#pragma default_attributes /* use default attributes as
listed above */
B Byte alignment
W Word alignment
D Double word alignment
P Page alignment
S Segment alignment
C PEC addressable
I IRAM addressable
L private (’Local’)
P Public
C Common
G Global
S Sysstack
U Usrstack
A address Absolute section AT constant address
(decimal, octal or hexadecimal number)
• • • • • • • •
3−36 Chapter 3
Examples:
1. The C module is called ’test.c’. The example illustrates how to allocate one
array in a special section with the class ’SLOWRAM’ and the rest of the
data in data section with default attributes. The generated code is listed
below:
C:
#pragma class nb=SLOWRAM
int array[1000];
#pragma default_attributes
int j;
Generated code:
TEST_1_NB SECTION LDAT WORD PUBLIC ’SLOWRAM’
TEST_1_NB_ENTRY LABEL BYTE
_array LABEL WORD
DS 2000
PUBLIC _array
TEST_1_NB ENDS
2. The C module is called ’test.c’. The example illustrates how to allocate one
C variable on a fixed memory location (address 8000H) and the rest of the
data in a data section with default attributes. As described in the ’TASKING
C166/ST10 Cross−Assembler, Linker/Locator, Utilities User’s Manual’, AT is
considered as an additional align−type and implies the default combine
type PRIVATE.
LANGUAGE
C:
#pragma combine nb=A32768
volatile int cntrl_reg;
/* e.g. an I/O register of peripheral chip */
#pragma default_attributes
int i;
Language Implementation 3−37
Generated code:
TEST_1_NB SECTION LDAT WORD AT 08000h ’CNEAR’
TEST_1_NB_ENTRY LABEL BYTE
_cntrl_reg LABEL WORD
DS 2
PUBLIC _cntrl_reg
TEST_1_NB ENDS
These pragmas are especially useful in combination with the smart linking
feature of the linker/locator. When you use smart linking, the linker will
only link sections that are referenced. Thus if each function has its own
section, only functions that are actually called (referenced) are linked
rather than all functions in an .obj file at once.
• • • • • • • •
3−38 Chapter 3
Example:
void func1( void ) { } /* Code section 1 */
#pragma fragment
void func2( void ) { } /* Code section 2 */
void func3( void ) { } /* Code section 3 */
#pragma fragment
void func5( void ) { } /* Code section 4 */
#pragma fragment
_near void func9( void ) { } /* Code section 6 */
When the −Oe option is enabled the following changes are in effect for
the small memory model:
Language Implementation 3−39
To move jump tables separately from string and floating point constants to
various locations, you can use the following pragmas:
#pragma switch_tabmem_far
For the small memory model, jump tables are placed in far ROM. The
location of string and floating point constants is still controlled by the
−Oe/−OE option as described above. The ROM section where the jump
tables are placed have class ’CFARROM’. The code generated for accessing
the jump table in far ROM is slightly slower compared to the situation
where jump tables reside in near ROM.
#pragma switch_tabmem_near
For the small memory model, jump tables are placed in near ROM. The
location of string and floating point constants is still controlled by the −Oe
/ −OE option as described above. The ROM section where the jump tables
are placed have class ’CNEARROM’.
#pragma switch_tabmem_default
This is the default. Use this pragma to return the control of the jump table
locations back to the −Oe / −OE command line option as described above.
• • • • • • • •
3−40 Chapter 3
The pragmas can be passed through the command line by using the
−zpragma command line option.
All library modules are re−compiled and the libraries are rebuilt by these
makefiles.
Before running these makefile you should have rights to write to the
LANGUAGE
Restriction:
When the #pragma initeram or #pragma initiram is used, only the last
pragma in the source file affects the section attributes of the near ram data
sections for string and floating point constants.
Language Implementation 3−41
In the tiny memory model, the address is limited to 64Kbytes. In all other
models, the address space of the used device is the limit.
The _at() attribute has no effect on variables which are declared extern.
For near variables, the locator automatically assigns the correct page to the
correct DPP register. Note that all other relocatable variables in the
concerning page will also be moved. The dynamic assignments of DPP
registers can be overruled by the linker/locator controls. However, in case
of absolute variables, this will usually lead to errors because there is only
one valid DPP−register / page−number combination.
If two sections overlap, or if not all near sections can be located the
linker/locator will generate an error message.
The _at() attribute cannot be used with the _bit, _system, _bita,
_sfr, _esfr, _xsfr and _iram memory modifiers.
Examples:
_near int i _at(0x29000);
_far const char ch _at(0x2A900) = 100;
int j, * k _at(0x2B002);
int * (* * fptr)(int, int) _at(0x12344);
• • • • • • • •
3−42 Chapter 3
This will generate the following sections, when compiled in the small
memory model:
TEST_1_NB SECTION LDAT WORD AT 029000h ’CNEAR’
TEST_1_NB_ENTRY LABEL BYTE
_i LABEL WORD
DS 2
PUBLIC _i
TEST_1_NB ENDS
DS 2
PUBLIC _j
TEST_5_NB ENDS
Examples:
_sfr P0;
_sfrbit P0_6 _atbit( P0, 6 );
The storage class of the defined bit is ignored. The storage class is
inherited from the _bitword variable instead.
• • • • • • • •
3−44 Chapter 3
In the following situation, the bit b0 will be allocated statically. Yet it will
be initialized at run−time, each time the function is entered:
_bit funct ( void )
{
static _bitword bw;
_bit b0 _atbit( bw, 2 ) = 1;
return b0;
}
Example:
_inline int
add( int a, int b )
{
return( a + b );
}
void
main( void )
{
int c = add( 1, 2 );
}
The pragmas asm and endasm are allowed in inline functions. This makes
LANGUAGE
it possible to define inline assembly functions. See also section 3.11, Inline
Assembly in this chapter.
Language Implementation 3−45
Since the code that is generated is less efficient (two byte instructions), use
this attribute only when really needed. For example, for data exchange
with 8−bit processors.
• • • • • • • •
3−46 Chapter 3
You can use the _packed attribute on struct and union types only. The
_packed attribute applies to the struct/union definition itself, rather than
to an instance of the struct/union. So, each instance of the struct/union
must also have the _packed attribute. The following example
demonstrates the usage of the _packed attribute:
_packed struct ps
{
char c; /* offset 0 bytes */
int i; /* offset 1 byte */
};
LANGUAGE
The _packed attribute does not say anything about the alignment of the
struct/union itself. Therefore, when an instance of a struct/union does not
need alignment you must add the _noalign attribute:
typedef _packed struct ps
{
char c; /* offset 0 bytes */
int i; /* offset 1 byte */
char byte; /* offset 3 bytes */
} tPS; /* struct size: 4 bytes */
When you do not use the _noalign attribute on _packed structures, the
compiler can use the word copy routines for _packed struct/unions.
Since the code that is generated after the _packed qualifier is less
efficient, use packed structures only when really needed, for example for
data exchange with 8−bit processors. Consider in such case first other
solutions like for example, mapping structures on character arrays.
• • • • • • • •
3−48 Chapter 3
In this example, there is a gap of one bit between bf7 and bf10 and the
total size of the structure is 3 bytes. The alignment is needed because
otherwise 3 byte moves are needed in order to access all bits of bf10.
The latter example does not need alignment nor padding. The size of the
structure is 2 bytes.
Note that an unnamed bit field with size 0 aligns to the next word
boundary as is the case with non−packed struct/unions.
LANGUAGE
Language Implementation 3−49
When the Task Concept is strictly followed, the entry point of each task is
an interrupt function, either activated by hardware (interrupt) or by
software (TRAP instruction). Each task has only one entry point and no
code and data is shared. This implies that reentrancy of code does not
exist. See section 3.12, Interrupt in this chapter for more details about
interrupt functions.
• • • • • • • •
3−50 Chapter 3
Example:
C module is called test.c. The example illustrates how to declare a ROM
table (array) as ’shared among several tasks’ and the rest of the C data in a
normal data section. The generated code is listed below.
#pragma save_attributes
#if _MODEL == ’l’ || _MODEL == ’m’
#pragma combine fc=C
#define FAR _far /* far common data */
#else
#pragma combine nc=C
#define FAR /* normal common data */
#endif
/*
* COMMON data section in ROM, linked with
* each task and overlaid by the locator:
* shared data among all tasks.
*/
FAR const char table[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
#pragma restore_attributes
/*
* public within task scope: each task can have
* it’s own instance of the public variable i.
*/
int i; /* task scope */
/*
* static within module scope: each module can have
* it’s own instance of the static variable s.
*/
static int s; /* module scope */
TEST_1_NC ENDS
The same object module (containing the common section) must be linked
with all tasks using the shared data, because the module name is part of
the section name. Of course it is not possible for shared code to access
non automatic data which is not shared.
If the medium or large model is used, a shared ’near’ data section will
cause all near data sections of all tasks to be allocated in the same page,
limiting the total near data area of the whole application to 16K. However,
it is still possible to have both shared (common) and non−shared (public)
near data sections of each task in this area.
If the feature of a 16K near data area for every task is needed, the shared
data must be explicitly declared _far (or _huge or _shuge) as done in
the example above.
Example:
An application consists of two tasks TASK_A and TASK_B.
The #pragma global promotes the scope of the variable gi from the
task scope (public) to the application scope (global).
• • • • • • • •
3−52 Chapter 3
• • • • • • • •
3−54 Chapter 3
Many operators cause conversions and yield result types in a similar way.
The effect is to bring operands into a common type, which is also the type
of the result. This pattern is called the usual arithmetic conversions.
Sometimes surprising results may occur, for example when unsigned char
is promoted to int. You can always use explicit casting to obtain the type
required. The following example makes this clear:
static unsigned char a=0xFF, b, c;
void f()
{
b=~a;
if ( b == ~a )
{
/* This code is never reached because,
* 0x0000 is compared to 0xFF00.
* The compiler converts character ’a’ to
* an int before applying the ~ operator
*/
...
}
c=a+1;
while( c != a+1 )
{
/* This loop never stops because,
* 0x0000 is compared to 0x0100.
* The compiler evaluates ’a+1’ as an
* integer expression. As a side effect,
* the comparison will also be an integer
* operation
*/
...
}
}
• • • • • • • •
3−56 Chapter 3
void f()
{
b=~a;
if ( b == (unsigned char)~a )
{
/* This code is always reached */
...
}
c=a+1;
while( c != (unsigned char)(a+1) )
{
/* This code is never reached */
...
}
}
void f()
{
h = i * j; /* int * int = int */
k = l * m; /* long * long = long */
In strict ANSI−C, character arithmetic does not exist: all character variables
are converted to integer before the operation is performed.
However, if the integer result is not used (e.g. by assigning it to a character
variable) the operation could have been evaluated using character
arithmetic, giving the same result. This is how c166 works.
There is one exception to this rule, dealing with the sizeof operator:
char a, b;
int i;
void
main()
{
i = sizeof( ’A’ ); /* −Ac: 1, −AC option: 2 */
i = sizeof( a + b ); /* −Ac: 1, −AC option: 2 */
}
• • • • • • • •
3−58 Chapter 3
3. A bit type variable can be exchanged with all other type−variables. The
compiler generates the correct conversion.
5. Structure of bit is supported, with the restriction that no other type than bit
is member of this structure. Structure of bit is not allowed as parameter or
return value of a function.
6. A union of a bit structure and another type is not allowed. The bitword
type can be used for this purpose.
7. A bit type variable is not allowed as parameter. The allowed classes for bit
are: automatic, static, public or extern.
The constants need a (bit) cast operator in order to enable bit operations
such as ’&’, ’^’. Of course this is not needed with (compound)
assignments.
The following table shows which operators are allowed with bit type
LANGUAGE
variables:
Allowed is:
==, !=, <, <=, >, >=
&&, ||, !, ~
? :, CALL, RETURN
&, |, ^
&=, |=, ^=
conversions to/from char/int/long/float/double
bit structures (bit members only)
unary plus
Language Implementation 3−59
For example:
_bitword bw1, bw2; /* bitaddressable words */
if ( _getbit( bw1, 3 ) )
_putbit( 1, bw2, 7 ); /* set bit 7 of bw2 */
• • • • • • • •
3−60 Chapter 3
c166 also recognizes the keyword: _xsfr. The _xsfr keyword is used to
access special function registers outside the (E)SFR areas but within
internal RAM (DPP3). Variables declared as xsfr are not bitaddressble.
Example: PEC source and destination pointers (SRCPx/DSTPx).
c166 emits the name of the special function register in the assembly code.
c166 does not perform any check whether the name is correct or not, but
passes the name to a166. The assembler checks the validity of the name.
All reg*.h files consist of a number of parts, which are all included by
default. However, if you do not need every part in your source file, you
can omit each part by defining the appropriate macro before you include
this file. These ’control’ macros are described in the reg*.h files.
You can make your own special function register header file, but in that
case you must supply the same names to a166 by an STDNAMES file.
Because the special function registers are dealing with I/O, it is not correct
to optimize away the access to these registers. Therefore, c166 deals with
special function registers as if they were declared with the volatile
qualifier.
• • • • • • • •
3−62 Chapter 3
Macro Description
_DOUBLE_FP Defined when you do not use compiler option −F
(Treat double as float)
_SINGLE_FP Defined when you use compiler option −F (Treat
double as float)
_C166 Identifies the compiler. You can use this symbol to flag
parts of the source which must be recognized by the
c166 compiler only. It expands to the version number
of the compiler. For example, if you use version 8.6r3
of the compiler, _C166 expands to 86 (dot and
revision number are omitted).
_CPUTYPE Expands to a value representing the CPU type,
depending on option −x:
−x 0x167 (default)
−xd 0x272
−x1 0x1661
−x2 0x1662
−x22 0x16622
_MODEL Identifies the memory model. Expands to the
argument of option −M. See section 3.2.1.6,
_MODEL.
_USMLIB Expands to _usm if −P is specified, or _nousm
otherwise. See section 3.2.2, User Stack Model, for
more information.
Example:
#if _CPUTYPE == ’0x1662’ /* XC16x/Super10 */
...
#endif
Language Implementation 3−63
If a function prototype is used with a function call but NOT with the
function body (or vice versa), run−time errors may occur due to parameter
type mismatches.
• • • • • • • •
3−64 Chapter 3
A function that does not call any other function is called a ’leaf’ function. If
a function is a leaf function and the C code does not calculate the address
of a parameter (via the & operator) the parameters of this function do not
have to be saved. Thus, the parameters of such a function are left in the
input registers. A lot of C library functions (such as strlen(), strcpy() etc.)
meet these requirements.
Non−leaf functions must save the parameter registers on the user stack at
function entry, as if they were pushed by the caller. However, the code
generator tries to use the register copies of these parameters as long as
possible. If automatic registers are available, these registers are used
instead of the user stack.
Example 1:
void func1( long l1, int i, long l2, char *p );
/* R12−R13 R14 stack stack: not R15 */
better:
void func1( long l1, int i, char *p, long l2 );
/* R12−R13 R14 R15 stack */
Example 2:
void func2( double d, double *p, int i );
/* stack stack stack */
LANGUAGE
better:
void func2( double *p, int i, double d );
/* R12 R13 stack */
This means that all arithmetic operations (add, and, cmp, or, subb
and xor) with a stack variable need an extra register move, before
the operation can be done. With static memory variables a register
move is not needed, because the operations mentioned above allow
the usage of the MEM operand.
• Heavy usage of instruction 1) is slowing down execution time,
because this instruction takes twice as much time as any other move
instruction or arithmetic operation (200ns instead of 100ns at
40MHz).
Therefore, code size and execution speed can be improved if the
non−register function automatics may be treated by the compiler as if they
were static and it is possible to allocate these ’automatic’ variables in the
fast internal RAM of the C166/ST10 using a CLASSES or ADDRESSES(
SECTIONS ) locator control. Of course, this is not possible with recursive
functions. Because function automatics do not have any interaction with
other functions (unlike parameters), it is not necessary to introduce a
special static model to support this optimization. It is even possible to
enable this optimization for only one function in a module.
2. pragmas.
• • • • • • • •
3−66 Chapter 3
The usage of the −S option (or pragma static) does not change the
semantic behavior of c166 with automatics: explicit storage type specifiers
(far, near, huge, shuge) remain illegal and the initialization of an automatic
variable is done run−time (each time the function is entered).
The code generator of c166 uses a ’saved by callee’ strategy. This means
that a function which needs one or more registers for register variables,
must save the contents of these registers and restore before returning to
the caller. The major advantage of this approach is, that only registers
which are really used by the function are saved. If the function does not
have any register variable, the registers of the caller function remain valid
LANGUAGE
The code generator prefers to assign the register character type automatics
to R6 or R7 (using RL6/RL7) and the other types to the rest in the order of
their declaration.
Language Implementation 3−67
i ==> R9
c ==> RL6
l ==> R7−R8
If f() would have been a leaf function, the register automatics would
have been allocated in the following registers:
i ==> R15
c ==> R14
l ==> R12−R13
All basic data types which are allowed as automatic variable are
supported, except float/double/bit: char, int, long, near/far/huge/shuge
pointer. Of course _sfr, _sfrbit, _xsfr and _bitword are not
possible.
• • • • • • • •
3−68 Chapter 3
Static initialized variables use the same amount of space in both ROM and
RAM. The only exception is an initialized variable residing in ROM, by
means of either the #pragma romdata or the const storage type
qualifier. For normal initialized RAM variables, you can specify the class
name (’CINITIRAM’ or ’CINITERAM’) to be used with #pragma iramdata
or #pragma eramdata. You can use the CLASSES locator control to affect
the location of these variables. See section 3.2.3, Section Allocation, for
details on section names and section attributes.
Language Implementation 3−69
c166 treats romdata variables as if they were declared with the const
storage type qualifier.
From EDE: from the Projects menu, select Project Options... Expand the
C Compiler entry and select Allocation of Variables. Disable the check
box Perform ’clearing’ of non−initialized static/public variables.
• • • • • • • •
3−70 Chapter 3
It is not possible to remove the ’clearing code’ from the startup file,
because other C modules (and the C libraries) depend on it too.
3.10 STRINGS
In this section the word ’string’ means the separate occurrence of a string
in a C program. So variables initialized with strings are just initialized
character arrays and are not considered as ’strings’. See section 3.8,
Initialized Variables, for more information on this topic.
Strings have static storage. The ANSI X3.159−1989 standard permits string
literals to be put in ROM. Because there is no difference in accessing ROM
LANGUAGE
or RAM, c166 allocates strings in ROM only. This approach also saves
RAM, which can be very scarce in an embedded (single chip) application.
The Standard states that identical string literals need not be distinct, i.e.
may share the same memory. To save ROM space, c166 overlays identical
strings within the same module.
• • • • • • • •
3−72 Chapter 3
The pragma can appear anywhere in the source and remains in effect until
the pragma is used again to set a different memory space.
LANGUAGE
Language Implementation 3−73
You should realize that using these pragmas results into non portable and
hard to ’simulate’ code. Therefore, usage of these pragmas should be
minimal.
@[w|b|i]num
• • • • • • • •
3−74 Chapter 3
Examples:
Example:
#pragma asm( @w1=var1, @b2=var2, @i3=var3, @4 )
EXTERN XVAL:WORD, BVAL:BYTE, YVAL:WORD
MOV @4, @w1 ; fill temporary register
MOV XVAL, @4 ; save in some memory location
MOV BVAL, @b2 ; save in some memory location
MOV @i3, #2 ; small instruction (Rn, #data4)
MOV @w1, YVAL ; get some memory location
#pragma endasm( retval=@w1 )
The compiler will take care that the requested registers are free to be used
and that their original content is saved and restored if needed. When the
LANGUAGE
Defining inline assembly functions can be done by using the pragma asm
interface in an inline C function.
Example:
_inline int swap_add( int a, int b )
{
int rv;
#pragma asm ( @1=a, @2=b, @3 )
MOV @3, @1
MOV @1, @2
MOV @2, @3
ADD @3, @1
#pragma endasm ( rv=@3 )
return rv;
}
• • • • • • • •
3−76 Chapter 3
The ’MODULE SUMMARY’ of c166, reporting code size and data size of
the module, is no longer valid if code or data has been added using inline
assembly.
3.12 INTERRUPT
c166 supports both the ’Infineon Task Concept’ and the ’Flat Interrupt
Concept’. These two concepts are explained in the chapter Software
Concept of the ’TASKING Cross−Assembler, Linker/Locator, Utilities User’s
Manual’. We strongly recommend reading this section first! See also section
3.3 Task Scope in this chapter.
For example:
void _interrupt( 0x22 ) timer( void )
{
...
}
Interrupt Frame
c166 generates an interrupt frame inheriting the user stack pointer from
the previous task, switching context to a new register bank, saving DPP
registers and MDC, MDH and MDL registers. When the −Oh command line
option is set (default) the compiler optimizes the interrupt frame so that it
only contains the parts needed to save resources used by the interrupt
function. You can also tell the compiler to omit the whole interrupt frame
via the following pragma:
#pragma noframe
With the _using(push) function qualifier you can tell the compiler to
use PUSH/POP instructions to save GPRs in the interrupt frame, instead of
using a SCXT instruction. Only the GPRs that are used in the interrupt
function, are saved.
void _interrupt( 0x22 ) _using(push) timer( void )
{
...
}
• • • • • • • •
3−78 Chapter 3
This way you can define several interrupt functions in one module with
each function having its own register bank. Or you can share a register
bank between several interrupt functions which have the same interrupt
level and thus can never interrupt each other. When several interrupt
functions in a source module are ’using’ a register bank with the same
name, the compiler uses the same register bank for these functions. l166
will ’overlay’ register banks with equal names.
All interrupt functions without the _using keyword use a register bank
with a name derived from the module name. This means that all interrupt
functions in one C source file which do not have the _using keyword use
the same register bank and therefore they should have the same interrupt
level. Different interrupt levels can be used, but in this case #pragma
regdef is needed to instruct the compiler to use non−overlapping register
sets.
With #pragma regdef you can define the register set that the compiler
uses for code generation. The pragma affects all functions after the
pragma, until #pragma regdef is used again to define another register
set. When #pragma regdef is used without an argument, or with
argument 0, the REGDEF assembler directives used for interrupt functions
will be omitted, even when the _using() qualifier is used. In this case
the compiler does not generate code to switch to another global register
bank.
You can use the −r command line option to name the register bank of a
module. With an optional flag the register bank can be declared ’common’.
When a register bank definition is supplied with the −r option, this register
set is used until the next #pragma regdef in the source.
When the −r option is used without any arguments, the REGDEF directive
for this module will be omitted. This does not affect the REGDEF
directives originating from the _using() qualifier. Interrupt functions that
LANGUAGE
do not have the _using() qualifier use the module’s REGDEF. Since this
REGDEF is omitted, no code will be generated in the interrupt frame to
switch register banks.
Only the _localbank (0) qualifier can be used in conjunction with the
_using qualifier. The correct register bank will not be selected when
#pragma noframe is entered before the interrupt function.
Since local register banks are not memory mapped, the compiler can not
copy the user stack pointer (R0) to the new register bank. Therefore,
each local register bank will have its own user stack area:
C166_US0: will be used together with register bank 1
• • • • • • • •
3−80 Chapter 3
The compiler estimates the size of each seperate stack based upon the
code inside interrupt functions only. User stack space occupied by
functions which are called from the interrupt function are not taken into
account.
The estimated user stack size can be adjusted using a new function
qualifier:
_stacksize (num)
Where num specifies the user stack adjustment in bytes. A positive number
increases the compiler estimates by num bytes, a negative value decreases
it. If the sum of the compiler estimation and the stack adjustment is
negative, a warning will be generated and the value will be truncated. The
value of num must be even.
The _stacksize qualifier can only be used in combination with the local
register banks (for example: _localbank (0) is NOT allowed) and
interrupt functions.
ISR(void)
{
return;
}
−inum
When either option is supplied to the compiler, it will try to reorder and
move code from the interrupt frame to the interrupt vector table. Where
possible the context switch will be done just before the JMPS instruction
which jumps to the ISR. By doing this, the execution time of the JMPS
instruction will be hidden by the context switch.
the compiler will put all sections that have to be inlined in a special
section called:"C166_INT" with class:"C166_VECTAB". An example of an
inlined interrupt function is shown below:
; ****************************************************
; * Section which will be located at vector position
; * 0x10 by the locator, the scaling = 3
; * (32bytes/entry available in vector table)
; ****************************************************
PUSH
CP ;; 2 bytes
SCXT
MDC,#010h ;; 4 bytes
PUSH
DPP0 ;; 2 bytes
MOV
DPP0,#PAG ?BASE_DPP0 ;; 4 bytes
PUSH
DPP2 ;; 2 bytes
MOV
DPP2,#PAG ?BASE_DPP0 ;; 4 bytes
PUSH
MDH ;; 2 bytes
MOV
SCALEDVE_RB,R0 ;; 4 bytes
MOV
CP,#SCALEDVE_RB ;; 4 bytes
;; (Context switch right before JMPS)
JMPS SEG _ISR1,_ISR1 ;; 4 bytes
RETV ;; −−−−−−−−+
_3 ENDP ;; 32 bytes
C166_INT ENDS
• • • • • • • •
3−82 Chapter 3
; *********************
; * Start of ISR
; *********************
; *********************
; * User code goes here
; *********************
POP MDL
POP MDH
POP DPP2
POP DPP0
POP MDC
POP CP
RETI
_ISR1 ENDP
Examples:
1. The C module is called ’intrpt.c’ (present in the examples/c directory).
The example illustrates how to tell the compiler to omit the interrupt frame
code. The C source and the generated code (large) is listed below:
#pragma global
bit b; /* interrupt handler sets a global bitvariable */
#pragma public
• • • • • • • •
3−84 Chapter 3
i = ext_func( 3 );
}
_f ENDP
INTRPT_1_PR ENDS
Instead of using #pragma regdef 6 you can also use the command line
option −r6. When you use the −r command line option, you can also
specify the register bank name to be used and whether this register bank
should be COMMON or not.
It is very useful to share the register bank of interrupt functions, which are
at the same interrupt priority level, so they cannot be active
simultaneously. This approach saves internal RAM space, which is a
scarce resource.
ASSUME DPP3:SYSTEM
INTRPT_1_NB SECTION DATA WORD PUBLIC ’CNEAR’
ASSUME DPP2:INTRPT_1_NB
INTRPT_1_NB_ENTRY LABEL BYTE
_i LABEL WORD
DS 2
PUBLIC _i
INTRPT_1_NB ENDS
• • • • • • • •
3−86 Chapter 3
3. total number of ’gaps’ between the case labels (when sorted) does not
exceed the number of case labels.
It is obvious (especially with large switch statements) that the jump table
approach executes faster than the jump chain approach. If speed is
needed (e.g. an interrupt function) it might be acceptable to use a jump
table, even if the number of gaps between the (sorted) case labels exceeds
the number of case labels itself. Therefore the second and third
requirement can be overruled by using:
#pragma switch_force_table
which is the default situation. The command line equivalents are −Os
(switch_force_table) and −OS (default, switch_smart).
The location of jump tables in the small memory model can be controlled
by using
#pragma switch_tabmem_far
LANGUAGE
Register Usage
R0 User Stack Pointer (USP)
R1−R5, R10, R11 General registers (codegen, temporary results,
C return values)
R6−R9 C register variables and saved register
parameters
R12−R15 Fast C parameter passing and C register
variables
• • • • • • • •
3−88 Chapter 3
seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm
s = sign, e = exponent, m = mantissa
C D
value (−1) s 1 m23 2 e127
2
An example:
0x40490fdb
LANGUAGE
s = 0
e = 0x80 = 128
m = 0x490fdb = 4788187
C D
value (−1) 0 1 4788187 2 1 1 (1 0.5707964) 2 3.14159274
8388608
Language Implementation 3−89
s000000000000000 0000000000000000
seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm
s = sign, e = exponent, m = mantissa
s111111111111111 1111111111111111
seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm
s = sign, e = exponent, m = mantissa
According to the IEEE standard not all mantissa bits have to be set for a
number to be handled as NaN.
s111111110000000 0000000000000000
seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm
s = sign, e = exponent, m = mantissa
• • • • • • • •
3−90 Chapter 3
C D
value (−1) s 1 m52 2 e1023
2
Address +0 +1 +2 +3 +4 +5 +6 +7
Single precisions numbers can be stored in a register pair. In this case the
format is:
R4 R5
seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm
s = sign, e = exponent, m = mantissa
R10 R11
seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm
s = sign, e = exponent, m = mantissa
R4 R5
seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm
s = sign, e = exponent, m = mantissa
• • • • • • • •
3−92 Chapter 3
R4 R5
seeeeeeeemmmmmmm mmmmmmmmmmmmmmmm
s = sign, e = exponent, m = mantissa
• • • • • • • •
3−94 Chapter 3
• • • • • • • •
3−96 Chapter 3
• • • • • • • •
3−98 Chapter 3
A floating point routine calls the trap routine if an error condition occurs.
The type of error is specified by a trap code which is passed via register
R1 to the trap routine. The result of a floating point operation is not
undefined in an error situation. On error the result will be a special
floating point number, such as infinite, not a number etc., except when a
floating point underflow or overflow occurs.
The following table lists all the trap codes and the corresponding error
description and result:
Only the floating point libraries which perform floating point trapping
contain a floating point trap stub. This floating point trap stub loops
infinitely, which is very helpful when you want to find a bug in your
application. But when it is expected or allowed or even wanted that
floating point operations generate results that are out of range, then
program execution must continue after entering the floating point trap
handler.
It is not possible to simply return from the floating point trap handler,
because the floating point accumulator(s) contain a value which is out of
range. In the same floating point operation or else in a next floating point
operation there will be another call to the floating point trap handler,
because the value in the floating point accumulator(s) remain out of range.
This results in a succession of floating point traps.
Interpretation of the error condition in the floating point trap handler and
then continuing the floating point operation will result in most cases in a
new error condition or unpredictable result. So, this is not a good solution
to handle floating point error situations.
• • • • • • • •
3−100 Chapter 3
The C listing below shows how to save an environment with setjmp. The
assembly listing of the floating point trap handler below shows how
longjmp is used to return to the saved environment.
There are several ways to write a C function which handles floating point
traps using setjmp and longjmp. Always keep in mind that the longjmp
function restores the environment saved by the most recent invocation of
the setjmp function. And the environment must be saved before the
longjmp function is called by the floating point trap handler, else
program execution will be undefined.
LANGUAGE
Language Implementation 3−101
/*
* Example program which handles floating point traps by printing
* the floating point trap code on stdout. See also floating point
* trap handler in module trap.asm
*/
#include <stdio.h>
#include <setjmp.h>
void
main( void )
{
int exception;
/*
* Do not use floating point operations before this if
* statement, because there is no environment saved to jump to.
* The trap handler loops infinite when a floating
* point operation is called from this point which traps!
*/
/*
* When the setjmp function has saved the environment it returns
* zero into the exception variable, so the floating point
* operations are executed. But if a floating point trap occurs,
* the trap handler calls the function longjmp.
* The longjmp function restores the environment and returns the
* trap code in the exception variable. The trap code is a
* non−zero value, so the else part of this if statement will be
* executed on a floating point trap.
*/
if( !( exception = setjmp( _FP_ENV ) ) )
{
/*
* Insert your floating point operations here.
*/
} else
{
/* The exception code is a non−zero value. */
printf("Floating point exception: %d\n", exception );
}
/*
* When there is a floating point operation after this if
* statement and it generates a floating point trap. Then the
* program execution also continues in the else part of this if
* statement, because the environment buffer was saved to it !
*/
}
• • • • • • • •
3−102 Chapter 3
The floating point trap handler described by the assembly listing in figure
3−7 is archived in the floating point libraries.
$case
$genonly
;******************************************************************
;*
;* MODULE : trap.asm
;*
;* APPLICATION : Floating point library 80166
;*
;* DESCRIPTION : Floating point trap handler which uses longjmp to
;* return to a previous saved environment or loops
:* infinite when no environment is save to return to.
;*
;* INPUT : Register R1 contains the trap code
;*
;* Trap code R1,old R1,IEEE Description
;* EIOVFL 3 ; Integer overflow
;* EFOVFL 4 4 ; Float overflow
;* EFUNFL 5 8 ; Float underflow
;* EFDIVZ 7 2 ; Float division by zero
;* EFUND/EFINVOP 9 1 ; Float invalid operation
;* ECONV 10 32 ; Conversion error
;* ESTKUN 11 ; Floating point stack underflow
;* ESTKOV 12 ; Floating point stack overflow
;* EFINEXCT 16 ;
;*
;* ANALIST : Guus Jansman
;*
;* Copyright 1991−2002 Altium BV
;*
;******************************************************************
$INCLUDE( head.asm )
@ENDI
;******************************************************************
;* floating point trap handler
;******************************************************************
@IF( @EQS(@MODEL,"TINY") | @EQS(@MODEL,"MEDIUM") )
__fptrap8 PROC NEAR
@ELSE
__fptrap8 PROC FAR
@ENDI
__fptrap4: ; entry floating point trapping routine for single
; precision operations.
• • • • • • • •
3−104 Chapter 3
__fptrap8 ENDP
__FPCODE ENDS
;******************************************************************
;* data section for floating point environment buffer which is
;* cleared at startup with C166_BSS. jmp_buf _FP_ENV;
;******************************************************************
@IF( @EQS(@MODEL, "TINY") | @EQS(@MODEL, "SMALL" ) )
__FP_ENV_BUF SECTION LDAT WORD PUBLIC ’CNEAR’
@ELSE
__FP_ENV_BUF SECTION DATA WORD PUBLIC ’CNEAR’
@ENDI
__FP_ENV LABEL WORD
DS 16 ; sizeof( jmp_buf )
__FP_ENV_BUF ENDS
@ENDI
END
The data section containing the floating point jump buffer __FP_ENV is
cleared at startup. The initialization codes for it are stored in the C166_BSS
sections.
There are two entry points available in the floating point trap handler, one
for double precision floating point functions causing a trap, and one for
single precision floating point functions causing a trap. This default trap
handler is precision independent, but if you want to write a trap handler
for each precision you need these two entry points.
You can use your own floating point trap handler by linking the object
module, overruling the floating point trap handler of the floating point
library. Or you can replace the floating point trap object module in the
floating point library with the object module of your own floating point
trap handler.
• • • • • • • •
3−106 Chapter 3
#pragma noclear
jmp_buf _FP_ENV;
Because the ANSI specification states that public C names starting with an
underscore are implementation defined, all intrinsic functions names have
a leading underscore.
Several of the intrinsic functions have restricted operand types. There are
two possible restricted types. The first is called ICE which denotes that the
operand must be a Integral Constant Expression rather than any type of
integral expression, this is because the BMOV instruction et al do not
support otherwise. The second is called BITADDR which means that the
operand must be a bit addressable integer (i.e. bitword, bitaddressable sfr
or bitaddressable esfr) object.
_CoABS
Use the CoABS instruction to change the MAC accumulator’s contents to its
absolute value. Only available when the MAC instruction set is enabled
with the compiler option −xd, −x2 or −x22.
Returns nothing.
_CoABS();
CoABS
• • • • • • • •
3−108 Chapter 3
_CoADD
Use the CoADD instruction to add a 32−bit value to the MAC accumulator.
Only available when the MAC instruction set is enabled with the compiler
option −xd, −x2 or −x22.
Returns nothing.
_CoADD( arg1 );
CoADD R12, R13
_CoADD2
Returns nothing.
_CoADD2( arg1 );
CoADD2 R12, R13
_CoASHR
Use the CoASHR instruction to (arithmetic) shift right the contents of the
MAC accumulator count times. Only available when the MAC instruction
LANGUAGE
The CoASHR instruction has a maximum value for count. Check your CPU
manual for the CoASHR behaviour for large arguments.
Returns nothing.
_CoASHR( 2 );
CoASHR #02h
Language Implementation 3−109
_CoCMP
_CoLOAD
Returns nothing.
_CoLOAD( arg1 );
CoLOAD R12, R13
_CoLOAD2
Returns nothing.
_CoLOAD2( arg1 );
CoLOAD2 R12, R13
• • • • • • • •
3−110 Chapter 3
_CoMAC
Use the CoMAC instruction to add the multiplication result of two signed
16−bit values to the MAC accumulator. Only available when the MAC
instruction set is enabled with the compiler option −xd. Note that the MP
flag influences the result (it is highly recommended to keep the MP flag
cleared).
Returns nothing.
_CoMAC( arg1, arg2 );
CoMAC R12, R13
_CoMACsu
Returns nothing.
_CoMACsu( arg1, arg2 );
CoMACsu R12, R13
_CoMACu
Returns nothing.
_CoMACu( arg1, arg2 );
CoMACu R12, R13
Language Implementation 3−111
_CoMAC_min
Returns nothing.
_CoMAC_min( arg1, arg2 );
CoMAC− R12, R13
_CoMACsu_min
Returns nothing.
_CoMACsu_min( arg1, arg2 );
CoMACsu− R12, R13
_CoMACu_min
Returns nothing.
_CoMACu_min( arg1, arg2 );
CoMACu− R12, R13
• • • • • • • •
3−112 Chapter 3
_CoMAX
Use the CoMAX instruction to change the MAC accumulator’s contents if its
value is lower than the argument’s value. Only available when the MAC
instruction set is enabled with the compiler option −xd, −x2 or −x22.
Returns nothing.
_CoMAX( arg1 );
CoMAX R12, R13
_CoMIN
Use the CoMIN instruction to change the MAC accumulator’s contents if its
value is higher than the argument’s value. Only available when the MAC
instruction set is enabled with the compiler option −xd, −x2 or −x22.
Returns nothing.
_CoMIN( arg1 );
CoMIN R12, R13
_CoMUL
Use the CoMUL instruction to store the multiplication result of two signed
16−bit values in the MAC accumulator. Only available when the MAC
LANGUAGE
instruction set is enabled with the compiler option −xd, −x2 or −x22. Note
that the MP flag influences the result (it is highly recommended to keep the
MP flag cleared).
Returns nothing.
_CoMUL( arg1, arg2 );
CoMUL R12, R13
Language Implementation 3−113
_CoMULsu
Returns nothing.
_CoMULsu( arg1, arg2 );
CoMULsu R12, R13
_CoMULu
Returns nothing.
_CoMULu( arg1, arg2 );
CoMULu R12, R13
_CoNEG
Returns nothing.
_CoNEG();
CoNEG
• • • • • • • •
3−114 Chapter 3
_CoNOP
Returns nothing.
_CoNOP();
CoNOP [R0]
_CoRND
Returns nothing.
_CoRND();
CoRND
_CoSHL
Use the CoSHL instruction to shift left the contents of the MAC
accumulator count times. Only available when the MAC instruction set is
enabled with the compiler option −xd, −x2 or −x22.
LANGUAGE
The CoSHL instruction has a maximum value for count. Check your CPU
manual for the CoSHL behaviour for large arguments.
Returns nothing.
_CoSHL( 2 );
CoSHL #02h
Language Implementation 3−115
_CoSHR
Use the CoSHR instruction to (logical) shift right the contents of the MAC
accumulator count times. Only available when the MAC instruction set is
enabled with the compiler option −xd, −x2 or −x22.
The CoSHR instruction has a maximum value for count. Check your CPU
manual for the CoSHR behaviour for large arguments.
Returns nothing.
_CoSHR( 2 );
CoSHR #02h
_CoSTORE
Use the CoSTORE instruction to retrieve the 32−bit value, stored in the
MAC accumulator MAH and MAL. Only available when the MAC
instruction set is enabled with the compiler option −xd, −x2 or −x22.
_CoSTOREMAH
Use the CoSTORE instruction to retrieve the 16−bit value, stored in MAH.
Only available when the MAC instruction set is enabled with the compiler
option −xd, −x2 or −x22.
• • • • • • • •
3−116 Chapter 3
_CoSTOREMAL
Use the CoSTORE instruction to retrieve the 16−bit value, stored in MAL.
Only available when the MAC instruction set is enabled with the compiler
option −xd, −x2 or −x22.
_CoSTOREMAS
Use the CoSTORE instruction to retrieve the 16−bit value, stored in MAS.
Only available when the MAC instruction set is enabled with the compiler
option −xd, −x2 or −x22.
_CoSTOREMSW
Use the CoSTORE instruction to retrieve the 16−bit value, stored in MSW.
Only available when the MAC instruction set is enabled with the compiler
LANGUAGE
_CoSUB
Use the CoSUB instruction to subtract a 32−bit value from the MAC
accumulator. Only available when the MAC instruction set is enabled with
the compiler option −xd, −x2 or −x22.
Returns nothing.
_CoSUB( arg1 );
CoSUB R12, R13
_CoSUB2
Returns nothing.
_CoSUB2( arg1 );
CoSUB2 R12, R13
_rol
• • • • • • • •
3−118 Chapter 3
_ror
_testclear
*/
g();
CALLA cc_UC,_g
b = 1; /* end critical actions: free
* semaphore */
BSET _b
}
_3:
Language Implementation 3−119
_testset
_bfld
• • • • • • • •
3−120 Chapter 3
_getbit
_putbit
_int166
_idle
Use IDLE instruction to enter the idle mode. In this mode the CPU is
powered down while the peripherals remain running.
Returns nothing.
if( save_power )
MOV R5,_save_power
JMPR cc_Z,_12
_idle(); /* wait until peripheral interrupt
* or external interrupt occurs.
*/
IDLE
_12:
_nop
A NOP instruction is generated, before and behind the nop instruction the
peephole is flushed. Code generation for _nop() is exactly the same as the
following inline assembly.
#pragma asm
nop ; inline nop instruction
#pragma endasm
Returns nothing.
value = P0; /* read from port P0 */
MOV R12,P0
_nop(); /* delay for one cycle */
NOP
P1 = value; /* write to port P1 */
MOV P1,R12
• • • • • • • •
3−122 Chapter 3
_prior
_pwrdn
Use PWRDN instruction to enter the power down mode. In this mode, all
peripherals and the CPU are powered down until an external reset occurs.
Returns nothing.
if( standby_mode )
MOV R4,_standby_mode
JMPR cc_Z,_13
_pwrdn(); /* CPU is powered down until
* an external interrupt occurs.
*/
PWRDN
_13:
LANGUAGE
_srvwdt
Returns nothing.
Language Implementation 3−123
_diswdt
Returns nothing.
_diswdt(); /* disable watchdog timer */
DISWDT
_einit
Returns nothing.
_einit(); /* end of initialization */
EINIT
_atomic
Returns nothing.
_atomic( 3 ); /* next 3 instructions are
* not interrupted.
*/
ATOMIC #03h
• • • • • • • •
3−124 Chapter 3
_mul32
_mulu32
_div32
_divu32
_mod32
_modu32
long m32;
int d32;
• • • • • • • •
3−126 Chapter 3
MOV R15,MDL
JNB V,_15
errno = OVERFLOW;
MOV R4,#01h
MOV _errno,R4
_15:
return( d32 );
MOV R4,R15
_pag
_pof
_seg
_sof
_mkfp
• • • • • • • •
3−128 Chapter 3
_mkhp
_mksp
Example:
The file builtin.c in the c subdirectory of the examples directory is a
C source file demonstrating the c166 intrinsic functions. Compile the file
using the −s option to inspect generated code.
Language Implementation 3−129
the compiler tries to find this file in the same way as normal include files
(#include "icall.h") are searched. See section 4.4, Include Files.
In this file you can specify the prototypes of the user defined intrinsics. An
intrinsic function can be defined by using the _intrinsic keyword, for
example:
_intrinsic float intrinsic_func(int*,long);
The compiler forces all parameters to be kept in registers, except for the
parameters of type struct/union and double. Those exceptions are
passed on to the user stack. Finally, the compiler generates a macro
preprocessor call:
@intrinsic_func(R8,R6,R7)
When a parameter is passed on to the user stack the stack offset of the
parameter is filled in at the appropriate position, for example:
_intrinsic void i_func(double);
• • • • • • • •
3−130 Chapter 3
The parameter order within these groups will not differ from the order at
C−level. The parameters passed on the user stack will be passed (and
evaluated) to the macro after the parameters that are passed in registers.
For example:
_intrinsic void i_func( double, struct a, int, struct b );
^ ^ ^ ^
| | | +−− struct b (offset 0)
| | |
| | +−−−−− struct a (offset 8)
| |
| +−−−−−−−− double (offset 16)
+−−−−−−−−−−−− int
The macro call parameter assignments will be included in the output file
as comment, similar to the following:
; Macro call parameter assignments:
;
; i1 = R12
; l1 = R13R14
; d1 = offset 16
; func(ifunc(i2), d2) = offset 8
; d2 = offset 0
;
@function(R12,R13,R14,16,8,0)
LANGUAGE
If a parameter occupies more than one register, all registers will be passed
separately to the macro. See the example above, where parameter ’l1’ has
type ’long int’. This parameter is passed in R13/R14 at position 2 and 3
in the parameter list. If there are more registers needed then available
(max. 13) an error will be generated:
E 745: no registers left for expression
Language Implementation 3−131
The compiler will take care of copying this value to the stack location
reserved for the return value, and for releasing the top stack entry. The
stack space for the return value will also be reserved by the compiler
before the intrinsic function is called. A typical code example is:
• • • • • • • •
3−132 Chapter 3
; test.c 30 r = double_func( f );
SUB R0,#08h ; stackspace for return value
SUB R0,#08h ; stackspace for parameter
MOV R12,R0
MOV R4,#_f
CALLS SEG __load8n,__load8n ; load parameter on user stack
MOV R4,R12
CALLS SEG __store8n,__store8n ; store parameter
ADD R0,#08h ; release space allocated by __load8n
For clarity, this example was compiled using −OJ (disabling the peephole).
Normally the ADDs and SUBs on R0 are combined.
Intrinsic functions with a variable argument list are not allowed. If this
occurs, the compiler generates an error:
E 771: variable argumentlist not allowed with
intrinsic function: "%s()"
There are three points that should be considered when you create an
LANGUAGE
intrinsic function:
1. Special care must be taken when pointers are passed to a user defined
intrinsic. When default pointers are used, the size will differ when an
application is compiled in an other memory model. It is therefore
advisable to specify the memory the pointer refers to and thus the pointer
will always have the same size.
will generate:
$INCLUDE(myinclude.inc)
Examples
_CoLOAD( arg1 );
_CoABS();
Note that the MP flag influences the result (it is highly recommended to
keep the MP flag cleared).
• • • • • • • •
3−134 Chapter 3
You can use code memory banking in C by using the function qualifier:
_bank(number)
This function qualifier uses the same syntax rules as the other function
qualifiers _interrupt(number) and _stackparm. A function qualifier
is allowed in both the function prototype (for the caller) and the function
body itself:
int _bank(1) func_b1( char *, long ); /* prototype */
int _bank(2)
func_b2( int parm ) /* function body */
{
}
You can also use a function qualifier when you declare function pointers.
The following line of C code declares a table called ’fptable’ of 6 function
pointers, all containing addresses of functions which are located in bank 3
and expecting their parameters (2 int types) via the user stack and
returning a long:
long _stackparm _bank(3) (*fptable[6])( int, int );
Although banked interrupt functions are allowed you should not use them
because they are not called as a banked function from the interrupt vector.
It is recommended to make a non−banked interrupt function and call a
banked function from that interrupt function.
• • • • • • • •
3−136 Chapter 3
int x;
char *p;
long l;
LANGUAGE
.
.
MOV R12,_p ; pass character pointer
MOV R13,_l ; pass long value
MOV R14,(_l+2) ;
MOV R4,#SOF _func_b1; pass inter−segment address of
MOV R5,#SEG _func_b1; banked function.
MOV R3,#0001H ; pass code bank number and no
; restore of current bank at
; return
MOV [−R0],R3 ; save code bank number(s)
; on the user stack
CALLS SEG __banksw, __banksw
; call code bank switch function
ADD R0,#2 ; Remove code bank number(s)
; from the user stack
MOV _x,R4 ; return result from banked
; function
.
.
The bank switch function may not introduce a conflict with the register
usage and user stack usage implementation of C function parameter
passing and C register variables. See section 3.15, Register Usage for details.
The registers which are used for fast C parameter passing (R12−R15) may
not be used by the code bank switch function and also the registers which
are used for C register variables (R6−R9) may not be altered without saving
them at entry and restoring them at return of the bank switch function.
Register R1−R5, R10 and R11 are free for use. However, registers R4 and R5
may contain a return value from the banked function. The user stack
pointer (R0) may not be changed, otherwise compiler pre−calculated
offsets are affected. Keep these restrictions in mind when writing your
own bank switch function. The bank switch function is a run−time library
function and not a C function !
The compiler emits a special class reflecting the bank number for the code
section of a banked function (e.g. class ’BANK1’). You can use these class
names with the locator OVERLAY control.
• • • • • • • •
3−138 Chapter 3
The following listing shows the assembly code for simulating code
banking. The number of code banks is restricted to the number of pages
which are available for code banking. The physical page the code banks
are overlaid in and executed from is defined by the equate CODE_PAGE.
The default value of CODE_PAGE is page 15. The following locator control
can be used:
OVERLAY ( ’BANK4’, ’BANK5’ ( RANGEP(15) ) )
This control instructs the locator to overlay the classes BANK4 and BANK5
LANGUAGE
in page 15. Remember that, when using our simulation code, the code
from bank 4 must be located in page 4 and the code from bank 5 must be
located in page 5. You can use the regular CLASSES control to achieve this.
See the description of the OVERLAY locator control in the assembler
manual for a detailed example.
Language Implementation 3−139
The code bank number of the currently active code bank is pushed on the
user stack and afterwards removed from it by the function calling the bank
switch function. It is not possible to save the current code bank number
on the user stack at function entry of the bank switch function, because
this affects the user stack pointer, introducing a conflict with precalculated
offsets for C function parameters and automatics. When code execution
returns from the banked function, this code bank number is read from the
user stack and, when needed, the previous code bank is reactivated by
calling __pgbk again. This allows you to call a banked function from a
banked function in a different code bank.
You can use the skeleton bankswh.asm, in the bank subdirectory of the
examples directory, as a starting point to implement your hardware
implementation of bank switching. In this case, you only have to replace
the code from __pgbk with your own code, actually performing the
hardware bank switch. It is obvious that your hardware bank switch
approach is not limited to the size of a page.
• • • • • • • •
3−140 Chapter 3
Implementation issues
The MISRA C implementation in the compiler supports most 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, some rules are not implemented. These unsupported rules are
visible in the C Compiler | MISRA C | MISRA C Rules entry of the
Project Options dialog in EDE, but cannot be selected (grayed out).
You can change the level of error messages from errors to warnings on the
required MISRA C rules and the advisory MISRA C rules, with the following
C compiler command line options:
−misrac−required−warnings
−misrac−advisory−warnings
Language Implementation 3−141
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.
If the MISRA C error level is set to ’warnings’, then the MISRA C rules are
marked as checked.
• • • • • • • •
3−142 Chapter 3
void
f()
{
DSTP0 = (int)buffer; /* when you use the c++ compiler,
use a long cast instead of an
integer: DSTP0 = (long)buffer; */
}
PUBLIC _f
PEC1_2_PR SECTION CODE WORD PUBLIC ’CPROGRAM’
_f PROC FAR
MOV R4,#SOF (_buffer)
MOV DSTP0,R4
RETS
_f ENDP
PEC1_2_PR ENDS
#include <reg166.h>
PUBLIC _f
PEC1_2_PR SECTION CODE WORD PUBLIC ’CPROGRAM’
_f PROC FAR
MOV R4,#SOF _buffer
MOV DSTP0,R4
RETS
_f ENDP
PEC1_2_PR ENDS
f()
{
PECSEG0 &= 0xFF00;
PECSEG0 |= seg( buffer );
DSTP0 = sof( buffer );
}
• • • • • • • •
3−144 Chapter 3
This header file checks if the predefined macro _C166 is defined (c166
only). If not, all C166/ST10 language extensions (read keywords) are
redefined to ANSI C equivalents. Furthermore an adapted prototype of
each C166/ST10 intrinsic function is present, because these functions are
not known by another ANSI compiler. If you use these functions, you
should write them in C, performing the same job as the C166/ST10
processor and link these functions with your application for simulation
purposes.
Note that you do not have to edit all the ’old style’ function bodies of your
application into ’new style’ ANSI function bodies. You only have to add a
full prototype declaration before any function is called and before any
function definition.
The following example shows how to migrate from old style programs to
new style without editing the function bodies of the program. The
advantage of this method is, that if ’prototyping’ is not possible (because
the C program must be translated with a non−ANSI compiler), the program
does not have to be changed:
Language Implementation 3−145
#ifdef prototyping
#define FD(x) x /* full function prototype */
#else
#define FD(x) () /* return type only: no arguments */
#endif
void
main()
{
char *p;
p = cg_var( "text", 2 );
}
char *
cg_var( name, offset )
char *name;
int offset;
{
return ( name + offset );
}
4. In most of the cases it is safe to use the −Oa option, which results in better
code density. However, you have to check your application on ’aliases’. If
this option is not used (default), c166 ’forgets’ all register contents bound
to C variables if an indirect write operation (e.g. MOV [R4],R5) is
performed.
5. Use the −Om option (default) and non−protected library if multiply and
divide instructions do not have to be protected against interrupts. This
results in better code density and faster execution.
• • • • • • • •
3−146 Chapter 3
8. Avoid static initialized bit variables (which must have the value ’1’ after
startup), because this takes a lot of ROM space and is very time consuming
during system startup.
9. Use the −t option, to inspect the size of the code generated. This is useful,
when ’experimenting’ with compiler options.
10. Use the −Of optimization option to prefer speed instead of code density
(−OF is default).
11. Use the −Ox optimization option to enable extra inlining of C library
functions when you prefer speed instead of code density.
LANGUAGE
CHAPTER
COMPILER USE
4
4−2 Chapter 4
CHAPTER
4
USAGE
Compiler Use 4−3
Options are preceded by a ’−’ (minus sign). Controls are reserved words.
The input file can have any extension as explained below.
When you use a UNIX shell (Bourne shell, C−shell), arguments containing
special characters (such as ’( )’ and ’?’) must be enclosed with "" or
escaped. The −? option (in the C−shell) becomes: "−?" or −\?.
• • • • • • • •
4−4 Chapter 4
• Arguments with a .out suffix are interpretes as input files for the
Motorola S formatter, IEEE formatter or Intel Hex formatter. Specify
the formatter respectively with the options −srec, −ieee or −ihex.
• Everything else is considered an object file and is passed to the
linker.
Normally, cc166 tries to compile and assemble all files specified, and link
and locate them into one output file. There are however, options to
suppress the assembler, linker or locator stage. The control program
produces unique filenames for intermediate steps in the compilation
process. These files are removed afterwards. If the compiler and assembler
are called in one phase, the control program prevents preprocessing of the
generated assembly file. Normally assembly input files are preprocessed
first.
Option Description
−? Display invocation syntax
−V Display version header and stop
−Waarg Pass argument directly to the assembler
−Wcarg Pass argument directly to the compiler
−Wcparg Pass argument directly to the C++ compiler
−Wfarg Pass argument directly to the object formatter
−Wlarg Pass argument directly to the linker
−Wmarg Pass argument directly to the macro preprocessor
−Woarg Pass argument directly to the locator
−Wplarg Pass argument directly to the C++ pre−linker
−c++ Force .c files to C++ mode
−c Do not link: stop at .obj
−cc Compile C++ files to .c and stop
−cf Skip the linking phase; call the locator directly
USAGE
Option Description
−f file Read arguments from file ("−" denotes standard input)
−gs Pass −cl to ieee166, set compatibility mode to 1
−ieee Produce an IEEE−695 output file
−ihex Produce an Intel hex output file
−lib directory Specify the location of user−built libraries
−libcan Link CAN library
−libfmtiovariant Link MEDIUM or LARGE printf( )/scan( ) library variants
−libmac Link MAC optimized runtime library
−noc++ Force C++ files to C mode
−nolib Do not link with the standard libraries
−nostl Do not link the STLport library
−nostlo Do not link the STLport extension library
−o file Specify the output file
−srec Produce an S−record output file
−tmp Keep intermediate files
−trap Use a floating point library with trap handler.
−notrap Use a floating point library without trap handler.
−v Verbose option: show commands invoked
−v0 Same as −v, but commands are not started
−wc++ Enable C and assembler warnings for C++ files
For more detailed information about the control program cc166, refer to
section cc166 in Chapter Utilities of the Cross−Assembler Linker/Locator,
Utilities User’s Manual.
• • • • • • • •
4−6 Chapter 4
4.2 COMPILER
The invocation syntax of the C166 compiler is:
The input file must have the extension .c or .i. Options are preceded by
a ’−’ (minus sign). Options cannot be combined after a single ’−’. After you
have successfully compiled your C sources, the compiler has generated
assembly files, with the extension .src (the default for a166).
When you use a UNIX shell (Bourne shell, C−shell), arguments containing
special characters (such as ’( )’ and ’?’) must be enclosed with "" or
escaped. The −? option (in the C−shell) becomes: "−?" or −\?.
Option Description
−? Display invocation syntax
−A[flag...] Enable/disable specific language extensions
−B[flag...] Control CPU problem bypasses
−Dmacro[=def] Define preprocessor macro
−E[m|c|i|p|x] Preprocess only
−F[flag...] Control floating point
−Ggroupname Use groupname to group near data sections
(−Mm, −Ml or −Mh only)
−Hfile Include file before starting compilation
−Idirectory Look in directory for include files
−M{t|s|m|l|h} Select memory model: tiny, small, medium,
large or huge
−Oflag... Control optimization
−P[d] Use user stack model stack frame (calling
convention) (to be used with special stack
USAGE
Option Description
−T[size],size2 In addition to the previous option, you can also
specify a threshold for intiialized data.
Default:infinite
−Umacro Remove preprocessor macro
−V Display version header only
−e Remove output file if compiler errors occur
−err Send diagnostics to error list file (.err)
−exit Alternative exit values
−f file Read options from file
−g[b|f|l|s] Enable symbolic debug information
−gso Enable GSO (acquire phase)
−gso=file.gso Enable GSO (allocation phase)
−iscale Specify scaling of interrupt vector table
(needs −x2):
0 − for no scaling (default)
1 − for x2
2 − for x4
3 − for x8
−mmem=size Specify memory size
−mmem=[size],n Specify maximum section size for mem and in
addition a threshold n for switching to a new
section
−misracn,n,... Enable individual MISRA C checks
−misrac−advisory−warnings Generate warnings for advisory MISRA C rules
−misrac−required−warnings Generate warnings for required MISRA C rules
−n Send output to standard output
−o file Specify name of output file
−r[name[,c][,regdef] Omit REGDEF or specify number (nr) of GPR
registers, the name of the register bank and c
for common
−s[i] Merge C−source code with assembly output
−t Display module summary and write section
information in output file
−u Treat all ’char’ variables as unsigned
−w[number] Suppress one or all warning messages
−wstrict Suppress warning messages 183,196 and 216
• • • • • • • •
4−8 Chapter 4
Option Description
−x[1|2|22|d] Allow all or some functions of the extended
architectures (to be used with ext or ext2
library sets)
−zpragma Identical to ’#pragma pragma’ in the C source
Description Options
Include options
Read options from file −f file
Include file before starting compilation −Hfile
Look in directory for include files −Idirectory
Preprocess options
Preprocess only −E[m|c|i|p|x]
Define preprocessor macro −Dmacro[=def]
Remove preprocessor macro −Umacro
Allocation control options
Use groupname to group near data sections −Ggroupname
(−Mm, −Ml or −Mh only)
Change class name, combine type or align −R{cl|co|al}mem=new
type of section for mem
Static allocation of automatics −S
Use size as threshold before allocating data in −Tsize
default data group (−Mm/−Ml/−Mh only)
In addition to the previous option, you can also −T[size],size2
specify a threshold for intiialized data.
Default:infinite
Specify memory size −mmem=size
Specify maximum section size for mem and in −mmem=[size],n
addition a threshold n for switching to a new
section.
USAGE
Description Options
Control optimization −Oflag...
Use user stack model stack frame (calling −P[d]
convention) (to be used with special stack
frame C library if ’d’ is not specified)
Enable GSO (acquire phase) −gso
Enable GSO (allocation phase) −gso=file.gso
Specify scaling of interrupt vector table −iscale
(needs −x2):
0 − for no scaling (default)
1 − for x2
2 − for x4
3 − for x8
Omit REGDEF or specify number (nr) of GPR −r[name[,c][,regdef]
registers, the name of the register bank and C
for common
Allow all or some functions of the extended −x[1|2|22|d]
architectures (to be used with ext or ext2
library sets)
Identical to ’#pragma pragma’ in the C source −zpragma
Language control options
Enable/disable specific language extensions −A[flag...]
Treat all ’char’ variables as unsigned −u
Output file options
Remove output file if compiler errors occur −e
Send output to standard output −n
Specify name of output file −o file
Merge C−source code with assembly output −s[i]
Diagnostic options
Display invocation syntax −?
Display version header only −V
Send diagnostics to error list file (.err) −err
Alternative exit values −exit
Enable symbolic debug information −g[b|f|l|s]
Enable individual MISRA C checks −misracn,n,...
Generate warnings for advisory MISRA C rules −misrac−advisory−warnings
• • • • • • • •
4−10 Chapter 4
Description Options
Generate warnings for required MISRA C rules −misrac−required−warnings
Display module summary and write section −t
information in output file
Suppress one or all warning messages −w[number]
Suppress warning messages 183, 196 and −wstrict
216
With options that can be set from within EDE, you will find a mouse icon
that describes the corresponding action.
USAGE
Compiler Use 4−11
−?
Option:
−?
Description:
Display an explanation of options at stdout.
Example:
c166 −?
• • • • • • • •
4−12 Chapter 4
−A
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Language.
In the Language extensions box, select Enable all extensions or select
Custom extensions and enable or disable one or more language
extensions.
−A[flags]
Arguments:
Optionally one or more language extension flags.
Default:
−A1
Description:
Control language extensions. Without the −A option all c166 language
extensions are enabled. −A without any flags, specifies strict ANSI mode;
all language extensions are disabled. This is equivalent with
−ACDFIKLMPSTUVWX and −A0.
Flags which are controlled by a letter, can be switched on with the lower
case letter and switched off with the uppercase letter. Note that the usage
of these options might have effect on code density and code execution
performance. The following flags are allowed:
• • • • • • • •
4−14 Chapter 4
u Default. Use type unsigned char for 0x80−0xff. The type of an octal
or hexadecimal constant, not suffixed with ’L’ or ’l’, is the first of the
corresponding list in which its value can be represented:
U Do not use type unsigned char for 0x80−0xff. The type of an octal
or hexadecimal constant, not suffixed with ’L’ or ’l’, is the first of the
corresponding list in which its value can be represented:
Compiler Use 4−15
v Allow type cast of an lvalue object with incomplete type void and
lvalue cast which does not change the type and memory of an lvalue
object.
Example:
void *p; ((int*)p)++; /* allowed */
int i; (char)i=2; /* NOT allowed */
V Default. A cast may not yield an lvalue, to conform strict ANSI−C mode.
Example:
To disable character arithmetic and C++ comments enter:
c166 −ACP test.c
• • • • • • • •
4−16 Chapter 4
−B
Option:
From the Project menu, select Project Options...
Expand the Application entry, expand the Processor entry and select
CPU Problem Bypasses and Checks. Enable or disable one or more
bypasses.
−B[flags]
Arguments:
Optionally one or more CPU functional problem bypass flags.
Default:
−Babdefhijklmnou
Description:
Enable/disable bypass for certain CPU functional problems. Without the −B
option the default is −Babdefhijklmnou (all bypasses off).
nofix_byte_write.
B Place two NOP instructions after each instruction which does a byte
write. These instructions are: ADDB, ADDCB, ANDB, CPLB, MOVB,
NEGB, ORB, SUBB, SUBCB, XORB. This is a bypass for CPU problem
S1, as described in Appendix C, CPU Functional Problems. This option
is equivalent to the pragma fix_byte_write.
Compiler Use 4−17
• • • • • • • •
4−18 Chapter 4
The instruction to delete the return address from the system stack is part of
the interrupt frame. If #pragma noframe was used, this instruction will
not be generated, you have to do it manually.
This is a bypass for many CPU problems, among which are problem 7,
problem 13, problem 17, CPU.2, CPU.11 and CPU.18. as described in
USAGE
Zc166sv1div
Do not generate unprotected division instructions. This is a bypass for
the CR105893 functional problem.
Zno_c166sv1div
Default. Allow generation of unprotected division instructions.
Zc166sv1ext
Do not jump from extend sequences. This is a bypass for the CR107092
functional problem.
Zno_c166sv1ext
Default. Jump from extend sequences.
Zc166sv1jbc
Do not use JBC and JNBS instructions, unless the first operand is a
GPR. This is a bypass for the CR105981 functional problem.
Zno_Zc166sv1jbc
Default. Always use JBC and JNBS instructions.
Zc166sv1trap
Insert a NOP before a TRAP instruction. This is a bypass for the
CR105619 functional problem.
• • • • • • • •
4−20 Chapter 4
Zno_c166sv1trap
Default. Do not insert a NOP before a TRAP instruction.
Zcpu_jmpra_cache
Fix broken program flow after not taken JMPR/JMPA instruction. This is
a bypass for the CR108400 functional problem.
Zno_cpu_jmpra_cache
Default. Do not fix broken program flow after not taken JMPR/JMPA
instruction.
Zcpu_reti_int
Fix lost interrupt while executing RETI instruction. This is a bypass for
the CR108342 functional problem.
Zno_cpu_reti_int
Default. Do not lost interrupt while executing RETI instruction.
Zinsert_div_mdl
Insert NOP instructions between DIV and the read of MDL. This is a
bypass for the CR108309 functional problem.
Zno_insert_div_mdl
Default. Do not insert NOP instructions between DIV and the read of
MDL.
Zinsert_mdlh_muldiv
Insert NOP instruction between write to MDL/MDH and DIVx/MULx
instruction. This is a bypass for the CR108904 functional problem.
Zno_insert_mdlh_muldiv
Default. Do not insert NOP instruction between write to MDL/MDH
and DIVx/MULx instruction.
Zmovbjb
Insert NOP instruction between an explicit byte−register modification
and a bit−jump that uses the opposite byte of the same word GPR.
Zno_movbjb
USAGE
−D
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Preprocessing.
In the Define user macro box, click on an empty Macro field and enter
a macro name. Optionally, click in the Definition field and enter a
definition.
−Dmacro[=def]
Arguments:
The macro you want to define and optionally its definition.
Description:
Define macro to the preprocessor, as in #define. If def is not given (’=’ is
absent), ’1’ is assumed. Any number of symbols can be defined. The
definition can be tested by the preprocessor with #if, #ifdef and #ifndef,
for conditional compilations. If the command line is getting longer than
the limit of the operating system used, you can use the −f option.
Example:
The following command defines the symbol NORAM as 1 and defines the
symbol PI as 3.1416.
c166 −DNORAM −DPI=3.1416 test.c
−U
• • • • • • • •
4−22 Chapter 4
−E
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Preprocessing.
Enable the Store preprocessor output (<file>.i) check box.
−E[m|c|i|p|x]
Description:
Run the preprocessor of the compiler only and send the output to stdout.
When you use the −E option, use the −o option to separate the output
from the header produced by the compiler.
Examples:
The following command preprocesses the file test.c and sends the
output to the file preout.
c166 −E −o preout test.c
The following command generates dependency rules for the file test.c
which can be used by mk166 (the C166/ST10 ’make’ utility).
c166 −Em test.c
test.obj : test.c
USAGE
Compiler Use 4−23
−e
Option:
EDE always removes the output file on errors.
−e
Description:
Remove the output file when an error has occurred. With this option the
’make’ utility always does the proper productions.
Example:
c166 −e test.c
• • • • • • • •
4−24 Chapter 4
−err
Option:
In EDE this option is not useful.
−err
Description:
Write errors to the file source.err instead of stderr.
Example:
To write errors to the test.err instead of stderr, enter:
c166 −err test.c
USAGE
Compiler Use 4−25
−exit
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Diagnostics.
Enable the Exit with error status even if only warnings were
generated check box.
−exit
Description:
Use alternative exit values in case warnings are reported. In case warnings
are reported, the compiler returns an exit value as if there were errors
reported.
• • • • • • • •
4−26 Chapter 4
−F
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Floating Point.
Enable or disable floating point options.
−F[flags]
Arguments:
Optionally a floating point control flag.
Default:
−Fs
Description:
Control floating point. The flags which are controlled by a letter can be
switched on with the lowercase letter and switched off with the uppercase
letter. −F used without flags is the same as using −Fs. Currently the
following flags are implemented.
S Default
USAGE
Compiler Use 4−27
−f
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Miscellaneous.
Add the option to the Additional options field.
−f file
Arguments:
A filename for command line processing. The filename "−" may be used to
denote standard input.
Description:
Use file for command line processing. To get around the limits on the size
of the command line, it is possible to use command files. These command
files contain the options that could not be part of the real command line.
Command files can also be generated on the fly, for example by the make
utility.
a. If the embedded quotes are only single or double quotes, use the
opposite quote around the argument. Thus, if a argument should
contain a double quote, surround the argument with single quotes.
b. If both types of quotes are used, we have to split the argument in such
a way that each embedded quote is surrounded by the opposite type
of quote.
• • • • • • • •
4−28 Chapter 4
Example:
"This has a single quote ’ embedded"
or
’This has a double quote " embedded’
or
’This has a double quote " and \
a single quote ’"’ embedded"
Example:
"This is a continuation \
line"
−> "This is a continuation line"
control(file1(mode,type),\
file2(type))
−>
control(file1(mode,type),file2(type))
Example:
Suppose the file mycmds contains the following lines:
−err
test.c
c166 −f mycmds
Compiler Use 4−29
−G
Option:
From the Project menu, select Project Options...
Expand the Application entry and select Memory Model.
Select the Medium or Large memory model.
Expand the C Compiler entry and select Allocation of Variable.
Enter a name in the Near data group name field.
−Ggroupname
Arguments:
The name for a group of near data sections.
Description:
With this option you can specify a name for a group of near data sections.
This option can only be used in the medium and large memory model.
• • • • • • • •
4−30 Chapter 4
−g
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Miscellaneous.
Enable the Generate high level language debug infomation check box.
Optionally, enable one or more of the other check boxes.
−g[b|f|l|s]
Description:
Add directives to the output files, incorporating symbolic information to
facilitate high level debugging. Note: using −g may turn off some peephole
optimizations.
With −gb ’bit’ type information and pointer behavior description is omitted
for compatibility with old IEEE−695 consuming tools.
With −gf high level language type information is also emitted for types
which are not referenced by variables. Therefore, this suboption is not
recommended.
Examples:
To add symbolic debug information to the output files, enter:
c166 −g test.c
USAGE
To add symbolic debug information to the output files but disable lifetime
information for all types, enter:
c166 −gl test.c
Compiler Use 4−31
−gso
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Miscellaneous.
Add the option to the Additional options field.
−gso
−gso=file.gso
Arguments:
The name of a .gso file with object allocation information for the final
build.
Description:
Enable the global storage optimizer. Please refer to section gso166 in
Chapter Utilities of the Cross−Assembler, Linker/locator, Utilities User’s
Manual for more details.
Examples:
c166 module.c −gso
• • • • • • • •
4−32 Chapter 4
−H
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Preprocessing.
Enter one or more filenames in the Include these files before source
field, separated by semicolons.
−Hfile
Arguments:
The name of an include file.
Description:
Include file before compiling the C source. This is the same as specifying
#include "file" at the first line of your C source.
Example:
c166 −Hstdio.h test.c
−I
USAGE
Compiler Use 4−33
−i
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Miscellaneous.
Select a scaling factor in the Interrupt vector scale box. Note that this
item is only available for XC16x/Super10 architectures (ext2).
−iscale
Arguments:
Specify scaling of the interrupt vector table.
Description:
The XC16x/Super10 architectures (ext2) allows a scalable interrupt vector
table. This option can be used to specify the scaling factor:
Depending on the size of an interrupt vector table entry, the compiler will
try to place as much code from an interrupt function inside the vector
table as possible.
This option can only be used in conjunction with the −x2 option.
Example:
c166 −x2 −i3 test.c
• • • • • • • •
4−34 Chapter 4
−I
Option:
From the Project menu, select Directories...
Add one or more directory paths to the Include Files Path field.
−Idirectory
Arguments:
The name of the directory to search for include file(s).
Description:
Change the algorithm for searching #include files whose names do not
have an absolute pathname to look in directory. Thus, #include files
whose names are enclosed in "" are searched for first in the directory of
the file containing the #include line, then in directories named in −I
options in left−to−right order. If the include file is still not found, the
compiler searches in a directory specified with the environment variable
C166INC. C166INC may contain more than one directory. Finally, the
directory ../include relative to the directory where the compiler binary
is located is searched. This is the standard include directory supplied with
the compiler package.
For #include files whose names are in <>, the directory of the file
containing the #include line is not searched. However, the directories
named in −I options (and the one in C166INC and the relative path) are
still searched.
Example:
c166 −I/proj/include test.c
−M
Option:
From the Project menu, select Project Options...
Expand the Application entry and select Memory Model.
In the Memory model box, select a memory model.
−Mmodel
Arguments:
The memory model to be used, where model is one of:
Default:
−Ms
Description:
Select the memory model to be used.
Example:
c166 −Ml test.c
• • • • • • • •
4−36 Chapter 4
−m
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Miscellaneous.
Add the option to the Additional options field.
−mmem=size
or
−mmem=[size],threshold
Arguments:
A memory space with a memory size. mem can be one of:
Description:
Specify the memory size (limits) to be used by the compiler for checking
static memory allocations of the module being processed. If the −t option
is used the size allocated by the module is reported, when c166 completes
compilation.
Compiler Use 4−37
When a section is equal or larger than the threshold size, the compiler will
switch to a new selection with the identical attributes and class for
subsequent allocations. The threshold size is memory dependent. A size of
zero means no threshold and this is the default. Specifying a threshold size
is particularly useful when compiling very big modules or when there are
too many initiialized variables in a single module.
Example:
−mPR=0,4000
is suitable for compiling modules with more than 64Kb code without
getting too many sections.
Likewise:
−mFB=0,4000
• • • • • • • •
4−38 Chapter 4
−misrac
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select MISRA C.
Select a MISRA C configuration. Optionally, in the MISRA C Rules entry,
specify the individual rules.
−misracn,n,....
Arguments:
The MISRA C rules to be checked.
Description:
With this option, the MISRA C rules to be checked can be specified. Refer
to Appendix A MISRA C for a list of supported and unsupported MISRA C
rules.
Example:
c166 −misrac9 test.c
−misrac−advisory−warnings /
−misrac−required−warnings
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select MISRA C.
Select Generate warnings instead of errors for required rules and/or
Generate warnings instead of errors for advisory rules.
−misrac−advisory−warnings
−misrac−required−warnings
Description:
With this option, you can change the error level for messages on the
required and advisory MISRA C rules to warnings. The default messages
are errors. Refer to Appendix A, MISRA C for a list of MISRA C rules.
Example:
c166 −misrac9 −misrac−required−warnings test.c
• • • • • • • •
4−40 Chapter 4
−n
Option:
−n
Description:
Do not create output files but send the output to stdout.
Example:
c166 −n test.c
The compiler sends the output (normally test.src) to stdout and does
not create the file test.src.
USAGE
Compiler Use 4−41
−O
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select an optimization level in the Optimization box.
−Oflags
Arguments:
One or more optimization flags.
Default:
−O1
Description:
Control optimization. By default c166 performs as much code
optimizations as possible (same as −O1).
Flags which are controlled by a letter, can be switched on with the lower
case letter and switched off with the uppercase letter. These options are
described together. An overview of the flags is given below.
• • • • • • • •
4−42 Chapter 4
n − NOP removal
o − code order rearranging
p − control flow optimization
q − use far pointer when converting to/from long
r − optimize allocation of register variables
s − use jump table for switch statement
t − turn tentative into defining occurrence
u − use user stack for interrupt
v − data flow analysis peephole (DFAP)
w − relax alias checking: assume no cross type aliasing
x − inline the intrinsic version of some C library functions
Example:
c166 −OAcdFhkLnprstVw test.c
USAGE
Compiler Use 4−43
−Onumber
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select an optimization level in the Optimization box.
−Onumber
Arguments:
A number in the range 0 − 3.
Default:
−O1
Description:
Control optimization. You can specify a single number in the range 0 − 3,
to enable or disable optimization. The options are a combination of the
other optimization flags:
Example:
To optimize for code size, enter:
c166 −O2 test.c
• • • • • • • •
4−44 Chapter 4
−Oa / −OA
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Relax all alias checking.
−Oa / −OA
Pragma:
noalias / alias
Default:
−OA
Description:
With −Oa you relax alias checking. If you specify this option, c166 will
not erase remembered register contents of user variables if a write
operation is done via an indirect (calculated) address. You must be sure
this is not done in your C code (check pointers!) before turning on this
option.
With −OA you specify strict alias checking. If you specify this option, the
compiler erases all register contents of user variables when a write
operation is done via an indirect (calculated) address.
Example:
An example is given in section 4.6 Alias in this chapter.
−Ob / −OB
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Allocation of Variables.
Enable or disable the Perform ’clearing’ of of non−initialized
static/public variables check box.
−Ob / −OB
Default:
−OB
Description:
With −Ob the compiler performs no ’clearing’ of non−initialized static and
public variables.
• • • • • • • •
4−46 Chapter 4
−Oc / −OC
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Common Subexpression Elimination (CSE).
−Oc / −OC
Default:
−Oc
Description:
With −Oc you enable CSE (common subexpression elimination). With this
option specified, the compiler tries to detect common subexpressions
within the C code. The common expressions are evaluated only once, and
their result is temporarily held in registers or on the user stack.
With −OC you disable CSE (common subexpression elimination). With this
option specified, the compiler will not try to search for common
expressions.
Example:
/*
* Compile with −OC −O0,
* Compile with −Oc −O0, common subexpressions are found
* and temporarily saved.
*/
char x, y, a, b, c, d;
void
main( void )
{
x = (a * b) − (c * d);
USAGE
−Od / −OD
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Constant and copy propagation.
−Od / −OD
Default:
−Od
Description:
With −Od you enable constant and copy propagation. With this option, the
compiler tries to find assignments of constant values to a variable, a
subsequent assignment of the variable to another variable can be replaced
by the constant value.
Example:
/*
* Compile with −OD −O0, ’i’ is actually assigned to ’j’
* Compile with −Od −O0, 15 is assigned to ’j’, ’i’ was
* propagated
*/
int i;
int j;
void
main( void )
{
i = 10;
j = i + 5;
}
• • • • • • • •
4−48 Chapter 4
−Oe / −OE
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Allocation of Variables.
Enable or disable the Allocate constant ROM data in near memory
check box.
−Oe / −OE
Default:
−OE
Description:
With −Oe you enable allocation of constant romdata ’CROM’ in paged data
sections (PDAT). This option is explained in section 3.2.5 Constant
Romdata Section Allocation.
These options only affect the code generation and section allocation in the
small memory model.
−Of / −OF
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Favor code size above execution speed.
−Of / −OF
Pragma:
speed / size
Default:
−OF
Description:
With −Of you produce fast code. Favour execution speed above code
density. Note that this option may increase code size.
With −OF you produce small code. Favour code density above execution
speed. If −OF is specified, c166 calls a run−time library routine for a
number of operations.
• • • • • • • •
4−50 Chapter 4
−Og / −OG
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Code recognition to generate optimal code for
expressions.
−Og / −OG
Default:
−Og
Description:
With −Og you enable expression recognition. Expressions for which very
efficient code can be generated are recognized and optimal code is
emitted.
−Oh / −OH
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Optimization of interrupt frame code for C
interrupt functions.
−Oh / −OH
Default:
−Oh
Description:
With −Oh you enable optimization of interrupt frame code for C interrupt
functions.
With −Oh you disable optimization of interrupt frame code for C interrupt
functions.
• • • • • • • •
4−52 Chapter 4
−Oj / −OJ
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Peephole optimizer (remove redundant code).
−Oj / −OJ
Default:
−Oj
Description:
With −Oj you enable peephole optimization. Remove redundant code.
−Ok / −OK
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Trace contents of registers for reuse without
reloading.
−Ok / −OK
Default:
−Ok
Description:
With −Ok you trace the contents of registers and try to reuse the registers
without reloading.
Example:
/*
* Compile with −OK −O0
* Compile with −Ok −O0, register contents tracing,
* one register is reused
*/
int a, c;
• • • • • • • •
4−54 Chapter 4
−Ol / −OL
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Generate fast loops (increases code size).
−Ol / −OL
Default:
−OL
Description:
With −Ol you enable fast loops. Duplicate the loop condition. Evaluate the
loop condition one time outside the loop, just before entering the loop,
and at the bottom of the loop. This saves one unconditional jump and
gives less code inside a loop.
With −OL you disable fast loops. The smallest code is generated for loops.
Example:
/*
* Compile with −OL −O0
* Compile with −Ol −O0, compiler duplicates the loop
* condition, the unconditional jump is removed.
*/
int i;
void
main( void )
{
do_something();
}
}
Compiler Use 4−55
−Om / −OM
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable the Instruction reordering check box.
−Om / −OM
Default:
−Om
Description:
With −Om you enable instruction reordering for ext2 targets.
• • • • • • • •
4−56 Chapter 4
−On / −ON
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable NOP removal by peephole optimizer.
−On / −ON
Default:
−On
Description:
With −On you enable NOP removal by peephole optimizer.
−Oo / −OO
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Code order rearranging in flow optimization.
−Oo / −OO
Default:
−Oo
Description:
With −Oo you enable code rearranging in flow optimization.. Try to move
(sub)expressions to get faster code. Some debuggers may have difficulties
with such options.
• • • • • • • •
4−58 Chapter 4
−Op / −OP
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Extra flow optimization pass on intermediate
representation.
−Op / −OP
Default:
−Op
Description:
With −Op you enable control flow optimizations on the intermediate code
representation, such as jump chaining and conditional jump reversal.
Example:
/*
* Compile with −OP −O0
* Compile with −Op −O0, compiler finds first time ’i’ is
* always < 10, the unconditional jump is removed.
*/
int i;
void
main( void )
{
for( i=0; i<10; i++ )
{
do_something();
}
USAGE
}
Compiler Use 4−59
−Oq / −OQ
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Convert pointer to/from long as far pointer.
−Oq / −OQ
Default:
−OQ
Description:
With −Oq you treat casting a pointer to long equal to casting a pointer to a
far pointer.
With −OQ you treat casting a pointer to long equal to casting a pointer to
a huge pointer.
• • • • • • • •
4−60 Chapter 4
−Or / −OR
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Automatic C register variable allocation.
−Or / −OR
Default:
−Or
Description:
With −Or you retrieve better code. Enable automatic C register variable
allocation, unless overruled by the −rnr option. If you do not want a
certain automatic to be allocated in a register (e.g. setjmp()/longjmp()
pair used), you can declare this variable to be volatile and yet still use the
−Or option!
−Os / −OS
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Use smart approach for switch statement (do not
force jump table).
−Os / −OS
Default:
−OS
Description:
With −Os you force the compiler to generate jump tables for switch
statements.
With −OS the compiler chooses the best switch method possible, jump
chain or jump table. So, with −OS a jump table can still be generated.
Example:
/*
* Compile with −OS, generate jump chain.
* Compile with −Os, generate jump table.
*/
int i;
void
main( void )
{
switch (i)
{
case 1: i = 0;
case 2: i = 1;
case 3: i = 2;
default: i = 3;
}
}
• • • • • • • •
4−62 Chapter 4
−Ot / −OT
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Allocation of Variables.
Select an item from the Tentative declarations box.
−Ot / −OT
Default:
−Ot (medium and large model)
−OT (tiny and small model)
Description:
With −Ot the compiler turns tentative declarations (such as ’int i;’) into
defining occurrences (e.g. ’int i=0;’).
−Ou / −OU
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Use user stack for interrupt functions.
−Ou / −OU
Default:
−OU
Description:
With −Ou the compiler uses the user stack instead of the system stack for
task switch (interrupt).
With −OU the compiler uses the system stack for task switch (interrupt).
• • • • • • • •
4−64 Chapter 4
−Ov / −OV
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable the Dataflow analysis peephole (DFAP) check box.
−Ov / −OV
Default:
−OV
Description:
With −Ov you enable the data flow analysis peephole (DFAP) optimizer.
With −OV you disable the data flow analysis peephole (DFAP) optimizer.
This optimizer uses data flow analysis in the peephole to optimize the
generated code. Unlike the normal peephole, DFAP has function scope
and can optimize when there are program flow changes involved.
Note that the use of DFAP may have a performance penalty on the
compiler itself. The DFAP optimizations are rather aggressive and can
make programs less debugable.
The −OV option overrules the pragmas dfap/nodfap in the source. So,
−OV (default) always disables the DFAP optimizer, no matter the pragma
settings in your source. With −Ov active you can control the DFAP
optimizer with the pragmas dfap/nodfap. If none of these pragmas are
present in your source, the default is dfap.
−Ow / −OW
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Relax cross type alias checking.
−Ow / −OW
Default:
−Ow
Description:
With −Ow the compiler relaxes alias checking, assuming there are no
pointer aliases for different type. For example, when a pointer to an int is
dereferenced (written), it is reasonable to assume that this cannot have any
effect on char objects.
• • • • • • • •
4−66 Chapter 4
−Ox / −OX
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Optimization.
Select Custom optimization in the Optimization box.
Enable or disable Inlining of some small C library functions.
−Ox / −OX
Default:
−OX
Description:
With −Ox you enable extra inlining of C library functions. It is only
worthwhile to inline C library functions which are very small and
frequently used. Therefore, only the following C library functions are
inlined in small and tiny memory model. Inlining C library functions is not
conform the ANSI−C standard. Extra inlining will be disabled when
compiling with inlining allowed, see option −Ai/−AI. Remember that you
cannot take the address of an inline function and you cannot define one
of these functions yourself when −Ox is active.
The next C library functions are inlined for tiny and small memory model:
With −OX you disable extra inlining of the C library functions mentioned
above.
USAGE
Compiler Use 4−67
−o
Option:
−o file
Arguments:
An output filename. The filename may not start immediately after the
option. There must be a tab or space in between.
Default:
Module name with .src suffix.
Description:
Use file as output filename, instead of the module name with .src suffix.
Special care must be taken when using this option, the first −o option
found acts on the first file to compile, the second −o option acts on the
second file to compile, etc.
Example:
When specified:
c166 file1.c file2.c −o file3.src −o file2.src
two files will be created, file3.src for the compiled file file1.c and
file2.src for the compiled file file2.c.
• • • • • • • •
4−68 Chapter 4
−P
Option:
From the Project menu, select Project Options...
Expand the Application entry and select Memory Model.
Enable the Use user stack for return addresses check box.
−P[d]
Description:
Enable user stack model. See section 3.2.2, User Stack Model for details.
Requires linking with user stack model library unless −Pd is specified.
−R
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Miscellaneous.
Add the option to the Additional options field.
−R{cl|co|al}mem=new
Pragma:
class / combine / align
Arguments:
mem is a two letter abbreviation indicating the memory area of a C
program. mem can be one of:
mem Description
BI bits
CO strings / floating point
BA bitwords
NB near data
FB far data
XB shuge data
HB huge data
PR functions
SB system data
IR internal ramdata
new is the new class name, combine type or align type for mem.
Description:
The compiler defaults to a section naming convention as described in the
section 3.2.3, Section Allocation. With this option you can change the class
name, combine type or align type of a compiler generated section for
mem.
• • • • • • • •
4−70 Chapter 4
−r
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Miscellaneous.
Enter the register definition in the Register usage field.
Optionally, enter a register name in the Register bank name field. If the
bank must be ’common’ enable the Make register bank common check
box.
−r[name[,c]][,regdef]
Pragma:
regdef
Arguments:
name is the name of the register bank for this module.
Description:
With the −r option you can specify the name of the register bank, and
optionally if this register bank must be ’common’ (c) or not.
Rx[−Ry]
When only the name and optional common flag are used in the −r option,
a full register bank consisting of R0−R15 is the default.
• • • • • • • •
4−72 Chapter 4
When the −r option is used without any arguments, the REGDEF directive
for this module will be omitted. Note that register banks originating from
the _using() function qualifier will still be generated. Interrupt functions
that do not have the _using() qualifier use the module’s register bank.
Since this bank will be omitted, no code will be generated in the interrupt
frame to switch register banks.
With #pragma regdef the used register set can be redefined. A pragma
setting will remain active until the next #pragma regdef. The syntax for
regdef is the same as in the −r option. As an alternative the number of
registers, starting from R0 may be specified.
When different register sets are used for different functions, the compiler
will combine the register sets for the same register bank.
When the register set that the compiler can use for code generation is
limited this can result in larger code. When the register set is too small the
compiler may not be able to generate code at all. In this case assertion
errors can be expected. This is a known restriction and the register set
should be increased prior to reporting the assertion error.
Examples:
−rmybank
This option causes all functions (non−interrupt and interrupt) to use the
registers from the given set.
USAGE
Compiler Use 4−73
The functions ISR0 and ISR1 will use register bank SOMEBANK. Function
ISR0 will only use registers R0 and R1. Function ISR1 will only use
registers R0 and R2. The compiler will combine the used register sets and
generates the following REGDEF directive:
SOMEBANK REGDEF R0−R2
Function ISR2 will only use the registers R0 and R3. Since #pragma
regdef without arguments is used, the compiler will not generate a
REGDEF directive, nor will code be generated to perform a context switch.
−rcomnbank,c,R0,R1,R2−R5
This option declares a common register bank with the name "comnbank":
COMNBANK COMREG R0−R5
• • • • • • • •
4−74 Chapter 4
−S
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Allocation of Variables.
Enable the Static allocation of automatics (instead of user stack)
check box.
−S
Pragma:
static
Description:
All functions of the C module are compiled using static memory for
non−register function automatics. This option can be useful for non
recursive applications.
−s
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Output.
Enable the Merge C source code with assembly output check box.
−s [ i ]
Pragma:
source
Description:
Merge C source code with generated assembly code in output file.
When the additional ’i’ sub option is specified, the C source of the include
files will also be merged.
Example:
c166 −s test.c
NAME TEST_C
; test.c 1 int i;
; test.c 2
; test.c 3 int
; test.c 4 main( void )
; test.c 5 {
PUBLIC _main
TEST_1_PR SECTION CODE WORD PUBLIC ’CPROGRAM’
_main PROC FAR
• • • • • • • •
4−76 Chapter 4
−T
Option:
From the Project menu, select Project Options...
Expand the Application entry and select Memory Model.
Select the Medium or Large memory model.
Expand the C Compiler entry and select Allocation of Variables.
Enter a size in the Threshold for automatic near data allocation field.
−Tsize
or
−T[size], size2
Arguments:
The maximum threshold size in bytes (size). Or the threshold size for
initialized variables (size2)
Default:
−T256
Description:
With this option you can specify a maximum size (threshold) for allocating
data in default data sections. This is useful when you want to limit the size
of the default data group. You can use this option in the medium and large
model only.
Example:
To allocate values of maximum 128 bytes long in default far data sections,
USAGE
enter:
c166 −T128 −Mm test.c
−t
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Output.
Enable the Display module summary check box.
−t
Description:
With this option the C compiler produces totals (a module summary) on
stdout and writes section information in an output file.
Example:
c166 −t test.c
MODULE SUMMARY
• • • • • • • •
4−78 Chapter 4
−U
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Preprocessing.
Undefine one or more predefined macros by disabling the corresponding
check box.
−Uname
Arguments:
The name macro you want to undefine.
Description:
With this option you can undefine an earlier defined macro name as with
#undef. This option is for example useful to undefine predefined macros.
__TIME__ "hh:mm:ss"
Example:
To undefine the predefined macro _C166, enter:
c166 −U_C166 test.c
USAGE
−D
Section 3.5, Predefined Macros.
Compiler Use 4−79
−u
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Language.
Enable the Treat all ’char’ variables unsigned check box.
−u
Description:
Treat ’character’ type variables as ’unsigned character’ variables. By default
char is the same as specifying signed char. With −u char is the same
as unsigned char.
Example:
With the following command char is treated as unsigned char:
c166 −u test.c
• • • • • • • •
4−80 Chapter 4
−V
Option:
−V
Description:
Display version information.
Example:
c166 −V
TASKING C166/ST10 C compiler vx.yrz Build nnn
Copyright years Altium BV Serial# 00000000
USAGE
Compiler Use 4−81
−w
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Diagnostics.
Enable one of the options Display all warnings, Suppress all
warnings, or Suppress only certain warnings and enter the numbers,
separated by commas, of the warnings you want to suppress.
−w[num]
−wstrict
Arguments:
Optionally the warning number to suppress.
Description:
−w suppress all warning messages. −wnum only suppresses the given
warning. −wstrict suppresses extensive warnings 183, 196 and 216.
Example:
To suppress warning 135, enter:
c166 file1.c −w135
• • • • • • • •
4−82 Chapter 4
−x
Option:
From the Project menu, select Project Options...
Expand the Application entry and select Processor.
From the Processor box, select a processor or select User Defined.
If you selected User Defined, expand the Processor entry, select User
Defined Processor and make your changes.
−x[1|2|22|d]
Arguments:
Optional features:
Description:
The −x option selects the processor architecture.
Example:
To use an Infineon XC167, enter:
c166 −x2 file.c
• • • • • • • •
4−84 Chapter 4
−z
Option:
From the Project menu, select Project Options...
Expand the C Compiler entry and select Miscellaneous.
Add the option to the Additional options field.
−zpragma
Arguments:
A pragma as listed in section 4.5, Pragmas.
Description:
With this option you can give a pragma on the command line. This is the
same as specifying ’#pragma pragma’ in the C source. Dashes (’−’) on the
command line in the pragma are converted to spaces.
Example:
To issue a ’#pragma autobita 2’ using the command line, enter:
c166 −zautobita−2 file.c
PC:
c166 ..\..\source\test.c
UNIX:
c166 ../../source/test.c
c166 first searches in the directory ..\source (../source for UNIX) for
include files.
If you compile a source file in the directory where the file is located (c166
test.c), the compiler searches for include files in the current directory.
This first step is not done for include files enclosed in <>.
PC:
c166 −I..\include message.c
UNIX:
c166 −I../include message.c
• • • • • • • •
4−86 Chapter 4
PC:
set C166INC=..\include
c166 message.c
UNIX:
4. When an include file is not found with the rules mentioned above, the
compiler tries the subdirectory include, one directory higher than the
directory containing the c166 binary. For example:
PC:
UNIX:
When you specify more than one directory to the environment variable
C166INC, you have to use one of the following separator characters:
PC:
; , space
UNIX:
: ; , space
• • • • • • • •
4−88 Chapter 4
4.5 PRAGMAS
According to ANSI (3.8.6) a preprocessing directive of the form:
#pragma pragma−token−list new−line
When the pragma text consists of multiple tokens, they can be separated
on the command line with dashes. For example,
#pragma class mem=name
would become
−zclass−mem=name
USAGE
alias
Default. Same as −OA option. Perform strict alias checking. See also
section 4.6 Alias.
Compiler Use 4−89
noalias
Same as −Oa option. Relax alias checking.
align32
When #pragma align32 is used:
• long data types are aligned on 32−bit boundaries (not for stack
objects)
• struct/union data types are aligned on 32−bit boundaries (not for
stack objects)
• the size of a struct/union will always be a multiple of 4 bytes
• the _packed keyword overrules the pragma
• struct/union members of type long or bit−field are 32−bit aligned.
Packing of bit−field members will still be done according to the
base type (int). Meaning that a bit−field will be aligned to the next
32−bit boundary if the bit−field crosses a 16−bit boundary, or if the
bit−field is located at a 16−bit boundary.
struct s /* offset */
{
int bf1 : 15; /* 0 bits */
int bf2 : 2; /* 32 bits */
int bf3 : 2; /* 34 bits */
int : 12;
int bf4 : 5; /* 64 bits */
};
A bit−field of size 0 will align any struct member to the next 32−bit
boundary.
noalign32
Default. 16−bit alignment.
suspend_align32
resume_align32
Whith these pragmas you can temporarily suspend/resume the #pragma
align32.
• • • • • • • •
4−90 Chapter 4
asm [args]
Insert the following (non preprocessor lines) as assembly language source
code into the output file. The inserted lines are not checked for their
syntax. The args are an interface to the C language. See section 3.11 Inline
Assembly for details.
asm_noflush
Same as asm, except that the peephole optimizer does not flush the code
buffer and assumes register contents remain valid.
endasm [args]
Switch back to the C language. With the args variables can be passed to
the C language. See section 3.11 Inline Assembly for details.
autobita threshold
Move chars, (long) ints and struct/unions which are smaller than or equal
to the threshold to bitaddressable memory. The declaration may not
contain any memory modifiers. The default threshold value is set to zero
bytes.
Pointers, arrays and function return values are not moved to bitaddressable
memory. Local variables are only moved to bitaddressable memory when
declared static or compiled with the −S option. See also bita in section
3.2.1.9.
autobitastruct threshold
Move struct/unions which contain at least one bitfield with length 1 to
bitaddressable memory. This only applies for structs/unions which are
smaller than or equal to the specified threshold. The declaration may not
contain any memory modifiers. The default threshold value is set to 4
bytes.
Pointers, arrays and function return values are not moved to bitaddressable
memory. Local structs/unions are only moved to bitaddressable memory
when declared static or compiled with the −S option. See also bita in
USAGE
section 3.2.1.9.
automatic
Default. Use stack approach for non register function automatics. Support
recursion.
Compiler Use 4−91
static
Use static memory for non register function automatics. Same as −S option.
See section 3.6.1 Static Approach of Function Automatics.
align mem=atype
Same as −Ral option. Use atype as align type for section of area mem.
class mem=name
Same as −Rcl option. Use name as class for section of area mem.
combine mem=ctype
Same as −Rco option. Use ctype as combine type for section of area mem.
cse suspend
cse resume
When the CSE optimization is switched on (−Oc) then a sequence of
#pragma cse suspend
#pragma cse resume
has the effect that expressions in between are not part of the CSE
optimization. The pragmas have function scope and do not have any effect
unless the CSE optimization is switched on. The CSE optimization for
expressions can be switch off in a single function by placing
#pragma cse suspend
custack
Default. Generate a ’C166_US’ section estimating the stack usage of a
module.
nocustack
Suppress the user stack estimation.
clear
Default. Same as −OB option. Perform ’clearing’ of non−initialized
static/public variables. See section 3.9 Non−Initialized Variables for more
information.
• • • • • • • •
4−92 Chapter 4
noclear
Same as −Ob option. No ’clearing’ of non−initialized static/public variables.
See section 3.9 Non−Initialized Variables for more information.
default_attributes
Default. Use default section attributes. See the section 3.2.3 Section
Allocation for details.
save_attributes
Save the current section attributes. See the section 3.2.3 Section Allocation
for details about changing section attributes.
restore_attributes
Restore the last saved section attributes. A warning is issued when no
section attributes were saved. See the section 3.2.3 Section Allocation for
details about changing section attributes.
dfap
Default. Enable the data flow analysis peephole. The −Ov option must be
active for this pragma to work.
nodfap
Disable the data flow analysis peephole.
eramdata
Allocate all non automatic initialized variables in both ROM and RAM. The
RAM data section has the class name ’CINITERAM’ (unless part of the
default data group where all sections must have the same class name).
Copy from ROM to RAM at startup (transparent for the user). See section
3.8 Initialized Variables for details.
iramdata
Default. Allocate all non automatic initialized variables in both ROM and
USAGE
RAM. The RAM data section has the class name ’CINITIRAM’ (unless part
of the default data group where all sections must have the same class
name). Copy from ROM to RAM at startup (transparent for the user). See
section 3.8 Initialized Variables for details.
Compiler Use 4−93
romdata
Allocate all non−automatic variables in ROM only. The ROM data section
can have the class names ’CROM’, ’CNEARROM’, ’CFARROM’ or
’CHUGEROM’ (unless part of the default data group where all sections
must have the same class name). See section 3.8 Initialized Variables for
details.
fix_byte_write
For all code following this pragma the compiler generates two NOP
instructions after each instruction which does a byte write. These
instructions are: ADDB, ADDCB, ANDB, CPLB, MOVB, NEGB, ORB,
SUBB, SUBCB, XORB. This is a bypass for the erroneous byte forwarding
on internal RAM problem. This pragma is equivalent to the new command
line option −BB.
nofix_byte_write
Default. For all code following this pragma the compiler does not generate
two NOP instructions after each instruction which does a byte write. This
pragma is equivalent to the new command line option −Bb. By default the
generation of two extra NOP instructions after a byte write operation is
disabled.
fragment
fragment resume
fragment continue
Controls fragmentation of code memory. See section 3.2.4, Code Memory
Fragmentation for details.
global_dead_store_elim
Default. Enable dead store elimination on global and local static variables.
• • • • • • • •
4−94 Chapter 4
no_global_dead_store_elim
Disable dead store elimination on global and local static variables.
Example:
void func (void)
{
enable=1;
while ( !activity );
enable=0;
}
The first assignment will not be optimized away when this pragma was
used.
indirect_access [([_]near)]address[−address],...
With this pragma you can specify the address (ranges) that have to be
accessed using an indirect addressing mode. When a near address is
specified the near or _near keyword must be added, otherwise the
address will be interpreted as _huge. In the segmented memory models,
_near, _xnear and _system/_iram/_bita are all separate near memory
spaces. The correct DPP−number must be included in the address.
m166include "include−file"
This pragma is intended to be used together with user defined intrinsics.
This pragma will generate a:
$INCLUDE( header.asm )
Compiler Use 4−95
control in the output file. This header file can be used to include the
definition of macro (functions) emitted by the compiler when user defined
intrinsics are used.
Example:
#pragma m166include "header.asm"
macro
Default. Perform macro expansion.
nomacro
Do not perform macro expansion.
noframe
Do not emit the interrupt frame code for C interrupt functions. See the
section 3.12 Interrupt for details.
preserve_mulip
Make the MULIP bit available for use inside interrupt handlers by
saving/restoring PSW in interrupt function prologue/epilogue respectively.
public
Default. Public C variables have task scope. See section 3.3 Task Scope for
details.
global
Public C variables have application scope. See section 3.3 Task Scope for
details.
regdef [regdef]
See −r option and section 3.12 Interrupt for details.
reorder
Enable instruction reordering for the XC16x/Super10 architecture (−x2
option).
noreorder
Disable instruction reordering for the XC16x/Super10 architecture.
• • • • • • • •
4−96 Chapter 4
savemac
Save MAC SFRs in an interruptframe. You must use this pragma together
with the −xd, −x2 or −x22 option.
This pragma will not save anything if used together with the noframe
pragma.
nosavemac
Do not save MAC SFRs in an interrupt frame. You must use this pragma
together with the −xd, −x2 or −x22 option
autosavemac
Save MAC registers in an interrupt frame only when needed. You must use
this pragma together with the −xd, −x2 or −x22 option. If you use this
pragma in conjuction with #pragma noframe, nothing will be saved.
source
Same as −s option. Enable mixing C source with assembly code.
nosource
Default. Disable generation of C source within assembly code.
size
Default. Same as −OF option. Favour code density above execution speed.
speed
Same as −Of option. Favour execution speed above code density.
stringmem memory−space
Controls the allocation of string constants. See section 3.10 Strings for
details.
switch_force_table
USAGE
switch_smart
Default. Same as −OS option. Try to use jump table if it is worthwhile. See
section 3.14 Switch Statement for more details.
switch_tabmem_far
Place jump tables for the small memory model in far ROM. The ROM
section where the jump tables are placed have class ’CFARROM’. See
section 3.2.5 Constant Romdata Section Allocation for details.
switch_tabmem_near
Place jump tables for the small memory model in near ROM. The ROM
section where the jump tables are placed have class ’CNEARROM’. See
section 3.2.5 Constant Romdata Section Allocation for details.
switch_tabmem_default
Default. Jump tables are located as specified by the −Oe/−OE option. See
section 3.2.5 Constant Romdata Section Allocation for details.
volatile_union
Treat unions as if declared volatile, prohibiting certain optimizations
which clash with non−ANSI use of unions: Sometimes a union is used for
converting data by writing one member but reading back another.
novolatile_union
Default. Treat unions conform their definition.
• • • • • • • •
4−98 Chapter 4
4.6 ALIAS
By default the compiler assumes that each pointer may point to any object
created in the program, so when any pointer is dereferenced, all register
contents are assumed to be invalid afterwards.
Example 1:
int i;
void
func( )
{
char * p;
char c;
char d;
if( i )
p = &c;
else
p = &d;
c = 2;
d = 3;
Example 2:
int i;
void
func( char *p )
{
char c;
char d;
c = 2;
d = 3;
Example 3:
int array[2];
main()
{
array[0] = 1;
array[1] = −1;
• • • • • • • •
4−100 Chapter 4
Most of the actual compiler limits are determined by the amount of free
memory in the host system. In this case a ’D’ (Dynamic) is given between
parentheses. Some limits are determined by the size of the internal
compiler parser stack. These limits are marked with a ’P’. Although the size
of this stack is 200, the actual limit can be lower and depends on the
structure of the translated program.
• 15 nesting levels of compound statements, iteration control
structures and selection control structures (P > 15)
• 8 nesting levels of conditional inclusion (50)
• 12 pointer, array, and function declarators ( in any combinations )
modifying an arithmetic, a structure, a union, or an incomplete type
in a declaration (12)
• 31 nesting levels of parenthesized declarators within a full
declarator (P > 31)
• 32 nesting levels of parenthesized expressions within a full
expression (P > 32)
• 31 significant characters in an external identifier (full ANSI−C
mode),
500 significant characters in an external identifier (non ANSI−C
mode)
• 511 external identifiers in one translation unit (D)
• 127 identifiers with block scope declared in one block (D)
• 1024 macro identifiers simultaneously defined in one translation unit
(D)
• 31 parameters in one function declaration (D)
• 31 arguments in one function call (D)
USAGE
• • • • • • • •
4−102 Chapter 4
USAGE
CHAPTER
COMPILER
DIAGNOSTICS
5
5−2
DIAGNOSTICS
5
CHAPTER
Chapter 5
Compiler Diagnostics 5−3
5.1 INTRODUCTION
c166 has three classes of messages: user errors, warnings and internal
compiler errors.
The error numbers and warning numbers are divided in two groups. The
frontend part of the compiler uses numbers in the range 0 to 499, whereas
the backend (code generator) part of the compiler uses numbers in the
range 500 and higher. Note that most error messages and warning
messages are produced by the frontend.
If a (non fatal) user error occurs during compilation, c166 displays the C
source line that contains the error, the error number and the error message
on the screen. If the error is generated by the code generator, the C source
line displayed always is the last line of the current C function, because
code generation is started when the end of the function is reached by the
front end. However, in this case, c166 displays the line number causing
the error before the error message. c166 always generates the error
number in the assembly output file, exactly matching the place where the
error occurred.
void
err()
{
b = 1; /* OK */
b += 1; /* Not allowed */
}
test.c: 8: }
E 539: (line 7) ’+=’ not allowed on bit type
• • • • • • • •
5−4 Chapter 5
So, when a compilation is not successful, the generated output file is not
accepted by the assembler, thus preventing a corrupt application to be
made (see also the −e option).
The last class of messages are the internal compiler errors. The following
format is used:
S number: assertion failed − please report
These errors are caused by failed internal consistency checks and should
never occur. However, if such a ’SYSTEM’ error appears, please report the
occurrence to TASKING, using a Problem Report form. Please include a
small C program causing the error.
c166 returns an exit status to the operating system environment for testing.
For example,
in a BATCH−file you can examine the exit status of the program executed
with ERRORLEVEL:
c166 −s %1.c
IF ERRORLEVEL 1 GOTO STOP_BATCH
Compiler Diagnostics 5−5
In a bourne shell script, the exit status can be found in the $? variable, for
example:
c166 $*
case $? in
0) echo ok ;;
1|2|3) echo error ;;
esac
The exit status of c166 is one of the numbers of the following list:
• • • • • • • •
5−6 Chapter 5
I information
E error
F fatal error
S system error
W warning
Frontend
F 1 evaluation expired
Your product evaluation period has expired. Contact your local
TASKING office for the official product.
E 5 no source modules
You must specify at least one source file to compile.
DIAGNOSTICS
E 14 ’;’ inserted
An expression statement needs a semicolon. For example, after ++i in
{ int i; ++i }.
• • • • • • • •
5−8 Chapter 5
char *s = #S ; // error
E 26 undefined control
A control line (line with a ’#identifier’) must contain one of the known
preprocessor directives.
Compiler Diagnostics 5−9
W 28 empty program
The source file must contain at least one external definition. A source
file with nothing but comments is considered an empty program.
#define B(b) 1
int j = B(1; /* error */
E 33 "name" redefined
The given identifier was defined more than once, or a subsequent
declaration differed from a previous one. The following examples
generate this error:
int i;
char i; /* error */
main()
{
}
• • • • • • • •
5−10 Chapter 5
main()
{
int j;
int j; /* error */
}
I 44 in initializer "name"
Informational message when checking for a proper constant initializer.
E 47 missing operator
An operator was expected in the expression.
E 52 missing operand
An operand was expected.
• • • • • • • •
5−12 Chapter 5
f()
{
lab1:
lab1: /* error */
}
E 61 type clash
The compiler found conflicting types. For example, a long is only
allowed on int or double, no specifiers are allowed with struct,
union or enum. The following is an example of this error:
E 63 "name" redeclared
The specified identifier was already declared. The compiler uses the
second declaration. The following is an example of this error:
struct T { int i; };
struct T { long j; }; /* error */
• • • • • • • •
5−14 Chapter 5
E 90 #error message
The message is the descriptive text supplied in a ’#error’ preprocessor
directive.
• • • • • • • •
5−16 Chapter 5
• • • • • • • •
5−18 Chapter 5
• • • • • • • •
5−20 Chapter 5
• • • • • • • •
5−22 Chapter 5
• • • • • • • •
5−24 Chapter 5
main()
{
int i;
f( i ); /* i is not a struct */
}
• • • • • • • •
5−26 Chapter 5
void f(void);
main()
{
int i;
i = (int)f(); /* error */
}
}
main()
{
a();
}
• • • • • • • •
5−28 Chapter 5
main()
{
int b;
b = a(); /* error */
};
int a;
int f(void)
{
int i;
if ( a )
{
i = 0; /* statement not reached */
}
return i; /* warning */
}
Compiler Diagnostics 5−29
• • • • • • • •
5−30 Chapter 5
Note that this warning is formally correct, but not very useful is most
cases. Consider the following situation:
unsigned int a;
a = 0x1234u & ~0x00FFu;
When you compile this example with option −Au (default), this
warning appears. Here the type of the unary ’~’ operator is int.
Constant folding optimizes the expression to:
DIAGNOSTICS
In most cases you can safely switch off this warning (−w196 or
−wstrict).
• • • • • • • •
5−32 Chapter 5
main()
{
int i;
i = f(i); /* error */
i = f(); /* OK */
}
main()
{
int i;
i = f(i,i); /* error, one too many */
i = f(i); /* OK */
}
void f(void)
{
*p;
return;
}
• • • • • • • •
5−34 Chapter 5
Backend
W 501 initializer was truncated
Some most significant bits are non−zero. Due to a cast, the most
significant bits are stripped off.
for bit are: static, public or extern. See also section 3.4.3, The Bit Type.
• • • • • • • •
5−36 Chapter 5
E 562 it is not allowed to change the align type for internal ram data
sections
Internal ram data sections are always IRAM addressable.
E 568 more than 16K initialized data for ’name’: use ’shuge’ or use the
−m option
more than 64K initialized data for ’name’: use ’huge’ or use the
−m option
Declare explicitiy initialized variables in shuge or huge memory when
the total size of those variables in a module exceeds 16K or 64K
respectively. An alternative is to omit the initializer and to initialize the
variable at run−time as far as needed. cstartx.asm clears variables
without explicit initializer automatically.
−m option
• • • • • • • •
5−38 Chapter 5
E 589 interrupt function must have void result and void parameter list
A function declared with interrupt(n) may not accept any
arguments and may not return anything.
• • • • • • • •
5−40 Chapter 5
• • • • • • • •
5−42 Chapter 5
• • • • • • • •
5−44 Chapter 5
you to allocate variables in DPP1 which shares this page with the user
stack. In the tiny/small memory model the user stack is located in
_near memory where normal data is also located. Hence this memory
space is already shared. Therefore there is no need for an _xnear
memory space in the tiny/small memory model.
etc.
• • • • • • • •
5−46 Chapter 5
The object can never be located at an odd address. Despite this, the
compiler sometimes generates code to access the object as if it were
unaligned. This will lead to an unneccessary increase of code size.
Therefore, you should remove the _noalign qualifier when this
warning is generated. Whether or not the compiler generates unaligned
proof code is undefined in this case.
Sample warnings:
automatic/parameter ’p’ is always aligned
return value of ’func’ is always aligned
Compiler Diagnostics 5−47
F 882 common register bank can consist of one range only and must
start with R0
Adjust the register bank definition accordingly. See the −r option for
the correct syntax.
W 884 common register bank can consist of one range only and must
start with R0 −− extended
Adjust the register bank definition accordingly. See the −r option for
the correct syntax.
• • • • • • • •
5−48 Chapter 5
LIBRARIES
6
6−2
LIBRARIES
6
CHAPTER
Chapter 6
Libraries 6−3
6.1 INTRODUCTION
c166 comes with libraries per memory model and with header files
containing the appropriate prototype of the library functions. The library
functions are also shipped in source code (C or assembly).
Four sets of libraries are delivered to meet specific requirements for the
various C16x/ST10, XC16x/Super10 microcontroller architectures. These
sets are located in separate directories:
ext The extended libraries are needed for the C16x/ST10 and
similar architectures. These architectures feature the extended
instruction set, extended special function registers, 24−bit
addressing and extended PEC pointers. Use these libraries in
conjunction with the compiler option −x or −x1.
Another four sets of libraries are delivered to meet specific User Stack
Model requirements for the various microcontroller architectures. These
libraries must be used in conjunction with the additional compiler option
−P. These sets are located in separate directories:
• • • • • • • •
6−4 Chapter 6
c166?[s].lib C library. The optional [s] stands for single precision floating
point (all floating point arithmetic is in single precision
instead of ANSI double precision).
fp166?[t].lib
Floating point library. The optional [t] stands for trapping
floating point (using boundary checking and the floating
point trap mechanism).
rt166?[s][m].lib
Run−time library. The optional [s] stands for single precision
floating point. The optional [m] stands for MAC optimized
(use MAC instructions in some basic operations for
optimization).
The question mark ’?’ in these library names must be replaced by a letter
representing the selected memory model:
t tiny
s small
m medium
l large
h huge
Because c166 generates assembly code (and not object code) it adds a
leading underscore to the names of (public) C variables to distinguish
these symbols from 80166 registers. So if you use a function with a leading
underscore, the assembly label for this function contains two leading
underscores. This function name could cause a name conflict (double
defined) with one of the run−time library functions. Therefore, you should
avoid names starting with an underscore. Note that ANSI states that it is
not portable to use names starting with an underscore for public C
variables and functions, because results are implementation defined.
Libraries 6−5
The code sections of the C166 library have the class ’CLIBRARY’,
’SHAREDCLIB’, ’RTLIBRARY’ or ’SHAREDRTLIB’ allowing the library to be
allocated in a special memory area via the CLASSES control of l166.
t tiny
s small
m medium
l large
h huge
These I/O formatter libraries are included in all library sets. You can use
the control program options −libfmtiom and −libfmtiol to select the
MEDIUM and LARGE I/O formatter libraries.
• • • • • • • •
6−6 Chapter 6
To improve the code size and execution speed, the compiler supports the
option −F to force single precision floating point usage. If you use −F, a
float variable passed as an argument is no longer promoted to double
when calling a variable argument function or an old style K&R function,
and the type double is treated as float. It is obvious that this affects the
whole application (including libraries). Therefore special single precision
versions of the floating point libraries are now delivered with the package.
When using −F, these libraries must be used. It is not possible to mix C
modules created with the −F option and C modules which are using the
regular ANSI approach.
For compatibility with the old −F option, the −Fc option is introduced.
This option only treats floating point constants (having no suffix) as float
instead of double.
CAN libraries are supplied with the 32−bit Windows 95/98/NT version of
this product. The file ap292201.pdf describes the usage of these
libraries. This file is located in the doc/pdf directory.
See section 6.7, CAN Library Interface Description, for a description of the
CAN library routines.
The can166?.Lib CAN libraries are available for all memory models in the
ext, extp, uext and uextp library sets. These libraries can be rebuilt
using the corresponding makefiles.
Libraries 6−7
<assert.h> assert
<can_ext.h>
CAN libraries function prototypes: check_busoff_16x,
check_mo_16x, check_mo15_16x, def_mo_16x, init_can_16x,
ld_modata_16x, rd_modata_16x, rd_mo15_16x, send_mo_16x
<canr_16x.h>
Definitions of CAN module control registers. No C functions.
<iso646.h>
Alternative spellings. No C functions.
<math.h> acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
frexp, hypot, hypotf, hypotl, ldexp, log, log10, modf, pow,
sin, sinh, sqrt, tan, tanh
• • • • • • • •
6−8 Chapter 6
<stdlib.h> abort, abs, atexit, atof, atoi, atol, bsearch, calloc, div, exit,
fcalloc, ffree, fmalloc, frealloc, free, getenv, hcalloc, hfree,
hmalloc, hrealloc, labs, ldiv, malloc, mblen, mbstowcs,
mbtowc, ncalloc, nfree, nmalloc, nrealloc, qsort, rand,
realloc, scalloc, sfree, smalloc, srand, srealloc, strtod, strtol,
strtoul, wcstombs, wctomb
<vt100.h> VT100 Terminal Emulation escape sequences for use with the
CrossView Pro FSS feature.
<wchar.h>
fwprintf, wprintf, swprintf, vfwprintf, vwprintf, vswprintf,
fwscanf, wscanf, swscanf, fgetwc, fgetws, fputwc, fputws,
fwide, getwc, getwchar, putwc, putwchar, ungetwc, wcstod,
wcstol, wcstoul, wcscpy, wcsncpy, wcscat, wcsncat, wcscmp,
wcscoll, wcsncmp, wcsxfrm, wcschr, wcscspn, wcspbrk,
wcsrchr, wcsspn, wcsstr, wcstok, wcslen, wmemchr,
wmemcmp, wmemcpy, wmemmove, wmemset, wcsftime,
btowc, wctob, mbsinit, mbrlen, mbrtowc, wcrtomb,
mbsrtowcs, wcsrtombs
<wctype.h>
iswalnum, iswalpha, iswcntrl, iswdigit, iswgraph, iswlower,
iswprint, iswpunct, iswspace, iswupper, iswxdigit, towlower,
towupper, wctype, iswctype, wctrans, towctrans
• • • • • • • •
6−10 Chapter 6
_close
#include <stdio.h>
int _close( int fd );
Low level file close function. _close is used by the functions close and
fclose. The given file descriptor should be properly closed, any buffer is
already flushed.
_fstrcat
#include <string.h>
char far *_fstrcat( char far *s, const char far *ct );
Returns s
_fstrchr
#include <string.h>
char far *_fstrchr( const char far *cs, int c );
_fstrcmp
#include <string.h>
int _fstrcmp( const char far *cs,
const char far *ct );
_fstrcpy
#include <string.h>
char far *_fstrcpy( char far *s, const char far *ct );
Copies far string ct into the far string s, including the trailing NULL
character.
Returns s
_fstrcspn
#include <string.h>
size_t _fstrcspn( const char far *cs,
const char far *ct );
_fstrlen
#include <string.h>
size_t _fstrlen( const char far *cs );
Returns the length of the far string in cs, not counting the NULL
character.
• • • • • • • •
6−12 Chapter 6
_fstrncat
#include <string.h>
char far *_fstrncat( char far *s,
const char far *ct,
size_t n );
Returns s
_fstrncmp
#include <string.h>
int _fstrncmp( const char far *cs,
const char far *ct,
size_t n );
_fstrncpy
#include <string.h>
char far *_fstrncpy( char far *s,
const char far *ct,
size_t n );
LIBRARIES
Copies far string ct onto the far string s, at most n characters are copied.
Add a trailing NULL character if the string is smaller than n characters.
Returns s
Libraries 6−13
_fstrpbrk
#include <string.h>
char far *_fstrpbrk( const char far *cs,
const char far *ct );
_fstrrchr
#include <string.h>
char far *_fstrrchr( const char far *cs, int c );
Returns a far pointer to the last occurrence of c in the far string cs. If
not found, NULL is returned.
_fstrspn
#include <string.h>
size_t _fstrspn( const char far *cs,
const char far *ct );
_fstrstr
#include <string.h>
char far *_fstrstr( const char far *cs,
const char far *ct );
Returns a far pointer to the first occurrence of far string ct in the far
string cs. Returns NULL if not found.
• • • • • • • •
6−14 Chapter 6
_fstrtok
#include <string.h>
char far *_fstrtok( char far *s, const char far *ct );
Search the far string s for tokens delimited by characters from far string
ct. It terminates the token with a NULL character.
_hstrcat
#include <string.h>
char huge *_hstrcat( char huge *s,
const char huge *ct );
Returns s
_hstrchr
#include <string.h>
char huge *_hstrchr( const char huge *cs, int c );
_hstrcmp
LIBRARIES
#include <string.h>
int _hstrcmp( const char huge *cs,
const char huge *ct );
_hstrcpy
#include <string.h>
char huge *_hstrcpy( char huge *s,
const char huge *ct );
Copies huge string ct into the huge string s, including the trailing NULL
character.
Returns s
_hstrcspn
#include <string.h>
size_t _hstrcspn( const char huge *cs,
const char huge *ct );
_hstrlen
#include <string.h>
size_t _hstrlen( const char huge *cs );
Returns the length of the huge string in cs, not counting the NULL
character.
_hstrncat
#include <string.h>
char huge *_hstrncat( char huge *s,
const char huge *ct,
size_t n );
Returns s
• • • • • • • •
6−16 Chapter 6
_hstrncmp
#include <string.h>
int _hstrncmp( const char huge *cs,
const char huge *ct,
size_t n );
_hstrncpy
#include <string.h>
char huge *_hstrncpy( char huge *s,
const char huge *ct,
size_t n );
Copies huge string ct onto the huge string s, at most n characters are
copied. Add a trailing NULL character if the string is smaller than n
characters.
Returns s
_hstrpbrk
#include <string.h>
char huge *_hstrpbrk( const char huge *cs,
const char huge *ct );
LIBRARIES
_hstrrchr
#include <string.h>
char huge *_hstrrchr( const char huge *cs, int c );
_hstrspn
#include <string.h>
size_t _hstrspn( const char huge *cs,
const char huge *ct );
_hstrstr
#include <string.h>
char huge *_hstrstr( const char huge *cs,
const char huge *ct );
_hstrtok
#include <string.h>
char huge *_hstrtok( char huge *s,
const char huge *ct );
Search the huge string s for tokens delimited by characters from huge
string ct. It terminates the token with a NULL character.
_lseek
#include <stdio.h>
off_t _lseek( int fd, off_t offset, int whence );
Low level file positioning function. _lseek is used by all file positioning
functions (fgetpos, fseek, fsetpos, ftell, rewind).
• • • • • • • •
6−18 Chapter 6
_open
#include <stdio.h>
int _open( const char *name, int flags );
Low level file open function. _open is used by the functions fopen and
freopen. The given file should be properly opened.
_read
#include <stdio.h>
size_t
_read( int fd, char *buffer, size_t size );
Low level block input function. It reads a block of characters from the
given stream. This function interfaces to CrossView Pro’s I/O Simulation
feature.
_stime
#include <time.h>
void _stime( time_t *s );
Returns nothing.
_sstrcat
#include <string.h>
LIBRARIES
Returns s
Libraries 6−19
_sstrchr
#include <string.h>
char shuge *_sstrchr( const char shuge *cs, int c );
_sstrcmp
#include <string.h>
int _sstrcmp( const char shuge *cs,
const char shuge *ct );
_sstrcpy
#include <string.h>
char shuge *_sstrcpy( char shuge *s,
const char shuge *ct );
Copies shuge string ct into the shuge string s, including the trailing NULL
character.
Returns s
_sstrcspn
#include <string.h>
size_t _sstrcspn( const char shuge *cs,
const char shuge *ct );
• • • • • • • •
6−20 Chapter 6
_sstrlen
#include <string.h>
size_t _sstrlen( const char shuge *cs );
Returns the length of the shuge string in cs, not counting the NULL
character.
_sstrncat
#include <string.h>
char shuge *_sstrncat( char shuge *s,
const char shuge *ct,
size_t n );
Returns s
_sstrncmp
#include <string.h>
int _sstrncmp( const char shuge *cs,
const char shuge *ct,
size_t n );
_sstrncpy
#include <string.h>
char shuge *_sstrncpy( char shuge *s,
const char shuge *ct,
size_t n );
Copies shuge string ct onto the shuge string s, at most n characters are
copied. Add a trailing NULL character if the string is smaller than n
characters.
Returns s
_sstrpbrk
#include <string.h>
char shuge *_sstrpbrk( const char shuge *cs,
const char shuge *ct );
_sstrrchr
#include <string.h>
char shuge *_sstrrchr( const char shuge *cs, int c );
_sstrspn
#include <string.h>
size_t _sstrspn( const char shuge *cs,
const char shuge *ct );
• • • • • • • •
6−22 Chapter 6
_sstrstr
#include <string.h>
char shuge *_sstrstr( const char shuge *cs,
const char shuge *ct );
_sstrtok
#include <string.h>
char shuge *_sstrtok( char shuge *s,
const char shuge *ct );
Search the shuge string s for tokens delimited by characters from shuge
string ct. It terminates the token with a NULL character.
_tolower
#include <ctype.h>
int _tolower( int c );
_toupper
LIBRARIES
#include <ctype.h>
int _toupper( int c );
_tzset
#include <time.h>
int _tzset( const char *s );
Converts the widely used time zone format string pointed to by s to tzone
format. That string takes the form EST05EDT, where the number in the
middle counts the hours West of UTC.
_unlink
#include <stdio.h>
int _unlink( const char *name );
Low level file remove function. _unlink is used by the function remove.
_write
#include <stdio.h>
size_t
_write( int fd, char *buffer, size_t count );
Low level block ouput function. It writes a block of characters to the given
stream. This function interfaces to CrossView Pro’s I/O Simulation feature.
abort
#include <stdlib.h>
void abort( void );
Returns nothing.
• • • • • • • •
6−24 Chapter 6
abs
#include <stdlib.h>
int abs( int n );
access
#include <unistd.h>
int access( const char * name, int mode );
Use the file system simulation feature of CrossView Pro to check the
permissions of a file on the host. mode specifies the type of access and is a
bit pattern constructed by a logical OR of the following values:
acos
#include <math.h>
double acos( double x );
asctime
#include <time.h>
char *asctime( const struct tm *tp );
Converts the time in the structure *tp into a string of the form:
Mon Jan 21 16:15:14 1993\n\0
asin
#include <math.h>
double asin( double x );
assert
#include <assert.h>
assert( expr );
is printed.
Returns nothing.
atan
#include <math.h>
double atan( double x );
atan2
#include <math.h>
double atan2( double y, double x );
• • • • • • • •
6−26 Chapter 6
atexit
#include <stdlib.h>
int atexit( void (*fcn)( void ) );
atof
#include <stdlib.h>
double atof( const char *s );
atoi
#include <stdlib.h>
int atoi( const char *s );
atol
LIBRARIES
#include <stdlib.h>
long atol( const char *s );
bsearch
#include <stdlib.h>
void *bsearch( const void *key,
const void *base, size_t n,
size_t size, int (*cmp)
(const void *, const void *) );
btowc
#include <wchar.h>
wint_t btowc( int c );
calloc
#include <stdlib.h>
void *calloc( size_t nobj, size_t size );
The allocated space is filled with zeros. The maximum space that can be
allocated can be changed by customizing the heap size (see section 7.3,
Heap Size). By default no heap is allocated.
• • • • • • • •
6−28 Chapter 6
ceil
#include <math.h>
double ceil( double x );
chdir
#include <unistd.h>
int chdir( const char *path );
Use the file system simulation feature of CrossView Pro to change the
current directory on the host to the directory indicated by path.
clearerr
#include <stdio.h>
void clearerr( FILE *stream );
Returns nothing.
clock
#include <time.h>
clock_t clock( void );
LIBRARIES
To perform real−time clock support, you must customize this function. See
the file time.c in the examples\time directory demonstrating an
implementation of this low−level time function.
close
#include <unistd.h>
int close( int fd );
File close function. The given file descriptor should be properly closed.
This function calls _close.
cos
#include <math.h>
double cos( double x );
cosh
#include <math.h>
double cosh( double x );
ctime
#include <time.h>
char *ctime( const time_t *tp );
Converts the calender time *tp into local time, in string form. This
function is the same as:
asctime( localtime( tp ) );
• • • • • • • •
6−30 Chapter 6
difftime
#include <time.h>
double difftime( time_t time2, time_t time1 );
div
#include <stdlib.h>
div_t div( int num, int denom );
Both arguments are integers. The returned quotient and remainder are also
integers.
exit
#include <stdlib.h>
void exit( int status );
exp
LIBRARIES
#include <math.h>
double exp( double x );
fabs
#include <math.h>
double fabs( double x );
fcalloc
#include <stdlib.h>
void _far *fcalloc( size_t nobj, size_t size );
fclose
#include <stdio.h>
int fclose( FILE *stream )
Flushes any unwritten data for stream, discards any unread buffered input,
frees any automatically allocated buffer, then closes the stream.
feof
#include <stdio.h>
int feof( FILE *stream );
ferror
#include <stdio.h>
int ferror( FILE *stream );
• • • • • • • •
6−32 Chapter 6
fflush
#include <stdio.h>
int fflush( FILE *stream );
ffree
#include <stdlib.h>
void ffree( void _far *p );
Returns nothing
fgetc
#include <stdio.h>
int fgetc( FILE *stream );
fgetpos
LIBRARIES
#include <stdio.h>
int fgetpos( FILE *stream, fpos_t *ptr );
Stores the current value of the file position indicator for the stream pointed
to by stream in the object pointed to by ptr. The type fpos_t is
suitable for recording such values.
fgets
#include <stdio.h>
char *fgets( char *s, int n, FILE *stream );
Reads at most the next n−1 characters from the given stream into the
array s until a newline is found.
fgetwc
#include <wchar.h>
wint_t fgetwc( FILE *stream );
fgetws
#include <wchar.h>
wchar_t *fgetws( wchar_t *s, int n, FILE *stream );
Reads at most the next n−1 wide characters from the given stream into
the array s until a newline is found.
floor
#include <math.h>
double floor( double x );
fmalloc
#include <stdlib.h>
void _far *fmalloc( size_t size );
• • • • • • • •
6−34 Chapter 6
fmod
#include <math.h>
double fmod( double x, double y );
fopen
#include <stdio.h>
FILE *fopen( const char *filename, const char *mode );
"w" write; create text file for writing; if the file already exists its
contents is discarded
"a" append; open existing text file or create new text file for
writing at end of file
"a+" append; open or create text file for update, writes at end of
file
The update mode (with a ’+’) allows reading and writing of the same file.
In this mode the function fflush must be called between a read and a write
or vice versa. By including the letter "b" after the initial letter, you can
indicate that the file is a binary file. E.g. "rb" means read binary, "w+b"
means create binary file for update. The filename is limited to
FILENAME_MAX characters. At most FOPEN_MAX files may be open at
once.
Libraries 6−35
fprintf
#include <stdio.h>
int fprintf( FILE *stream, const char *format, ... );
fputc
#include <stdio.h>
int fputc( int c, FILE *stream );
fputs
#include <stdio.h>
int fputs( const char *s, FILE *stream );
fputwc
#include <wchar.h>
wint_t fputwc( int c, FILE *stream );
• • • • • • • •
6−36 Chapter 6
fputws
#include <wchar.h>
int fputws( const wchar_t *s, FILE *stream );
Writes the wide string to a stream. The terminating NULL wide character
is not written.
fread
#include <stdio.h>
size_t fread( void *ptr, size_t size,
size_t nobj, FILE *stream );
Reads nobj members of size bytes from the given steam into the array
pointed to by ptr.
frealloc
#include <stdlib.h>
void _far *frealloc( void _far *p, size_t size );
free
LIBRARIES
#include <stdlib.h>
void free( void *p );
Returns nothing
Libraries 6−37
freopen
#include <stdio.h>
FILE *freopen( const char *filename,
const char *mode, FILE *stream );
Opens a file for a given mode associates the stream with it. This function
is normally used to change the files associated with stdin, stdout, or stderr.
frexp
#include <math.h>
double frexp( double x, int *exp );
fscanf
#include <stdio.h>
int fscanf( FILE *stream, const char *format, ... );
• • • • • • • •
6−38 Chapter 6
fseek
#include <stdio.h>
int fseek( FILE *stream, long offset, int origin );
Sets the file position indicator for stream. A subsequent read or write will
access data beginning at the new position. For a binary file, the position is
set to offset characters from origin, which may be SEEK_SET for the
beginning of the file, SEEK_CUR for the current position in the file, or
SEEK_END for the end−of−file. For a text stream, offset must be zero, or
a value returned by ftell. In this case origin must be SEEK_SET.
fsetpos
#include <stdio.h>
int fsetpos( FILE *stream, const fpos_t *ptr );
fstat
#include <unistd.h>
int fstat( int fd, struct stat * buf );
ftell
#include <stdio.h>
long ftell( FILE *stream );
fwide
#include <wchar.h>
int fwide( FILE *stream, int mode );
Determines the orientation of the stream. If mode is greater than zero, the
function first attempts to make the stream wide oriented. If mode is less
than zero, the function first attempts to make the stream byte oriented.
Otherwise, mode is zero and the function does not alter the orientation of
the stream.
Returns a value greater than zero if, after the call, the stream has wide
orientation, a value less than zero if the stream has byte
orientation, or zero if the stream has no orientation.
fwprintf
#include <wchar.h>
int fwprintf( FILE *stream,
const wchar_t *format, ... );
Writes output to the given stream under control of the wide string
pointed to by format that specifies how subsequent arguments are
converted for output.
• • • • • • • •
6−40 Chapter 6
fwrite
#include <stdio.h>
size_t fwrite( const void *ptr,
size_t size, size_t nobj,
FILE *stream );
Writes nobj members of size bytes to the given stream from the array
pointed to by ptr.
fwscanf
#include <wchar.h>
int fwscanf( FILE *stream,
const wchar_t *format, ... );
Reads input from the given stream, under control of the wide string
pointed to by format that specifies the admissible input sequences and
how they are to be converted for assignment, using subsequent arguments
as pointers to the objects to receive the converted input.
getc
#include <stdio.h>
int getc( FILE *stream );
LIBRARIES
getchar
#include <stdio.h>
int getchar( void );
getcwd
#include <unistd.h>
char * getcwd( char * buf, size_t size );
Use the file system simulation feature of CrossView Pro to retrieve the
current directory on the host.
getenv
#include <stdlib.h>
char *getenv( const char *name );
gets
#include <stdio.h>
char *gets( char *s );
Reads all characters from standard input until a newline is found. The
newline is replaced by a NULL−character.
• • • • • • • •
6−42 Chapter 6
getwc
#include <wchar.h>
wint_t getwc( FILE *stream );
getwchar
#include <wchar.h>
wint_t getwchar( void );
gmtime
#include <time.h>
struct tm *gmtime( const time_t *tp );
Converts the calender time *tp into Coordinated Universal Time (UTC).
hcalloc
#include <stdlib.h>
void _huge *hcalloc( unsigned long nobj,
LIBRARIES
hfree
#include <stdlib.h>
void hfree( void _huge *p );
Returns nothing
hmalloc
#include <stdlib.h>
void _huge *hmalloc( unsigned long size );
hrealloc
#include <stdlib.h>
void _huge *hrealloc( void _huge *p,
unsigned long size );
hypot
#include <math.h>
double hypot( double x, double y );
hypotf
#include <math.h>
float hypotf( float x, float y );
• • • • • • • •
6−44 Chapter 6
hypotl
#include <math.h>
long double hypotl( long double x, long double y );
isalnum
#include <ctype.h>
int isalnum( int c );
isalpha
#include <ctype.h>
int isalpha( int c );
isascii
#include <ctype.h>
int isascii( int c );
iscntrl
#include <ctype.h>
int iscntrl( int c );
isdigit
#include <ctype.h>
int isdigit( int c );
isgraph
#include <ctype.h>
int isgraph( int c );
isinf
#include <float.h>
int isinf( double d );
isinff
#include <float.h>
int isinff( float f );
islower
#include <ctype.h>
int islower( int c );
• • • • • • • •
6−46 Chapter 6
isnan
#include <float.h>
int isnan( double d );
isnanf
#include <float.h>
int isnanf( float f );
isprint
#include <ctype.h>
int isprint( int c );
ispunct
#include <ctype.h>
int ispunct( int c );
LIBRARIES
isspace
#include <ctype.h>
int isspace( int c );
isupper
#include <ctype.h>
int isupper( wint_t wc );
iswalnum
#include <wctype.h>
int iswalnum( wint_t wc );
iswalpha
#include <wctype.h>
int iswalpha( wint_t wc );
iswcntrl
#include <wctype.h>
int iswcntrl( wint_t wc );
iswctype
#include <wctype.h>
int iswctype( wint_t wc, wctype_t desc );
Returns a non−zero value (true) if and only if the value of the wide
character wc has the property described by desc.
• • • • • • • •
6−48 Chapter 6
iswdigit
#include <wctype.h>
int iswdigit( wint_t wc );
iswgraph
#include <wctype.h>
int iswgraph( wint_t wc );
iswlower
#include <wctype.h>
int iswlower( wint_t wc );
iswprint
#include <wctype.h>
int iswprint( wint_t wc );
iswpunct
LIBRARIES
#include <wctype.h>
int iswpunct( wint_t wc );
iswspace
#include <wctype.h>
int iswspace( wint_t wc );
iswupper
#include <wctype.h>
int iswupper( wint_t wc );
iswxdigit
#include <wctype.h>
int iswxdigit( wint_t wc );
isxdigit
#include <ctype.h>
int isxdigit( int c );
labs
#include <stdlib.h>
long labs( long n );
• • • • • • • •
6−50 Chapter 6
ldexp
#include <math.h>
double ldexp( double x, int n );
ldiv
#include <stdlib.h>
ldiv_t ldiv( long num, long denom );
Both arguments are long integers. The returned quotient and remainder
are also long integers.
localeconv
#include <locale.h>
struct lconv *localeconv( void );
Sets the components of an object with type struct lconv with values
appropriate for the formatting of numeric quantities according to the rules
of the current locale.
localtime
#include <time.h>
LIBRARIES
log
#include <math.h>
double log( double x );
log10
#include <math.h>
double log10( double x );
longjmp
#include <setjmp.h>
void longjmp( jmp_buf env, int val );
Returns nothing.
lstat
#include <unistd.h>
int lstat( const char * name, struct stat * buf );
• • • • • • • •
6−52 Chapter 6
malloc
#include <stdlib.h>
void *malloc( size_t size );
The allocated space is not initialized. The maximum space that can be
allocated can be changed by customizing the heap size (see section 7.3,
Heap Size). By default no heap is allocated.
mblen
#include <stdlib.h>
int mblen( const char *s, size_t n );
mbrlen
#include <wchar.h>
size_t mbrlen( const char *s, size_t n,
mbstate_t *ps);
mbrtowc
#include <wchar.h>
size_t mbrtowc( wchar_t *pwc, const char *s,
size_t n, mbstate_t *ps );
mbsinit
#include <wchar.h>
int mbsinit( const mbstate_t *ps );
• • • • • • • •
6−54 Chapter 6
mbsrtowcs
#include <wchar.h>
size_t mbsrtowcs( wchar_t *dst, const char **src,
size_t len, mbstate_t *ps );
mbstowcs
#include <stdlib.h>
size_t mbstowcs( wchar_t *pwcs,
const char *s, size_t n );
mbtowc
#include <stdlib.h>
int mbtowc( wchar_t *pwc,
const char *s, size_t n );
memchr
#include <string.h>
void *memchr( const void *cs, int c, size_t n );
memcmp
#include <string.h>
int memcmp( const void *cs,
const void *ct, size_t n );
• • • • • • • •
6−56 Chapter 6
memcpffb
#include <string.h>
void memcpffb( void far *dest,
void far *src, size_t n);
Copies n bytes from far data pointed by src to far data pointed by dest.
No care is taken if the two objects overlap and page boundaries are not
checked. ( 0 < n <= 16384 )
Returns nothing
memcpffw
#include <string.h>
void memcpffw( void far *dest,
void far *src, size_t n);
Copies n words from far data pointed by src to far data pointed by dest.
No care is taken if the two objects overlap and page boundaries are not
checked. ( 0 < n <= 8192 )
Returns nothing
memcpfhb
#include <string.h>
void memcpfhb( void huge *dest,
void far *src, size_t n);
Copies n bytes from far data pointed by src to huge data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
LIBRARIES
checked for huge data but not checked for far data.
( 0 < n <= 16384 )
Returns nothing
Libraries 6−57
memcpfhw
#include <string.h>
void memcpfhw( void huge *dest,
void far *src, size_t n);
Copies n words from far data pointed by src to huge data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for far data.
( 0 < n <= 8192 )
Returns nothing
memcpfnb
#include <string.h>
void memcpfnb( void near *dest,
void far *src, size_t n);
Copies n bytes from far data pointed by src to near data pointed by
dest. No care is taken if the two objects overlap and page boundaries are
not checked. ( 0 < n <= 16384 )
Returns nothing
memcpfnw
#include <string.h>
void memcpfnw( void near *dest,
void far *src, size_t n);
Copies n words from far data pointed by src to near data pointed by
dest. No care is taken if the two objects overlap and page boundaries are
not checked. ( 0 < n <= 8192 )
Returns nothing
• • • • • • • •
6−58 Chapter 6
memcpfsb
#include <string.h>
void memcpfsb( void shuge *dest,
void far *src, size_t n);
Copies n bytes from far data pointed by src to shuge data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for far data.
( 0 < n <= 16384 )
Returns nothing
memcpfsw
#include <string.h>
void memcpfsw( void shuge *dest,
void far *src, size_t n);
Copies n words from far data pointed by src to shuge data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for far data.
( 0 < n <= 8192 )
Returns nothing
memcphfb
#include <string.h>
void memcphfb( void far *dest,
void huge *src, size_t n);
LIBRARIES
Copies n bytes from huge data pointed by src to far data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for far data.
( 0 < n <= 16384 )
Returns nothing
Libraries 6−59
memcphfw
#include <string.h>
void memcphfw( void far *dest,
void huge *src, size_t n);
Copies n words from huge data pointed by src to far data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for far data.
( 0 < n <= 8192 )
Returns nothing
memcphhb
#include <string.h>
void memcphhb( void huge *dest,
void huge *src, size_t n);
Copies n bytes from huge data pointed by src to huge data pointed by
dest. No care is taken if the two objects overlap.
( 0 < n <= 65535 )
Returns nothing
memcphhw
#include <string.h>
void memcphhw( void huge *dest,
void huge *src, size_t n);
Copies n words from huge data pointed by src to huge data pointed by
dest. No care is taken if the two objects overlap.
( 0 < n <= 65535 )
Returns nothing
• • • • • • • •
6−60 Chapter 6
memcphnb
#include <string.h>
void memcphnb( void near *dest,
void huge *src, size_t n);
Copies n bytes from huge data pointed by src to near data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for near data. ( 0 < n <= 16384 )
Returns nothing
memcphnw
#include <string.h>
void memcphnw( void near *dest,
void huge *src, size_t n);
Copies n words from huge data pointed by src to near data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for near data. ( 0 < n <= 8192 )
Returns nothing
memcphsb
#include <string.h>
void memcphsb( void shuge *dest,
void huge *src, size_t n);
Copies n bytes from huge data pointed by src to shuge data pointed by
dest. No care is taken if the two objects overlap.
LIBRARIES
Returns nothing
Libraries 6−61
memcphsw
#include <string.h>
void memcphsw( void shuge *dest,
void huge *src, size_t n);
Copies n words from huge data pointed by src to shuge data pointed by
dest. No care is taken if the two objects overlap.
( 0 < n <= 65535 )
Returns nothing
memcpnfb
#include <string.h>
void memcpnfb( void far *dest,
void near *src, size_t n);
Copies n bytes from near data pointed by src to far data pointed by
dest. No care is taken if the two objects overlap.
( 0 < n <= 16384 )
Returns nothing
memcpnfw
#include <string.h>
void memcpnfw( void far *dest,
void near *src, size_t n);
Copies n words from near data pointed by src to far data pointed by
dest. No care is taken if the two objects overlap.
( 0 < n <= 8192 )
Returns nothing
• • • • • • • •
6−62 Chapter 6
memcpnhb
#include <string.h>
void memcpnhb( void huge *dest,
void near *src, size_t n);
Copies n bytes from near data pointed by src to huge data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for near data. ( 0 < n <= 16384 )
Returns nothing
memcpnhw
#include <string.h>
void memcpnhw( void huge *dest,
void near *src, size_t n);
Copies n words from near data pointed by src to huge data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for huge data but not checked for near data. ( 0 < n <= 8192 )
Returns nothing
memcpnnb
#include <string.h>
void memcpnnb( void near *dest,
void near *src, size_t n);
Copies n bytes from near data pointed by src to near data pointed by
dest. No care is taken if the two objects overlap and page boundaries are
LIBRARIES
Returns nothing
Libraries 6−63
memcpnnw
#include <string.h>
void memcpnnw( void near *dest,
void near *src, size_t n);
Copies n words from near data pointed by src to near data pointed by
dest. No care is taken if the two objects overlap and page boundaries are
not checked. ( 0 < n <= 8192 )
Returns nothing
memcpnsb
#include <string.h>
void memcpnsb( void shuge *dest,
void near *src, size_t n);
Copies n bytes from near data pointed by src to shuge data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for shuge data but not for near data. ( 0 < n <= 16384 )
Returns nothing
memcpnsw
#include <string.h>
void memcpnsw( void shuge *dest,
void near *src, size_t n);
Copies n words from near data pointed by src to shuge data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for shuge data but not for near data. ( 0 < n <= 8192 )
Returns nothing
• • • • • • • •
6−64 Chapter 6
memcpsfb
#include <string.h>
void memcpsfb( void far *dest,
void shuge *src, size_t n);
Copies n bytes from shuge data pointed by src to far data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for shuge data but not checked for far data. ( 0 < n <= 16384 )
Returns nothing
memcpsfw
#include <string.h>
void memcpsfw( void far *dest,
void shuge *src, size_t n);
Copies n words from shuge data pointed by src to far data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for shuge data but not checked for far data. ( 0 < n <= 8192 )
Returns nothing
memcpshb
#include <string.h>
void memcpshb( void huge *dest,
void shuge *src, size_t n);
Copies n bytes from shuge data pointed by src to huge data pointed by
dest. No care is taken if the two objects overlap.
LIBRARIES
Returns nothing
Libraries 6−65
memcpshw
#include <string.h>
void memcpshw( void huge *dest,
void shuge *src, size_t n);
Copies n words from shuge data pointed by src to huge data pointed by
dest. No care is taken if the two objects overlap.
( 0 < n <= 8192 )
Returns nothing
memcpsnb
#include <string.h>
void memcpsnb( void near *dest,
void shuge *src, size_t n);
Copies n bytes from shuge data pointed by src to near data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for shuge data but not for near data.
( 0 < n <= 16384 )
Returns nothing
memcpsnw
#include <string.h>
void memcpsnw( void near *dest,
void shuge *src, size_t n);
Copies n words from shuge data pointed by src to near data pointed by
dest. No care is taken if the two objects overlap. Page boundaries are
checked for shuge data but not for near data.
( 0 < n <= 8192 )
Returns nothing
• • • • • • • •
6−66 Chapter 6
memcpssb
#include <string.h>
void memcpssb( void shuge *dest,
void shuge *src, size_t n);
Copies n bytes from shuge data pointed by src to shuge data pointed by
dest. No care is taken if the two objects overlap.
( 0 < n <= 16384 )
Returns nothing
memcpssw
#include <string.h>
void memcpssw( void shuge *dest,
void shuge *src, size_t n);
Copies n words from shuge data pointed by src to shuge data pointed by
dest. No care is taken if the two objects overlap.
( 0 < n <= 8192 )
Returns nothing
memcpy
#include <string.h>
void *memcpy( void *s, const void *ct, size_t n );
Returns s
memmove
#include <string.h>
void *memmove( void *s, const void *ct, size_t n );
Returns s
Libraries 6−67
memset
#include <string.h>
void *memset( void *s, int c, size_t n );
Returns s
mktime
#include <time.h>
time_t mktime( struct tm *tp );
Converts the local time in the structure *tp into calendar time.
modf
#include <math.h>
double modf( double x, double *ip );
Splits x into integral and fractional parts, each with the same sign as x. It
stores the integral part in *ip.
ncalloc
#include <stdlib.h>
void _near *ncalloc( size_t nobj, size_t size );
• • • • • • • •
6−68 Chapter 6
nfree
#include <stdlib.h>
void nfree( void _near *p );
Returns nothing
nmalloc
#include <stdlib.h>
void _near *nmalloc( size_t size );
nrealloc
#include <stdlib.h>
void _near *nrealloc( void _near *p, size_t size );
offsetof
#include <stddef.h>
int offsetof( type, member );
open
#include <fcntl.h>
int open( const char * name, int flags );
Opens a file a file for reading or writing. This function calls _open.
perror
#include <stdio.h>
void perror( const char *s );
The contents of the error message are the same as those returned by the
strerror function with the argument errno.
Returns nothing.
pow
#include <math.h>
double pow( double x, double y );
A domain error occurs if x=0 and y<=0, or if x<0 and y is not an integer.
• • • • • • • •
6−70 Chapter 6
printf
#include <stdio.h>
int printf( const char *format, ... );
The format string may contain plain text mixed with conversion
specifiers. Each conversion specifier should be preceded by a ’%’
character. The conversion specifier should be build in order :
− Flags (in any order):
− specifies left adjustment of the converted argument.
space
a negative number is preceded with a sign, positive numbers
with a space.
Character Printed as
d, i int, signed decimal
o int, unsigned octal
x, X int, unsigned hexadecimal in lowercase or uppercase
respectively
u int, unsigned decimal
c int, single character (converted to unsigned char)
s char *, the characters from the string are printed until
a NULL character is found. When the given precision
is met before, printing will also stop
f double
e, E double
g, G double
n int *, the number of characters written so far is written
into the argument. This should be a pointer to an
integer in default memory. No value is printed.
• • • • • • • •
6−72 Chapter 6
Character Printed as
p pointer; printed as a hexadecimal number, prefixed
with: <near>, <far> or <huge>.
For the different pointer types the following formats
are used:
<near> OOOO
<far> PPPP:OOOO
<huge> SS:OOOO
where:
O is offset
P is page
S is segment
% No argument is converted, a ’%’ is printed.
The ’p’ conversion character can be used to print pointers. In the tiny and
small memory models, pointers will be printed as near pointers by default.
In the medium and large memory models, pointers will be printed as far
pointers by default. By specifying one of the length modifiers ’h’, ’l’ or ’L’,
a pointer will always be printed as near, far or huge respectively.
putc
#include <stdio.h>
int putc( int c, FILE *stream );
putchar
#include <stdio.h>
int putchar( int c );
puts
#include <stdio.h>
int puts( const char *s );
putwc
#include <wchar.h>
wint_t putwc( wchar_t c, FILE *stream );
putwchar
#include <wchar.h>
wint_t putwchar( wchar_t c );
• • • • • • • •
6−74 Chapter 6
qsort
#include <stdlib.h>
void qsort( void *base, size_t n,
size_t size, int (*cmp)
( const void *, const void *) );
This function sorts an array of n members. The initial base of the array is
given by base. The size of each member is specified by size. The given
array is sorted in ascending order, according to the results of the function
pointed to by cmp.
This function is recursive, and therefore may need an increased user stack
section!
raise
#include <signal.h>
int raise( int sig );
rand
#include <stdlib.h>
int rand( void );
RAND_MAX.
read
#include <unistd.h>
size_t read( int fd, char * buffer, size_t count );
realloc
#include <stdlib.h>
void *realloc( void *p, size_t size );
Reallocates the space for the object pointed to by p. The contents of the
object will be the same as before calling realloc(). The maximum space
that can be allocated can be changed by customizing the heap size (see
section 7.3, Heap Size). By default no heap is allocated.
Returns NULL and *p is not changed, if there is not enough space for
the new allocation. Otherwise a pointer to the newly
allocated space for the object is returned.
remove
#include <stdio.h>
int remove( const char *filename );
rename
#include <stdio.h>
int rename( const char *oldname,
const char *newname );
• • • • • • • •
6−76 Chapter 6
rewind
#include <stdio.h>
void rewind( FILE *stream );
Sets the file position indicator for the stream pointed to by stream to the
beginning of the file. This function is equivalent to:
Returns nothing.
scalloc
#include <stdlib.h>
void _shuge *scalloc( size_t nobj, size_t size );
scanf
#include <stdio.h>
int scanf( const char *format, ... );
Character Scanned as
d int, signed decimal.
i int, the integer may be given octal (i.e. a leading 0 is
entered) or hexadecimal (leading "0x" or "0X"), or just
decimal.
o int, unsigned octal.
u int, unsigned decimal.
x int, unsigned hexadecimal in lowercase or upper
case.
c single character (converted to unsigned char).
s char *, a string of non white space characters. The
argument should point to an array of characters,
large enough to hold the string and a terminating
NULL character.
f float
e, E float
g, G float
n int *, the number of characters written so far is written
into the argument. No scanning is done.
• • • • • • • •
6−78 Chapter 6
Character Scanned as
p pointer; interpreted as a hexadecimal number, must
be prefixed with: <near>, <far> or <huge>.
For the different pointer types the following formats
are expected:
<near> OOOO
<far> PPPP:OOOO
<huge> SS:OOOO
where:
O is offset
P is page
S is segment
[...] Matches a string of input characters from the set be
tween the brackets. A NULL character is added to
terminate the string. Specifying []...] includes the ’]’
character in the set of scanning characters.
[^...] Matches a string of input characters not in the set
between the brackets. A NULL character is added to
terminate the string. Specifying [^]...] includes the ’]’
character in the set.
% Literal ’%’, no assignment is done.
The ’p’ conversion character can be used to read pointers. In the tiny and
small memory models, pointers will be read as near pointers by default. In
the medium and large memory models, pointers will be read as far
pointers by default. By specifying one of the length modifiers ’h’, ’l’ or ’L’,
a pointer will always be read as near, far or huge respectively.
setbuf
#include <stdio.h>
void setbuf( FILE *stream, char *buf );
Returns nothing.
setjmp
#include <setjmp.h>
int setjmp( jmp_buf env );
Returns the value 0 after a direct call to setjmp(). Calling the function
"longjmp()" using the saved env restores the current
environment and jumps to this place with a non−zero return
value.
setlocale
#include <locale.h>
char *setlocale( int category, const char *locale );
Returns the string associated with the specified category for the
new locale if the selection can be honored.
null pointer if the selection cannot be honored.
• • • • • • • •
6−80 Chapter 6
setvbuf
#include <stdio.h>
int setvbuf( FILE *stream, char *buf,
int mode, size_t size );
Controls buffering for the stream; this function must be called before
reading or writing. mode can have the following values:
sfree
#include <stdlib.h>
void sfree( void _shuge *p );
Returns nothing
LIBRARIES
Libraries 6−81
signal
#include <signal.h>
void (*signal( int sig, void (*handler)(int)))(int);
When a signal sig subsequenly occurs, the signal is restored to its default
behavior; then the signal−handler function is called, as if by
(*handler)(sig) . If the handler returns, the execution will resume
where it was when the signal occurred.
sin
#include <math.h>
double sin( double x );
sinh
#include <math.h>
double sinh( double x );
• • • • • • • •
6−82 Chapter 6
smalloc
#include <stdlib.h>
void _shuge *smalloc( size_t size );
sprintf
#include <stdio.h>
int sprintf( char *s, const char *format, ... );
sqrt
#include <math.h>
double sqrt( double x );
srand
#include <stdlib.h>
void srand( unsigned int seed );
srealloc
#include <stdlib.h>
void _shuge *srealloc( void _shuge *p, size_t size );
sscanf
#include <stdio.h>
int sscanf( char *s, const char *format, ... );
stat
#include <unistd.h>
int stat( const char * name, struct stat * buf );
Use the file system simulation feature of CrossView Pro to stat() a file on
the host platform.
strcat
#include <string.h>
char *strcat( char *s, const char *ct );
Returns s
strchr
#include <string.h>
char *strchr( const char *cs, int c );
• • • • • • • •
6−84 Chapter 6
strcmp
#include <string.h>
int strcmp( const char *cs, const char *ct );
strcoll
#include <string.h>
int strcoll( const char *cs, const char *ct );
strcpy
#include <string.h>
char *strcpy( char *s, const char *ct );
Copies string ct into the string s, including the trailing NULL character.
Returns s
LIBRARIES
strcspn
#include <string.h>
size_t strcspn( const char *cs, const char *ct );
strerror
#include <string.h>
char *strerror( size_t n );
strftime
#include <time.h>
size_t strftime( char *s, size_t maxsize,
const char *format,
const struct tm *timeptr );
Formats date and time information from the structure *timeptr into s
according to the specified format format. format is analogous to a
printf format. Each %c is replaced as described below:
• • • • • • • •
6−86 Chapter 6
strlen
#include <string.h>
size_t strlen( const char *cs );
Returns the length of the string in cs, not counting the NULL
character.
strncat
#include <string.h>
char *strncat( char *s, const char *ct, size_t n );
Returns s
strncmp
#include <string.h>
int strncmp( const char *cs,
const char *ct, size_t n );
LIBRARIES
strncpy
#include <string.h>
char *strncpy( char *s, const char *ct, size_t n );
Copies string ct onto the string s, at most n characters are copied. Adds a
trailing NULL character if the string is smaller than n characters.
Returns s
strpbrk
#include <string.h>
char *strpbrk( const char *cs, const char *ct );
strrchr
#include <string.h>
char *strrchr( const char *cs, int c );
strspn
#include <string.h>
size_t strspn( const char *cs, const char *ct );
strstr
#include <string.h>
char *strstr( const char *cs, const char *ct );
• • • • • • • •
6−88 Chapter 6
strtod
#include <stdlib.h>
double strtod( const char *s, char **endp );
strtok
#include <string.h>
char *strtok( char *s, const char *ct );
Search the string s for tokens delimited by characters from string ct. It
terminates the token with a NULL character.
strtol
#include <stdlib.h>
long strtol( const char *s, char **endp, int base );
starting with ’0x’ or ’0X’ are taken hexadecimal. Other numbers are taken
decimal. When endp is not a NULL pointer, after this function is called,
*endp will point to the first character not used by the conversion.
strtoul
#include <stdlib.h>
unsigned long strtoul( const char *s,
char **endp, int base );
strxfrm
#include <string.h>
size_t
strxfrm( char *ct, const char *cs, size_t n );
Transforms the string pointed to by cs and places the resulting string into
the array pointed to by ct. No more than n characters are placed into the
resulting string pointed to by ct, including the terminating null character.
swprintf
#include <wchar.h>
int swprintf( const wchar_t *s, size_t n,
const wchar_t *format, ... );
• • • • • • • •
6−90 Chapter 6
swscanf
#include <wchar.h>
int swscanf( const wchar_t *s,
const wchar_t *format, ... );
tan
#include <math.h>
double tan( double x);
tanh
#include <math.h>
double tanh( double x);
time
#include <time.h>
time_t time( time_t *tp );
tmpfile
#include <stdio.h>
FILE *tmpfile( void );
tmpnam
#include <stdio.h>
char *tmpnam( char s[L_tmpnam] );
toascii
#include <ctype.h>
int toascii( int c );
• • • • • • • •
6−92 Chapter 6
tolower
#include <ctype.h>
int tolower( int c );
toupper
#include <ctype.h>
int toupper( int c );
towctrans
#include <wctype.h>
wint_t towctrans( wint_t wc, wctrans_t desc );
towlower
#include <wctype.h>
wint_t towlower( wint_t wc );
LIBRARIES
towupper
#include <wctype.h>
wint_t towupper( wint_t wc );
ungetc
#include <stdio.h>
int ungetc( int c, FILE *fin );
Pushes at the most one character back onto the input buffer.
ungetwc
#include <wchar.h>
wint_t ungetwc( wint_t c, FILE *stream );
Pushes at the most one wide character back onto the input stream.
unlink
#include <unistd.h>
int unlink( const char * name );
Removes the named file, so that a subsequent attempt to open it fails. This
function calls _unlink.
• • • • • • • •
6−94 Chapter 6
va_arg
#include <stdarg.h>
va_arg( va_list ap, type );
Returns the value of the next argument in the variable argument list.
It’s return type has the type of the given argument type. A
next call to this macro will return the value of the next
argument.
va_end
#include <stdarg.h>
va_end( va_list ap );
This macro must be called after the arguments have been processed. It
should be called before the function using the macro ’va_start’ is
terminated (ANSI specification).
va_start
#include <stdarg.h>
va_start( va_list ap, lastarg );
This macro initializes ap. After this call, each call to va_arg() will return
the value of the next argument. In our implementation, va_list cannot
contain any bit type variables. Also the given argument lastarg must be
the last non bit type argument in the list.
vfprintf
LIBRARIES
#include <stdio.h>
int vfprintf( FILE *stream,
const char *format, va_list arg );
vprintf
#include <stdio.h>
int vprintf( const char *format, va_list arg );
vsprintf
#include <stdio.h>
int vsprintf( char *s, const char *format,
va_list arg );
vfwprintf
#include <wchar.h>
int vfwprintf( FILE *stream,
const wchar_t *format, va_list arg );
• • • • • • • •
6−96 Chapter 6
vswprintf
#include <wchar.h>
int vswprintf( const wchar_t *s, size_t n,
const wchar_t *format, va_list arg );
vwprintf
#include <wchar.h>
int vwprintf( const wchar_t *format, va_list arg );
wcrtomb
#include <wchar.h>
size_t wcrtomb( char *s, wchar_t wc, mbstate_t *ps );
wcscat
#include <wchar.h>
wchar_t *wcscat( wchar_t *s1, const wchar_t *s2 );
Returns s1
wcschr
#include <wchar.h>
wchar_t *wcschr( const wchar_t *s, wchar_t c );
wcscmp
#include <wchar.h>
int wcscmp( const wchar_t *s1, const wchar_t *s2 );
wcscoll
#include <wchar.h>
int wcscoll( const wchar_t *s1, const wchar_t *s2 );
• • • • • • • •
6−98 Chapter 6
wcscpy
#include <wchar.h>
wchar_t *wcscpy( wchar_t *s1, const wchar_t *s2 );
Copies wide string s2 intto wide string s1. including the trailing null wide
character.
Returns s1
wcscspn
#include <wchar.h>
size_t wcscspn(const wchar_t *s1, const wchar_t *s2 );
wcsftime
#include <wchar.h>
size_t wcsftime( wchar_t *s, size_t maxsize,
const wchar_t *format,
const struct tm *timeptr );
wcslen
#include <wchar.h>
size_t wcslen( const wchar_t *s );
Returns the length of the wide string in s, not counting the null wide
character.
wcsncat
#include <wchar.h>
wchar_t *wcsncat( wchar_t *s1, const wchar_t *s2,
size_t n );
Returns s1
wcsncmp
#include <wchar.h>
int wcsncmp( const wchar_t *s1, const wchar_t *s2,
size_t n);
wcsncpy
#include <wchar.h>
wchar_t *wcsncpy( wchar_t *s1, const wchar_t *s2,
size_t n );
Copies at most n characters of wide string s2 onto the wide string s1.
Adds trailing null characters if the string is smaller than n wide characters.
Returns s1
• • • • • • • •
6−100 Chapter 6
wcspbrk
#include <wchar.h>
wchar_t *wcspbrk( const wchar_t *s1,
const wchar_t *s2 );
wcsrchr
#include <wchar.h>
wchar_t *wcsrchr( const wchar_t *s, wchar_t c );
wcsrtombs
#include <wchar.h>
size_t wcsrtombs( char *dst, const wchar_t **src,
size_t len, mbstate_t *ps );
wcsspn
#include <wchar.h>
size_t wcsspn( const wchar_t *s1, const wchar_t *s2 );
wcsstr
#include <wchar.h>
wchar_t *wcsstr( const wchar_t *s1,
const wchar_t *s2);
wcstod
#include <wchar.h>
double wcstod( const wchar_t *nptr,
wchar_t **endptr );
• • • • • • • •
6−102 Chapter 6
wcstok
#include <wchar.h>
wchar_t *wcstok( wchar_t *s1, const wchar_t *s2,
wchar_t **ptr );
Searches the wide string s1 for tokens delimited by wide characters from
wide string s2. It terminates the token with a null character.
wcstol
#include <wchar.h>
long int wcstol( const wchar_t *nptr,
wchar_t **endptr, int base );
Converts the initial portion of the wide string pointed to by nptr to long
int. Initial white spaces are skipped. Then a value is read using the given
base. When base is zero, the base is taken as defined for integer
constants. I.e. numbers starting with an ’0’ are taken octal, numbers
starting with ’0x’ or ’0X’ are taken hexadecimal. Other numbers are taken
decimal. A pointer to the final wide string is stored in the object pointed to
by endptr, provided that endptr is not a null pointer.
wcstombs
#include <stdlib.h>
size_t wcstombs( char *s, const wchar_t *pwcs,
size_t n );
wcstoul
#include <wchar.h>
unsigned long int wcstoul( const wchar_t *nptr,
wchar_t **endptr, int base );
Same as wcstol, except that it converts the initial portion of the wide
string to unsigned long int.
wcsxfrm
#include <wchar.h>
size_t wcsxfrm( wchar_t *s1, const wchar_t *s2,
size_t n);
Transforms the wide string pointed to by s2 and places the resulting string
into the array pointed to by s1. No more than n wide characters are
placed into the resulting array pointed to by s1, including the terminating
null wide character.
• • • • • • • •
6−104 Chapter 6
wctob
#include <wchar.h>
int wctob( wint_t c );
wctomb
#include <stdlib.h>
int wctomb( char *s, wchar_t wchar );
wctrans
#include <wctype.h>
LIBRARIES
wctype
#include <wctype.h>
wctype_t wctype( const char *property );
wmemchr
#include <wchar.h>
wchar_t *wmemchr( const wchar_t *s,
wchar_t c, size_t n );
wmemcmp
#include <wchar.h>
int wmemcmp( const wchar_t *s1,
const wchar_t *s2, size_t n );
• • • • • • • •
6−106 Chapter 6
wmemcpy
#include <wchar.h>
wchar_t *wmemcpy( wchar_t *s1,
const wchar_t *s2, size_t n );
Copies n wide characters from s2 to s1. Does not check for memory
overlapping.
Returns s1
wmemmove
#include <wchar.h>
wchar_t *wmemmove( wchar_t *s1,
const wchar_t *s2, size_t n );
Returns s1
wmemset
#include <wchar.h>
wchar_t *wmemset( wchar_t *s, wchar_t c, size_t n );
Returns s
wprintf
LIBRARIES
#include <wchar.h>
int wprintf( const wchar_t *format, ... );
wscanf
#include <wchar.h>
int wscanf( const wchar_t *format, ... );
write
#include <unistd.h>
size_t write( int fd, char * buffer, size_t count );
• • • • • • • •
6−108 Chapter 6
check_busoff_16x
#include <can_ext.h>
unsigned char check_busoff_16x( void );
Check if a bus off situation has occurred and recover from bus off.
Returns one if CAN controller was in bus off state, zero otherwise.
check_mo_16x
#include <can_ext.h>
unsigned char check_mo_16x( unsigned char nr );
Returns one if the specified message object contains new date, zero
otherwise.
check_mo15_16x
#include <can_ext.h>
unsigned char check_mo15_16x( void );
def_mo_16x
LIBRARIES
#include <can_ext.h>
void def_mo_16x( unsigned char nr, unsigned char xtd,
unsigned long id, unsigned char dir,
unsigned char dlc, unsigned char txie,
unsigned char rxie );
Returns nothing.
Libraries 6−109
init_can_16x
#include <can_ext.h>
void init_can_16x( unsigned int baud_rate,
unsigned char eie,
unsigned char sie,
unsigned char ie );
Returns nothing.
ld_modata_16x
#include <can_ext.h>
void ld_modata_16x( unsigned char nr,
unsigned char * upl_data_ptr );
Returns nothing.
rd_modata_16x
#include <can_ext.h>
void rd_modata_16x( unsigned char nr,
unsigned char * downl_data_ptr );
Returns nothing.
rd_mo15_16x
#include <can_ext.h>
void rd_mo15_16x( unsigned char * mo15_db_ptr,
unsigned long * mo15_id_ptr,
unsigned char * mo15_dlc_ptr );
Returns nothing.
• • • • • • • •
6−110 Chapter 6
send_mo_16x
#include <can_ext.h>
void send_mo_16x( unsigned char nr );
Returns nothing.
LIBRARIES
Libraries 6−111
When creating your own library, the order of the objects in the library file
is very important. To know the exact order in which the objects should be
placed in the library, make a list of the order in which the delivered
libraries are made by using the command ’ar166 t c166m.lib’,for
example.
The easiest method to create your own library is to make a copy of the
existing library (use the library in the same memory model you want to
create) and replace the existing objects in it by your own made objects
with the command ’ar166 crv libname objectname ...’ . This way
the order of the objects in the library will be maintained. At link time you
only have to link the newly made library to your application instead of a
delivered library.
You can rebuild your library with mk166. To use the correct makefile, first
make sure you are in the directory of the library you want to rebuild:
lib\src\architecture\library (Windows) or
lib\src\architecture\library (UNIX). Use mk166 to rebuild your
library now. (You may want to make a backup copy of the original library
first.)
• • • • • • • •
6−112 Chapter 6
LIBRARIES
CHAPTER
RUN−TIME
ENVIRONMENT
7
7−2
RUN−TIME
7
CHAPTER
Chapter 7
Run−time Environment 7−3
This file specifies the run−time environment of your C166 application. The
file is delivered in assembly source (start.asm) in the directory
lib\src. The file start.asm includes the file cstartx.asm or
cstartx2.asm depending on the selected architecture. Modifications to
these files are not necessary since all parameters can be manipulated using
macro preprocessor symbols.
3. Disable the check box Generate system startup code and add it to
project.
4. Click OK.
5. Remove the file start.asm from the project and add your own startup
code.
• • • • • • • •
7−4 Chapter 7
3. Enable the check box Generate system startup code and add it to
project.
5. Click OK.
After this multiple startup code files may be present in your project.
6. Manually remove the obsolete startup code files from the project.
You can control the contents of the generated startup code from the
Startup entry in the Project Options dialog. From the subentries under
Startup you can specify the registers and their settings that must be
known to the startup code: enable the Include in startup code check
box for the register settings you want to add to the startup code. EDE
automatically generates the register initializations in the startup code.
You must specify the memory model for the preprocessing phase.
Therefore you have to define the preprocessor symbol MODEL. You can
do this with the m166 command line control DEFINE by defining the
memory model you are using. When preprocessing the startup file,
MODEL is checked to select, skip or include certain pieces of code.
The new start.obj can be supplied to l166 when linking the module
containing main(). l166 will use this object instead of the object from the
RUN−TIME
library.
In the startup file the following preprocessor symbols are used (please also
review cstartx.asm or cstartx2.asm ):
NOBITCLEAR
When set, skips clearing of the bitaddressable RAM.
_USRSTACK
Must be enabled (set to 1) to support the user stack model.
Default disabled. See section 3.2.2, User Stack Model for more
details.
• • • • • • • •
7−6 Chapter 7
CALLEINIT
Can be set to a function to be called before the EINIT
instruction is executed, but after register initialization. Like
the CALLINIT function, it may not have a return value or any
arguments.
CALL_USER
Can be set to an include file containing the _main label
entry.
SSKENABLE
If set, intializes the system stack for XC16x/Super10
architectures using a modifiable SYSSTACK system.
First the system is configured using a macro for each configuration item:
wait states, read/write signal delay, system clock output, segmentation
control, system stack size etc. You must specify these values using the
appropiate macros, depending on the specific needs of your target system.
RUN−TIME
The system stack registers (overflow, underflow and stack pointer) are
initialized using the predefined symbols ?SYSSTACK_BOTTOM and
?SYSSTACK_TOP. The assembler, linker and locator treat predefined
symbols (all starting with a ’?’) in a special way. They give the assembler
programmer access to information which is normally not available before
the locate stage of the application.
Run−time Environment 7−7
After the context pointer register is set to the register bank of this task,
write output is enabled and the ’end−of−initialization’ instruction (EINIT) is
executed.
All bit addressable memory is cleared, because this guarantees all non
initialized bit variables of each task to have the value of 0.
Finally, the DPP registers are initialized, depending on the memory model
used. DPP0 to DPP2 are initialized accordingly. The predefined symbols
?BASE_DPP0 to ?BASE_DPP2 are used to initialize DPP0 to DPP2.
Last but not least, the user stack pointer is initialized using the predefined
symbol ?USRSTACK_TOP.
At the assembly label __EXIT, the system stack pointer, the user stack
pointer and the floating point stack (if floats are used) are restored and the
program performs an endless loop setting the CPU in power down mode
(IDLE instruction).
• • • • • • • •
7−8 Chapter 7
The system stack is used for return addresses (CALL/RET instructions) and
can be accessed via PUSH/POP instructions (using the SP register).
Because the system stack is very small (internal memory for the
C166/ST10), c166 tries to avoid it as much as possible. Code generator
temporaries are pushed on the user stack. Via the −Ou option it is even
possible to let a task switch (interrupt) use the user stack instead of the
system stack. As described above, you must specify the size of the system
stack size in the system startup code (SYSCON register), which is the
system stack size for all tasks (the whole application).
From EDE you can set the system stack size in the Stack and Heap page
of the Linker/Locator entry in the Project | Project Options dialog.
If −P is used, the system stack is not used at all. See section 3.2.2, User
Stack Model for details.
The user stack is the so−called ’C stack’. c166 uses R0 as ’User Stack
Pointer’ and the [−R0]/[R0+] addressing modes perform push/pop
sequences. If data paging is used (medium and large memory model), the
user stack is limited to 16K (one page). In these models, c166 uses DPP1
as ’user−stack page number’. The locator combines the user stack areas of
each task to one global user stack area (with cumulated size). A context
switch inherits the user stack pointer (R0) value in the new register bank
and DPP1 remains unchanged.
RUN−TIME
c166 estimates the needed user stack size for each C module by adding
the stack sizes of each function to each other. This amount of bytes is
allocated in the data section called C166_US (see section 3.2.3, Section
Allocation). However, in most cases this is too big, because not all
functions are active simultaneously. In other cases, the size will be too
small, e.g. when recursive functions are present (note that qsort() is
implemented as a recursive function).
You can modify the user stack size using the SECSIZE control of the
locator.
Run−time Environment 7−9
double precision
return value
conventional
parameters
pushed register
parameters
conventional
stacksize
automatics
Example:
l166 task t1.lno SECSIZE(C166_US(−50))
task t2.lno SECSIZE(C166_US(−10))
TO applic.out
• • • • • • • •
7−10 Chapter 7
When the Flat Interrupt Concept is used the link stage is skipped and the
locator generates the ?C166_NHEAP and ?C166_FHEAP sections when it is
needed. You can use the HEAPSIZE control for changing the heap size at
locate stage. The dynamic memory management library functions are not
reentrant, because they use static data for the memory management. This
means that when the memory management functions are used, it is not
possible to interrupt them with an interrupt function which also uses the
memory management functions. If reentrancy is needed with memory
management functions, you should use the Task Concept where each
interrupt can have its own memory management.
In the tiny and small model the default memory allocation routines use the
?C166_NHEAP section, which has the section type ’LDAT’ allowing a total
heap size up to 64K. Because paging is not used (except for the small SND
variant, a linear 16−bit pointer is returned), the maximum amount of
memory asked for is not limited to a page (16K).
In the medium and large model the ?C166_FHEAP section is used by the
default memory allocation routines. This section has the section type
’HDAT’ allowing a total heap size greater then 64K. However, in these
models paging is used: a far pointer is returned. This means that you
cannot allocate (dynamically) a single buffer greater than one page (16K).
Of course you can allocate the whole heap in pieces of (approximately)
16K. In these models, you should use memory allocation with great care,
RUN−TIME
Please note that the non−near variants of the memory allocation routines
all use the same heap stack ?C166_FHEAP and are in the same source
module. Use of the fmalloc() routine will therefore automatically
include support for the smalloc() and hmalloc() routines.
• • • • • • • •
7−12 Chapter 7
{
return( c + i );
}
Now compile this module, using the correct memory model. The compiler
makes the correct frame, and you can edit the generated assembly
module, to make the real assembly function inside this frame.
Run−time Environment 7−13
Inline assembly
A second method to create an interface to assembly is to use inline
assembly in C. Assembly lines in the C source must be introduced by a
’#pragma asm’, the end is indicated by a ’#pragma endasm’.
For example:
int
inline( char c, int i )
{
int j = i − c;
if ( j > 5 )
{
#pragma asm
NOP ; do something in assembly
#pragma endasm
j = 0;
}
return ( j );
}
If the inserted assembly code does not change any registers, like in the
example above, also ’#pragma asm_noflush’ may be used instead of
’#pragma asm’. The advantage of this pragma is that the peephole buffer is
not flushed, so the compiler will emit a JMPR instructions instead of a
JMPA instruction for the condition above. Note that the inserted assembly
is NOT interpreted, so code size reported is only the code generated for C
statements. The disadvantage of the ’#pragma asm_noflush’ is that the
distance checking for relative jumps becomes your responsibility !
Note that the compiler also does NOT recognize inline CALL instructions.
If a function does not call any other function from C, it is treated like a
’leaf’ function, so parameter registers of this function are not saved on the
user stack at function entry. If a ’leaf’ function calls another function using
inline assembly, it is your responsibility to preserve the parameter registers
(if any) of this ’leaf’ function.
• • • • • • • •
7−14 Chapter 7
module1.c:
#include "header.h"
...
int c=CONSTANT;
module2.asm:
#include "header.h"
...
MOV R0, CONSTANT
and
c166 −E −o module2.src module2.asm
a166 module2.src TO module2.obj
When you use the control program, the default preprocessor for assembly
files is m166. You can change this default by using the −cprep option,
which forces the control program to use the C preprocessor instead. The
above files can thus be easily built with the following single command:
RUN−TIME
Please note that the C preprocessor will not replace anything between
#pragma asm and #pragma endasm in your C source.
APPENDIX
MISRA C
A
A−2
MISRA C
A
APPENDIX
Appendix A
MISRA C A−3
• • • • • • • •
A−4 Appendix A
• • • • • • • •
A−6 Appendix A
parentheses
x 86. (A) If a function returns error information, it should be tested
87. (R) #include shall only be preceded by other directives or
comments
88. (R) Non−standard characters shall not occur in #include
directives
MISRA C A−7
• • • • • • • •
A−8 Appendix A
112. (R) Bit fields of type "signed int" shall be at least 2 bits long
113. (R) All struct/union members shall be named
114. (R) Reserved and standard library names shall not be redefined
115. (R) Standard library function names shall not be reused
x 116. (R) Production libraries shall comply with the MISRA C
restrictions
x 117. (R) The validity of library function parameters shall be checked
118. (R) Dynamic heap memory allocation shall not be used
119. (R) The error indicator "errno" shall not be used
120. (R) The macro "offsetof" shall not be used
121. (R) <locale.h> and the "setlocale" function shall not be used
122. (R) The "setjmp" and "longjmp" functions shall not be used
123. (R) The signal handling facilities of <signal.h> shall not be used
124. (R) The <stdio.h> library shall not be used in production code
125. (R) The functions atof/atoi/atol shall not be used
126. (R) The functions abort/exit/getenv/system shall not be used
127. (R) The time handling functions of library <time.h> shall not be
used
B
B−2
DEBUG ENVIRONMENT
B
APPENDIX
Appendix B
Debug Environment B−3
Please see the CrossView user’s manual which areas are in use by the
monitor that is used for your evaluation board.
In the start.asm file, the @EVA symbol must be enabled (set to 1).
When using a ROM monitor with a dual vector table, the vector table of
your application should be located at the memory location where the
monitor expects it to be. Use the l166 VECTAB locator control to supply
the vector table start location to the locator. For example:
VECTAB( 08000h )
Please refer to the CrossView user’s manual for the required vector table
location for the board and monitor that you use.
When using this dual vector table ROM monitor, you must also supply the
−sstartaddress option to the ieee166 IEEE−695 object formatter. The
startaddress should be address where you located the vector table with the
VECTAB control. This address will be generated in the absolute file.
CrossView Pro will start execution at this address after a program reset.
• • • • • • • •
B−4 Appendix B
2 KONTRON DEBUGGER
When using Kontron debuggers, the following operation remarks exist:
• Use the TASKING ieee166 converter program to generate an
IEEE−695 output file from the absolute (located) output file. The
Kontron KSE695 filter program is needed to translate this
IEEE−695 file into Kontron object and symbol files.
• You can use the compiler option −g to generate debug information
for use by Kontron debuggers. Versions of KSE695 previous to v4.3
(04) may require using the compiler option −gb. The −gb option
prevents c166 from emitting ’bit’, ’bitfield’ and ’80166 pointer
behavior’ high level language information.
• The KSE695 command line option ’−t t −x .’ must be used when
converting IEEE−695 format to Kontron format.
−t t = Specify TASKING c166 IEEE−695 format.
where, inputfile is the file you would normally process with the TASKING
macro preprocessor or assembler and outputfile is the instrumented output
file. This output file is the file you must use for preprocessing/assembly.
The input and output filename must differ.
Debug Environment B−5
Batch file when TASKING m166 used Batch file when m166 not used
@echo off @echo off
rem RELINE1.BAT rem RELINE2.BAT
line166 %1.asm %1.a66 line166 %1.asm %1.a66
if errorlevel 1 goto end if errorlevel 1 goto end
m166 %1.a66 a166 %1.a66 debug
if errorlevel 1 goto end if errorlevel 1 goto end
del %1.a66 del %1.a66
a166 %1.src debug :end
if errorlevel 1 goto end
del %1.src
:end
or,
reline2 asmfile
• • • • • • • •
B−6 Appendix B
You should use the l166 RESERVE MEMORY locator control to prevent the
locator from locating sections in these regions.
For example:
RE( ME( 00000hTO 079FFh ),
ME( 40000hTO 401FFh ),
ME( 40200hTO 415FFh ),
ME( 0FCE0hTO 0FCFFh ) )
DEBUG ENVIRONMENT
4 PLS FAST−VIEW66
When using the fast−view66 debugger, the following operation remarks
exist:
• Use the −g compiler option to generate debug information for use
with fast−view66.
• Fast−view66 supports all C/C++ language debug information
generated by c166/cp166.
• You can use the absolute output file format (locator output file) for
download to the C166/ST10 target hardware.
• • • • • • • •
B−8
DEBUG ENVIRONMENT Appendix B
APPENDIX
CPU FUNCTIONAL
PROBLEMS
C
C−2
CPU PROBLEMS
C
APPENDIX
Appendix C
CPU Functional Problems C−3
1 INTRODUCTION
Infineon Components and STMicroelectronics regularly publishe
microcontroller errata sheets for reporting both functional problems and
deviations from the electrical and timing specifications.
Please refer to the Infineon / STMicroelectronics errata sheets for the CPU
step you are using, to verify if you need to use one of these bypasses.
• • • • • • • •
C−4 Appendix C
−BH
Use libraries:
lib\[u]ext2p\*.lib
−BE
CPU PROBLEMS
Use libraries:
lib\[u]extp\*.lib
−BU
Use libraries:
lib\[u]166p\*.lib
lib\[u]extp\*.lib
lib\[u]ext2p\*.lib
This solution should be used where failures occur for interrupts during the
MUL and MULU instructions:
− For C166 derivatives, the compiler option −BU emits code using
run−time library calls for the multiply operations. In these run−time
library calls, the operations are protected against interrupts, so that
the problem cannot occur.
− For ext and ext2 derivatives, multiply operations are protected inline
using ATOMIC instructions. In some cases, an additional NOP might
be generated after the multiply instruction. When you want to use
the inline protection, you should use both the compiler options
−x[i] and −BU.
When using the −BU option you should also link libraries in which the
divide operations are protected. The libraries in the directories lib\166p,
lib\extp and lib\ext2p also have the divide protected against
interrupts, but can be used safely to bypass this CPU problem.
• • • • • • • •
C−6 Appendix C
−BF
Use libraries:
lib\[u]166p\*.lib
lib\[u]extp\*.lib
lib\[u]goldp\*.lib
2. when [Rn] points to the internal RAM or SFR/ESFR address space, (a)
the (correct) data value [mem] is written to [Rn]+1, i.e. to the odd byte
address of the selected word in case [Rn] points to an even byte
address, (b) the (correct) data value [mem] is written to [Rn]−1, i.e. to
CPU PROBLEMS
the even byte address of the selected word in case [Rn] points to an
odd byte address.
−BM
Use libraries:
lib\[u]166p\*.lib
lib\[u]extp\*.lib
lib\[u]ext2p\*.lib
This solution should be used where failures occur for interrupts during the
MUL, MULU, DIV, DIVU, DIVL and DIVLU instructions:
− For C166 derivatives, the compiler option −BM emits code using
run−time library calls for the multiply and divide operations. In
these run−time library calls, the operations are protected against
interrupts, so that the problems cannot occur.
− For ext and ext2 derivatives, multiply and divide operations are
protected inline using ATOMIC instructions. In some cases, an
additional NOP might be generated after the multiply or divide
instruction. When you want to use the inline protection, you should
use both the compiler options −x[i] and −BM.
−BM is a workaround for many MUL/DIV problems. Besides CPU.18 it
fixes problem 7, problem 13, problem 17, CPU.2 and CPU.11.
When using the −BM option you should also link libraries in which the
multiply and divide operations are protected.
• • • • • • • •
C−8 Appendix C
−BO
Use libraries:
lib\[u]extp\*.lib
The opcode MOV (B) Rn, [Rm+#data16] can cause the CPU to hang. The
problem is encountered under the following conditions:
• [Rm+#data16] is used to address the source operand
• [Rm+#data16] points to the program memory
• a hold cycle has to be generated by the ir_ready signal at the
beginning of the operand fetch cycle
Since the compiler is unaware of the actual location the source operand
[Rm+#data16] refers to, the generation of this addressing mode is
completely surpressed.
−BK
Use libraries:
lib\[u]extp\*.lib
−BZmovbjb
Use libraries:
lib\[u]extp\*.lib
Example 1:
; Assume Rx.0 is 0 (x any GPR 0..7)
MOVB RxH, any_value ; Any Byte write instruction on RxH
JB Rx.0, jump_address ; WILL BE WRONGLY TAKEN!
Example 2:
; Assume Rx.y is 1 (x any GPR 0..7; y any bit except bit0)
MOVB RxL, any_value ; Any Byte write instruction on
; RxL for y= 8..15 or RxH for y= 1..7
JNB Rx.y, jump_address ; WILL BE WRONGLY TAKEN!
Example 3:
; Assume Rx.0 is 0(x any GPR 0..7)
MOVB RxH, any_value ; Any Byte write instruction on R0H
JNB Rx.0, jump_address ; WILL NOT BE TAKEN!
Example 4:
; Assume Rx.y is 1(x any GPR 0..7; y any bit except bit0)
MOVB RxL, any_value ; Any Byte write instruction on
; RxL for y= 8..15 or RxH for y= 1..7
JB Rx.y, jump_address ; WILL NOT BE TAKEN!
Note that the bug is only visible when the bit used for the jump evaluation
is set (i.e."1") for all the bits Rx.15 to Rx.1, or not−set (i.e."0") for Rx.0.
• • • • • • • •
C−10 Appendix C
Note that the bug exists also when the byte write operation writes into the
GPR using indirect addressing mode or memory addressing mode. This
situation includes also the use of PECB/DPECB which destination pointer
points into a GPR (i.e. data write is performed on a GPR).
Workaround:
−BZc166sv1div
Use libraries:
lib\[u]extp\*.lib
In the first states of a division several internal control signals are set that
are used in later states of the division. If a division is interrupted and in
the interrupt service routine (ISR) another division is executed, it overrides
the old internal values. After the return the interrupted division proceeds
with the (probably wrong) internal states of the last division. The affected
internal signals are dividend_sign , divisisor_sign and mdl_0. The
first two bits represent the operand signs (=Bit 15). mdl_0 is set if MDL is
0xFFFF.
Workaround:
−BZc166sv1jbc
Use libraries:
lib\[u]extp\*.lib
Note that these instructions work properly for GPR operands and SFR
operands.
• • • • • • • •
C−12 Appendix C
Workaround:
Do not use JBC and JNBS instructions, unless the first operand is a
GPR.
−BZc166sv1trap
Use libraries:
lib\[u]extp\*.lib
Due to the previous operation the TRAP is canceled and at the same time
a real interrupt occurs. As a result of this, the last previously executed
interrupt is injected and then the real interrupt is injected too (if its priority
is high enough).
CPU PROBLEMS
Note that instructions modifying the PSW are almost all the instructions:
arithmetic/logical instructions, MOVs,..... For a detailed list of instructions
modifying PSW refer to the User Manual.
Workaround:
−BZc166sv1ext
Use libraries:
lib\[u]extp\*.lib
Affected are the instructions EXTR, EXTP, EXTPR, EXTS, EXTSR and
ATOMIC since the responsible code generates the control signals for all
these instructions, however, the effects will differ.
Example:
EXTR #1
JB DP1H.6, JMP_TARGET ; taken jump
MOV MDC, #0000Fh
MOV MDH, MDL
CALL never_reached
JMP_TARGET:
MOV MDC, #0000Fh
MOV MDH, MDL
In this example the jump is correctly executed and taken. However, the
control signal for the extended register sequence is not reset. So, at
JMP_TARGET the extend sequence is still effective. This means that the
move instruction is extended and instead of writing to the SFR MDC
(FF0Eh) the move instruction writes to address F10Eh, an ESFR address.
The bug occurs with taken conditional jumps only, since they are
executed as two cycle commands and therefore re−injected in the pipeline.
If the jump is not taken or unconditional, the sequence above will work
properly, since these jumps are executed as single cycle commands! With
"extr #2" in the sequence above, the second move will be affected as well!
ATOMIC instructions seem to be a minor issue, since they do not create
invalid accesses; in this case the consequence of the bug is that the
ATOMIC sequence will be extended to the target instructions also.
Workaround:
• • • • • • • •
C−14 Appendix C
−BZinsert_div_mdl
Use libraries:
The V flag can be wrongly calculated for signed divisions: the V flag is
only set if the most significant bit of the result is set (that is, if the result is
negative).
Workaround:
−BZcpu_reti_int
Use libraries:
The bug occurs when two interrupts are trying to get into the CPU while a
RETI instruction is being executed. In this case it can happen that one
interrupt is lost (the first one, even if it has a higher priority). Furthermore,
the program flow after the ISR can be broken. Only the RETI instruction is
affected by this bug. This is because this instruction is specially managed.
The instruction following the RETI is internally marked as not
interruptable. This means that no interrupt will be served by the CPU
between the RETI and its following instruction. This bug is the
consequence of an error in how this special treatment is implemented in
the logic, specifically in the generation of the "not interruptable"
indication.
−BZcpu_jmpra_cache
Use libraries:
• • • • • • • •
C−16 Appendix C
−BZinsert_mdl_muldiv
Use libraries:
CPU PROBLEMS
Workaround:
−BN
Use libraries:
lib\[u]extp\*.lib
• • • • • • • •
C−18 Appendix C
−BL
Use libraries:
lib\[u]ext2p\*.lib
Description:
JMPI
When the program hits a breakpoint right before a JMPI instruction, the
first instruction injected in the pipeline will not be processed by the core.
This leads to a deny of all interrupts and OCE injection requests. The
problem may also occur when single stepping right before a JMPI
instruction.
CALLI
−BA
Use libraries:
lib\[u]ext2p\*.lib
Use libraries:
lib\[u]166p\*.lib
lib\[u]extp\*.lib
lib\[u]ext2p\*.lib
lib\[u]goldp\*.lib
• • • • • • • •
C−20 Appendix C
−BI
Use libraries:
In this case the previously mentioned workaround can be used, but at the
price of an increased worst case interrupt response time.
−BB
Use libraries:
lib\[u]166p\*.lib
This problem occurs on older steps of the FLASH EPROM version of the
CPU. With the −BB option the compiler generates two NOP instructions
after each instruction which does a byte write operation. These
instructions are: ADDB, ADDCB, ANDB, CPLB, MOVB, NEGB, ORB,
SUBB, SUBCB, XORB. The pragma fix_byte_write and nofix_byte_write
can be used to switch this option on the fly in your source code. To
reduce the number of NOP instructions to be generated, you can use the
disassembler d166 to detect where erroneous sequences are generated for
the CPU.
• • • • • • • •
C−22 Appendix C
−BJ
Use libraries:
lib\[u]extp\*.lib
The compiler prevents the JMPS instruction from interfering with the PEC
transfers by inserting an ATOMIC #2 instruction before a JMPS instruction.
This bypass option can only be used in combination with the extended
instuction set. Further more, all JMPS instructions in the interrupt vector
table are replaced by CALLS instructions. The compiler will generate an
ADD SP, #04h instruction in the interrupt frame to delete the return
address generated by the CALLS instruction from the system stack.
The assembler contains the $CHECKSTBUS1 control to check for this CPU
problem.
The instruction to delete the return address from the system stack is part of
the interrupt frame and will NOT be generated if #pragma noframe was
used.
CPU PROBLEMS
APPENDIX
D
D−2
USER STACK MODEL
D
APPENDIX
Appendix D
User Stack Model D−3
1 INTRODUCTION
This appendix describes the special coding methods used in the libraries
and C166/ST10 C compiler to support a special stack frame. This appendix
describes a user stack model approach, which is used in a special version
of the libraries.
If you use the −P option of c166, the compiler does not emit the regular
CALL/RET instructions, when calling a C function, but emits code using a
jumping mechanism, specifying the return address on the user stack. The
advantage of this approach is that the system stack is not used for the
function return address. The price paid for this feature is a run−time
execution speed performance penalty. The special libraries needed to
support this feature are included in the C and C++ compiler packages.
There are two valid reasons to use this option (and libraries):
• RTOS
When using a RTOS kernel, it is often not allowed to use the system
stack area (in fact change SP), because this area is reserved for the
kernel. Therefore, the −P option must be used when using RTOS.
• Heavy recursion
When the system stack area is getting too small and it is not possible to
implement a circular system stack approach (using SOV/SUN exception
handlers), the −P option can be used. In this case the compiler uses the
user stack instead of the system stack. You must link the application
with the user stack model libraries.
Using −P does not mean that you have to use a RTOS. You can run the
application as a standalone application, without any kernel.
The push and pop instructions are only allowed during hardware task
switches. Nevertheless, with the C compiler option −Ou, it is possible to
use the user stack instead of the system stack for hardware task switches.
See the −Ou option in section 4.3 Detailed Description of the Compiler
options in this manual.
• • • • • • • •
D−4 Appendix D
The conventions for register and data page usage, as well as the calling
conventions for functions, are fully documented in chapter 3 Language
Implementation. Section 3.6 Function Parameters of chapter 3, describes
when parameters are passed via registers and when they are passed via
the user stack.
RETURN
A direct intra−segment function call (near function call) is normally
performed with a CALLA instruction and returned with a RETN instruction.
But the direct intra−segment function call must be performed without
using the system stack.
Therefore, the user stack is used to pass the return label to the near
function. Then the near function is invoked using an absolute
intra−segment jump. At exit, the near function return is implemented using
an indirect jump on the contents of the user stack.
The following assembly listing displays the code the C compiler generates
for an absolute near function call. The near function called is named _f.
Rn is a register used by the C compiler for temporary results.
User Stack Model D−5
min.
code state
. size times
.
mov Rn, #SOF __RETURN_LABEL 4 2
mov [−R0], Rn 2 2
jmpa CC_UC, _f 4 4
__RETURN_LABEL:
. −− −−
. 10 8
The assembly listing described below displays the code the C compiler
generates to return to the caller of the near function.
min.
code state
. size times
.
mov R2, [R0+] 2 2
jmpi CC_UC, [R2] 2 4
retv ; virtual return 0 0
. −− −−
. 4 6
Temporary register R2 is used to pop the return address from the user
stack and to continue program execution at the return label via a indirect
jump on the contents of R2. The user stack pointer is updated by the
called function before it returns (see [R0+]). This is not the regular
method to handle the user stack pointer in a C function, but this saves one
instruction. Register R2 can be used, because it is always free for use at
function return. No parameters are returned via register R2.
The following assembly listing displays the code the C compiler generates
for an indirect near function call. The near function called indirectly is in
the function pointer array named _fp. Rx contains the index value. Rn is a
register used by the C compiler for temporary results.
• • • • • • • •
D−6 Appendix D
min.
code state
. size times
.
mov Rn, #SOF __RETURN_LABEL 4 2
mov [−R0], Rn 2 2
mov Rn, [Rx+#_fp] 4 4
jmpi CC_UC, [Rn] 2 4
__RETURN_LABEL:
. −− −−
. 12 12
The next assembly listing displays the code the C compiler generates for a
far function call when extended instructions are available.
The far function called is named _f. Rsof and Rseg are registers used by
the C compiler for temporary results.
min.
code state
. size times
.
mov Rsof, #SOF __RETURN_LABEL 4 2
mov [−R0], Rsof 2 2
mov Rseg, #SEG __RETURN_LABEL 4 2
mov [−R0], Rseg 2 2
jmps SEG _f, SOF _f 4 4
__RETURN_LABEL: −− −−
. 16 12
.
The next assembly listing displays the code the C compiler generates for a
far function to return to its caller.
• • • • • • • •
D−8 Appendix D
min.
code state
. size times
.
mov Rseg, [R0+] 2 2
mov Rsof, [R0+] 2 2
atomic #3 2 2
push Rseg 2 2
push Rsof 2 2
rets 2 4
. −− −−
. 12 14
Also now the segment number and segment offset of the return label must
be stored on the user stack before an indirect inter−segment jump can be
performed to the far function. The far function being invoked returns to its
caller by getting the return label from the user stack and then performing
an indirect inter−segment jump to the return label. The far function being
invoked is determined run−time. So, an indirect inter−segment jump is
needed. When segment number and segment offset of the far function
being called is determined run−time, the same mechanism as described in
section 2.4, can be used again to make the inter−segment jump.
The next assembly listing displays the code the C compiler generates for
an indirect far function call when extended instructions are available.
The far function called indirectly is in the function pointer array named
_fp. Rx contains the index value. Rseg and Rsof are registers used by
the C compiler for temporary results.
User Stack Model D−9
min.
code state
. size times
.
mov Rsof, #SOF __RETURN_LABEL 4 2
mov [−R0], Rsof 2 2
mov Rseg, #SEG __RETURN_LABEL 4 2
mov [−R0], Rseg 2 2
mov Rsof, [Rx+#_fp ] 4 4
mov Rseg, [Rx+#_fp+02H] 4 4
atomic #3 2 2
push Rseg 2 2
push Rsof 2 2
rets 2 4
__RETURN_LABEL: −− −−
. 28 26
.
It is obvious that the code, needed to return from a far function is always
the same, because the function does not know whether it is called directly
or indirectly. See section 2.4 for the code the C compiler generates to
return from a far function when extended instructions are available.
• • • • • • • •
D−10
USER STACK MODEL Appendix D
INDEX
INDEX
Index−2 Index
INDEX
INDEX
Index Index−3
nomacro, 4−95
Symbols noreorder, 4−95
?BASE_DPPn, 7−7 nosavemac, 4−96
#define, 4−21 nosource, 4−96
#include, 4−34, 4−85 novolatile_union, 4−97
#pragma, 4−88 preserve_mulip, 4−95
alias, 4−88 public, 4−95
align, 4−91 regdef, 4−95
align32, 4−89 reorder, 4−95
asm, 3−73, 4−90 restore_attributes, 4−92
asm_noflush, 3−73, 4−90 resume_align32, 4−89
autobita, 4−90 romdata, 3−68, 3−70, 4−93
automatic, 4−90 save_attributes, 4−92
autosavemac, 4−96 savemac, 4−96
class, 4−91 size, 4−96
clear, 4−91 source, 4−96
combine, 4−91 speed, 4−96
cse resume, 4−91 static, 4−91
cse suspend, 4−91 stringmem, 4−96
custack, 4−91 suspend_align32, 4−89
default_attributes, 4−92 switch_force_table, 4−96
dfap, 4−92 switch_smart, 4−97
endasm, 3−73, 4−90 switch_tabmem_default, 4−97
eramdata, 3−68, 4−92 switch_tabmem_far, 4−97
fix_byte_write, 4−93 switch_tabmem_near, 4−97
fragment, 4−93 volatile_union, 4−97
fragment continue, 4−93 #undef, 4−78
fragment resume, 4−93 −DMEASURE_TIME, 2−25
global, 4−95 −g option, D−4
global_dead_store_elim, 4−93 −Ou option, D−3
indirect_access, 4−94 −P option, D−3
iramdata, 3−68, 4−92 __banksw, 3−136
m166include, 4−94 __DATE__, 4−78
macro, 4−95 __FILE__, 4−78
no_global_dead_store_elim, 4−94 __FP_ENV, 3−105
noalias, 4−89 __LINE__, 4−78
noalign32, 4−89 __STDC__, 4−78
noclear, 4−92 __TIME__, 4−78
nocustack, 4−91 _at attribute, 3−41
nodfap, 4−92 _atbit attribute, 3−43
nofix_byte_write, 4−93 _atomic, 3−123
noframe, 3−77, 4−95 _bfld, 3−119
• • • • • • • •
Index−4 Index
_pag, 3−126
_pof, 3−126 A
_prior, 3−122 a166, 2−9
_putbit, 3−120 abort, 6−23
_pwrdn, 3−122 abs, 6−24
_read, 6−18 access, 6−24
_rol, 3−117 accessing memory, 3−5
_ror, 3−118 acos, 6−24
_seg, 3−127 address ranges, 3−5
_SINGLE_FP, 3−62 addresses linear, 3−8
_sof, 3−127 alias, 4−44, 4−88, 4−98
_srvwdt, 3−122 align, 4−91
_sstrcat, 6−18 align type, 3−30, 3−35, 4−69
_sstrchr, 6−19 align32, 4−89
_sstrcmp, 6−19 ansi standard, 2−3, 3−3, 3−68, 3−70
_sstrcpy, 6−19 ar166, 2−11
_sstrcspn, 6−19 asctime, 6−24
_sstrlen, 6−20 asin, 6−25
_sstrncat, 6−20 asm, 4−90
_sstrncmp, 6−20 asm_noflush, 4−90
_sstrncpy, 6−21 assembly language interfacing, 7−12
_sstrpbrk, 6−21 assembly source file, 2−9
_sstrrchr, 6−21 assert, 6−25
_sstrspn, 6−21 assert.h, 6−7
_sstrstr, 6−22 assert, 6−25
_sstrtok, 6−22 atan, 6−25
_stime, 6−18 atan2, 6−25
_testclear, 3−118 atexit, 6−26
_testset, 3−119 atof, 6−26
_tolower, 6−22 atoi, 6−26
_toupper, 6−22 atol, 6−26
_tzset, 6−23 atomic instruction, D−6
_unlink, 6−23 autobita, 4−90
_usm function qualifier, 3−28 autobitastruct, 4−90
_USMLIB, 3−62 automatic, 4−90
_USRSTACK, 7−5 automatic initializations, 3−68
_write, 6−23 autosavemac, 4−96
_xnear, 3−21
_xsfr keyword, 3−60
• • • • • • • •
Index−6 Index
CALLEINIT, 7−6
B CALLINIT, 7−6
backend calloc, 6−27
compiler phase, 2−5 CAN, 6−6
optimization, 2−5 CAN library, interface description,
bank, function qualifier, 3−135 6−108
bank switch, 3−137 can_ext.h, 6−7
benchmark, 2−25 check_busoff_16x, 6−108
bit, 3−53 check_mo_16x, 6−108
bit type, 3−58 check_mo15_16x, 6−108
BIT_INIT, 7−5 def_mo_16x, 6−108
bita, 3−26 init_can_16x, 6−109
bitword, 3−53 ld_modata_16x, 6−109
bitword type, 3−59 rd_mo15_16x, 6−109
bsearch, 6−27 rd_modata_16x, 6−109
btowc, 6−27 send_mo_16x, 6−110
build, viewing results, 2−23 canr_16x.h, 6−7
build an application, 2−24 casting pointer to long, 4−59, 4−62
command line, 2−24 cc166, 2−11, 4−3
control program, 2−24 ceil, 6−28
EDE, 2−23 character arithmetic, 3−57, 4−12
makefile, 2−29 chdir, 6−28
separate programs, 2−26 check_busoff_16x, 6−108
built−in functions, 3−107 check_mo_16x, 6−108
builtin.c, 3−128 check_mo15_16x, 6−108
class, 3−30, 4−91
class name, 4−69
clear, 4−91
C clearerr, 6−28
clearing variables, 4−45
C CLIBRARY, 6−5
inline functions, 3−44 clock, 6−28
language extensions, 3−3 close, 6−29
C function return types, 3−87 code checking, 3−140
C library, 6−4 code density, 4−49
creating your own, 6−111 code memory banking, 3−135
interface description, 6−10 code memory fragmentation, 3−37
C startup code, 7−3
INDEX
• • • • • • • •
Index−8 Index
• • • • • • • •
Index−10 Index
I
G identifier, 4−13
IEEE−754
general purpose registers, 3−87 error handling, 3−106
getc, 6−40 floating point format, 3−88
getchar, 6−41 ieee166, 2−9
getcwd, 6−41 ihex166, 2−11
getenv, 6−41 include files, 4−85
gets, 6−41 default directory, 4−86
getwc, 6−42 setting search directories, 1−5, 1−6
getwchar, 6−42 indirect_access, 4−94
global, 3−51, 4−95
• • • • • • • •
Index−12 Index
K license
floating, 1−9
keyword node−locked, 1−9
_bita, 3−26 obtaining, 1−10
_cached, 3−82 trial mode, 1−9
_far, 3−21 wait for available license, 1−7
_huge, 3−21 license file
_inline, 3−44 location, 1−13
_interrupt, 3−76 setting search directory, 1−7
• • • • • • • •
Index−14 Index
M mbstowcs, 6−54
mbtowc, 6−55
m166, 2−11 medium model, 3−23
m166include, 4−94 memchr, 6−55
macro, 4−95 memcmp, 6−55
macros in C, 3−62 memcpffb, 6−56
makefile memcpffw, 6−56
automatic creation of, 2−20 memcpfhb, 6−56
updating, 2−20 memcpfhw, 6−57
makefiles, 2−29 memcpfnb, 6−57
malloc, 6−52 memcpfnw, 6−57
math.h, 6−7 memcpfsb, 6−58
acos, 6−24 memcpfsw, 6−58
asin, 6−25 memcphfb, 6−58
atan, 6−25 memcphfw, 6−59
atan2, 6−25 memcphhb, 6−59
ceil, 6−28 memcphhw, 6−59
INDEX
• • • • • • • •
Index−16 Index
P iramdata, 4−92
m166include, 4−94
packed structures, 3−46 macro, 4−95
parser, 2−5 no_global_dead_store_elim, 4−94
PDAT, 3−12 noalias, 4−89
PEC support, 3−142 noalign32, 4−89
peephole optimization, 4−52 noclear, 4−92
perror, 6−69 nocustack, 4−91
pointer, casting to long, 4−59 nodfap, 4−92
register nofix_byte_write, 4−93
automatic register variable noframe, 4−95
allocation, 4−60 nomacro, 4−95
contents tracing, 4−53 noreorder, 4−95
portable c code, 3−144 nosavemac, 4−96
pow, 6−69 nosource, 4−96
pragma, 3−35, 4−88 novolatile_union, 4−97
alias, 4−88 on command line, 4−84
align, 4−91 preserve_mulip, 4−95
align32, 4−89 public, 4−95
asm, 4−90 regdef, 4−95
asm_noflush, 4−90 reorder, 4−95
autobita, 4−90 restore_attributes, 4−92
autobitastruct, 4−90 resume_align32, 4−89
automatic, 3−66, 4−90 romdata, 4−93
INDEX
• • • • • • • •
Index−18 Index
• • • • • • • •
Index−20 Index
• • • • • • • •
Index−22 Index
towlower, 6−92
towupper, 6−93 V
trap, 3−98 va_arg, 6−94
trap routine, 3−98 va_end, 6−94
trap.obj, 3−97 va_start, 6−94
trial mode, 1−9 variables
initialized, 3−68
non−initialized, 3−69
U version information, 4−80
vfprintf, 6−94
unaligned data, 3−45 vfwprintf, 6−95
ungetc, 6−93 volatile, 3−61
ungetwc, 6−93 volatile_union, 4−97
unistd.h, 6−8 vprintf, 6−95
access, 6−24 vsprintf, 6−95
chdir, 6−28 vswprintf, 6−96
close, 6−29 vwprintf, 6−96
fstat, 6−38
getcwd, 6−41
lstat, 6−51
read, 6−74 W
stat, 6−83 warnings, 5−6
unlink, 6−93 warnings (suppress), 4−81
write, 6−107 wchar.h, 6−9
unlink, 6−93 btowc, 6−27
unsigned fgetwc, 6−33
char, 3−53 fgetws, 6−33
int, 3−53 fputwc, 6−35
long, 3−53 fputws, 6−36
short, 3−53 fwide, 6−39
updating makefile, 2−20 fwprintf, 6−39
user defined intrinsics, 3−129 fwscanf, 6−40
user stack, 3−64, 7−8, D−3, D−4, D−5, getwc, 6−42
D−7, D−8 getwchar, 6−42
for task switch, 4−63, 4−65 mbrlen, 6−52
user stack model, 4−68, 4−74, D−9 mbrtowc, 6−53
special library, 3−28 mbsinit, 6−53
INDEX
• • • • • • • •
Index−24 Index
wmemmove, 6−106
wmemset, 6−106 X
wprintf, 6−106 XC16x C language extensions, 3−79
write, 6−107 xnear pointer, 3−53
wscanf, 6−107 xsfr, 3−53
INDEX