I'm working on a program in ARMv8, and when attempting to compile it using gcc, I get the error message "operand 3 must be an integer register" for the following lines of code:
67 mul x2, x2, 8
100 mul x16, x11, 4
117 mul x16, x11, 4
140 mul x16, x12, 4
Similarly, I get the error message "integer register expected in the extended/shifted operand register at operand 3"
66 add x2, xzr, #MAX_DIGITS
142 add x17, xzr, 1
What does this mean? How can I fix it?
AArch64
muldoesn't have a form that takes an immediate operand, check the manual.See https://godbolt.org/z/79oKc6fxq for what compilers do: shift instead of mul for a power of 2, otherwise mov-immediate to a register before
mul reg,reg,reg. Or for a 2^n+1 constant like9,add x0, x0, x0, lsl #3add-immediate withxzris impossible, since the same syntax compilers use for adding 1 (add reg, reg, #1) doesn't assemble if XZR is the source register.For some instructions, like
add-immediate, that register number is the stack pointer, not the zero register, so xzr isn't encodeable. That makes sense; there are instructions that can get a small integer into a register, but adding/subtracting is something you often want on the stack pointer.If you want to materialize a small immediate, use
movand let the assembler figure out which opcode to use. If you compile a function that doesreturn 1;, clang usesmov x0, #1for the asm source.