6

Im compiling the following ARM NEON intrinsics test code (in Eclipse with Android NDK):

void foo(uint64_t* Res)
{
    uint64_t x = 0xff12aa8902acf78dULL;
    uint64x1_t a,b;

    a = vld1_u64 (&x);
    b = vext_u64 (a, a, 3);
    vst1_u64 (Res,b);
}

but I keep getting the following compiler error:

/home/developer/adt/ndk/ndk-build all 
Install        : libneon_test.so => libs/armeabi/libneon_test.so
Compile thumb  : neon_test <= neon.c
jni/neon.c: In function 'foo':
jni/neon.c:17:1: error: constant out of range
make: *** [obj/local/armeabi-v7a/objs/neon_test/neon.o] Error 1` 

Line 17 is the last } brace of foo().

Does anyone have an idea what might be the cause of this strange error?

artless noise
  • 21,212
  • 6
  • 68
  • 105
NumberFour
  • 3,551
  • 8
  • 48
  • 72
  • what constant is it talking about? Line 17 of the code you posted is the } brace. Is it the value 3? – ThePosey Mar 09 '13 at 20:20
  • Thats the problem, I dont know either. The compiler always points this error to the last } brace which makes no sense. I think this might be a GCC bug with NEON so Im looking for some workaround maybe. – NumberFour Mar 09 '13 at 20:26
  • 1
    I think ThePosey's deleted answer is on the right track. What are you expecting `vext_u64(a, a, 3)` to do? – tc. Mar 09 '13 at 23:31

1 Answers1

6

Problem is in this line

b = vext_u64 (a, a, 3);

You can't have 3 as shift for vext_u64, it isn't allowed.

uint64x1_t vext_u64(uint64x1_t a, uint64x1_t b, __constrange(0,0) int c);  // VEXT.64 d0,d0,d0,#0

It looks like gcc's implementation (definition?) of neon intrinsics isn't as good as armcc's in this aspect.

A trick to understand such behavior is to pass -S to gcc to convert code to assembly then try to compile that assembly file. That way gcc will tell you exactly which line is giving the problem.

$ ~/bin/android-ndk-r8d/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/home/auselen/bin/android-ndk-r8d/platforms/android-14/arch-arm -std=c99 -S neon.c -mfloat-abi=softfp -mfpu=neon -O2
neon.c: In function 'foo':
neon.c:11:1: error: constant out of range
$ ~/bin/android-ndk-r8d/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/home/auselen/bin/android-ndk-r8d/platforms/android-14/arch-arm -std=c99 -c neon.s -mfloat-abi=softfp -mfpu=neon -O2
neon.s: Assembler messages:
neon.s:28: Error: shift out of range -- `vext.64 d16,d16,d16,#3'
auselen
  • 27,577
  • 7
  • 73
  • 114
  • I have the same problem when using `vecTmp = vrshrn_n_u32(vec128b, 15+8);`, the constant cannot be larger than 16, but in fact the constraint should be 0-31. I think is the bug of gcc tool chain of android? – QZHua Sep 24 '17 at 14:29