ARMv8 A64 汇编中的立即值范围

问题描述 投票:0回答:3

我的理解是ARMv8 A64汇编中的立即参数可以是12位长。如果是这样的话,为什么这行汇编代码会这样:

AND X12, X10, 0xFEF 

产生这个错误(用gcc编译时)

Error:  immediate out of range at operand 3 -- `AND X12, X10, 0xFEF'

有趣的是,这行汇编代码编译得很好:

ADD X12, X10, 0xFEF

我正在使用 aarch64-linux-gnu-gcc (Linaro GCC 2014.11) 4.9.3(预发布)

assembly arm64 gnu-assembler immediate-operand
3个回答
15
投票

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

  • 算术指令(
    add{s}
    sub{s}
    cmp
    cmn
    )采用带有可选 12 位左移的 12 位无符号立即数。
  • 移动指令(
    movz
    movn
    movk
    )将 16 位立即数选择性地移位到寄存器内的任何 16 位对齐位置。
  • 地址计算(
    adr
    adrp
    )采用 21 位有符号立即数,尽管没有实际的语法来直接指定它 - 为此,您必须诉诸汇编器表达式技巧来生成适当的“标签” .
  • 逻辑指令(
    and{s}
    orr
    eor
    tst
    )采用“立即位掩码”,我不确定我是否可以解释,所以我只是引用令人难以置信的复杂定义

这样的立即数是一个 32 位或 64 位模式,被视为大小为 e = 2、4、8、16、32 或 64 位的相同元素的向量。每个元素都包含相同的子模式:1 到 e-1 个非零位的单次运行,按 0 到 e-1 位循环。该机制可以生成 5,334 个独特的 64 位模式(作为 2,667 对模式及其按位逆)。


12
投票

这里有一段代码,用于按照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;
}

3
投票

位掩码立即数的另一种解释,现在是早上,我终于理解了“令人难以置信的复杂”定义。 (参见Notlikethat的答案。)也许有些人会更容易理解。

它是 X>0 个连续的 0,后面跟着 Y>0 个连续的 0,其中 X+Y 是 2 的幂,重复填充整个参数,然后任意旋转。

另请注意,其他立即格式中的可选移位是“精确”的位数,而不是“最多”。也就是说,16 位立即数可以精确移位 0、16、32 或 48 位,而 12 位立即数移位 0 或 12 位。

© www.soinside.com 2019 - 2024. All rights reserved.