Runtime EABI - Rtabi
Runtime EABI - Rtabi
Runtime EABI - Rtabi
Abstract
This document defines a run-time helper-function ABI for programs written in ARM-Thumb assembly language, C, and C++.
Keywords
Run-time ABI, run-time library, helper functions
Please report defects in this specification to arm dot eabi at arm dot com.
Licence
THE TERMS OF YOUR ROYALTY FREE LIMITED LICENCE TO USE THIS ABI SPECIFICATION ARE GIVEN IN SECTION 1.4, Your licence to use this specification (ARM contract reference LEC-ELA-00081 V2.0). PLEASE READ THEM CAREFULLY. BY DOWNLOADING OR OTHERWISE USING THIS SPECIFICATION, YOU AGREE TO BE BOUND BY ALL OF ITS TERMS. IF YOU DO NOT AGREE TO THIS, DO NOT DOWNLOAD OR USE THIS SPECIFICATION. THIS ABI SPECIFICATION IS PROVIDED AS IS WITH NO WARRANTIES (SEE SECTION 1.4 FOR DETAILS).
Proprietary notice
ARM, Thumb, RealView, ARM7TDMI and ARM9TDMI are registered trademarks of ARM Limited. The ARM logo is a trademark of ARM Limited. ARM9, ARM926EJ-S, ARM946E-S, ARM1136J-S ARM1156T2F-S ARM1176JZ-S Cortex, and Neon are trademarks of ARM Limited. All other products or services mentioned herein may be trademarks of their respective owners.
Page 1 of 28
Contents
1 ABOUT THIS DOCUMENT 4 4 4 4 4 5 6 7 8 9 9 9 10 10 10 10 10 11 11 12 12 14 14 14 14 15 15 19
1.1 Change control 1.1.1 Current status and anticipated changes 1.1.2 Change history 1.2 1.3 1.4 1.5 2 3 3.1 References Terms and abbreviations Your licence to use this specification Acknowledgements SCOPE INTRODUCTION References between separately built relocatable files
3.2 Standardized compiler helper functions 3.2.1 Rationale for standardizing helper functions 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 4 Private helper functions must be carried with the using file Some private functions might nonetheless be standardized Many run-time functions do not have a standard ABI A run-time library is all or nothing Important corollaries of this library standardization model Private names for private and AEABI-specific helper functions Library file organization __hardfp_ name mangling THE STANDARD COMPILER HELPER FUNCTION LIBRARY
4.1 Floating-point library 4.1.1 The floating point model 4.1.1.1 Base requirements on AEABI-complying FP helper functions 4.1.1.2 Restrictions on FP usage by ABI-complying programs 4.1.2 The floating-point helper functions 4.2 The long long helper functions
Page 2 of 28
4.3 Other C and assembly language helper functions 4.3.1 Integer (32/32 32) division functions 4.3.2 Division by zero 4.3.3 Unaligned memory access 4.3.4 Memory copying, clearing, and setting 4.3.5 Thread-local storage (new in v2.01) 4.4 C++ helper functions 4.4.1 Pure virtual function calls 4.4.2 One-time construction API for (function-local) static objects 4.4.3 Construction and destruction of arrays 4.4.3.1 Helper functions defined by the generic C++ ABI 4.4.3.2 Helper functions defined by the C++ ABI for the ARM Architecture 4.4.4 Controlling object construction order 4.4.5 Static object finalization 4.4.6 Name demangling 4.4.7 Exception-handling support 4.4.7.1 Compiler helper functions 4.4.7.2 Personality routine helper functions 4.4.7.3 Auxilliary functions related to exception processing
20 20 21 21 22 23 23 23 23 24 24 25 26 26 27 27 27 27 28
Page 3 of 28
Date 30 October 2003 24 March 2005 6 October 2005 23 January 2007 10 October 2007
th rd th th th
By LS LS LS LS LS
Change First public release. Second public release. Added specifications of __aeabi_read_tp() (4.3.5) and __cxa_get_exception_ptr() (4.4.7). Deprecated fneg/dneg in 4.1.2. In 3.8, replaced table by table shared with AAELF. Clarified 4.3.1, integer division. Updated the ARM ARM reference to include the version from www.arm.com. Document renumbered (formerly GENC-003537 v2.03). Add return value comments to __aeabi_* helper functions in 4.4.3.2. Added 3.10 to explain legacy, deprecated __hardfp_ name mangling; in 4.1.2, declared fneg/dneg obsolete; improved text specifying the registers maybe affected by a call to an FP helper; added conversion helpers between VFPv3 half-precision and float to Table 7. In 4.1.1.1, updated [ARM ARM] reference for signaling NaNs. In 4.1.2, removed __aeabi_dneg and __aeabi_fneg obsoleted in r2.08, and added conversion helpers from double to VFPv3 half-precision to Table 7.
2.02 2.03
th
LS LS LS
D, r2.09
30 November 2012
th
AC
1.2 References
This document refers to, or is referred to by, the following. Ref
AAELF AAPCS BSABI
Title ELF for the ARM Architecture. Procedure Call Standard for the ARM Architecture ABI for the ARM Architecture (Base Standard)
Page 4 of 28
Ref
CLIBABI CPPABI EHABI RTABI ADDENDA ARM ARM
Title C Library ABI for the ARM Architecture C++ ABI for the ARM Architecture Exception Handling ABI for the ARM Architecture Run-time ABI for the ARM Architecture (This document) Addenda to, and Errata in, the ABI for the ARM Architecture
(From http://infocenter.arm.com/help/index.jsp, via links ARM architecture, Reference manuals) (Registration required)
Manual
ARMv5 ARM GC++ABI (As for ARM ARM; no registration needed) http://mentorembedded.github.com/cxxabi/abi.html http://grouper.ieee.org/groups/754/ ARM DDI 0100I: ARMv5 Architecture Reference Manual
IEEE 754
VFP
Page 5 of 28
Specification means, and is limited to, the version of the specification for the Applications Binary Interface for the ARM Architecture comprised in this document. Notwithstanding the foregoing, Specification shall not include (i) the implementation of other published specifications referenced in this Specification; (ii) any enabling technologies that may be necessary to make or use any product or portion thereof that complies with this Specification, but are not themselves expressly set forth in this Specification (e.g. compiler front ends, code generators, back ends, libraries or other compiler, assembler or linker technologies; validation or debug software or hardware; applications, operating system or driver software; RISC architecture; processor microarchitecture); (iii) maskworks and physical layouts of integrated circuit designs; or (iv) RTL or other high level representations of integrated circuit designs. Use, copying or disclosure by the US Government is subject to the restrictions set out in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and (2) of the Commercial Computer Software Restricted Rights at 48 C.F.R. 52.227-19, as applicable. This Specification is owned by ARM or its licensors and is protected by copyright laws and international copyright treaties as well as other intellectual property laws and treaties. The Specification is licensed not sold. 1. Subject to the provisions of Clauses 2 and 3, ARM hereby grants to LICENSEE, under any intellectual property that is (i) owned or freely licensable by ARM without payment to unaffiliated third parties and (ii) either embodied in the Specification or Necessary to copy or implement an applications binary interface compliant with this Specification, a perpetual, non-exclusive, non-transferable, fully paid, worldwide limited licence (without the right to sublicense) to use and copy this Specification solely for the purpose of developing, having developed, manufacturing, having manufactured, offering to sell, selling, supplying or otherwise distributing products which comply with the Specification.
THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO WARRANTIES EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF SATISFACTORY QUALITY, MERCHANTABILITY, NONINFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE. THE SPECIFICATION MAY INCLUDE ERRORS. ARM RESERVES THE RIGHT TO INCORPORATE MODIFICATIONS TO THE SPECIFICATION IN LATER REVISIONS OF IT, AND TO MAKE IMPROVEMENTS OR CHANGES IN THE SPECIFICATION OR THE PRODUCTS OR TECHNOLOGIES DESCRIBED THEREIN AT ANY TIME.
2.
3.
This Licence shall immediately terminate and shall be unavailable to LICENSEE if LICENSEE or any party affiliated to LICENSEE asserts any patents against ARM, ARM affiliates, third parties who have a valid licence from ARM for the Specification, or any customers or distributors of any of them based upon a claim that a LICENSEE (or LICENSEE affiliate) patent is Necessary to implement the Specification. In this Licence; (i) affiliate means any entity controlling, controlled by or under common control with a party (in fact or in law, via voting securities, management control or otherwise) and affiliated shall be construed accordingly; (ii) assert means to allege infringement in legal or administrative proceedings, or proceedings before any other competent trade, arbitral or international authority; (iii) Necessary means with respect to any claims of any patent, those claims which, without the appropriate permission of the patent owner, will be infringed when implementing the Specification because no alternative, commercially reasonable, non-infringing way of implementing the Specification is known; and (iv) English law and the jurisdiction of the English courts shall apply to all aspects of this Licence, its interpretation and enforcement. The total liability of ARM and any of its suppliers and licensors under or in relation to this Licence shall be limited to the greater of the amount actually paid by LICENSEE for the Specification or
Page 6 of 28
US$10.00. The limitations, exclusions and disclaimers in this Licence shall apply to the maximum extent allowed by applicable law. ARM Contract reference LEC-ELA-00081 V2.0 AB/LS (9 March 2005)
1.5 Acknowledgements
This specification has been developed with the active support of the following organizations. In alphabetical order: ARM, CodeSourcery, Intel, Metrowerks, Montavista, Nexus Electronics, PalmSource, Symbian, Texas Instruments, and Wind River.
Page 7 of 28
2 SCOPE
Conformance to the ABI for the ARM architecture is intended to support inter-operation between:
Relocatable files generated by different tool chains. Executable and shared object files generated for the same execution environment by different tool chains.
This standard for run-time helper functions allows a relocatable file built by one conforming tool chain from ARMThumb assembly language, C, or stand alone C++ to be compatible with the static linking environment provided by a different conforming tool chain. Figure 1, Inter-operation between relocatable files
<header>
header
<header>
<header> <header>
header header
<header> <header>
Translator #2
Object Object code code Private Private helpers helpers Functions NOT standarized by the AEABI AEABI standard functions
In this model of inter-working, the standard headers used to build a relocatable file are those associated with the tool chain building it, not those associated with the library with which the relocatable fille will, ultimately, be linked.
Run-time library
Run-time library
Static linker #1
Static linker #2
Executable
Page 8 of 28
3 INTRODUCTION
A number of principles of inter-operation are implicit in, or compatible with, Figure 1, above. This section describes these principles as they apply to run-time helper functions, and gives a rationale for each one. The corresponding section (3) of [CLIBABI] discusses the same issues as they apply to C library functions.
An application header file must describe the same binary interface to declared data and functions, to every ABI-conforming compiler that reads it. Tool-chain-specific information in such header files must affect only the quality of implementation of the relocatable files whose sources includes the headers, not their binary interfaces.
Rationale: A relocatable file or library is distributed with a set of header files describing its interface. Different compilers must interpret the underlying binary interface description identically. Nevertheless, some compilers might comprehend pragmas or pre-processor-guarded language extensions that cause better code to be generated, or that trigger behavior that does not affect the binary compatibility of interfaces. Standard (system) headers describe run-time libraries In general, entities defined in run-time libraries are declared in standard (or system) header files (<header> in Figure 1). A standard header need not be intelligible to any tool chain other than the one that provides it. Rationale: Some language-standardized behavior cannot be securely or conveniently described in sourcelanguage terms that all compilers implement identically (for example, va_start and va_arg from Cs stdarg.h). So, a relocatable file must be built using the standard headers associated with the compiler building it.
Page 9 of 28
Without standard helper functions, each relocatable file would have to carry all of its support functions with it, either in ELF COMDAT groups within the relocatable file itself or in an adjunct library. Multiple tool chains (at least from ARM and GNU) implement essentially compatible floating-point arithmetic functions. (Corresponding functions have identical type signatures and semantics, but different names). In C++, even if no system headers are included, inter-working is only possible if implementations agree on the helpers to use in construction, destruction, and throwing exceptions.
3.3 Private helper functions must be carried with the using file
A needed helper function that is not available in all ABI-complying environmentsany helper not standardized by this ABI componentmust be supplied with the relocatable file that needs it. There are two ways to do this.
Provide the required helpers in a separate library (see 3.9) and provide the library with any relocatable file that might refer to it. Include the helpers in additional sections within the relocatable file in named ELF COMDAT groups. This is the standard way to distribute C++ constructors, destructors, out-of-line copies of inline functions, etc.
We encourage use of the second (COMDAT group) method, though the choice of method is properly a quality of implementation concern for each tool chain provider.
Page 10 of 28
Accepting this constraint gives considerable scope for private arrangements (not governed by this ABI) between these tool chain components, restricted only by the requirement to provide a well defined binary interface (ABI) to the functions described in 4.
The current list of registered vendor, and pseudo vendor, prefixes is given in Table 1 below. Table 1, Registered Vendors Name aeabi AnonXyz anonXyz ARM cxa FSL GHS Vendor Reserved to the ABI for the ARM Architecture (EABI pseudo-vendor) Reserved to private experiments by the Xyz vendor. Guaranteed not to clash with any registered vendor name. ARM Ltd (Note: the company, not the processor). C++ ABI pseudo-vendor Freescale Semiconductor Inc. Green Hills Systems
Page 11 of 28
Name gnu iar intel ixs llvm PSI RAL TASKING TI tls WRS
Vendor GNU compilers and tools (Free Software Foundation) IAR Systems Intel Corporation Intel Xscale The LLVM/Clang projects PalmSource Inc. Rowley Associates Ltd Altium Ltd. TI Inc. Reserved for use in thread-local storage routines. Wind River Systems.
To register a vendor prefix with ARM, please E-mail your request to arm.eabi at arm.com.
The library file format is the ar format describe in [BSABI]. It must not matter whether libraries are searched once or repeatedly (this is Q-o-I). Multiple adjunct libraries can appear in any order in the list of libraries given to the linker provided that they precede all libraries contributing to the run-time environment.
No member of an adjunct library can refer to a member of any other library other than to an entity specified by this ABI that contributes to the run-time environment. The names of adjunct members must be in a vendor-private name space (3.8). If run-time environment support functions are provided in multiple libraries, and these are intended to be usable by other ABI-conforming linkers, it must be possible to list the libraries in at least one order in which each reference between them is from a library to one later in the order. This order must be documented.
Page 12 of 28
Code that makes no use of FP values can be built to the Base Procedure Call Standard [AAPCS, 5] and will be compatible with an application built to the base standard or the VFP procedure call standard [AAPCS, 6.1]. Portable binary code that makes heavy use of FP will surely be offered in two variants: base-standard for environments that lack FP hardware and VFP-standard otherwise. Portable binary code that makes only light use of floating point might reasonably be offered in the base standard only with its FP-using functions declared in its supporting header files as base-standard interfaces using some Q-o-I means such as decoration with __softfp or __ATTRIBUTE((softfp))__.
Both the portable code and the application that uses it might refer to the same standard library function (such as strtod() or sin()). The portable code will expect a base-standard interface and the application will expect a VFP-standard interface. The variants are not call-compatible.
The scope of this problem is precisely: all non-variadic standard library functions taking floating-point parameters or delivering floating-point results. Implicit calls to conversion functions that arise from expressions such as double d = (double) int_val can also cause difficulties. A call is either to a floating-point (FP) helper function (such as __aeabi_i2d, Table 8, below]) defined by this ABI (4.1.2) or to a private helper function. The FP helpers defined by this ABI cause no difficulties because they always use a base-standard interface but a private helper function would suffer the same problem as strtod() or sin() if the same tool chain were used to build the application and the portable binary and the helper function were not forced to have a base-standard interface. The 1999 (pre-ABI) solution to this problem (first adopted by ADS 1.0) was as follows.
Identify those functions that would be expected to have VFP-standard interfaces when used in a VFPstandard application (such as strtod and sin). Mangle the name of the VFP-standard variant of each of these functions using the prefix __hardfp.
In 1999, VFP was not widely deployed in ARM-based products so it was reasonable to load these inter-operation costs on users of the VFP calling standard. Today, this ABI defines a clean way for tool chains to support this functionality without resorting to encoding the interface standard in a functions name. The Tag_ABI_VFP_args build attribute in [ADDENDA] records the interface intentions of a producer. In principle, this tag gives enough information to a tool chain to allow it to solve, using its own Q-o-I means, the problem described in this section that arises from the third use case. The problem described in this section arises in the most marginal of the three portable-code use cases described in the bullet points at the beginning of this section so we now recommend that tool chains should not mangle the affected names (essentially the functions described by the C librarys <math.h> and some from <stdlib.h>).
Page 13 of 28
A full IEEE implementation is a natural super-set. A producer can ensure that, by carefully choosing the correct helper function for the purpose, the intended application behavior does not change inappropriately if the helper-function implementations support more than the ABI-required, IEEE 754-specified behavior.
All IEEE NaN bit patterns with the most significant bit of the significand set are quiet, and all with the most significant bit clear are signaling (as defined by [ARM ARM], chapter A2, Application Level Programmers Model). When not otherwise specified by IEEE 754, the result on an invalid operation should be the quiet NaN bit pattern with only the most significant bit of the significand set, and all other significand bits zero.
Dispensation de-normal numbers De-normal numbers may be flushed to zero in an implementation-defined way. We permit de-normal flushing in deference to hardware implementations of floating-point, where correct IEEE 754 behavior might require supporting code that would be an unwelcome burden to an embedded system. Implementations that flush to zero will violate the Java numerical model, but we recognize that:
Often, higher performance and smaller code size legitimately outweigh floating-point accuracy concerns. High quality floating-point behavior inevitably requires application code to be aware of the floating-point properties of its execution environment. Floating-point code that has onerous requirements (rare in embedded applications) must advertise this.
Page 14 of 28
Dispensations relating to NaNs An implementation need not process or generate NaNs. In this case, the result of each invalid operation is implementation defined (and could, for example, simply be zero). If NaNs are supported, it is only required to recognize, process, and convert those values with at least one bit set in the 20 most significant bits of the mantissa. Remaining bits should be zero and can be ignored. When a quiet NaN of one precision is converted to a quiet NaN of the other precision, the most significant 20 bits of the mantissa must be preserved. Consequently:
A NaN can be recognized by processing the most significant or only word of the representation. The least significant word of a double NaN can be ignored (it should be zero). Each ABI-complying NaN value has a single-precision representation, and a corresponding double-precision representation in which the least significant word is zero. Each ABI-complying NaN value is converted between single- and double-precision in the same way that ARM VFP FCVTDS and FCVTSD instructions convert the values.
Page 15 of 28
Binary functions take their arguments in source order where the order matters. For example, __aeabi_op(x, y) computes x op y, not y op x. The exceptions are rsub, and rcmple whose very purpose is to operate the other way round. Table 2, Standard double precision floating-point arithmetic helper functions Name and type signature
double __aeabi_dadd(double, double) double __aeabi_ddiv(double n, double d) double __aeabi_dmul(double, double) double __aeabi_drsub(double x, double y) double __aeabi_dsub(double x, double y)
Description double-precision addition double-precision division, n / d double-precision multiplication double-precision reverse subtraction, y x double-precision subtraction, x y
Table 3, double precision floating-point comparison helper functions Name and type signature
void __aeabi_cdcmpeq(double, double) void __aeabi_cdcmple(double, double) void __aeabi_cdrcmple(double, double) int __aeabi_dcmpeq(double, double) int __aeabi_dcmplt(double, double) int __aeabi_dcmple(double, double) int __aeabi_dcmpge(double, double) int __aeabi_dcmpgt(double, double) int __aeabi_dcmpun(double, double)
Description non-excepting equality comparison [1], result in PSR ZC flags 3-way (<, =, ?>) compare [1], result in PSR ZC flags reversed 3-way (<, =, ?>) compare [1], result in PSR ZC flags result (1, 0) denotes (=, ?<>) [2], use for C == and != result (1, 0) denotes (<, ?>=) [2], use for C < result (1, 0) denotes (<=, ?>) [2], use for C <= result (1, 0) denotes (>=, ?<) [2], use for C >= result (1, 0) denotes (>, ?<=) [2], use for C > result (1, 0) denotes (?, <=>) [2], use for C99 isunordered()
Notes on Table 3, above, and Table 5, below 1. The 3-way comparison functions c*cmple, c*cmpeq and c*rcmple return their results in the CPSR Z and C flags. C is clear only if the operands are ordered and the first operand is less than the second. Z is set only when the operands are ordered and equal. This means that c*cmple is the appropriate helper to use for C language < and comparisons. For > and comparisons, the order of operands to the comparator and the sense of the following branch condition must both be reversed. For example, to implement if (a > b) {} else L1, use: __aeabi_cdcmple(b, a); BHS L1; or __aeabi_cdrcmple(a, b); BHS L1. The *rcmple functions may be implemented as operand swapping veneers that tail-call the corresponding versions of cmple. When implemented to the full IEEE specification, *le helpers potentially throw exceptions when comparing with quiet NaNs. The *eq helpers do not. Of course, all comparisons will potentially throw exceptions when comparing with signaling NaNs. ARM IHI 0043D Page 16 of 28
Minimal implementations never throw exceptions. In the absence of NaNs, c*cmpeq can be an alias for c*cmple. The 3-way, status-returning comparison functions preserve all core registers except ip, lr, and the CPSR 2. The six Boolean versions *cmp* return 1 or 0 in r0 to denote the truth or falsity of the IEEE predicate they test. As in note1, all except *cmpeq and *cmpun can throw an exception when comparing a quiet NaN. Table 4, Standard single precision floating-point arithmetic helper functions Name and type signature
float __aeabi_fadd(float, float) float __aeabi_fdiv(float n, float d) float __aeabi_fmul(float, float) float __aeabi_frsub(float x, float y) float __aeabi_fsub(float x, float y)
Description single-precision addition single-precision division, n / d single-precision multiplication single-precision reverse subtraction, y x single-precision subtraction, x y
Table 5, Standard single precision floating-point comparison helper functions Name and type signature
void __aeabi_cfcmpeq(float, float) void __aeabi_cfcmple(float, float) void __aeabi_cfrcmple(float, float) int __aeabi_fcmpeq(float, float) int __aeabi_fcmplt(float, float) int __aeabi_fcmple(float, float) int __aeabi_fcmpge(float, float) int __aeabi_fcmpgt(float, float) int __aeabi_fcmpun(float, float)
Description non-excepting equality comparison [1], result in PSR ZC flags 3-way (<, =, ?>) compare [1], result in PSR ZC flags reversed 3-way (<, =, ?>) compare [1], result in PSR ZC flags result (1, 0) denotes (=, ?<>) [2], use for C == and != result (1, 0) denotes (<, ?>=) [2], use for C < result (1, 0) denotes (<=, ?>) [2], use for C <= result (1, 0) denotes (>=, ?<) [2], use for C >= result (1, 0) denotes (>, ?<=) [2], use for C > result (1, 0) denotes (?, <=>) [2], use for C99 isunordered()
Description double to integer C-style conversion [3] double to unsigned C-style conversion [3] double to long long C-style conversion [3] double to unsigned long long C-style conversion [3] float (single precision) to integer C-style conversion [3]
Page 17 of 28
Description float (single precision) to unsigned C-style conversion [3] float (single precision) to long long C-style conversion [3] float to unsigned long long C-style conversion [3]
Note on Table 6, Standard floating-point to integer conversions 3. The conversion-to-integer functions whose names end in z always round towards zero, rather than going with the current or default rounding mode. This makes them the appropriate ones to use for C casts-to-integer, which are required by the C standard to round towards zero. Table 7, Standard conversions between floating types Name and type signature
float __aeabi_d2f(double) double __aeabi_f2d(float) float __aeabi_h2f(short hf) float __aeabi_h2f_alt(short hf)
Description double to float (single precision) conversion float (single precision) to double conversion IEEE 754 binary16 storage format (VFP half precision) to binary32 (float) conversion [4, 5]; __aeabi_h2f_alt converts from VFP alternative format [7]. IEEE 754 binary32 (float) to binary16 storage format (VFP half precision) conversion [4, 6]; __aeabi_f2h_alt converts to VFP alternative format [8]. IEEE 754 binary64 (double) to binary16 storage format (VFP half precision) conversion [4, 9]; __aeabi_d2h_alt converts to VFP alternative format [10].
Notes on Table 7, Standard conversions between floating types 4. IEEE P754 binary16 format is a storage-only format on which no floating-point operations are defined. Loading and storing such values is supported through the integer instruction set rather than the floating-point instruction set. Hence these functions convert between 16-bit short and 32-bit or 64-bit float. In the VFPv3 alternative format there are no NaNs or infinities and encodings with maximum exponent value encode numbers. 5. h2f converts a 16-bit binary floating point bit pattern to the 32-bit binary floating point bit pattern representing the same number, infinity, zero, or NaN. A NaN is converted by appending 13 0-bits to its representation. 6. f2h converts a 32-bit binary floating point bit pattern to the 16-bit binary floating point bit pattern representing the same number, infinity, zero, or NaN. The least significant 13 bits of the representation of a NaN are lost in conversion. Unless altered by Q-o-I means, rounding is RN, underflow flushes to zero, and overflow generates infinity. 7. h2f_alt converts a VFPv3 alternative-format 16-bit binary floating point bit pattern to the IEEE-format 32-bit binary floating point bit pattern that represents the same number. 8. f2h_alt converts an IEEE-format 32-bit binary floating point bit pattern to the VFPv3 alternative-format 16-bit binary floating point bit pattern that represents the same number. Unless altered by Q-o-I means, rounding is RN, underflow flushes to zero, and overflow generates the largest representable number.
Page 18 of 28
9. d2h converts a 64-bit binary floating point bit pattern to the 16-bit binary floating point bit pattern representing the same number, infinity, zero, or NaN. The least significant 42 bits of the representation of a NaN are lost in conversion. Unless altered by Q-o-I means, rounding is RN, underflow flushes to zero, and overflow generates infinity. 10. d2h_alt converts an IEEE-format 64-bit binary floating point bit pattern to the VFPv3 alternative-format 16-bit binary floating point bit pattern that represents the same number. Unless altered by Q-o-I means, rounding is RN, underflow flushes to zero, and overflow generates the largest representable number. Table 8, Standard integer to floating-point conversions Name and type signature
double __aeabi_i2d(int) double __aeabi_ui2d(unsigned) double __aeabi_l2d(long long) double __aeabi_ul2d(unsigned long long) float __aeabi_i2f(int) float __aeabi_ui2f(unsigned) float __aeabi_l2f(long long) float __aeabi_ul2f(unsigned long long)
Description integer to double conversion unsigned to double conversion long long to double conversion unsigned long long to double conversion integer to float (single precision) conversion unsigned to float (single precision) conversion long long to float (single precision) conversion unsigned long long to float (single precision) conversion
Description multiplication [1] signed long long division and remainder, {q, r} = n / d [2] unsigned signed ll division, remainder, {q, r} = n / d [2] logical shift left [1]
Page 19 of 28
Description logical shift right [1] arithmetic shift right [1] signed long long comparison [3] unsigned long long comparison [3]
Notes on Table 9, Long long functions, above 1. Because of 2s complement number representation, these functions work identically with long long replaced uniformly by unsigned long long. Each returns its result in {r0, r1}, as specified by the [AAPCS]. 2. A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}}, the quotient in {r0, r1}, and the remainder in {r2, r3}. The description above is written using ARM-specific function prototype notation, though no prototype need be read by any compiler. (In the table above, think of __value_in_regs as a structured comment). 3. The comparison functions return negative, zero, or a positive integer according to whether the comparison result is <, ==, or >, respectively (like strcmp). In practice, compilers can inline all comparisons using SUBS, SBCS (the test for equality needs 3 Thumb instructions). Implementations of ldivmod and uldivmod have full [AAPCS] privileges and may corrupt any register permitted to be corrupted by an AAPCS-conforming call. Thus, for example, an implementation may use a co-processor that has a division, or division-step, operation. The effect that such use has on the co-processor state is documented in a co-processor supplement. Otherwise, implementations of the long long helper functions are allowed to corrupt only the integer core registers permitted to be corrupted by the AAPCS (r0-r3, ip, lr, and CPSR).
Page 20 of 28
Implementations of idiv, uidiv, idivmod, and uidivmod have full [AAPCS] privileges and may corrupt any register an AAPCS-conforming call may corrupt. Thus, for example, an implementation may use a co-processor that has a division, or division-step, operation. The effect that such use has on co-processor state is documented in a separate co-processor supplement. The division functions take the numerator and denominator in that order, and produce the quotient in r0 or the quotient and the remainder in {r0, r1} respectively. Integer division truncates towards zero and the following identities hold if the quotient can be represented.
(numerator / denominator) = (numerator / -denominator) (numerator / denominator) * denominator + (numerator % denominator) = numerator
The quotient can be represented for all input values except the following.
denominator = 0 (discussed in 4.3.2). numerator = -2147483648 (bit pattern 0x80000000), denominator = -1. (the number 2147483648 has no representation as a signed int).
In the second case an implementation is may return any convenient value, possibly the original numerator.
Return the value passed to them as a parameter. Or, return a fixed value defined by the execution environment (such as 0). Or, raise a signal (often SIGFPE) or throw an exception, and do not return.
int __aeabi_idiv0(int return_value); long long __aeabi_ldiv0(long long return_value);
An application may provide its own implementations of the *div0 functions to force a particular behavior from *div and *divmod functions called out of line. Implementations of *div0 have full [AAPCS] privileges just like the *div and *divmod functions. The *div and *divmod functions may be inlined by a tool chain. It is Q-o-I whether an inlined version calls *div0 out of line or returns the values that would have been returned by a particular value-returning version of *div0. Out of line implementations of the *div and *divmod functions call *div0 with the following parameter values.
0 if the numerator is 0. The largest value of the type manipulated by the calling division function if the numerator is positive. The least value of the type manipulated by the calling division function if the numerator is negative.
Page 21 of 28
long long __aeabi_uread8(void *address); long long __aeabi_uwrite8(long long value, void *address);
We expect unaligned floating-point values to be read and written as integer bit patterns (if at all). Write functions return the value written, read functions the value read. Implementations of these functions are allowed to corrupt only the integer core registers permitted to be corrupted by the [AAPCS] (r0-r3, ip, lr, and CPSR).
These functions work like the ANSI C memcpy and memmove functions. However, __aeabi_memcpy8 may assume that both of its arguments are 8-byte aligned, __aeabi_memcpy4 that both of its arguments are 4-byte aligned. None of the three functions is required to return anything in r0. Each of these functions can be smaller or faster than the general memcpy or each can be an alias for memcpy itself, similarly for memmove. Compilers can replace calls to memcpy with calls to one of these functions if they can deduce that the constraints are satisfied. For example, any memcpy whose return value is ignored can be replaced with __aeabi_memcpy. If the copy is between 4-byte-aligned pointers it can be replaced with __aeabi_memcpy4, and so on. The size_t argument does not need to be a multiple of 4 for the 4/8-byte aligned versions, which allows copies with a non-constant size to be specialized according to source and destination alignment. Small aligned copies are likely to be inlined by compilers, so these functions should be optimized for larger copies. Memory clearing and setting In similar deference to run-time efficiency we define reduced forms of memset and memclr.
void __aeabi_memset8(void *dest, size_t n, int c); void __aeabi_memset4(void *dest, size_t n, int c); void __aeabi_memset(void *dest, size_t n, int c); void __aeabi_memclr8(void *dest, size_t n); void __aeabi_memclr4(void *dest, size_t n); void __aeabi_memclr(void *dest, size_t n);
Note that relative to ANSI memset, __aeabi_memset has the order of its second and third arguments reversed. This allows __aeabi_memclr to tail-call __aeabi_memset. The memclr functions simplify a very common special case of memset, namely the one in which c = 0 and the memory is being cleared to all zeroes. The size_t argument does not need to be a multiple of 4 for the 4/8-byte aligned versions, which allows clears and sets with a non-constant size to be specialized according to the destination alignment.
Page 22 of 28
In general, implementations of these functions are allowed to corrupt only the integer core registers permitted to be corrupted by the [AAPCS] (r0-r3, ip, lr, and CPSR). If there is an attached device with efficient memory copying or clearing operations (such as a DMA engine), its device supplement specifies whether it may be used in implementations of these functions and what effect such use has on the devices state.
Implementations of this function should corrupt only the result register (r0) and the non-parameter integer core registers allowed to be corrupted by the [AAPCS] (ip, lr, and CPSR). Registers r1-r3 must be preserved.
Description The initial value of a pure virtual function. Called if a not overridden pure virtual function is called.
Page 23 of 28
Table 11, One-time construction API Name and type signature Guard variable
int __cxa_guard_acquire(int *gv)
Description A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must be statically initialized to 0. If *gv guards an object under construction, wait for construction to complete (guard released) or abort (guard aborted). Then, if *gv guards a not-yet-constructed object, acquire the guard and return non-0. Otherwise, if *gv guards a constructed object, return 0. Pre-condition: *gv acquired, guarded object constructed. Post-condition: ((*gv & 1) = 1), *gv released. Pre-condition: *gv acquired, guarded object not constructed. Post-condition: ((*gv & 3) = 0), *gv released.
The one-time construction API functions may corrupt only the integer core registers permitted to be corrupted by the [AAPCS] (r0-r3, ip, lr, and CPSR). The one-time construction API is expected to be used in the following way.
if ((obj_guard & 1) == 0) { if ( __cxa_guard_acquire(&obj_guard) ) { ... initialize the object ...; ... queue object destructor with __cxa_atexit(); // See 4.4.5. __cxa_guard_release(&obj_guard); // Assert: (obj_guard & 1) == 1 } }
If the object constructor throws an exception, cleanup code can call __cxa_guard_abort to release the guard and reset its state to the initial state.
This ABI gives __cxa_vec_ctor and __cxa_vec_cctor a void * return type (highlighted in yellow below) instead of void. The value returned is the same as the first parameter a pointer to the array being constructed This ABI specifies the same array cookie format whenever an array cookie is needed. The cookie occupies 8 bytes, 8-byte aligned. It contains two 4-byte fields, the element size followed by the element count.
Below we list the functions and their arguments. For details see the references cited at the start of 4.4.3.
void *__cxa_vec_new( size_t count, size_t element_size, size_t cookie_size, void (*ctor)(void *), void (dtor)(void *)); void *__cxa_vec_new2( size_t count, size_t element_size, size_t cookie_size,
Page 24 of 28
void (*ctor)(void *this), void (*dtor)(void *this), void *(*alloc)(size_t size), void (*dealloc)(void *object)); void *__cxa_vec_new3( size_t count, size_t element_size, size_t cookie_size, void (*ctor)(void *this), void (*dtor)(void *this), void *(*alloc)(size_t size), void (*dealloc)(void *object, size_t size)); void *__cxa_vec_ctor( void *vector, size_t count, size_t element_size, void (*ctor)(void *this), void (*dtor)(void *this)); void __cxa_vec_dtor( void *vector, size_t count, size_t element_size, void (*dtor)(void *this)); void __cxa_vec_cleanup( void *vector, size_t count, size_t element_size, void (*dtor)(void *this)); void __cxa_vec_delete( void *vector, size_t element_size, size_t cookie_size, void (*dtor)(void *this)); void __cxa_vec_delete2( void *vector, size_t element_size, size_t cookie_size, void (*dtor)(void *this), void (*dealloc)(void *object)); void __cxa_vec_delete3( void *vector, size_t element_size, size_t cookie_size, void (*dtor)(void *this), void (*dealloc)(void *object, size_t size)); void *__cxa_vec_cctor( void *destination, void *source, size_t count, size_t element_size, void (*copy_ctor)(void *this, void *source), void (*dtor)(void *this));
4.4.3.2 Helper functions defined by the C++ ABI for the ARM Architecture
This ABI define the following new helpers which can be called more efficiently.
__aeabi_vec_ctor_nocookie_nodtor __aeabi_vec_ctor_cookie_nodtor __aeabi_vec_cctor_nocookie_nodtor __aeabi_vec_new_cookie_noctor __aeabi_vec_new_nocookie __aeabi_vec_new_cookie_nodtor __aeabi_vec_new_cookie __aeabi_vec_dtor __aeabi_vec_dtor_cookie __aeabi_vec_delete __aeabi_vec_delete3 __aeabi_vec_delete3_nodtor __aeabi_atexit
Compilers are not required to use these functions but runtime libraries complying with this ABI must supply them. Below we list the functions and their arguments. For details see [CPPABI] 3.2.2, Array construction and destruction. Each function is declared extern C.
Page 25 of 28
void* __aeabi_vec_ctor_nocookie_nodtor( void* user_array, void* (*constructor)(void*), size_t element_size, size_t element_count); void* __aeabi_vec_ctor_cookie_nodtor( array_cookie* cookie, void*(*constructor)(void*), size_t element_size, size_t element_count);
void* __aeabi_vec_cctor_nocookie_nodtor( // Returns: user_array_dest void* user_array_dest, void* user_array_src, size_t element_size, size_t element_count, void* (*copy_constructor)(void*, void*)); void* __aeabi_vec_new_cookie_noctor( size_t element_size, size_t element_count); void* __aeabi_vec_new_nocookie( size_t element_size, size_t
// Returns: new array element_count, void* (*constructor)(void*)); // Returns: new array element_count, void* (*constructor)(void*));
void* __aeabi_vec_new_cookie( // Returns: new array size_t element_size, size_t element_count, void* (*constructor)(void*), void* (*destructor)(void*)); void* __aeabi_vec_dtor( void* user_array, void* (*destructor)(void*), size_t element_size, size_t element_count); void* __aeabi_vec_dtor_cookie( void* user_array, void* (*destructor)(void*)); void __aeabi_vec_delete( void* user_array, void* (*destructor)(void*)); void __aeabi_vec_delete3( void* user_array, void* (*destructor)(void*), void (*dealloc)(void*, size_t)); void __aeabi_vec_delete3_nodtor( void* user_array, void (*dealloc)(void*, size_t)); int __aeabi_atexit( // Returns: 0 => OK; non-0 => failed void* object, void (*destroyer)(void*), void* dso_handle); // Returns: // cookie associated with user_array // (if there is one) // Returns: // cookie associated with user_array
Page 26 of 28
int __aeabi_atexit(void *object, void (*dtor)(void *this), void *handle); int __cxa_atexit(void (*dtor)(void *this), void *object, void *handle);
(It is slightly more efficient for the caller to call __aeabi_exit, and calling this function supports static allocation of memory for the list of destructions see [CPPABI] 3.2.4, subsection Static object destruction). The handle argument should be NULL unless the object was created by a dynamically loaded shared library (DSO or DLL). On exit, dtor(object) is called in the correct order relative to other static object destructors. When a user function F is registered by calling the C/C++ library function atexit, it must be registered by calling __aeabi_exit(NULL, F, NULL) or __cxa_atexit(F, NULL, NULL). The handle argument and the dynamically loaded shared object (DSOor DLL ) finalization function __cxa_finalize (listed below) are relevant only in the presence of DSOs or DLLs. The handle is the value passed to __cxa_finalize. See the relevant platform supplement or the generic C++ ABI for further information.
void __cxa_finalize(void *handle); // Not used in the absence of DLLs/DSOs
When a DSO is involved, handle must be an address that uniquely identifies the DSO. Conventionally, handle = &__dso_handle, where __dso_handle is a label defined while statically linking the DSO.
Page 27 of 28
struct __cxa_eh_globals *__cxa_get_globals(void); // Get a pointer to the implementation-defined, per-thread EH state const std::type_info *__cxa_current_exception_type(void);
Page 28 of 28