Floating Point Fun on Cortex‑M: When the Linker Says No

April 18, 2026
Close-up of hands assembling electronic components on a breadboard with wires.
Photo by Chengxin Zhao on Pexels

The problem, in plain English

A recent writeup digging into the PSA Crypto API on small MCUs highlights an annoyingly common trap: floating‑point ABI mismatches that stop builds cold. It has been reported that on the nRF52840 the ECDSA signature call eventually runs inside a closed‑source library that bridges the Cortex‑M4 and a TrustZone CryptoCell 310 — and if you mix objects compiled with different float ABIs you’ll likely see the linker puke the memorable error: ld.bfd: error: X uses VFP register arguments, Y does not. Ouch.

Why this blows up

ARM supports three floating‑point ABIs controlled by -mfloat-abi: soft, softfp, and hard. Soft emulates FP in software and passes FP values in integer registers. Softfp lets routines use FP instructions but keeps the integer calling convention. Hard fully uses the FPU and passes arguments in FP registers (s0–s15 for the first args on Cortex‑M with VFP). Mix soft/softfp objects with hard, and the linker refuses to merge their ARM attribute sections — it can tell the ABI by the ELF attributes. Tiny mismatch, big failure. Who knew a register choice could be so picky?

Real‑world frosting on the cake

On devices like the nRF52840 you can inspect the attribute block (via readelf) and see Tag_FP_arch: VFPv4‑D16 and Tag_CPU_arch: v7E‑M — in other words, the chip’s toolchain often assumes hard. When vendors ship both hard and soft variants of libraries, or when closed binaries control crypto offload, developers get trapped unless they rebuild everything with one consistent -mfloat-abi. It’s a classic embedded toolchain gotcha — subtle, silent until link time, and suddenly infuriating.

Takeaway

The fix is boring but simple: pick an ABI and be religious about it. Recompile libraries, align compiler flags, or stick to softfp if you need portability without retooling closed binaries. The broader lesson? As MCUs pack more features (TrustZone, CryptoCells, vector FP), the toolchain contract matters more than ever. The linker won’t compromise — so neither should your build settings.

Sources: danielmangum.com, Hacker News