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

32bit-64bit, arm, assembly, gcc

Solution

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.

Problem

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?

Original source