My understanding is that immediate parameters in ARMv8 A64 assembly can be 12 bits long. If that is the case, why does this line of assembly code:
AND X12, X10, 0xFEF
Produce this error (when compiled with gcc)
Error: immediate out of range at operand 3 -- `AND X12, X10, 0xFEF'
Interestingly enough, this line of assembly code compiles fine:
ADD X12, X10, 0xFEF
I'm using aarch64-linux-gnu-gcc (Linaro GCC 2014.11) 4.9.3 (prerelease)
Unlike A32's "flexible second operand", there is no common immediate format in A64. For immediate-operand data-processing instructions (ignoring the boring and straightforward ones like shifts),
add{s}
,sub{s}
,cmp
,cmn
) take a 12-bit unsigned immediate with an optional 12-bit left shift.movz
,movn
,movk
) take a 16-bit immediate optionally shifted to any 16-bit-aligned position within the register.adr
,adrp
) take a 21-bit signed immediate, although there's no actual syntax to specify it directly - to do so you'd have to resort to assembler expression trickery to generate an appropriate "label".and{s}
,orr
,eor
,tst
) take a "bitmask immediate", which I'm not sure I can even explain, so I'll just quote the mind-bogglingly complicated definition: