assemblyarmneonarmcc

armcc complains that `q0` is not defined compiling neon assembly


int main(){
__asm volatile
{
    // load data
    vld1.16 {q0, q1}, [r0]!

...

using command

armcc --cpu=Cortex-A9 -O2 -Otime --vectorize --remarks -g --md --depend_format=unix_escaped --no_depend_system_headers -c -o test.o test.c

It has error shows that

"test.c", line 7: Error:  #20: identifier "q0" is undefined
      vld1.16 {q0, q1}, [r0]!
               ^
"test.c", line 8: Error:  #20: identifier "q2" is undefined
          vld1.16 {q2, q3}, [r0]!
                   ^

Did I miss any flags in the armcc command?

The armcc version is

Product: ARM Compiler 5.05
Component: ARM Compiler 5.05 (build 41)
Tool: armcc [4d0eb9]
For support see http://www.arm.com/support/
Software supplied by: ARM Limited

Solution

  • Although I don't use armcc, I don't believe your compiler supports inline assembly for NEON.

    https://static.docs.arm.com/dui0472/k/DUI0472K_armcc_user_guide.pdf

    Take a look at section 7.3, which states:

    7.3 Restrictions on inline assembler support in the compiler

    The inline assembler in the compiler does not support a number of instructions. Specifically, the inline assembler does not support:

    • Thumb assembly language in processors without Thumb-2 technology. • VFP instructions that were added in VFPv3 or higher. • NEON instructions. • The ARMv6 SETEND instruction and some of the system extensions. • ARMv5 BX , BLX , and BXJ instructions.

    The reason it is probably almost working is that vld is part of VFPv2, which is supported, and it's not until it gets to the "q" that it gets confused.

    If you were using gcc/clang variants, then yes, I'd suggest you would need to implicitly compile targeting NEON with -march=armv7-a -mfpu=neon, specifying both the base ISA and the floating point unit extensions, but only to use compiler intrinsics, not inline assembly. (As mentioned in the comment).