Search code examples
floating-pointembedded-linuxarm64neonfixed-point

GCC flag for emulating floating point operations in software on ARMv8 platform with neon FPU


Background

I am trying to compile and run this on a Raspberry Pi 4 Model B Rev 1.4 running Ubuntu 20.04 LTS aarch64.

The output of the lscpu command is:

Architecture:            aarch64
  CPU op-mode(s):        32-bit, 64-bit
  Byte Order:            Little Endian
CPU(s):                  4
  On-line CPU(s) list:   0-3
Vendor ID:               ARM
  Model name:            Cortex-A72
    Model:               3
    Thread(s) per core:  1
    Core(s) per cluster: 4
    Socket(s):           -
    Cluster(s):          1
    Stepping:            r0p3
    CPU max MHz:         1800.0000
    CPU min MHz:         600.0000
    BogoMIPS:            108.00
    Flags:               fp asimd evtstrm crc32 cpuid

The target for gcc running in this environment is aarch64-linux-gnu. I understand that the Cortex-A72 has floating point hardware. I also know that the -mfloat-abi=soft flag is not supported on aarch64.

What I'm trying to do

I am trying to write a fixed-point arithmetic implementation of the C math atan() function. I would like to compare the runtime of my fixed-point implementation of this function, to atan(), where it's floating point operations are emulated in software routines, rather than executed on the FPU.

  1. I have a .c file containing my fixed-point function implementation using integer arguments.

  2. I have a .c reference file containing a call to atan() from the math library using floating point arguments

Question

Is there any way of telling GCC in this environment to assemble floating point instructions into emulations in software? Is this even possible? Or do I have to find a platform without floating-point hardware support to run this on?

I can compile my fixed-point implementation normally (no need for special flags, it contains no floating point instructions to be emulated).

I want to compile the reference function which involves floating point arguments, in such a way that it is actually translated to fixed-point assembly instructions emulating the floating-point behavior.

Thank you in advance


Solution

  • I think there's no straightforward solution to do exactly what you've described. GCC on AArch64 does have the option -mgeneral-regs-only (https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gcc/AArch64-Options.html#AArch64-Options) that will tell the compiler to avoid generating any FP/SIMD instructions, but if your source code has any floating-point arithmetic it will give you an error rather than trying to emulate it with fixed-point operations. The option exists for users like the Linux kernel where they want to avoid touching the FP/SIMD registers outside some very controlled contexts, and they don't use floating-point arithmetic in their code at all.

    Furthermore, there is no defined soft-float ABI for AArch64, all portable software assumes that FP/SIMD is present and available for use. This is baked into things like the calling convention. The GCC sources contain many floating-point emulation routines in libgcc that could act as building blocks for emulating many common floating-point operations, but the compiler for AArch64 is not wired up to use them, as they a soft-float AArch64 ABI is not supported