Using Sourcery G++ Lite for ARM uClinux

NEON SIMD Code

Sourcery G++ includes support for automatic generation of NEON SIMD vector code. Autovectorization is a compiler optimization in which loops involving normal integer or floating-point code are transformed to use NEON SIMD instructions to process several data elements at once.

To enable generation of NEON vector code, use the command-line options -ftree-vectorize -mfpu=neon -mfloat-abi=softfp. The -mfpu=neon option also enables generation of VFPv3 scalar floating-point code.

Sourcery G++ also includes support for manual generation of NEON SIMD code using C intrinsic functions. These intrinsics, the same as those supported by the ARM RealView® compiler, are defined in the arm_neon.h header and are documented in the 'ARM NEON Intrinsics' section of the GCC manual. The command-line options -mfpu=neon -mfloat-abi=softfp must be specified to use these intrinsics; -ftree-vectorize is not required.

Half-Precision Floating Point

Sourcery G++ for ARM uClinux includes support for half-precision (16-bit) floating point, including the new __fp16 data type in C and C++, support for generating conversion instructions when compiling for processors that support them, and library functions for use in other cases.

Representations

ARM supports two incompatible representations for half-precision floating-point values. You must choose one of the representations and use it consistently in your program. The linker gives an error if objects compiled or assembled with different half-precision float attributes are combined in the same executable.

Compiling or assembling with -mfp16-format=ieee selects the representation defined in the IEEE 754-2008 standard, with 1 sign bit, 5 exponent bits, and 10 significand bits (11 bits of significand precision, approximately 3 decimal digits). This format is capable of representing normalized values in the range of 2-14 to 65504. It includes support for infinities and NaNs, following the usual IEEE 754 rules.

ARM also supports an alternative half-precision representation, which you can select with -mfp16-format=alternative. This format does not include support for infinities and NaNs. Instead, the range of exponent values is extended, so that this format can represent normalized values in the range of 2-14 to 131008.

The default for this option is -mfp16-format=none, which disables support for half-precision floats.

C and C++ Usage

When you compile with -mfp16-format=ieee or -mfp16-format=alternative, GCC defines the __fp16 data type to represent half-precision float values. Objects of this type have a size of 2 bytes and a natural alignment of 2 bytes.

The __fp16 type is a storage format only. For purposes of arithmetic and other operations, __fp16 values are automatically promoted to float. In addition, you cannot declare a function with a return value or parameters of type __fp16.

Note that conversions from double to __fp16 involve an intermediate conversion to float. Because of rounding, this can sometimes produce a different result than a direct conversion.

Hardware and Library Support

ARM provides hardware support for conversions between __fp16 and float values as an extension to VFP and NEON (Advanced SIMD). GCC generates code using the instructions provided by this extension if you compile with the options -mfpu=neon-fp16 -mfloat-abi=softfp, in addition to the -mfp16-format option to select a half-precision format.

In other cases, conversions between __fp16 and float values are implemented as library calls.

ABI Compatibility

The Application Binary Interface (ABI) for the ARM Architecture is a collection of standards, published by ARM Ltd. and other organizations. The ABI makes it possible to combine tools from different vendors, including Sourcery G++ and ARM RealView®.

Sourcery G++ implements the ABI as described in these documents, which are available from the ARM Information Center:

  • BSABI - ARM IHI 0036A (25 October 2007)
  • BPABI - ARM IHI 0037A (25 October 2007)
  • EHABI - ARM IHI 0038A (25 October 2007)
  • CLIBABI - ARM IHI 0039A (25 October 2007)
  • AADWARF - ARM IHI 0040A (25 October 2007)
  • CPPABI - ARM IHI 0041A (25 October 2007)
  • AAPCS - ARM IHI 0042B (2 April 2008)
  • RTABI - ARM IHI 0043A (25 October 2007)
  • AAELF - ARM IHI 0044B (2 April 2008)
  • ABI Addenda - ARM IHI 0045A (13 November 2007)

Sourcery G++ currently produces DWARF version 2, rather than DWARF version 3 as specified in AADWARF.

Building uClinux Applications

When you use GCC to link a uClinux application, it creates two output files. The executable file, as specified by the -o command-line option, is a uClinux FLAT format binary (bFLT) file. This is the file you should copy to and run on your uClinux target. The second output file is an ELF-format file containing additional debug and symbol table information to allow you to debug your program with GDB, as described in the section called “GDB Server”. This file has a .gdb extension.

For example, if you specify the command

arm-uclinuxeabi-gcc foo.c -o bar

then bar is the FLAT-format executable and bar.gdb is the ELF-format file.

GDB Server

Sourcery G++ Lite contains a gdbserver for running on the target. The server executable is located in the sysroot/usr/bin directory of your installation, where sysroot is the pathname to the sysroot, as documented in the section called “Library Configurations”. You need to copy the appropriate gdbserver executable to your target system and then invoke it as

# gdbserver :port program

port can be any available TCP port; 5000 is a common choice. gdbserver waits for a connection from gdb and then commences serving requests for it. To connect to gdbserver from your host system, start gdb, but specify the special .gdb version of your program.

> arm-uclinuxeabi-gdb program.gdb

Then connect to the target system:

(gdb) target remote host:port

At this point you are able to debug as usual.