Issue
What is the difference between -mfloat-abi=softfp and -mfloat-abi=hard cross compiler flags?
I am working on an embedded Linux project and below is some info that you might need to answer my question please.
Processor: I.MX6ULL, Linux Kernel version: 4.19, Programing Language: C, Cross Compiler variant: arm-oe-linux-gnueabi-gcc (GCC) 8.2.0,
Many thanks,
Solution
Introduction if you are not familiar with assembly language
A CPU (and compiled programs) works very differently from high-level programming languages like C, Java etc...
The most important difference in the context of your question is that a CPU can neither pass arguments nor return values in a function call. So if you have some function call example(5, 6, 7)
, the compiler must store the values 5
, 6
and 7
somewhere and call the function example()
. The function example()
must know where the function arguments are stored.
The way how and where the function arguments are stored is called "calling convention".
If you use different "calling conventions" for different functions in your program and the compiler does not know about this, it is highly probable that the wrong function arguments are passed to a function.
One example: If you call a function with _pascal
calling convention in old 16-bit Windows but the compiler "thinks" that the function has _stdcall
calling convention, the program will perform example(7, 6, 5)
instead of example(5, 6, 7)
.
The meanings of the -mfloat-abi
flags
Comparing the difference of the assembly code generated on GCC 7.1.0, I have the following understanding:
-mfloat-abi=hard
The compiler stores the function arguments in the registers of the floating-point unit. (And it uses and requires a CPU with floating-point support, of course.)
-mfloat-abi=soft
The compiler stores the function arguments in integer registers.
Instead of using floating-point functionality of the CPU, it calls functions that perform basic operations (e.g. adding two floating point numbers).
This allows you to run the program on a CPU without floating-point support if you have a library that perform the "basic operations" using multiple integer operations.
-mfloat-abi=softfp
The compiler uses the floating-point unit, but it stores the function arguments in the integer registers.
This has the following consequences:
- Just like
-mfloat-abi=hard
, the program will only run on CPUs that have floating-point support because it uses the floating-point features of the CPU. - The code is a bit slower and longer than
-mfloat-abi=hard
, but faster than-mfloat-abi-soft
- You can mix up code compiled with
-mfloat-abi=soft
and-mfloat-abi=softfp
, but not with-mfloat-abi=hard
.
You would typically use this if you have a pre-compiled function (library or object file) compiled with -mfloat-abi=soft
and you want to use this in your project running on a CPU that supports floating-point.
What happens if the wrong flag is used?
As long as the entire code in your project (**) is compiled with the same flag (and your CPU has floating-point support), nothing happens.
(**) In this context, floating-point functions in shared libraries called by your program is also part of your project!
If a function compiled with -msoft-abi=hard
calls a function compiled with -msoft-abi=soft[fp]
or vice-versa, the called function will not interpret the function arguments correctly, just like the function example()
in the Windows 16 example above.
Answered By - Martin Rosenau Answer Checked By - Clifford M. (WPSolving Volunteer)