2019-05-02 02:45 AM
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 ?
2019-05-02 05:20 AM
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 !
2019-05-02 05:45 AM
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
2019-05-02 06:18 AM
>>Methinks there is a bug in the compiler !
It is GNU, try something more industrial..
2019-05-02 06:29 AM
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 ?
2019-05-02 06:43 AM
> 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...
2019-05-02 06:48 AM
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.
2019-05-02 07:08 AM
>>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