内联 asm,32b cpu 寄存器分配给 64b 变量

inline asm, 32b cpu registers assigned for 64b variable

有 32b CPU。为了使用 64b 变量,编译器分配了 2 个寄存器,例如 r0 是 'var64b_low',r1 是 'var64b_high'。 有没有办法知道在内联汇编中为 64b 变量分配了哪些寄存器。我想得到这样的东西:

asm volatile(
    "add  ll,  %[a], %[b]  \n\t"   // ll is LSB 32b of var64
    "add  hh,  %[a], %[b]  \n\t"   // hh is MSB 32b of var64
    :[some clobber for 64b output value]
    :[a]"r"(a), [b]"r"(b)
    :
);

谢谢。


PS:现在我在内存中写回低和高部分,但我想避免这些额外的 savings/loadings。

引用自this post to the gcc-help mailing list

On ARM the modifiers for accessing 64-bit types are

  • %<n> The lowest numbered register of a pair
  • %H The highest numbered register of a pair
  • %Q The register containing the least significant part of the 32-bit value
  • %R The register containing the most significant part of the 32-bit value

Why so many? Well it depends on whether you want your code to compile correctly for big-endian as well as little-endian systems.

然后post包含一个例子:

int64_t        a,b,r;
asm(
     "adds   %Q0,    %Q1,    %Q2"            "\n\t"
     "adds   %R0,    %R1,    %R2"            "\n\t"
     "mov    %R0,    %R0,    rrx"            "\n\t"
     "mov    %Q0,    %Q0,    rrx"
     : "=&r" (r) : "r" (a), "r" (b) : "cc" );

Note the use of =&r in the constraint for the variable 'r'. This ensures that your input operands won't be corrupted before they have been fully read.

我没有 ARM 设置,所以无法确认。然而,Richard Earnshaw(那个 post 的作者)是 gcc 的 ARM 端口维护者,所以他大概知道他在说什么。

可能还值得一提的是(与 x86 modifiers 不同)这些 ARM 修饰符未记录,这通常意味着它们也不受支持。依赖不受支持的功能(对于任何产品)是有风险的,因此请谨慎使用!