Arm STMCUBEIDE-H7系列强制使用SMLAL(带累积的有符号乘法(32×;32+;64),64位结果)指令

Arm STMCUBEIDE-H7系列强制使用SMLAL(带累积的有符号乘法(32×;32+;64),64位结果)指令,arm,stm32,Arm,Stm32,STM32CUBEIDE编译器生成效率低下的代码 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++)

STM32CUBEIDE编译器生成效率低下的代码

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];
        }
int16\t OscPhase[NumOsc];
国际石油公司(NumOsc);
int32_t OscVol[NumOsc];
int32_t Sine[65536];
国际贸易总额;
然后在main()中:
OSCTOAL=0;
对于(i=0;i
我希望H7使用SMLAL指令进行最终的乘法和累加,但它执行MUL.W,它只给出一个32位的结果,然后使用ADD.W和ADC.W将这32位添加到最终的64位结果中


关于如何强制它使用正确的代码,有什么建议吗?

对代码进行了一些实验后

#include <stdint.h>

int64_t mac (int64_t  sum, int32_t x, int32_t y) {
   return sum + ((int64_t)x*y);
}
当使用ARM GCC 7.2.1和标志
-march=armv7e-m-mcpu=cortex-m7-O3
编译时,如果
-O1
或未指定优化级别,则不会生成
SMLAL
指令

没有强制转换,它不会生成
SMLAL
,因为它正在执行32 x 32=>32乘法,而
SMLAL
会生成32 x 32=>64


如果在循环中使用,
mac
函数似乎是内联的,因此没有额外的分支。

尝试
osctall=osctall+(int64_t)Sine[OscPhase[i]*(int64_t)OscVol[i]
osctall=osctall+((int64_t)正弦[OscPhase[i]]*OscVol[i])我有一个遥远的记忆,必须将所有操作数强制转换为64位类型,才能让keil编译器吐出
SMLAL
您正在使用的编译器是什么?它是STM的新STM32CubeIDE,似乎使用了过时的GCC。你是对的-我最终得到了相同的答案,即将所有字符转换为64位是使用SMLAL的唯一方法。谢谢。我发现使用-O3时,编译器展开了M7上不需要的代码-正如您所说,O1会转储无法正确累积的代码。我发现-O2是最可靠的方法。我将尝试使用您的MAC声明,看看它是否内联,因为这样可以避免每次更改行时都需要检查汇编代码:-)编辑:是的,它内联了它。下一个问题是它执行64位加载,然后存储其每一侧,而不是将OSCTOAL保留在寄存器对中直到结束。正在做那件事。谢谢你的帮助
mac:
        smlal   r0, r1, r3, r2
        bx      lr