4

我想在 c99 代码库中引入一些汇编代码。我想使用 ARM CPU 的 UMULL 指令将 2 uint32_t 相乘,然后立即将结果转换为 uint64_t。

现在一个 uint64_t 需要 2 个寄存器,那么如何指定 asm 块的输出和约束呢?

4

2 回答 2

3

好问题!

以下代码输出您想要使用GCC -O或更高版本的内容,而无需使用汇编程序:

uint32_t a, b;
uint64_t c;
...
c = (uint64_t)a * (uint64_t)b;
或者如果你觉得你必须使用机器特定的 asm,你可以去:
uint32_t a, b;
uint64_t c;

asm ("umull %Q0, %R0, %1, %2" : "=r"(c) : "r"(a), "r"(b));

c的寄存器名称是寄存器对的第一个,%Q 和 %R 挑选出该对的低位和高位 32 位寄存器。有关示例,请参见 gcc/config/arm/arm.md -> umulsidi3。

但是,如果您可以留在 C 语言中,那么优化器就有机会做更多事情,并且对您的程序的读者更友善。

于 2010-02-12T18:14:24.647 回答
1

umull指令将其结果生成到两个 32 位寄存器中。我建议用类似的东西明确地重新组装 64 位值:

/* assuming the 64-bit result was stored in "hi" (upper
   half) and "lo" (lower half) */
uint64_t v = ((uint64_t)hi << 32) | (uint64_t)lo;

编译器优化器应该注意到左移是纯数据路由,结果代码应该没问题。可以肯定的是,只需用于-S检查编译器输出。

于 2010-02-03T17:20:10.177 回答