Because of a discrepancy between the ARMv7M Architecture and the ARM EABI, it is not safe to use normal C functions directly as interrupt handlers. The EABI requires the stack be 8-byte aligned, whereas ARMv7M only guarantees 4-byte alignment when calling an interrupt vector. This can cause subtle runtime failures, usually when 8-byte types are used.
Functions that are used directly as interrupt handlers should be
annotated with __attribute__((__interrupt__))
.
This tells the compiler to
add special stack alignment code to the function prologue.
The ARM CS3 implementation treats all systems as address vector processors. On traditional ARM systems (everything except M profile devices) an exception causes the processor to jump to a fixed address. However the arrangement of these addresses is such that the CS3 code vector model is not feasible.
The default CS3 vector table emulates an address vector system by placing an indirect branch at the real exception vector. If you override the entire vector table (rather than individual vectors) the indirect stubs are not included, and your replacement table is placed at address zero.
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.
Sourcery G++ for ARM EABI 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.
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.
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.
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.
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:
Sourcery G++ currently produces DWARF version 2, rather than DWARF version 3 as specified in AADWARF.
It is possible to create object files using Sourcery G++ for ARM EABI that are link-compatible with the GNU C library provided with Sourcery G++ for ARM GNU/Linux as well as with the Newlib C library provided with the ARM EABI toolchain. These object files are additionally link-compatible with other ARM C Library ABI-compliant static linking environments and toolchains.
To use this feature, when compiling your files with the bare-metal
ARM EABI toolchain define the preprocessor constant
_AEABI_PORTABILITY_LEVEL
to 1
before including any system header files.
For example, pass the option -D_AEABI_PORTABILITY_LEVEL=1
on your compilation command line.
No special options are required when linking the resulting object files.
When building applications for ARM EABI,
files compiled with this definition may be linked freely with those
compiled without it.
Files compiled in this manner may not use the
functions fgetpos
or fsetpos
, or reference the
type fpos_t. This is because Newlib assumes a
representation for fpos_t that is not AEABI-compliant.
Note that object files are only portable from EABI to GNU/Linux, and not vice versa; object files compiled for ARM GNU/Linux targets cannot be linked into ARM EABI executables.
Profiling is enabled by means of the -pg
compiler option. In this mode, the compiler inserts a call to
__gnu_mcount_nc
into every function prologue.
However, no implementation of __gnu_mcount_nc
is provided (to do so would be impossible without knowledge of
the execution environment).
You must provide your own implementation of
__gnu_mcount_nc
. Here are the requirements:
lr
register. The sp
register should
be adjusted accordingly. For example, this is how to write it
as a stub function:
.globl __gnu_mcount_nc .type __gnu_mcount_nc, %function __gnu_mcount_nc: mov ip, lr pop { lr } bx ip
r12
and the CPSR condition code bits. In particular all coprocessor
state and registers r0
-r3
must
be preserved.
lr
value stored on the top of the stack (on entry
to __gnu_mcount_nc
), and the callee can
be determined from the current value of the lr
register (i.e. the caller of this function).
gmon.out
when the program exits
(via atexit
). Refer to the
gprof profiler manual for more information.