Я пытаюсь скомпилировать файл для прошивки в 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
P.S. Мой профессор использует кросс-компилятор linaro, и он отлично работает
Большинство наборов инструментов Linaro по умолчанию настроено для ARMv7 hard-float (конечно, для Linux, я менее уверен в «голом железе»). Глядя на конфигурацию инструментальной цепочки arm-none-eabi, упакованную Arch, я предполагаю, что она просто использует значения GCC по умолчанию для подобных вещей, что подразумевает что-то вроде ARMv4t и, что особенно важно, ABI с мягким поплавком.
Хотя параметр
-mfpu
управляет генерацией кода, с точки зрения того, какие инструкции с плавающей запятой могут использоваться, очевидно, именно ABI с плавающей запятой определяет, позволит ли он вам делать вещи, которые действительно только имеют смысл на аппаратном FPU. , а не при эмуляции с плавающей запятой.Когда он не настроен по умолчанию, вам нужно явно выбрать ABI с плавающей запятой, подразумевающий фактический аппаратный FPU, то есть
-mfloat-abi=hard
(или-mfloat-abi=softfp
, но на самом деле нет причин использовать это, если вам не нужно связываться с другим кодом soft-float).-mfpu=vfpv3-d16 -mfloat-abi=hard
Чтобы дать более точное решение, мне пришлось добавить
-mfpu=vfpv3-d16
.Код теста
a.S
:Рабочая команда:
Обратите внимание, что
-mfloat-abi=hard
включен по умолчанию в этой конкретной сборкеarm-linux-gnueabihf-as
и может быть опущен.Значение по умолчанию
float-abi
, вероятно, зависит от-msoft-float
против-mhard-float
, контролируемых во время сборки GCC с помощью:как описано на странице: https://gcc.gnu.org/install/configure.html Вы можете получить флаги, используемые для сборки вашей инструментальной цепочки, с помощью
gcc -v
, как указано по адресу: Какие параметры конфигурации использовались при сборке gcc / libstdc ++? Однако я не смог бы легко определить его значение по умолчанию, если бы оно не было задано.Вас также может заинтересовать
-mfloat-abi=softfp
, который может создавать жесткие числа с плавающей запятой для исполняемого файла, но генерировать вызовы программных функций: Ошибка компиляции ARM, зарегистрированный VFP используется исполняемым файлом, а не объектным файломВозможные значения
-mfpu=
можно найти по адресу: https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/ARM-Options.html#ARM-OptionsТакже обратите внимание, что FMRX — это синтаксис до UAL для VMRS, который является более новым рекомендованным синтаксисом, см. Также: Являются ли инструкции ARM SWI и SVC одним и тем же?
Проверено на Ubuntu 16.04,
arm-linux-gnueabihf-as
2.26.1.