Fast 32x32 bit multiply on ARM M0
First of all, yes, CortexM0 lacks any way to do 32x32=64 multiplication in hardware. CortexM3 and CortexM4 have the umull instruction, which lets you do 32x32=64 really easily.

And yes, since you're writing in C, one possible implementation would be

uint64_t mul32x32(uint32_t r0, uint32_t r1) { return r0*(uint64_t)r1; }


but I assume you've already tried that (with -O3 and whatever other optimization and inlining options you can turn up) and discovered that your compiler doesn't inline the multiplication, but leaves it as a call to some internal libc function.

A quick Google search turned up this previous StackOverflow question on exactly the same topic, where someone in the comments linked to GCC's implementation of 64x64=64 multiplication for CortexM0 (here), with the suggestion that you could constant-propagate "upper bits are known to be zero" through the whole thing by hand and that would give you something decent. I don't know if that's true.

Have you also benchmarked the "naive" approach of

uint64_t mul32x32(uint32_t r0, uint32_t r1)
{ 
    uint16_t r0h = r0 &gt;&gt; 16, r0l = r0 &amp; 0xFFFF;
    uint16_t r1h = r1 &gt;&gt; 16, r1l = r1 &amp; 0xFFFF;
    uint64_t result = (r0h * r1h);
    result &lt;&lt;= 16;
    result += r0h*r1l;
    result += r0l*r1h;
    result &lt;&lt;= 16;
    result += r0l*r1l;
    return result;
}


or equivalently

uint64_t mul32x32(uint32_t r0, uint32_t r1)
{ 
    uint16_t r0h = r0 &gt;&gt; 16, r0l = r0 &amp; 0xFFFF;
    uint16_t r1h = r1 &gt;&gt; 16, r1l = r1 &amp; 0xFFFF;
    return ((uint64_t)(r0h * r1h) &lt;&lt; 32)
         + ((uint64_t)(r0h * r1l) &lt;&lt; 16)
         + ((uint64_t)(r0l * r1h) &lt;&lt; 16)
         + ((uint64_t)(r0l * r1l) &lt;&lt; 0);
}


? As long as none of the arithmetic operations get turned into library function calls, this has the benefit of being portable ANSI C and being susceptible to inlining by the compiler. If you care about speed, susceptibility-to-inlining should be your #1 concern.

Since you have access to your compiler and we don't (I'm guessing Green Hills, from the __asm{ } syntax for inline assembly blocks?), you might get better answers if you posted the assembly that results from the above three C implementations.

Finally, note that CortexM0's MULS instruction takes either 1 cycle or 32 cycles, depending on the processor. If you're on one of those 32-cycle processors, doing four MULS instructions in a row is probably one of the worst things you can do. If MULS only takes 1 cycle, then you're probably okay; I don't think there's any need to space out those MULS instructions the way one might on a machine where they took multiple cycles (software pipelining).