Estoy tratando de realizar una compilación cruzada de un archivo para actualizarlo en el Beaglebone Black. Todo funciona bien, pero si intento habilitar la FPU con

#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)

Recibo el siguiente 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

También probé con thumb mode, pero obtengo los mismos errores. Por supuesto, si elimino la parte del código que inicializa la FPU, funciona bien.

¿Por qué obtengo esos errores?

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
[...]

Estoy en Arch, kernel 4.8.1

PD Mi profesor usa el compilador cruzado linaro y funciona bien

8
igng 14 dic. 2016 a las 01:11

2 respuestas

La mejor respuesta

La mayoría de las cadenas de herramientas de Linaro están configuradas para ARMv7 hard-float de forma predeterminada (ciertamente las de Linux, estoy menos seguro acerca de las bare-metal). Al observar la configuración de la cadena de herramientas arm-none-eabi empaquetada por Arch, supongo que solo está usando los valores predeterminados de GCC para cosas como esa, lo que implica algo como ARMv4t y, fundamentalmente, ABI de flotación suave.

Si bien la opción -mfpu controla la generación de código en términos de qué instrucciones de punto flotante se pueden usar, aparentemente es la ABI flotante la que controla si te permitirá hacer cosas que realmente solo tienen sentido en una FPU de hardware, en lugar de en una emulación de punto flotante.

Cuando no está configurado de forma predeterminada, debe seleccionar explícitamente una ABI de punto flotante que implique una FPU de hardware real, es decir, -mfloat-abi=hard (o -mfloat-abi=softfp, pero realmente no hay razón para usar eso a menos que necesite vincular contra otro código de flotación suave).

3
Notlikethat 13 dic. 2016 a las 22:39

-mfpu=vfpv3-d16 -mfloat-abi=hard

Solo para dar una solución más directa, tuve que agregar -mfpu=vfpv3-d16.

Código de prueba a.S:

fmrx r2, fpscr

Comando de trabajo:

sudo apt-get install binutils-arm-linux-gnueabihf
arm-linux-gnueabihf-as -mfpu=vfpv3-d16 -mfloat-abi=hard a.S

Tenga en cuenta que -mfloat-abi=hard está habilitado de forma predeterminada en esta compilación en particular de arm-linux-gnueabihf-as y podría omitirse.

El valor predeterminado de float-abi probablemente dependa de -msoft-float frente a -mhard-float controlado en el momento de la compilación de GCC con:

./configure --with-float=soft

Como se documenta en: https://gcc.gnu.org/install/configure.html Puede obtener los indicadores utilizados para la construcción de su cadena de herramientas con gcc -v como se menciona en: ¿Qué opciones de configuración se usaron al compilar gcc / libstdc ++? Sin embargo, no podría determinar fácilmente su valor predeterminado si no se proporciona.

También puede estar interesado en -mfloat-abi=softfp, que puede producir flotadores duros para el ejecutable, pero generar llamadas a funciones suaves: Error de compilación ARM, VFP registrado usado por ejecutable, no por archivo de objeto

Los posibles valores de -mfpu= se pueden encontrar en: https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/ARM-Options.html#ARM-Options

También tenga en cuenta que FMRX es la sintaxis anterior a UAL para VMRS, cuya sintaxis recomendada más reciente, consulte también: ¿Son las instrucciones de ARM SWI y SVC exactamente lo mismo?

Probado en Ubuntu 16.04, arm-linux-gnueabihf-as 2.26.1.

1
Ciro Santilli 24 abr. 2019 a las 15:18