operand must be an int register in armv8

2.1k Views Asked by At

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?

1

There are 1 best solutions below

0
Peter Cordes On

AArch64 mul doesn'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 like 9, add x0, x0, x0, lsl #3


add-immediate with xzr is 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 mov and let the assembler figure out which opcode to use. If you compile a function that does return 1;, clang uses mov x0, #1 for the asm source.