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
CodePudding user response:
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
CodePudding user response:
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 as0x04
,0x6
,0xC
and0xE
.
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
.