gccarmcross-compilingbeagleboneblacknewlib

Cross compiling - Error: selected processor does not support `fmrx r3,fpexc' in ARM mode - Beaglebone


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


Solution

  • 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).