A solution for mixing hard&softfloat in ARM OABI

Hi all, I have found a solution how to use OABI (old ABI) for some partial mixing of hard- and softfloat.

The basic problem: Usually the ARM processor rarely has a FPU, although FPU instructions are defined and gcc can generate them.

There are two solutions a) hardfloat - where a kernel module emulates the FPU each time an ILLEGAL INSTRUCTION is hit b) softfloat - where e.g. a+b is replaced by the compiler with a call to a library function which does the math

It is recommended to use b) because it does not involve a kernel context switch and is therefore faster.

Mixing both is quite difficult because there is one major change between a and b for the return value of a float or double function. E.g. if you call fsqrt(2.0), the 2.0 is pushed in both modes to the stack, but the return value is expected in a) FP0 b) R0/R1

The specific problem:

Well, if you have control over the full system, you can recompile the kernel and the libraries to use softfloat only.

But if you can't touch the kernel and the libraries (because your devices are already in the hands of users and they have a lot of other applications installed) you may be lost like in this example:

There is some code that can be directly installed to run on the Sharp Zaurus with Linux 2.4.20 on the Sharp ROM. Therefore it uses OABI with FPU instructions and is linked to a hardfloat libc/libm.

Now, this (binary!) package should be universal so that it also runs on an OpenMoko device.

So, how can you write a package (library) that can run on both? FPU- Instructions are not the problem. Fortunately, there is a FPU emulator enabled Linux 2.6.x kernel for the OpenMoko. But the runtime libc/libm is compiled for softfloat which is heavily used by other parts of the device you have no control.

The solution is a softfloat wrapper and to compile your code for hardfloat.

Obviously you have to detect which type of library you have at runtime. You can do this by e.g. checking sqrt(4.0) == 2.0 which has a very high probability to fail on a softfloat library systems. The next step is to wrap all important math functions (ceil, floor, atof, rint, etc.) so that they use dlopen() and dlsym() to locate the softfloat function, call it, and then move the result in r0/r1 to fp0.

This approach works in mySTEP (GNUstep) and since it is LGPL code, please feel free to use it according to the licence conditions - and report bugs. The code can be found at the end of this file:

formatting link

I hope there is someone who finds this useful.

Nikolaus Schaller Golden Delicious Computers GmbH&Co. KG

formatting link

Reply to
hns
Loading thread data ...

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.