skip to Main Content

I’m maintaining an application that runs on GNU/Linux (x86, x86_64), Windows (x86, x86_64), Bionic/Android (armeabi-v7a, arm64-v8a, x86, x86_64) and also on Raspberry Pi (armhf). Since Raspberry OS is actually a modified version of GNU/Linux Debian, i can determine if i’m running linux (__linux__) on ARM (__arm__), but i can’t discern if it’s hard-float or not. (Yes, this may be an XY Problem.)

I need a way to pinpoint raspberry as some parts of the code are not to be implemented on Android. Yes, i could use -DRASPBERRY at compile time but was wondering if the compiler already does that for me. Preferably a standard macro instead of a compiler-specific one, but i’m cross-compiling on linux with gcc.

I’m considering __ARM_FP, but not sure.

This software runs on models 2 and up, any tips are appreciated.

Edit 1

To determine this, i’ve been using the output of the native gcc on linux x86_64, the 4 NDK variants and a mingw crross-compiler for x86. These caught my attention:

__ARM_ARCH is on all
__ARM_32BIT_STATE and __ARM_64BIT_STATE may be useful
__ARM_EABI__ and __ARMEL__ seem to only appear in Android’s armeabi-v7a and the gcc in Raspbian, so may be good candidates
__ARM_FP has a different value on all of them, which may also be useful once i figure out what it means

2

Answers


  1. Chosen as BEST ANSWER

    Well, according to Arm C Language Extensions

    5.5.1 Hardware floating point
    __ARM_FP is set if hardware floating-point is available.

    ...and proceeds to enumerate the possible valid values as 0x04, 0x6, 0xC and 0xE.

    The NDK sets 0xC for armeabi-v7a and 0xE for arm64-v8a and i got a bit confused because the gcc compiler in Raspberry OS sets it to 12... which is 0x0C.


  2. Approach the problem generally. How do you determine what flags are available? Use GCC dump preprocessor defines .

    i can’t discern if it’s hard-float or not.

    That’s trivial:

    • list all compiler macros with hard float
    • list all compiler macros without hard float
    • show the difference

    For exmaple: I take arm-none-eabi-gcc and cortex-m7 has hardware float support. I do:

    $ get() { arm-none-eabi-gcc -mcpu=cortex-m7 -dM -E - < /dev/null "$@" | sort; }
    $ diff <(get -mfloat-abi=soft) <(get -mfloat-abi=hard)
    26c26,27
    < #define __ARM_PCS 1
    ---
    > #define __ARM_FP 14
    > #define __ARM_PCS_VFP 1
    132a134,139
    > #define __FP_FAST_FMA 1
    > #define __FP_FAST_FMAF 1
    > #define __FP_FAST_FMAF32 1
    > #define __FP_FAST_FMAF32x 1
    > #define __FP_FAST_FMAF64 1
    > #define __FP_FAST_FMAL 1
    153,154c160,161
    < #define __GCC_IEC_559 0
    < #define __GCC_IEC_559_COMPLEX 0
    ---
    > #define __GCC_IEC_559 2
    > #define __GCC_IEC_559_COMPLEX 2
    299d305
    < #define __SOFTFP__ 1
    

    __SOFTFP__ might be super interesting for you (when using that particular compiler).

    Predefined macro to determine if running on a Raspberry?

    Well, you can’t know what your code will be running on, only the architecture it is compiled for. Seeing the output of:

    diff <(ssh myraspberry gcc -dM -E - < /dev/null | sort) <(gcc -dM -E - </dev/null | sort)
    

    Those macros might sound interesting:

    < #define __ARM_32BIT_STATE 1
    < #define __ARM_ARCH 6
    < #define __ARM_ARCH_6__ 1
    < #define __ARM_ARCH_ISA_ARM 1
    < #define __ARM_ARCH_ISA_THUMB 1
    < #define __ARM_EABI__ 1
    < #define __ARM_FEATURE_CLZ 1
    < #define __ARM_FEATURE_COPROC 15
    < #define __ARM_FEATURE_DSP 1
    < #define __ARM_FEATURE_LDREX 4
    < #define __ARM_FEATURE_QBIT 1
    < #define __ARM_FEATURE_SAT 1
    < #define __ARM_FEATURE_SIMD32 1
    < #define __ARM_FEATURE_UNALIGNED 1
    < #define __ARM_FP 12
    < #define __ARM_PCS_VFP 1
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search