|
TMS320C2000 C/C++ CODE GENERATION TOOLS
Release 3.11
Thank you for choosing Texas Instruments software development tools.
It is our goal to provide you with the most useful and efficient
development tools from which to develop your applications around
Texas Instruments processors. Please direct any questions or defect
reports to the customer support hotline (e-mail: support@ti.com,
phone: 972-644-5580).
Please contact Texas Instruments customer support at support@ti.com if you
have questions or concerns.
================================================================================
Table of Contents
================================================================================
1. BOOT ROM Support In Hex Convertor
2. C28x long double Floating Point Type Change
3. IQ Math Intrinsics
4. Linking C28x and C2XLP Code
5. Version Switch
6. C/C++ Unified Runtime Library
7. C28x Calling Conventions
8. DWARF Symbolic Debug Switch
9. Assembler Switches
10. The Ioport Keyword
11. Default Dual Pre-Fetch Branch Instructions
12. New Code-size Optimization Switch
13. Post-link Optimizer Update
======================================================================
1. BOOT ROM Support In Hex Convertor
======================================================================
The C2000 hex convertor utility has been updated to support F2810/12
boot loader.
Some of the C28x devices, such as the F2810/12, have a built-in boot
loader that initializes memory with one or more blocks of code or data.
The boot loader uses a special table (a boot table) stored in memory
(such as EPROM) or loaded from a device peripheral (such as a serial
or communications port) to initialize the code or data.
The input for a boot loader is the boot table. The boot table contains
records that instruct the on-chip loader to copy blocks of data contained
in the table to specified destination addresses.
The hex conversion utility now supports the boot loader by automatically
building the boot table. Using the utility, you specify the COFF sections
you want the boot loader to initialize and the table location. The hex
conversion utility builds a complete image of the table according to the
format specified and converts it into hexadecimal in the output files.
The following command line options are added to the hex conversion utility
to support the Boot loader.
-boot : Convert all input sections into bootable form. SECTIONS Note: When you use the SECTIONS directive in your command file the -boot When compiling C/C++ code for the TMS320C28x only, the long double C27x floating point types: C28x floating point types: If initializing a long double to a constant it is necessary to use long double a = 12.34L; /* correctly initializes to double precision */ printf("%Lg", 1.23L); This type change has resulted in a change in the C28x calling conventions. long double foo(long double a, long double b, long double c) long double a = 1.2L; void bar() In function bar(), at the call to foo(), the register values are: XAR4 = the address of 'a' The run-time-support library has been updated to include the necessary LCR F$$ADD This has been updated to: LCR FS$$ADD ; single precision add Any C27x/C28x routine that calls floating point arithmetic or conversion An IQ value is a 32-bit fixed-point type where the number of integer a) long = __IQ(long double A, int N) This will convert the long double A into the correct IQN b) long dst = __IQmpy(long A, long B, int N) The dst becomes ACC, A becomes XT: if N == 0: if 0 < N < 16: if 15 < N < 32: if N == 32: if N is a variable: The dst becomes ACC: if max and min are constants: if max and/or min are variables: d) long dst = __IQxmpy(long A, long B, int N) The dst becomes ACC, A becomes XT: if N == 0: if 0 < N < 17 if 0 > N > -17 if 16 < N < 33 if -16 > N > -33 if 32 < N < 49 if -32 > N > -49 if 48 < N < 65 if -48 > N > -65 ====================================================================== The error in the C28x linker to prevent linking code with a 64-word page extern void foo_veneer(int, int, int, int, int); The veneer function would look as follows: .sect ".text" ;set the size of the C2XLP frame (including args size) ;push args onto the C2XLP frame ;save the return address ;set AR1,ARP ;jump to C2XLP function Since the veneer function frame will act as the frame for all C2XLP calls, Global variables will be placed in the .bss sections for C28x C/C++ code. The shell switch -v28 must be used to generate code for the TMS320C28X. This release of the C27x/C28x toolset supports a unified C/C++ runtime The calling conventions for the C28x mode of the compiler have changed a) Any 32-bit arguments are placed in ACC. Here is the convention when a called function responds: a) If pointer arguments are expected, either a 16-bit value or 32-bit value Note, all C28x call/returns use the RPC register to hold return addresses Like the -g switch, -gw generates symbolic debugging directives that are As with -g, -gw can be used with the -o option to maximize the amount a)The assembler provides the -m27 for the TMS320C27X source compatibility. b) The shell option -mx expands the macros in the assembly source and then c) The -m20 option with the shell or the assembler makes the assembler accept ioport int port10; The code generator will generate dual pre-fetch branch instructions a) shell switch: -me ====================================================================== -ms: Increases the level of code-size optimization performed by the compiler. _prolog_c28x_1 The following gives an example of code compiled with the -ms switch. extern int x, y, *ptr; int main(int a, int b, int c) Here is the generated output: FP .set XAR2 ;*************************************************************** _main: ====================================================================== The post-link optimizer is updated to optimize the DP loads across function .global a . .global func1 The post-link optimizer removes the DP load after the statement 'LC func1'. A new shell option -nf is added to disable optimization across function In order to optimize across function calls the post-link optimizer assumes
E-mail:
info@telesys.ru
-sci8 : Specify the source of the boot loader table as the
SCI-A port, 8-bit mode.
-spi8 : Specify the source of the boot loader table as the
SPI-A port, 8-bit mode. This format initializes the
LOSPCP and SPIBRR registers. If initial values for
these registers were not specified the hex conversion
utility uses 0x02 and 0x7F respectively.
-gpio8 : Specify the source of the boot loader table as the
GP I/O port, 8-bit mode.
-gpio16 : Specify the source of the boot loader table as the
GP I/O port, 16-bit mode.
-bootorg
-lospcp
value is used only for the spi8 boot table format and
ignored for all other formats. If the value is greater
than 0x7F, the value is truncated to 0x7F.
-spibrr
value is used only for the spi8 boot table format and
ignored for all other formats. If the value is greater
than 0x7F, the value is truncated to 0x7F.
-e
after boot loading. The value can be an address or a
global symbol.
The SECTIONS directive now accepts the boot keyword to configure a section
for loading by the on-chip boot loader. This keyword can be used as follows
{
sname: [paddr=boot]
sname: [=boot]
}
option is ignored. You must explicitly specify any boot sections in
the SECTIONS directive.
======================================================================
2. C28x long double Floating Point Type Change
======================================================================
floating point type is now IEEE 64-bit double precision. No other
floating points have changed formats. In other words:
float: IEEE 32-bit single precision
double: IEEE 32-bit single precision
long double: IEEE 32-bit single precision
float: IEEE 32-bit single precision
double: IEEE 32-bit single precision
long double: IEEE 64-bit double precision
the 'l' or 'L' suffix. The constant is treated as a double type
without the suffix and the RTS double-to-long conversion routine
is called for the initialization. This could result in the loss of
precision. For example:
long double b = 56.78; /* converts single precision value to double
precision */
The formatting rules for long doubles in C I/O require a capital 'L'
in the format string. For example:
printf("%Le", 3.45L);
All long double arguments are passed by reference. A long double return
value is returned by reference. The first 2 long double arguments
will pass their addresses in XAR4 and XAR5. All other long double
arguments will have their addresses passed on the stack. It is necessary
to assume that these long double address will be in "far" memory. Thus
the called function will always read 32-bits for the addresses of long
double arguments. If a function returns a long double, the function
making that call will place the return address in XAR6. For example:
{
long double d = a + b + c;
return d;
}
long double b = 2.2L;
long double c = 3.2L;
long double d;
{
d = foo(a, b, c);
}
XAR5 = the address of 'b'
*-SP[2] = the address of 'c'
XAR6 = the address of 'd'
long double arithmetic operations and conversion functions. NOTE: all
C27x/C28x floating point RTS routines have had their names updated.
For example, a previous call to the floating point add routine was:
LCR FD$$ADD ; double precision add
routines will need to be recompiled.
======================================================================
3. IQ Math Intrinsics
======================================================================
and fractional bits are specified. For example, the floating point
value 14.5 is the IQ16 value 0xe8000. The following intrinsics have
been added to improve the efficiency of code using IQ fixed-point
types:
value returned as a long type. If both arguments are
constants the compiler will convert the arguments to the
IQ value during compile time. Otherwise a call the the
RTS routine, __IQ, is made. Note, this intrinsic cannot
be used to initialize global variables to the .cinit
section.
IMPYL ACC,XT,B
IMPYL P,XT,B
QMPYL ACC,XT,B
LSL64 ACC:P,#16
LSL64 ACC:P,#(16-N)
IMPYL P,XT,B
QMPYL ACC,XT,B
LSL64 ACC:P,#(32-N)
QMPYL ACC,XT,B
IMPYL P,XT,B
QMPY ACC,XT,B
MOV AX,#32
SUB AX,N
MOV T,AX
LSL64 ACC:P,T
c) long dst = __IQsat(long A, long max, long min)
MOVL ACC,A
MOV PL,#max lower 16 bits
MOV PH,#max upper 16 bits
MINL ACC,P
MOV PL,#min lower 16 bits
MOV PH,#min upper 16 bits
MAXL ACC,P
MOVL ACC,A
MINL ACC,max
MAXL ACC,min
IMPYL ACC,XT,B
IMPYL P,XT,B
QMYL ACC,XT,B
LSL64 ACC:P,#N
IMPYL P,XT,B
QMYL ACC,XT,B
ASR64 ACC:P,#abs(N)
IMPYL P,XT,B
QMYL ACC,XT,B
LSL64 ACC:P,#16
LSL64 ACC:P,#N - 16
IMPYL P,XT,B
QMYL ACC,XT,B
ASR64 ACC:P,#16
ASR64 ACC:P,#abs(N) - 16
IMPYL P,XT,B
QMYL ACC,XT,B
LSL64 ACC:P,#16
LSL64 ACC:P,#16
LSL64 ACC:P,#N - 16
IMPYL P,XT,B
QMYL ACC,XT,B
ASR64 ACC:P,#16
ASR64 ACC:P,#16
ASR64 ACC:P,#abs(N) - 16
IMPYL P,XT,B
QMYL ACC,XT,B
LSL64 ACC:P,#16
LSL64 ACC:P,#16
LSL64 ACC:P,#16
LSL64 ACC:P,#N - 16
IMPYL P,XT,B
QMYL ACC,XT,B
ASR64 ACC:P,#16
ASR64 ACC:P,#16
ASR64 ACC:P,#16
ASR64 ACC:P,#abs(N) - 16
4. Linking C28x and C2XLP Code
======================================================================
size (C28x) and a 128-word page size (C2XLP) has been changed to a warning.
It is possible to call a C2XLP assembly function from C28x C/C++ code. One
possible way is to replace the call to the C2XLP function with a veneer
function that correctly sets up the arguments and call stack for the
C2XLP code. For example, to make a call to a C2XLP function expecting
5 integer arguments, change the C28x code to:
void bar()
{
/* replace the C2XLP call with a veneer call */
/* foo(1, 2, 3, 4, 5); */
foo_veneer(1, 2, 3, 4, 5);
}
.global _foo_veneer
.global _foo
_foo_veneer:
;save registers
PUSH AR1:AR0
PUSH AR3:AR2
PUSH AR5:AR4
ADDB SP,#10
MOV *-SP[10],AL ;copy arg 1
MOV *-SP[9],AH ;copy arg 2
MOV *-SP[8],AR4 ;copy arg 3
MOV *-SP[7],AR5 ;copy arg 4
MOV AL,*-SP[19]
MOV *-SP[6],AL ;copy arg 5
MOV *-SP[5],#_label
MOV AL,SP
SUBB AL,#3
MOV AR1,AL
NOP *ARP1
LB _foo
_label:
;restore register
POP AR5:AR4
POP AR3:AR2
POP AR1:AR0
LRETR
it is necessary to add sufficient size to the frame for any subsequent calls
made by the first C2XLP function.
A C2XLP .bss section is not guaranteed to begin on a 128-word boundary
when linked with C28x code. To avoid this problem, change C2XLP globals
to a user-defined section and update the linker command file to ensure
this new section begins at a 128-word boundary.
======================================================================
5. Version Switch
======================================================================
======================================================================
6. C/C++ Unified Runtime Library
======================================================================
library. The libraries, rts2700.lib or rts2800.lib, can be linked with
either C or C++ object files with out recompiling the libraries. The
library, rts2700.lib is for code generated for the C27x. The library,
rts2800.lib, is for code generated for the C28x. Libraries for large
memory model are also available for each processor: rts2700_ml.lib,
rts2800_ml.lib.
======================================================================
7. C28x Calling conventions
======================================================================
over the C27x calling convention. There is no longer a distinction between
far and non-far arguments in C. There is no longer a difference in the
calling conventions between large memory model and non-large memory model for
C++. All pointer arguments will be placed in XAR4 and XAR5. All return
pointer values will be placed in XAR4. To review, here is the convention
when a function makes a call:
b) Pointer arguments are placed in XAR4 and XAR5. All other pointers are
placed on the stack.
c) Remaining 16-bit arguments are placed in the order AL, AH, AR4, AR5 if
they are available.
is read from XAR4 and XAR5 depending on the pointer arguments' type.
(For example, is it far or compiled under large memory model?)
b) Pointer return values are placed in XAR4. 16-bit integer values are
placed in AL. 32-bit integer values are placed in ACC.
by generating LCR and LRETR instructions.
======================================================================
8. New DWARF Symbolic Debug Switch: -gw
======================================================================
used by the C/C++ source-level debugger, and enables assembly source
debugging in the assembler. However, -gw generates debugging information
using the DWARF debugging information format, where -g uses standard
COFF debugging information. DWARF is a richer format, and can handle
complex C++ constructs that COFF debugging information cannot. COFF
debugging information is being provided only for backwards compatibility.
of optimization that is compatible with debugging. However, the symbolic
debugging options disable many optimizations, because they disrupt the
debugger.
======================================================================
9. Assembler Switches
======================================================================
When used with the -v28 switch, the C27x source can be assembled to produce
C28x object. This option can also be specified with the shell.
assembles the file. This is to help debugging the assembly files with
expanded macros.
C2xlp instructions to generate C28x object.
======================================================================
10. The Ioport Keyword
======================================================================
The ioport keyword enables access to the I/O port space of the TMS320C28x
device. The keyword has the form:
ioport type porthex_num
ioport is the keyword that indicates this is a port variable.
type must be char, short, int, or unsigned int.
porthex_num refers to the port number, hex_num is a hexadecimal number.
All declarations of port variables must be done at the file level.
Port variables declared at the function level are not supported.
Here is an example of the use of the ioport keyword. The code declares
the I/O port as int port 10h, writes a to port 10h and reads port 10h
into b. The code also shows how port variables can be used in other
types of expressions.
int a; int b; int c;
extern void foo(int);
void func()
{
port10 = a;
b = port10;
foo(port10);
c = port10 + b;
port10 += a;
}
======================================================================
11. Default Dual Pre-Fetch Branch Instructions
======================================================================
by default when possible. A command line switch has been added that
will disable the generation of fast branches:
b) code generator switch (if invoked separately): -e
12. New code-size optimization switch
======================================================================
These optimizations are done at the expense of performance. The
optimizations include procedural abstraction where common blocks of code
are replaced with function calls. For example, prolog and epilog code
may be replaced with functions that are defined in the run-time library.
Different functions are used depending on the number of SOE registers,
the size of the frame, and whether a frame pointer is used. These
functions are defined in each file with the -ms switch:
_prolog_c28x_2
_prolog_c28x_3
_epilog_c28x_1
_epilog_c28x_2
extern int foo();
{
ptr[50] = foo();
y = ptr[50] + x + y + a + b + c;
}
.global _prolog_c28x_1
.global _prolog_c28x_2
.global _prolog_c28x_3
.global _epilog_c28x_1
.global _epilog_c28x_2
.sect ".text"
.global _main
;* FNAME: _main FR SIZE: 6 *
;* *
;* FUNCTION ENVIRONMENT *
;* *
;* FUNCTION PROPERTIES *
;* 0 Parameter, 0 Auto, 6 SOE *
;***************************************************************
FFC XAR7,_prolog_c28x_1
MOVZ AR3,AR4 ; |5|
MOVZ AR2,AH ; |5|
MOVZ AR1,AL ; |5|
LCR #_foo ; |6|
; call occurs [#_foo] ; |6|
MOVW DP,#_ptr
MOVL XAR6,@_ptr ; |6|
MOVB XAR0,#50 ; |6|
MOVW DP,#_y
MOV *+XAR6[AR0],AL ; |6|
MOV AH,@_y ; |7|
MOVW DP,#_x
ADD AH,AL ; |7|
ADD AH,@_x ; |7|
ADD AH,AR3 ; |7|
ADD AH,AR1 ; |7|
ADD AH,AR2 ; |7|
MOVB AL,#0
MOVW DP,#_y
MOV @_y,AH ; |7|
FFC XAR7,_epilog_c28x_1
LRETR
; return occurs
13. Post-link optimizer - optimization across function calls
======================================================================
calls. If the called function is defined in the same file, the post-link
optimizer analyzes the function and uses the last DP load before the return to
optimize the DP loads following the function call. Consider the following code
segment.
.
MOV DP, #a ; 1
MOV AL,@a
LC func1
MOV DP, #a ; 2
ADD AH,@a
.
.
func1:
.
.
MOV DP, #a
MOV AL,@a
LRET
calls during post-link optimization. This option should only be specified
along with -plink option after the -z option in the command line.
that the function has only one return statement. In hand-coded assembly if
the user codes more than one return statement in a function, then the
post-link optimizer may produce incorrect code. The user should disable this
feature using the shell option -nf in such cases.
Ответы