To content | To menu | To search

Incompatibility between FPU and non-FPU code

While trying to compile an FPU application, I came through a problem, as I used a library that did not have a FPU version, and was using a function that was returning a float value (a double value could also cause the problem).

Current ABI for non-FPU code is to have return value in d0; of course, FPU code expects return value in fp0 register.

Now, if your application, compiled for -m68020-60 (or -m68030 -m68881) is linked against a library, and calls a function returning a float or double value, which does not have a m68020-60 build, it will be linked against the m68020 or m68000 version of said library, which returns the value in d0, and your application behaves strangely, or does not work at all, and you wonder why for hours :).

To make it short:

- FPU application + FPU library = OK

- FPU application + non-FPU library = OK only for functions not returning float/double values, bugs for the ones that return value of said type, in register fp0.

- non-FPU application + FPU library = same problem as above, in reverse direction. If your system does not have a FPU, you'll trigger an exception as soon as you try to execute FPU code. If you have an FPU, the library will return the value in fp0, but the non-FPU application expects result in d0.

- non-FPU application + non-FPU library = OK.

What should be done?

Do not mix non-FPU code with FPU-code, it means when using -m68020-60 to compile an application, gcc/ld should never use m68020 or m68000 version of libraries. The reverse is of course not possible due to gcc/ld multilib settings. When you compile your application for m68000 or m68020, it never links to libraries in m68020-60. But I did not check what happens when you compile your code with -m68881.