I'm trying to cross-compile a file to flash into the Beaglebone Black. All works fine, but if I try to enable the FPU with
#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)
I get the following error
Error: selected processor does not support `fmrx r3,fpexc' in ARM mode
Error: selected processor does not support `fmxr fpexc,r3' in ARM mode
I also tried with thumb mode
, but I get the same errors.
Of course if I remove the part of the code that initialize the FPU it works fine.
Why I get those errors?
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
[...]
I'm on Arch, kernel 4.8.1
P.S. My professor uses the linaro cross-compiler and it works just fine
Most of the Linaro toolchains are configured for ARMv7 hard-float by default (certainly the Linux ones, I'm less sure about the bare-metal ones). Looking at the configuration of the arm-none-eabi toolchain as packaged by Arch, I surmise it's just using the GCC defaults for things like that, which implies something like ARMv4t, and crucially, soft-float ABI.
Whilst the -mfpu
option controls code generation in terms of which floating-point instructions may be used, apparently it's the float ABI which controls whether it'll let you do things which really only make sense on a hardware FPU, rather than under floating-point emulation.
When it's not configured by default, you need to explicitly select a floating-point ABI implying an actual hardware FPU, i.e. -mfloat-abi=hard
(or -mfloat-abi=softfp
, but there's really no reason to use that unless you need to link against other soft-float code).