Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regarding the floating point abi flag used while compiling an application for arm target

I have recently written c applications for the arm target. In order to cross compile an application for the arm target, there was a flag -mfloat-abi=hard that had to be used. But I didn't actually understand what it means. Can someone please explain what the flag means. What changes will it make when compiling the application?

like image 866
Minions Avatar asked Jul 19 '15 11:07

Minions


2 Answers

The difference lies in the calling convention. ARM uses register-based calling conventions, in which both the arguments to a function (up to a limit, after which they start spilling to the stack), and the return value, are passed in registers (for the full gory details, see the Procedure Call Standard). When it comes to floating-point values, the presence or not of a hardware FPU coprocessor raises a slight conundrum over how to deal with floating point values, giving two possibilities when generating code:

  • Hard-float: you assume that floating point hardware is present, and FP arguments and return values are passed in FPU registers. It's more efficient when you do have an FPU, but is not portable to machines without one, where the code would blow up trying to access registers that don't exist.

  • Soft-float: floating-point arguments are passed in general-purpose registers the same way 32-bit or 64-bit integers would be. The callee function can then transfer them into FPU registers to do its work if it has hardware support, or fall back to floating-point emulation if not. Thus your code can work anywhere with the right library support, at the cost of a slight overhead even on real FPU hardware (which may become more significant for trivial functions).

From that, you can probably deduce whay you can't mix the two - say you could compile a function call as soft-float, but link to a hard-float library implementing that function - your calling code might put a float argument in r1, but the callee code will look for it in s0 and proceed to calculate nonsense with whatever garbage value was in there. Similarly, the library function would then return a float result in s0, but your code would run off with whatever happened to be left in r0 and be even more wrong.

Thus if your toolchain provides hard-float libraries, you can only link to them if you compile your code as hard-float, and vice-versa. Note that the magic of multilib means a single toolchain might support both, via having both versions of every library and automatically picking the right one when you link.

like image 72
Notlikethat Avatar answered Sep 30 '22 07:09

Notlikethat


Take a look at the documentation:

-mfloat-abi=name Specifies which floating-point ABI to use. Permissible values are: ‘soft’, ‘softfp’ and ‘hard’. Specifying ‘soft’ causes GCC to generate output containing library calls for floating-point operations. ‘softfp’ allows the generation of code using hardware floating-point instructions, but still uses the soft-float calling conventions. ‘hard’ allows generation of floating-point instructions and uses FPU-specific calling conventions.

The default depends on the specific target configuration. Note that the hard-float and soft-float ABIs are not link-compatible; you must compile your entire program with the same ABI, and link with a compatible set of libraries.

That means that hard uses hardware specific floating point instructions. soft will not use those instructions, but it will implement the FP operations as a software library.

Finally, the softfp means that it will use the soft calling conventions (and other ABI), that is it will not use the FP hardware registers to passing or taking parameters, but it will use the hardware FP instructions, if available.

The soft and softfp are link-compatible, that is they use the same ABI, so you can mix them in the same program. But hard will use hardware registers for argument passing, so it cannot be mixed with the other two.

Which one to use? Well, that depends on the system you are using. OS libraries will be compiled for one ABI or the other, and the native compiler will just use that. But if you are using a cross-compiler, then you may need to specify the ABI manually.

The exception is that if you are using a OS with soft ABI, and you are running it in a hardware that you know is capable of hard-FP, then you can compile your programs as softfp and take advantage of that feature without breaking the linking.

like image 45
rodrigo Avatar answered Sep 30 '22 07:09

rodrigo