Supporting floating point operations by linux kernel

  • 2021-06-28 14:45:38
  • OfStack

Most CPUs currently support floating-point unit FPU, which is placed outside the processor core as a separate coprocessor. But for embedded processors, floating-point operations are rarely used, and some embedded processors remove floating-point coprocessors.

X86Processor 1 generally has FPU.ARM PPC MIPS processor will appear without FPU.

How linux kernel handles floating-point operations is discussed in terms of processor with FPU and processor without FPU.

(The following is a summary of personal knowledge. The research is not deep and the errors are expected to be corrected and studied together.)

1 For processors with FPU

1 For linux kernel, the default compilation of kernel itself uses the -msoft-float option, which is compiled as a soft floating-point program. Soft floating-point implies that the gcc compiler simulates floating-point operations (provided by the glibc library) and replaces floating-point code with fixed-point operations.

For processors with FPU, we can remove the compilation option - msoft-float, which is usually in arch/xxx/Makefile.Compiling kernel to a hard floating point means that the processor's floating-point instructions compute floating points.

Hard floating-point operations are certainly more efficient than fixed-point simulations. (1 in kernel code generally does not have floating-point operations, so efficiency has little effect)

2 For app running on kernel, especially for graphics programs such as QT, there are many floating-point operations. We can compile them directly because the processor supports floating-point operations and floating-point instructions.

2 For non-FPU processors

1 For linux kernel, the compilation defaults to the -msoft-float option, the default compilation is a soft floating point program, linux kernel compilation does not rely on linking any libraries, kernel implements the corresponding simulated floating point ABI.

2 For app running on top of kernel, there are two ways to handle floating-point operations:

(1) Soft floating point is simulated by kernel.

Applications are compiled directly using hard floating points (compilers compile to hard floating point programs by default).

For kernel, the PPC MIPS processor I know has special floating-point operation exception handling. When the program runs against floating-point instructions and cannot run floating-point instructions, the hardware will produce interrupt exceptions. The kernel floating-point exception handler performs soft floating-point simulation operations according to the instructions, returns the results of the operations to the user space and executes them again.

For ARM, I did not find an exception entry for floating point calculation in its exception introduction, but kernel also has support for its soft floating point.

When configuring the ARM Linux kernel, you should see this configuration:


 menu "Floating point emulation"
 comment "At least one emulation must be selected"
 config FPE_NWFPE
  ...

This is used to configure an analog floating point processor inside the kernel.

How ARM implements soft floating-point support for anomaly simulation requires time to carefully look at the code, as shown in arch/arm/nwfpe.

The advantage of this approach is that the application does not need to be recompiled and floating point simulation needs to be turned on in kernel for ease of use.

However, the disadvantage is also obvious, each floating-point operation triggers interrupt exceptions, user space and kernel space switching, and the execution efficiency is too low.

(2) Recompile app using soft floating point

This can avoid the above problems, app needs to be compiled with the glibc library, using --msoft-float, using glibc's analog floating point, instead of fixed-point operation, which has the advantage of running better.

The disadvantage, however, is that with different compilation options, the use of ABI may change if a library or application does not use the same compilation option (ABI is different).

The system may run unexpectedly or even cause a crash.

According to recent debugging records of PPC1 processors, kernel startup normally enters console and dies at an address. User-space floating-point operations are heavy. When IC is asked, FPU is removed and the processor floating-point exception is not enabled.

When a floating-point instruction is encountered, the processor does not trigger an exception or know how to run it.

Therefore, it is also important to know if kernel is present in the processor when migrating to kernel. If the processor removes FPU and the core does not handle it accordingly (enabling floating-point exceptions), then the floating-point instructions of APP will run unpredictably and the APP can be compiled using a soft floating-point tool chain.

Here's a little thought:

For a processor, there is a floating-point exception in the processor design (both MIPS and PPC), which can also be connected to FPU.

After receiving FPU, the processor core should shield floating-point exceptions. Otherwise, if floating-point operations or floating-point exceptions occur, FPU has no practical significance.

Without FPU, the processor core needs to be able to handle floating-point exceptions, otherwise, like the problem I encountered above, the processor does not know how to run the floating-point instructions and the results are unpredictable.


Related articles: