我的理解是,ARMv 8 A64汇编中的即时参数可以是12位长。如果是这样的话,为什么这行汇编代码:
AND X12, X10, 0xFEF
产生此错误(使用gcc编译时)
Error: immediate out of range at operand 3 -- `AND X12, X10, 0xFEF'
有趣的是,这行汇编代码编译得很好:
ADD X12, X10, 0xFEF
我使用的是aarch 64-linux-gnu-gcc(Linaro GCC 2014.11)4.9.3(预发行版)
3条答案
按热度按时间jfewjypa1#
与A32的“灵活第二操作数”不同,A64中没有通用的立即数格式。对于立即操作数数据处理指令(忽略无聊和简单的指令,如移位),
add{s}
、sub{s}
、cmp
、cmn
)采用12位无符号立即数,并带有可选的12位左移位。movz
、movn
、movk
)采用16位立即数,可选择移位到寄存器内的任何16位对齐位置。adr
,adrp
)需要一个21位的有符号立即数,尽管没有实际的语法来直接指定它-要这样做,你必须求助于汇编表达式技巧来生成一个适当的“标签”。and{s}
,orr
,eor
,tst
)采用“位掩码立即数”,我不确定我是否能解释,所以我只引用the mind-bogglingly complicated definition:这样的立即数是32位或64位模式,被视为大小为e = 2、4、8、16、32或64位的相同元素的向量。每个元素包含相同的子模式:由0到e-1位旋转的1到e-1个非零位的单次运行。该机制可以生成5,334个唯一的64位模式(作为2,667对模式及其按位逆)。
f45qwnt82#
下面是一段代码,用于按照Notlikethat's answer中引用的机制转储所有法律的位掩码立即数。希望这有助于理解生成位掩码立即数的规则是如何工作的。
ghhkc1vu3#
另一种解释bitmask immediates,现在是早上,我终于明白了“令人难以置信的复杂”的定义。(见不喜欢的答案。)也许这将是更容易为一些理解。
它是X>0个连续的0,后面是Y>0个连续的1,其中X+Y是2的幂,重复以填充整个参数,然后任意旋转。
还要注意,其他立即格式中的可选移位是按精确位数,而不是“高达”。也就是说,16位立即数可以 * 精确地 * 移位0、16、32或48位,而12位立即数 * 仅 * 移位0或12位。