assembly ARMv8 A64组件中的即时值范围

bz4sfanl  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(128)

我的理解是,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(预发行版)

jfewjypa

jfewjypa1#

与A32的“灵活第二操作数”不同,A64中没有通用的立即数格式。对于立即操作数数据处理指令(忽略无聊和简单的指令,如移位),

  • 算术指令(add{s}sub{s}cmpcmn)采用12位无符号立即数,并带有可选的12位左移位。
  • 移动指令(movzmovnmovk)采用16位立即数,可选择移位到寄存器内的任何16位对齐位置。
  • 地址计算(adradrp)需要一个21位的有符号立即数,尽管没有实际的语法来直接指定它-要这样做,你必须求助于汇编表达式技巧来生成一个适当的“标签”。
  • 逻辑指令(and{s}orreortst)采用“位掩码立即数”,我不确定我是否能解释,所以我只引用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对模式及其按位逆)。

f45qwnt8

f45qwnt82#

下面是一段代码,用于按照Notlikethat's answer中引用的机制转储所有法律的位掩码立即数。希望这有助于理解生成位掩码立即数的规则是如何工作的。

#include <stdio.h>
#include <stdint.h>

// Dumps all legal bitmask immediates for ARM64
// Total number of unique 64-bit patterns: 
//   1*2 + 3*4 + 7*8 + 15*16 + 31*32 + 63*64 = 5334

const char *uint64_to_binary(uint64_t x) {
  static char b[65];
  unsigned i;
  for (i = 0; i < 64; i++, x <<= 1)
    b[i] = (0x8000000000000000ULL & x)? '1' : '0';
  b[64] = '\0';
  return b;
}

int main() {
  uint64_t result;
  unsigned size, length, rotation, e;
  for (size = 2; size <= 64; size *= 2)
    for (length = 1; length < size; ++length) {
      result = 0xffffffffffffffffULL >> (64 - length);
      for (e = size; e < 64; e *= 2)
        result |= result << e;
      for (rotation = 0; rotation < size; ++rotation) {
        printf("0x%016llx %s (size=%u, length=%u, rotation=%u)\n",
            (unsigned long long)result, uint64_to_binary(result),
            size, length, rotation);
        result = (result >> 63) | (result << 1);
      }
    }
  return 0;
}
ghhkc1vu

ghhkc1vu3#

另一种解释bitmask immediates,现在是早上,我终于明白了“令人难以置信的复杂”的定义。(见不喜欢的答案。)也许这将是更容易为一些理解。
它是X>0个连续的0,后面是Y>0个连续的1,其中X+Y是2的幂,重复以填充整个参数,然后任意旋转。
还要注意,其他立即格式中的可选移位是按精确位数,而不是“高达”。也就是说,16位立即数可以 * 精确地 * 移位0、16、32或48位,而12位立即数 * 仅 * 移位0或12位。

相关问题