I'm tuning some source files to use inline assembly in select places. One place is a rotate, where I'm seeing 4 to 6 instructions generated with the NDK tools. (Related, see Near constant time rotate that does not violate the standards).
When I try and use something like:
template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
{
assert(y < sizeof(word32));
__asm__ ("ror %0, %1" : "+g" (x) : "I" ((unsigned char)(32-y)));
return x;
}
template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
{
assert(y < sizeof(word32));
__asm__ ("ror %0, %1" : "+g" (x) : "I" ((unsigned char)y));
return x;
}
It results in:
$ make -f GNUmakefile-cross
arm-linux-androideabi-g++ -DNDEBUG -g2 -Os -mfloat-abi=softfp -mfpu=vfpv3-d16 \
-mthumb --sysroot=/opt/android-ndk-r10e/platforms/android-21/arch-arm \
-I/opt/android-ndk-r10e/sources/cxx-stl/stlport/stlport/ -c 3way.cpp
.../ccwZw2eI.s: Assembler messages:
.../ccwZw2eI.s:2123: Error: ror #imm not supported -- `ror r0,#16'
.../ccwZw2eI.s:2133: Error: ror #imm not supported -- `ror r3,#24'
.../ccwZw2eI.s:2847: Error: ror #imm not supported -- `ror r6,#10'
...
So the compiler does not support an immediate-8 version of a rotate. Its not big loss since there are so many registers available (relatively speaking). But I'd like to be able to identify the situation because rotlFixed
and rotrFixed
are supposed to use the immediate version of the instruction.
Now, looking for something to key on to identify the situation:
$ arm-linux-androideabi-cpp -dM < /dev/null | grep -i android
#define __ANDROID__ 1
$ arm-linux-androideabi-cpp -dM < /dev/null | grep -i aosp
$ arm-linux-androideabi-cpp -dM < /dev/null | grep -i ndk
$
It appears the NDK toolchain only provides __ANDROID__
. I believe other native mobile toolchains define it too, so I can't use it. And there's no __ANDROID_CC__
or similar.
How can I detect the Android NDK toolchain?