这是GCC错误,还是我做错了什么?

时间:2019-05-04 15:47:13

标签: gcc arm

我正在尝试在下面的代码中进行最终累加,以使用ARM M7 SMLAL 32 * 32-> 64位累加函数。如果我包括T3 = T3 + 1,那么它会使用它,但是如果我注释掉它,它会完成一个完整的64 * 64位,并使用3个乘法和2个加法指令累加。我实际上并不想在T3中加1,所以需要去。

我已经分解了代码,以便可以更详细地分析它,而且似乎绝对是T3转换为int32_t并从乘法中舍去了低32位的内容,而这并不是编译器,它认为T3仍具有64位。当我加上T3的简单增量时,它会正确。我尝试加零,但后来又回到了完整的64 * 64位乘法。

我正在STM的STM32CubeIDE上使用-O2优化,该版本使用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++;

0 个答案:

没有答案