已选择硬浮点abi,但GCC在STM32上使用软浮点库

已选择硬浮点abi,但GCC在STM32上使用软浮点库,gcc,floating-point,stm32,Gcc,Floating Point,Stm32,我正在开发一个STM32L4,它嵌入了一个FPv4 SP FPU。 我正在测试FPU的使用情况。我正在使用硬浮点abi进行编译: arm-atollic-eabi-gcc -c (...) __VFP_FP__ -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard xxx.o -o xxx.o xxx.c 我在link命令中添加了相同的选项-mfloat abi,尽管我认为它没有什么用处 但是,在查看汇编代码时,我注意到软件

我正在开发一个STM32L4,它嵌入了一个FPv4 SP FPU。 我正在测试FPU的使用情况。我正在使用硬浮点abi进行编译:

arm-atollic-eabi-gcc -c  (...)  __VFP_FP__ -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard xxx.o  -o xxx.o xxx.c
我在link命令中添加了相同的选项-mfloat abi,尽管我认为它没有什么用处

但是,在查看汇编代码时,我注意到软件浮点库函数被称为:

35          volatile float f = 0.125;
0800a2b4:   mov.w   r3, #1040187392 ; 0x3e000000
0800a2b8:   str     r3, [r7, #4]
37          f = f/0.4;
0800a2ba:   ldr     r3, [r7, #4]
0800a2bc:   mov     r0, r3
0800a2be:   bl      0x8000348 <__extendsfdf2>
0800a2c2:   add     r3, pc, #100    ; (adr r3, 0x800a328 <csem_tests+136>)
0800a2c4:   ldrd    r2, r3, [r3]
0800a2c8:   bl      0x8000644 <__divdf3>

我遗漏了什么?

我不知道回答我自己的问题是否正确,如果不是,很抱歉给您带来不便,但我想这比删除帖子要好

我发现了一个问题:我用于测试的浮点变量实际上被转换为双精度,而且由于FPU仅为单精度,因此操作是在软件中处理的。强制变量如下所示浮动:

float f = (float)0.125;
f = f/(float)0.68768;

解决了这个问题,即使我真的不明白为什么编译器将这个变量转换为double。

我不知道回答我自己的问题是否正确,如果不是,很抱歉给您带来不便,但我想这比删除帖子要好

我发现了一个问题:我用于测试的浮点变量实际上被转换为双精度,而且由于FPU仅为单精度,因此操作是在软件中处理的。强制变量如下所示浮动:

float f = (float)0.125;
f = f/(float)0.68768;

解决了这个问题,即使我真的不明白编译器为什么将这个变量强制转换为double。

因为字符串常量始终是double,如果其中一个操作数是double,则所有操作都在double上执行,除非您使用命令行选项-fssingle precision constant的“f”后缀-0.125


如果想要纯FPU代码,还需要使用-ffast math&-fno math errno

,因为字符串常量始终是双精度的,并且如果其中一个操作数是双精度的,则所有操作都在双精度上执行,除非命令行选项-fssingle precision constant使用“f”后缀-0.125


如果想要纯FPU代码,还需要使用-ffast math&-fno math errno

断言-ffast math和-fno math errno是必需的依据是什么?@EricPostpischil--fno math errno&-ffast math是编译对单个vsqrt.f32 ARM指令的sqrtf函数调用所必需的。所以我编写了没有包装的纯FPU代码。基础是什么?经验和gcc文档+不同设置下生成代码的分析如果未使用开关,结果是对使用硬件平方根指令的sqrtf例程的调用,但也提供对负操作数的测试,并在这种情况下返回errno中的错误以及可能的其他消息处理,还是对使用软件浮点的sqrtf例程的调用?是-但具体实现取决于工具链。如果您的编译器是使用multilib选项编译的,而您是使用硬件浮点编译的,那么sqrt将由包装函数中的硬件sqrtf计算。您需要进行实验,看看它是如何在您的工具链中准确完成的。就我个人而言,当我在uCs上使用浮点数时,我通常不太关心参数检查,因为我不会进行任何真正的数值计算。断言-ffast math和-fno math errno是必需的依据是什么?@EricPostpischil--fno math errno和-ffast math是编译对单个vsqrt.f32 ARM指令。所以我编写了没有包装的纯FPU代码。基础是什么?经验和gcc文档+不同设置下生成代码的分析如果未使用开关,结果是对使用硬件平方根指令的sqrtf例程的调用,但也提供对负操作数的测试,并在这种情况下返回errno中的错误以及可能的其他消息处理,还是对使用软件浮点的sqrtf例程的调用?是-但具体实现取决于工具链。如果您的编译器是使用multilib选项编译的,而您是使用硬件浮点编译的,那么sqrt将由包装函数中的硬件sqrtf计算。您需要进行实验,看看它是如何在您的工具链中准确完成的。就我个人而言,当我在uCs上使用浮点数时,我通常不太关心参数检查,因为我不会进行任何真正的数值计算。您只需编写0.125f和0.68768f即可。正如C语法中所定义的,0.125和0.068768是双常量。f后缀使它们成为浮点常量。最好使用浮点常量,因为编译器随后应将十进制源文本直接转换为浮点值。对于双精度常量的强制转换,编译器必须首先将源文本解释为双精度,然后将其转换为浮点。您只需编写0.125f和0.68768f即可。正如C语法中所定义的,0.125和0.068768是双常量。f后缀使它们成为浮点常量。最好使用浮点常量,因为编译器随后应将十进制源文本直接转换为浮点值 卢。对于双常量的强制转换,编译器必须首先将源文本解释为双精度,然后将其转换为浮点。