assemblyclangneonarmv7

Compiling assembly-code on ARMv7: CLang vs. GNU


I'm trying to build x265 on an ARMv7 system, and am getting the following error with one of the assembly-sources:

/usr/bin/c++ -mcpu=native -mfloat-abi=hard -mfpu=vfp -marm -DPIC -c .../source/common/arm/blockcopy8.S -o blockcopy8.S.o
.../source/common/arm/blockcopy8.S:835:21: error: expected immediate or register in shift operand

The compiler -- /usr/bin/c++ is clang-16.0.6. Using g++ 13.2.0 the same code compiles without a problem, which must be why the developers have never seen the problem. The problematic line reads:

mov             r0, r0, lsr 16

How do I correct it so it compiles with clang just as well as it does with g++?


Solution

  • On My POV: error you're encountering is due to a difference in how Clang and GCC handle certain ARM assembly syntax. The line that's causing the issue is:

    mov             r0, r0, lsr 16
    

    This syntax is using the "flexible second operand" feature of ARM assembly, which GCC accepts but Clang doesn't in this context. To make it compatible with both compilers, you need to use a more explicit syntax that Clang understands.

    Here's how you can modify the line to work with both Clang and GCC:

    lsr             r0, r0, #16
    

    This modification does the exact same thing (logical shift right by 16 bits) but uses a syntax that both compilers understand. The lsr instruction is explicitly used instead of relying on the flexible second operand of mov.

    It's worth noting that this is a known difference between GCC and Clang in handling ARM assembly. If you're able to, you might want to report this issue to the x265 developers so they can update their assembly code to be compatible with both compilers.