我正在尝试交叉编译文件以闪存到Beaglebone Black。一切正常,但如果我尝试启用FPU
#define set_en_bit_in_fpexc() do { \
int dummy; \
__asm__ __volatile__ ("fmrx %0,fpexc\n\t" \
"orr %0,%0,#0x40000000\n\t" \
"fmxr fpexc,%0" : "=r" (dummy) : :); \
} while (0)
我收到以下错误
Error: selected processor does not support `fmrx r3,fpexc' in ARM mode
Error: selected processor does not support `fmxr fpexc,r3' in ARM mode
我也试过thumb mode
,但我得到了同样的错误。当然,如果我删除初始化FPU的代码部分,它工作正常。
为什么我会收到这些错误?
Makefile文件
[...]
CROSSPATH?=/usr/bin
CROSSPFX=$(CROSSPATH)/arm-none-eabi-
CC=$(CROSSPFX)gcc
AS=$(CROSSPFX)as
LD=$(CROSSPFX)ld
NM=$(CROSSPFX)nm
OBJCOPY=$(CROSSPFX)objcopy
OBJDUMP=$(CROSSPFX)objdump
CFLAGS=-Wall -Wextra -O2 -ffreestanding
ARCHFLAGS=-mcpu=cortex-a8 -march=armv7-a -mfpu=neon
CCARCHFLAGS=$(ARCHFLAGS) -marm
[...]
我在Arch,内核4.8.1
附:我的教授使用linaro交叉编译器,它工作得很好
大多数Linaro工具链默认配置为ARMv7硬浮动(当然是Linux的,我对裸机的不太确定)。看看由Arch打包的arm-none-eabi工具链的配置,我推测它只是使用GCC默认值来表示像ARMv4t这样的东西,最重要的是,软浮动ABI。
虽然-mfpu
选项根据可以使用的浮点指令来控制代码生成,但显然它是浮动ABI,它控制它是否会让你做的事情只在硬件FPU上有意义,而不是在浮点下仿真。
如果默认情况下没有配置,则需要明确选择一个浮点ABI,暗示一个实际的硬件FPU,即-mfloat-abi=hard
(或-mfloat-abi=softfp
,但除非你需要链接其他软浮点代码,否则没有理由使用它)。
-mfpu=vfpv3-d16 -mfloat-abi=hard
只是为了提供更直接的解决方案,我不得不添加-mfpu=vfpv3-d16
。
测试代码a.S
:
fmrx r2, fpscr
工作指令:
sudo apt-get install binutils-arm-linux-gnueabihf
arm-linux-gnueabihf-as -mfpu=vfpv3-d16 -mfloat-abi=hard a.S
请注意,-mfloat-abi=hard
默认在arm-linux-gnueabihf-as
的这个特定版本上启用,可以省略。
float-abi
的默认值可能取决于在GCC构建时控制的-msoft-float
vs -mhard-float
:
./configure --with-float=soft
如下所述:https://gcc.gnu.org/install/configure.html您可以使用gcc -v
获取用于工具链构建的标志,如下所述:What configure options were used when building gcc / libstdc++?如果没有给出,我无法轻易确定其默认值。
您可能也对-mfloat-abi=softfp
感兴趣,它可以为可执行文件生成硬浮点数,但生成软函数调用:ARM compilation error, VFP registered used by executable, not object file
-mfpu=
的可能值可以在:https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/ARM-Options.html#ARM-Options找到
另请注意,FMRX是VMRS的前UAL语法,它是较新推荐的语法,另请参阅:Are ARM instructuons SWI and SVC exactly same thing?
在Ubuntu 16.04上测试,arm-linux-gnueabihf-as
2.26.1。