This is a STM32CubeIDE question, or GCC issue regarding the inline asm() and a cortex m4. rdhi and rdlo must be different for UMULL instruction, but not for the SMULL instruction for some reason.
I need to inline some simple functions for a reverb pedal project, but ran into a bug regarding the reuse of registers and the 'umull' and 'smull' instruction.
I am using a cortex M4 with a single cycle UMULL so, I should be able to use the same registers for source and destination eg. good:UMULL r1,r0,r0,r1 This should be ok on a M4.
On an M3 WITHOUT a single cycle multiply this could be an issue eg. good:UMULL r2,r3,r0,r1 bad:UMULL r1,r0,r0,r1 because source destination register reuse. But I am using an M4 so...
The code in assembly is easy to understand but impossible to inline ...
uumul_asm: // return ((r0 * r1) >> 32)
UMULL r1, r0, r0, r1
bx lr
ssmul_asm: // return ( (r0 * r1) >> 32)
SMULL r1, r0, r0, r1
bx lr
Now the abomination to inline the these is ...
static inline __attribute__((always_inline)) U32 uumul(U32 x,U32 y)
{
asm(" umull %[yy],%[xx],%[xx],%[yy]" :: [xx] "r" (x) , [yy] "r" (y) );
return(x);
}
static inline __attribute__((always_inline)) S32 ssmul(S32 x,S32 y)
{
asm(" smull %[yy],%[xx],%[xx],%[yy]" :: [xx] "r" (x) , [yy] "r" (y) );
return(x);
}
The issue is that S32 ssmul(S32 x,S32 y) will compile without issues no problem...
but U32 uumul(U32 x,U32 y) will produce an error regarding the reuse of source and destination registers.
/tmp/cccWoXGD.s:667: rdhi and rdlo must be different
/tmp/cccWoXGD.s:730: rdhi and rdlo must be different
/tmp/cccWoXGD.s:1098: rdhi and rdlo must be different
/tmp/cccWoXGD.s:1189: rdhi and rdlo must be different
