how can I get the ARM MULL instruction to produce its output in a uint64_t in gcc?

谁都会走 提交于 2020-01-14 11:53:33

问题


I would like to introduce some assembly code into a c99 codebase. I want to use the UMULL instruction from the ARM CPU to multiply 2 uint32_t and get the result immediately into a uint64_t.

Now a uint64_t needs 2 registers, so how do I specify the output and the constraints of the asm block?


回答1:


Good question!

The following code outputs what you want using GCC -O or higher without resorting to assembler:

uint32_t a, b;
uint64_t c;
...
c = (uint64_t)a * (uint64_t)b;
or if you feel you must use machine-specific asm, you can go:
uint32_t a, b;
uint64_t c;

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

c's register name is the first of the register pair, and %Q and %R pick out the lower and upper 32-bit registers of the pair. See gcc/config/arm/arm.md -> umulsidi3 for an example.

However, if you can stay in C, that gives the optimizer a chance to do more and is kinder on readers of your program.




回答2:


The umull instruction produces its results into two 32-bit registers. I suggest explicitly reassembling the 64-bit value with something like that:

/* 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;

The compiler optimizer should notice that the left-shift is pure data routing, and the resulting code should be fine. To be sure, just use -S to check the compiler output.



来源:https://stackoverflow.com/questions/2193542/how-can-i-get-the-arm-mull-instruction-to-produce-its-output-in-a-uint64-t-in-gc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!