【发布时间】:2011-01-12 16:57:52
【问题描述】:
我想在 c99 代码库中引入一些汇编代码。我想使用 ARM CPU 的 UMULL 指令将 2 uint32_t 相乘,然后立即将结果转换为 uint64_t。
现在一个uint64_t需要2个寄存器,那么如何指定asm块的输出和约束呢?
【问题讨论】:
标签: gcc assembly arm 32bit-64bit
我想在 c99 代码库中引入一些汇编代码。我想使用 ARM CPU 的 UMULL 指令将 2 uint32_t 相乘,然后立即将结果转换为 uint64_t。
现在一个uint64_t需要2个寄存器,那么如何指定asm块的输出和约束呢?
【问题讨论】:
标签: gcc assembly arm 32bit-64bit
好问题!
以下代码使用 GCC -O 或更高版本输出您想要的内容,而无需使用汇编程序:
asm ("umull %Q0, %R0, %1, %2" : "=r"(c) : "r"(a), "r"(b));
c 的寄存器名称是寄存器对的第一个,%Q 和 %R 挑选出这对寄存器的低位和高位 32 位寄存器。有关示例,请参见 gcc/config/arm/arm.md -> umulsidi3。
但是,如果您可以留在 C 中,那么优化器就有机会做更多事情,并且对您的程序的读者更友善。
【讨论】:
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 来检查编译器输出。
【讨论】: