Skip to content
Tech News
← Back to articles

Floating Point Fun on Cortex-M Processors

read original get ARM Cortex-M Floating Point Emulator → more articles
Why This Matters

This article highlights the importance of understanding floating-point ABI options on Cortex-M processors, which can impact the compatibility and performance of cryptographic operations and other floating-point computations. For developers working with embedded systems, choosing the correct ABI ensures smoother integration and avoids linker errors, ultimately leading to more reliable and efficient applications.

Key Takeaways

In my recent post on the PSA Crypto API, I demonstrated the use of the API on two different MCUs: the nRF52840 and the ESP32-S3. In the case of the former, the ECDSA signature operation was eventually executed in a closed source library that manages communication between the Arm Cortex-M4 processor and the Arm TrustZone CryptoCell 310 security subsytem. Readers that ventured down the rabbit hole of links in the post may have noticed that there are variants of the nrf_cc310_mbedcrypto libraries for hard-float and soft-float . If you have ever hit an error from your linker of the following style, you know exactly why.

ld.bfd: error: X uses VFP register arguments, Y does not ld.bfd: failed to merge target specific data of file

Arm defines three floating point Application Binary Interface (ABI) options, which are controlled by the -mfloat-abi compiler flag.

soft : Soft ABI without FPU hardare: All floating-point operations are handled by the runtime library functions. Values are passed through integer register bank.

: Soft ABI without FPU hardare: All floating-point operations are handled by the runtime library functions. Values are passed through integer register bank. softfp : Soft ABI with FPU hardware: This allows the compiled code to generate codes that directly access the FPU. But, if a calculation needs to use a runtime library function, a soft-float calling convention is used. Values are passed through integer register bank.

: Soft ABI with FPU hardware: This allows the compiled code to generate codes that directly access the FPU. But, if a calculation needs to use a runtime library function, a soft-float calling convention is used. Values are passed through integer register bank. hard : Hard ABI: This allows the compiled code to generate codes that directly accesss the FPU and use FPU-specific calling conventions when calling runtime library functions.

Arm, like most Instruction Set Architectures (ISAs), passes arguments to subroutines in general purpose registers (GPRs), specifically r0 - r3 . When the number or size of arguments exceeds the available GPRs, the remaining arguments are “spilled” to the stack, where they can be accessed by the callee. However, when a processor includes a Floating Point Unit (FPU) (more specifically for Armv7-M processors, the C10 and C11 coprocessors), and thus the floating point extension, there is an additional register bank with 32 floating point registers ( s0 - s31 ).

Side note: you may see the term Vector Floating Point (VFP) when referring to floating point on Armv7-M processors, such as the Cortex-M4. The reference manual explains why this is the case: “In the ARMv7-A and ARMv7-R architecture profiles, floating point instructions are called VFP instructions and have mnemonics starting with V. Because ARM assembler is highly consistent across architecture versions and profiles, ARMv7-M retains these mnemonics, but normally describes the instructions as floating point instructions, or FP instructions.”

When using the hard ABI, the s0 - s15 registers can be used for passing arguments to subroutines. The use of hard also indicates that floating point instructions (load and store, register transfer, data processing) may be used within routines.

When using softfp , floating point instructions are allowed within routines, but arguments cannot be passed in floating point registers. soft uses the same calling convention as softfp , and is thus compatible, but does not allow for the use of floating point instructions. When floating point operations are performed without support for floating point instructions, they must be emulated in software. When you see the error described at the beginning of this post, you are mixing soft / softfp with hard , which the linker will refuse. It is able to determine the ABI of an object file being linked by looking at the Arm attributes section, which differs for each variant. For example, on the nRF52840, the attributes appear as follows (extracted via readelf ).

... continue reading