EmbeddedRelated.com

FPU

Category: Architecture | Also known as: floating point unit

A floating-point unit (FPU) is a hardware block that executes IEEE 754 floating-point arithmetic operations -- addition, subtraction, multiplication, division, and often square root -- directly in silicon, rather than emulating them in software. On MCUs that include an FPU, single-precision (32-bit) float operations typically execute in a small number of cycles instead of the hundreds of cycles required by a software floating-point library.

In practice

Whether an MCU includes an FPU depends heavily on the core. ARM Cortex-M4 and M7 cores include an optional single-precision FPU (the VFPv4-SP unit); Cortex-M33 and M55 also optionally include floating-point hardware, but the exact configuration varies by implementation. Some Cortex-M7 implementations also optionally add double-precision support, though this is not common across all silicon variants. Cortex-M0, M0+, and M3 cores have no FPU at all. On the RISC-V side, the F and D standard extensions add single- and double-precision hardware floating point, respectively, and their presence varies by vendor. 8-bit and 16-bit architectures such as PIC, AVR, and MSP430 almost never include an FPU.

In practice, using the FPU requires more than just having the hardware present. On ARM Cortex-M parts, the FPU is disabled at reset and must be enabled by setting the CP10 and CP11 bits in the CPACR register before any floating-point instructions are executed -- a step that startup code or a CMSIS SystemInit call typically handles. The compiler must also be told to emit hardware floating-point instructions; in GCC/Clang, this means passing the correct -mfpu and -mfloat-abi flags. Mixing object files compiled with different float-ABI settings (soft, softfp, hard) is a common source of link-time errors or, at calling boundaries, silent ABI mismatches.

The FPU introduces context-switching overhead in RTOS environments. On Cortex-M4/M7, the FPU adds up to 32 single-precision registers (S0-S31) and the FPSCR status register. An RTOS must save and restore this state on every task switch if any task uses floating point -- roughly 136 bytes of extra stack space per task, though the exact overhead depends on FPU configuration and stacking behavior. Many RTOSes support lazy stacking, a hardware feature on Cortex-M that defers saving FPU registers until an FPU instruction actually executes in the new context; however, RTOS support for this mechanism typically requires explicit configuration and is not automatically active. This reduces overhead when floating point is used infrequently.

When no FPU is present, the compiler falls back to a software floating-point library (such as GCC's libgcc soft-float routines or ARM's proprietary equivalent). This emulation is functionally correct but can be 20x to 100x slower and significantly increases code size. For applications with tight cycle budgets, replacing float arithmetic with fixed-point math is a common alternative on FPU-less targets.

Frequently asked

How do I know if my MCU's FPU is actually enabled and being used by the compiler?
Check two things. First, verify your startup code enables the FPU -- on ARM Cortex-M, this means setting bits 20-23 in SCB->CPACR (address 0xE000ED88). Second, confirm your compiler flags: for GCC targeting Cortex-M4, you need at minimum -mfpu=fpv4-sp-d16 and either -mfloat-abi=hard or -mfloat-abi=softfp. You can disassemble a function that uses float and check whether the output contains VFP instructions like VMUL.F32 or VADD.F32, or fall-through calls to __aeabi_fmul and similar soft-float helpers.
What is the difference between -mfloat-abi=soft, softfp, and hard?
With 'soft', the compiler emulates all floating-point in software and passes float arguments in integer registers -- no FPU instructions are emitted at all. With 'softfp', the compiler emits FPU instructions for computation but still passes float arguments in integer registers, maintaining compatibility with soft-float libraries. With 'hard', the compiler emits FPU instructions and passes float arguments directly in FPU registers, giving the best performance but producing an ABI incompatible with soft or softfp code. Mixing object files with different float-ABI settings will cause linker errors or silent incorrect behavior.
Does having an FPU mean double-precision (64-bit) operations are also fast?
Not necessarily. Most Cortex-M4 and Cortex-M33 FPUs are single-precision only (VFPv4-SP). Double-precision operations on those cores are still emulated in software even with the FPU enabled. Cortex-M7 optionally includes a double-precision unit, but not all silicon vendors enable it -- check the specific device datasheet. If your algorithm relies on double, profile it or check the assembly output to confirm hardware double support on your exact part.
How does an FPU affect RTOS task switching?
On Cortex-M4/M7, the FPU adds S0-S31 and FPSCR to the register set. Without special handling, an RTOS must save and restore these on every context switch involving a task that uses floating point, adding up to 136 bytes of stack usage per task. Most modern RTOSes (FreeRTOS, Zephyr, ThreadX) support the hardware lazy-stacking mechanism, where the hardware only saves FPU registers if a floating-point instruction is actually executed in the new context. Check your RTOS configuration options to ensure FPU support is enabled; leaving it disabled while using float in tasks causes hard faults or data corruption.
If my MCU has no FPU, should I avoid floating-point entirely?
Not necessarily -- it depends on your performance and code-size budget. Software float emulation is functionally correct and sometimes acceptable, for example in initialization code or low-rate calculations. For performance-critical or interrupt-driven code on FPU-less parts like Cortex-M0+ or AVR, fixed-point arithmetic is usually preferable: it uses integer instructions, is predictable in cycle count, and avoids the large library overhead. A common approach is to keep float for offline configuration or calibration steps and use Q-format fixed-point in the main signal-processing loop.

Differentiators vs similar concepts

An FPU is sometimes confused with a DSP or a vector processing unit. A DSP extension (such as the ARM Cortex-M4 DSP instructions) adds fixed-point SIMD and multiply-accumulate operations for integer data -- it is separate from and independent of the FPU. Some parts include DSP extensions but no FPU (Cortex-M4 without FPU option), and vice versa. An FPU is also not an FPGA: an FPGA is a reconfigurable logic fabric, not a fixed arithmetic unit, despite the similar abbreviation.