PowerPC 55xx ELF Topics

This appendix describes topics that are specific to the GNAT for PowerPC 55xx ELF cross configurations.

Introduction

The PowerPC 55xx ELF toolset targets Book E variants of the PowerPC architecture. It was originally developed for the Freescale e200 core used in the MPC5554 microcontroller.

The prefix generally used for target-specific executables in the PowerPC 55xx ELF toolset is powerpc-eabispe. E.g., the compiler is powerpc-eabispe-gcc and the binder is powerpc-eabispe-gnatbind. The one exception is the debugger, which is shared with the powerpc-elf toolset and is invoked via the powerpc-elf-gdb command.

The powerpc-elf toolset (which targets 603-like processors) is used for the discussion in Bareboard Topics, and understanding the contents of that section is presumed in this Appendix, which focuses on a few 55xx-specific topics.

Floating Point

The processors targeted by GNAT for the PowerPC 55xx ELF incorporate an ‘Embedded Scalar FPU’ that performs floating-point operations on values in the general-purpose registers. Relative to the 603, there are different instructions (esfxxxx), and there are no floating-point registers nor any of the 603 floating-point instructions.

That FPU is not fully IEEE compliant (see section IEEE std 754tm Compliance in the SPEPEM manual). In particular, the FPU doesn’t handle denormals and cannot produce NaN or infinities. Also, the FPU is not able to compute the result if it is near the overflow. To follow the language semantics, overflow, invalid, and divide-by-zero exceptions are enabled in the provided assembly setup code so that a CPU exception is generated when the FPU cannot compute the result correctly. On the ravenscar-full runtime, this exception is converted into a Constraint_Error exception.

Processors based on the e500v2 core (but not e500mc) support both single- and double-precision operations, while processors based on e200 or e500v1 cores support only single-precision operations.

For the latter, the version of the libgcc library provided with this toolset implements double-precision operations in software. The compiler will generate scalar FPU instructions when appropriate and calls to the double-precision routines when needed. Developers may want to use the scalar FPU support for efficiency, and/or avoid the library routines for certification. For objects and values of single-precision types, the hardware instructions will be used. However, some operations that are not simple floating-point operations may require usage of double-precision values, and therefore generate calls to support routines in libgcc. For example, Ada semantics for rounding may force floating-point to integer conversions to use double precision.

For the developer who wants to eliminate or minimize the use of double precision, the issues are how to detect and how to work around such usage. If it is acceptable to eliminate support from libgcc entirely, then excluding it from the final linking step (e.g., using -nostdlib if linking with gcc, or simply not naming it if using ld directly), will result in error messages and failure to create an executable if any compiler-generated usage of double precision has occurred. Then, to identify the source code involved, you can use objdump to inspect the object file that ld flagged as containing the unresolved reference. Invoke objdump (preceded by the prefix) using the –disassemble and –source switches. (Note: this requires that the code be compiled with debugging enabled.) The objdump command will produce a mixed source/assembly listing that can be searched for the undefined symbol named by ld.

If some minimal usage is acceptable, then various procedures are available to find new occurrences of double precision, such as occasionally linking without libgcc to look for new references, or inspecting object files with nm.

Eliminating a call to a double-precision routine depends upon the particular case and can involve modifying the source to use different constructs, adding qualifications or conversions, or providing machine-code insertions.

Note

  • In order for powerpc-eabispe-objdump to disassemble the scalar floating-point instructions, the -M e500 option is required.

  • For CGNAT users: the -fsingle-precision-constant option to gcc will prevent floating-point constants from being implicitly converted to double precision.

EABI

The compiler is configured to conform with the EABI by default. However, we recommend avoiding the small data sections for simplicity. By default, gcc will place some data into .sbss, .sbss2, .sdata and .sdata2, and GPRs 2 and 13 will only be used for relative addressing as specified by the ABI and the EABI. Also, the compiler generates a call to __eabi before main, where the initialization of 2 and 13 can be made, and libgcc provides such a routine. By compiling with -mno-sdata, no objects will be placed in any of the .sXXX sections and no use will be made of R2 and R13. This simplifies the construction of a linker script and allows the replacement of __eabi with these lines in the startup code:

  .global __eabi
__eabi:
 blr

The provision of this dummy __eabi allows complete independence from libgcc for many programs.

Debugging

For bareboard MPC5554 targets, you can use debugging hardware that connects to the JTAG or Nexus port of the MPC5554 and provides a gdb-server.