A solution for mixing hard&softfloat in ARM OABI

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

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:

http://www.quantum-step.com/download/sources/mySTEP/Foundation/Sources/NSObjCUtilities.m

I hope there is someone who finds this useful.

Nikolaus Schaller
Golden Delicious Computers GmbH&Co. KG
http://www.goldelico.com


Site Timeline