cancel
Showing results for 
Search instead for 
Did you mean: 

STMCUBEIDE - H7 series force use of SMLAL (Signed Multiply with Accumulate (32 × 32 + 64), 64-bit result) instruction

MikeDB
Lead

Code is :

int16_t 	OscPhase[NumOsc];
int32_t 	OscInc[NumOsc];
int32_t 	OscVol[NumOsc];
int32_t 	Sine[65536];
 
int64_t 	OscTotal;
 
 
and then in main() :
 
		OscTotal = 0;
		for (i = 0; i < NumOsc; i++)
		{
			OscPhase[i] = OscPhase[i] + OscInc[i];
			OscTotal = OscTotal + Sine[OscPhase[i]]  * OscVol[i];
		}

I was expecting the H7 to use the SMLAL instruction for the final multiply and accumulate but instead it performs a MUL.W which only gives a 32 bit result and then uses an ADD.W and ADC.W to add these 32 bits into the final 64 bit result.

Any suggestions on how to force it to use the correct code ?

16 REPLIES 16

Amazingly that works !!

ldr.w   r3, [r9, r0, lsl #2]

smlal   r4, r5, r1, r3

Definition of SMLAL is

SMLAL       R4, R5, R1, R3   ; Signed (R5,R4) = (R5,R4) + R1 × R3

Casting Sine to be 64 bits surely should force a 32*64 multiply but in fact it is indeed creating a 32*32 multiply (R1 x R3) ?

Methinks there is a bug in the compiler !

Indeed, the 32-bit multiplication has 32-bit result.

C99, #6.3.1.8 Usual arithmetic conversions

[...] Unless explicitly stated otherwise, the common real type is also the corresponding real type of

the result [...]

JW

>>Methinks there is a bug in the compiler !

It is GNU, try something more industrial..

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

As I said earlier, as STM have just introduced this as their official IDE and hence presumably STM intend everybody to move to it over time, I thought I'd give it a try. I've just looked to see if I can use a different compiler but that doesn't seem to be an option.

Also just found this worrying instruction on the latest compile :

smlal   sl, fp, r2, r3

Surely if an interupt is called whilst in this loop, having the sl and fp registers being used for my 64 bit total accumulator could crash the processor ?

> Surely if an interupt is called whilst in this loop, having the sl and fp registers being used for my 64 bit total accumulator could crash the processor ?

Not crash (wich would be fine IMHO), but corrupt the result.

I suggest to read the M7 technical reference manual at ARMs infocenter webpage.

I know some instructions are resumed after an interrupt, and others are restarted.

I dive down into such detail only if necessary...

I already had it opened but hadn't noticed that possibility. Thanks for the hint.

I notice on recompiling it assigns the registers pretty randomly.

>>Methinks there is a bug in the compiler !

> It is GNU, try something more industrial..

As I've said, this is the behaviour the C standard stipulates, being compiler industrial or not.

JW