如何解决ARM Cortex M 的 gcc 没有 FPU 支持吗?
我在使用 gcc-arm-none-eabi-10-2020-q4-major
编译的一个众所周知的基准测试中有以下函数:
#include <unistd.h>
double b[1000],c[1000];
void tuned_STREAM_Scale(double scalar)
{
ssize_t j;
for (j = 0; j < 1000; j++)
b[j] = scalar* c[j];
}
我正在使用以下编译器选项:
arm-none-eabi-gcc -O3 -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -c test.c
但是,如果我检查编译后的代码,编译器似乎无法使用基本的 FPU 乘法指令,而仅使用 __aeabi_dmul
中的 libgcc
函数(但是我们可以看到 FPU {{ 1}} 使用):
vmov
如果与其他编译器相比,代码效率更高:
00000000 <tuned_STREAM_Scale>:
0: e92d 41f0 stmdb sp!,{r4,r5,r6,r7,r8,lr}
4: 4c08 ldr r4,[pc,#32] ; (28 <tuned_STREAM_Scale+0x28>)
6: 4d09 ldr r5,#36] ; (2c <tuned_STREAM_Scale+0x2c>)
8: f504 58fa add.w r8,r4,#8000 ; 0x1f40
c: ec57 6b10 vmov r6,d0
10: e8f4 0102 ldrd r0,r1,[r4],#8
14: 4632 mov r2,r6
16: 463b mov r3,r7
18: f7ff fffe bl 0 <__aeabi_dmul>
1c: 4544 cmp r4,r8
1e: e8e5 0102 strd r0,[r5],#8
22: d1f5 bne.n 10 <tuned_STREAM_Scale+0x10>
24: e8bd 81f0 ldmia.w sp!,pc}
如果我根据 cpu 或 FPU 选项检查 gcc 包内部的各种 00000000 <tuned_STREAM_Scale>:
0: 4808 ldr r0,#32] ; (24 <tuned_STREAM_Scale+0x24>)
2: b580 push {r7,lr}
4: 4b06 ldr r3,#24] ; (20 <tuned_STREAM_Scale+0x20>)
6: 27c8 movs r7,#200 ; 0xc8
8: c806 ldmia r0!,{r1,r2}
a: ec42 1b11 vmov d1,r2
e: ee20 1b01 vmul.f64 d1,d0,d1
12: 1e7f subs r7,#1
14: ec52 1b11 vmov r1,r2,d1
18: c306 stmia r3!,r2}
1a: d1f5 bne.n 8 <tuned_STREAM_Scale+0x8>
1c: bd80 pop {r7,pc}
目标文件,我在 libgcc
或任何其他函数中找不到任何 FPU 指令。
我觉得很奇怪 gcc 不能使用基本的 FPU 乘法,而且我在任何文档或自述文件中都找不到这个限制,所以我想知道我是否做错了什么。我检查了旧的 gcc 版本,但仍然有这个问题。是因为 gcc 还是 ARM 编译的二进制文件?
解决方法
线索就在您已经发布的编译器选项中:
-mfpu=fpv5-sp-d16
"sp" 表示单精度。
您告诉它不要生成硬件双指令,这对于大多数 Cortex-M7 处理器来说是正确的,因为它们无法执行它们。如果您有 M7,那么您需要设置正确的 fpu 参数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。