Я пытаюсь получить окончательное накопление в приведенном ниже коде, чтобы использовать функцию накопления ARM M7 SMLAL 32 * 32-> 64 бит. Если я включаю T3 = T3 + 1, то он использует это, но если я закомментирую это, он делает полный 64 * 64 бит и накапливает, используя 3 умножения и 2 инструкции добавления. На самом деле я не хочу добавлять 1 к T3, поэтому он должен идти.
Я разбил код на части, чтобы я мог проанализировать его более подробно, и определенно кажется, что приведение T3 к int32_t и отбрасывание 32 младших битов из умножения не воспринимается компилятор, и он думает, что T3 все еще имеет 64 бита. Бит, когда я добавляю простое приращение T3, оно становится правильным. Я попытался добавить ноль, но затем он возвращается к полному 64 * 64-битному умножению.
Я использую оптимизацию -O2 для STM STM32CubeIDE, которая использует версию GCC. Другие оценки никогда не используют SMLAL и не развертывают все.
int64_t T4 = 0;
osc = key * NumHarmonics;
harmonic = 0;
do
{
if (OscLevel[osc] > 1)
{
OscPhase[osc] = OscPhase[osc] + (uint32_t)(T2);
int32_t T5 = Sine[(OscPhase[osc] >> 16) & 0x0000FFFF];
int64_t T6 = (int64_t)T1 * Tremelo[harmonic];
int32_t T3 = (int32_t)(T6 >> 32); // grab the most significant register
// T3 = T3 + 1; // needs the +1 to force use of SMLAL in next instruction ! (+0 doesn't help)
T4 = T4 + (int64_t)T3 * (int64_t)T5; // should be SMLAL but does a full 64*64 mult if no +1 above
}
osc++;
harmonic++;
}
while (harmonic < NumHarmonics);
OscTotal = T4;
without the addition :
800054e: 4b13 ldr r3, [pc, #76] ; (800059c <main+0xd8>)
8000550: f853 1024 ldr.w r1, [r3, r4, lsl #2]
8000554: ea4f 79e1 mov.w r9, r1, asr #31
8000558: fba7 4501 umull r4, r5, r7, r1
800055c: fb07 f309 mul.w r3, r7, r9
8000560: fb01 3202 mla r2, r1, r2, r3
8000564: 4415 add r5, r2
8000566: e9dd 2300 ldrd r2, r3, [sp]
800056a: 1912 adds r2, r2, r4
800056c: 416b adcs r3, r5
800056e: e9cd 2300 strd r2, r3, [sp]
}
osc++;
8000572: 3001 adds r0, #1
harmonic++;
with the addition
8000542: 4b0b ldr r3, [pc, #44] ; (8000570 <main+0xac>)
8000544: f853 3020 ldr.w r3, [r3, r0, lsl #2]
8000548: fbc3 6701 smlal r6, r7, r3, r1
}
osc++;
800054c: 3201 adds r2, #1
harmonic++;