Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raspberry Pi ARM Float ABI Compatibility

I am currently performing some cross-compiling tests for Raspberry Pi on my Ubuntu machine. My current understanding is that Raspberry Pi supports hardware floating point and the default Raspbian OS image was built with hardware floating point (armhf). Correct?

If I build my application using the "arm-linux-gnueabi" toolchain (without specifying any ARM flags), then my application will use soft float ABI. Correct?

In this case, all my dependencies also have to use the same ABI in order to be able to link correctly. Correct?

If my application uses soft float ABI, then my application surely was linked to a soft float ABI shared standard library. When I run my application on my Raspberry Pi everything works as expected. How can this be, if Raspbian uses hard float ABI (and I'm guessing the shared standard library also does)?

FYI: my default arm-linux-gnueabi is configured with:

--with-float=soft
--with-arch=armv5

And I'm compiling my application like this:

arm-linux-gnueabi-g++ test.cpp -o test

My program does include floating point calculations:

double test = (123.456 + 789.123) * 1.23;
printf("%f\n", test); // prints: 1122.472170
printf("%f\n", std::floor(test)); // prints: 1122.000000
like image 272
pqvst Avatar asked Mar 23 '23 04:03

pqvst


1 Answers

All your affirmations are correct, I just want to add a little precision concerning Raspbian's armhf.

Debian's armhf (arm-linux-gnueabihf) targets ARMv7t hard-float. Since Raspbian is based on Debian you'd expect the same, but Raspbian's armhf targets ARMv6 hard-float (which is the very reason of the existence of Raspbian in the first place: find a middle ground between Debian's armel -- ARMv4t soft-float -- and armhf architectures to correctly exploit the Raspberry's CPU).

So it is a bit treacherous for Raspbian to speak of armhf, especially since many people will use Debian (or a derivative such as Ubuntu) as a host system and thus are likely to confuse the two. If you ask me, the guys at Raspbian made a mistake keeping the same architecture name, it really should be arm6hf.

When I run my application on my Raspberry Pi everything works as expected. How can this be, if Raspbian uses hard float ABI (and I'm guessing the shared standard library also does)?

As far as I know, the only difference between arm-linux-gnueabi and arm-linux-gnueabihf is the calling conventions that involve floating points (the former passes them using integer registers, the latter using floating-point registers).

If you never make use of the floating-point ABI in your test program (what I mean is you don't pass floats to external libraries through CPU/FPU registers -- however you could perfectly make a floating point calculation internally -- using soft-float -- and eg. cast the result to int before actually "using" it in a third party library), then you never hit the ABI difference and all works.

Concerning the examples you gave where you use floating-points, I believe they fall in the category that I just described: you never make use of the hard-float ABI.

  • In all probability std::floor is inlined (the best way to make sure of that is to look at your assembly dump).
  • printf uses variadic arguments so you are in fact using a legacy C calling convention, ie. the arguments are passed on the stack, not through CPU/FPU registers.

Anyway, you should steer clear from your current arm-linux-gnueabi toolchain and use one that is specifically designed for Raspbian. Just search "Raspberry Pi cross-compiler" on the web. This way you won't be bothered.

like image 81
syam Avatar answered Mar 29 '23 22:03

syam