Issue
For some time now (since this patch in 2017), gcc has been able to infer the right -mfpu
value from -mcpu
. However, it's not clear to me if the -mfloat-abi
is also automatically inferred, or needs to be set manually.
The documentation states somewhat cryptically that "The default [value of mfloat-abi] depends on the specific target configuration."
So, to be specific: if I compile with -mcpu=cortex-m4
, which by default enables floating-point instructions, will I automatically get -mfloat-abi=hard
, or at least softfp
? Or might I end up with the suboptimal soft
?
Solution
I think the answer is "No."
-mfpu
First let's look at how -mfpu
is inferred.
https://github.com/gcc-mirror/gcc/blob/releases/gcc-13.2.0/gcc/config/arm/arm.opt#L164-L166
mfpu=
Target RejectNegative Joined Enum(arm_fpu) Var(arm_fpu_index) Init(TARGET_FPU_auto) Save
Specify the name of the target floating point hardware/format.
The default, TARGET_FPU_auto
is a defined value of the arm_fpu
enum:
https://github.com/gcc-mirror/gcc/blob/releases/gcc-13.2.0/gcc/config/arm/arm-tables.opt#L473-L474
Enum
Name(arm_fpu) Type(enum fpu_type)
Known ARM FPUs (for use with the -mfpu= option):
EnumValue
Enum(arm_fpu) String(auto) Value(TARGET_FPU_auto)
So TARGET_FPU_auto
is an FPU enum value which is handled in a few places in arm.cc
.
I won't claim to completely understand how it works -- it involves masking ISA and FPU bitmaps in various places, e.g. arm_identify_fpu_from_isa
.
It's clear enough to me though, that when opts->x_arm_fpu_index == TARGET_FPU_auto
, some "automatic" selection happens.
-mfloat-abi
Let's compare that to the -mfloat-abi
default.
https://github.com/gcc-mirror/gcc/blob/releases/gcc-13.2.0/gcc/config/arm/arm.opt#L122-L124
mfloat-abi=
Target RejectNegative Joined Enum(float_abi_type) Var(arm_float_abi) Init(TARGET_DEFAULT_FLOAT_ABI)
Specify if floating point hardware should be used.
You'll note that the default, TARGET_DEFAULT_FLOAT_ABI
, is not one of the float_abi_type
enum values:
Enum
Name(float_abi_type) Type(enum float_abi_type)
Known floating-point ABIs (for use with the -mfloat-abi= option):
EnumValue
Enum(float_abi_type) String(soft) Value(ARM_FLOAT_ABI_SOFT)
EnumValue
Enum(float_abi_type) String(softfp) Value(ARM_FLOAT_ABI_SOFTFP)
EnumValue
Enum(float_abi_type) String(hard) Value(ARM_FLOAT_ABI_HARD)
Instead, it is a #define
, set by the "target configuration", as you noted from the docs:
$ cd gcc/config/arm
$ git grep TARGET_DEFAULT_FLOAT_ABI
arm.h:414:#ifndef TARGET_DEFAULT_FLOAT_ABI
arm.h:415:#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
arm.opt:123:Target RejectNegative Joined Enum(float_abi_type) Var(arm_float_abi) Init(TARGET_DEFAULT_FLOAT_ABI)
freebsd.h:88:#undef TARGET_DEFAULT_FLOAT_ABI
freebsd.h:90:#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_HARD
freebsd.h:92:#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
linux-eabi.h:36:#undef TARGET_DEFAULT_FLOAT_ABI
linux-eabi.h:37:#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
linux-eabi.h:62: GLIBC_DYNAMIC_LINKER_DEFAULT and TARGET_DEFAULT_FLOAT_ABI. */
linux-elf.h:30:#undef TARGET_DEFAULT_FLOAT_ABI
linux-elf.h:31:#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_HARD
netbsd-eabi.h:31: (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_SOFT \
semi.h:35:#ifndef TARGET_DEFAULT_FLOAT_ABI
semi.h:36:#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_HARD
So when not specified on the command line, it is not set to an value indicating "automatic" selection should apply, but rather an actual default option.
And it would appear (this is conjecture), from the output of grep
, that if you're targeting baremetal or an RTOS (as one would for a Cortex M4), that you might get the default ARM_FLOAT_ABI_SOFT
from arm.h
.
Answered By - Jonathon Reinhart Answer Checked By - Candace Johnson (WPSolving Volunteer)