When compiling C/C++ code for the TMS320C28x, the long double floating point type uses the IEEE 64-bit double precision format.
The double type differs depending on whether you are compiling for COFF or EABI. For COFF, it uses the IEEE 32-bit single precision type. For EABI it uses IEEE 64-bit double precision.
C28x floating point types are:
Type | Format |
---|---|
float | IEEE 32-bit single precision |
double (COFF) | IEEE 32-bit single precision |
double (EABI) | IEEE 64-bit double precision |
long double | IEEE 64-bit double precision |
It is recommended that 32-bit floating point values be declared as float, not as double.
When you initialize a long double to a constant, you must use the l or L suffix. The constant is treated as a double type without the suffix and the run-time support double-to-long conversion routine is called for the initialization. This could result in the loss of precision. For example:
long double a = 12.34L; /* correctly initializes to double precision */
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("%Lg", 1.23L);
printf("%Le", 3.45L);
For EABI mode, see the C28x Embedded Application Binary Interface Application Report (SPRAC71) for information on calling conventions for 64-bit types.
For COFF, the calling conventions for the long double type are as follows:
All long double arguments are passed by reference. A long double return value is returned by reference. The first two long double arguments will pass their addresses in XAR4 and XAR5. All other long double arguments will have their addresses passed on the stack.
If a function returns a long double, the function making that call will place the return address in XAR6. For example:
long double foo(long double a, long double b, long double c)
{
long double d = a + b + c;
return d;
}
long double a = 1.2L;
long double b = 2.2L;
long double c = 3.2L;
long double d;
void bar()
{
d = foo(a, b, c);
}
In function bar(), at the call to foo(), the register values are:
Register | Equals |
---|---|
XAR4 | The address of a |
XAR5 | The address of b |
*−SP[2] | The address of c |
XAR6 | The address of d |
The run-time-support library includes the necessary long double arithmetic operations and conversion functions.