我想将一些汇编代码引入c99代码库。我想使用ARM CPU的UMULL指令来乘以2 uint32_t,并立即得到结果到uint64_t。如何获得ARM MULL指令以在gcc中的uint64_t中生成其输出?
现在uint64_t需要2个寄存器,那么如何指定输出和asm块的约束呢?
我想将一些汇编代码引入c99代码库。我想使用ARM CPU的UMULL指令来乘以2 uint32_t,并立即得到结果到uint64_t。如何获得ARM MULL指令以在gcc中的uint64_t中生成其输出?
现在uint64_t需要2个寄存器,那么如何指定输出和asm块的约束呢?
好问题!
以下代码输出你想使用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位和高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
来检查编译器输出。
感谢您的回答!事实上,C版本做我想做的事情,非常酷。 非常感谢%Q和%R语法,这就是我一开始就在寻找的东西。 – user265429 2010-02-15 10:43:25