我正在尝试使用 STM/LDM 指令在使用 ARM Compiler 5 armcc 编译的 .c 文件中的内联汇编中生成AXI总线突发访问。
inline void STMIA2(uint32_t addr, uint32_t w0, uint32_t w1)
{
__asm {
STMIA addr!, { w0, w1 }
}
}
但是 ARM 编译器 armcc 用户指南第 7.18 段说:“所有 LDM 和 STM 指令都扩展为具有等效效果的 LDR 和 STR 指令序列。但是,编译器随后可能会在优化期间将单独的指令重新组合成 LDM 或 STM。 "
这就是实际发生的情况,在某些情况下,LDM/STM 会扩展为一组 LDR/STR,并且这些指令的顺序是任意的。这会影响性能,因为我们使用针对突发处理进行优化的硬件。这也破坏了功能的正确性,因为我们使用的硬件考虑了单词的顺序并忽略了偏移量(但编译器认为更改指令的顺序是安全的)。
为了解决这个问题,可以使用嵌入式汇编程序而不是内联汇编程序,但这会导致额外的函数调用——返回影响性能的因素。
所以我想知道是否有办法在不损失性能的情况下正确生成 LDM/STM?我们能够在 GCC 中做到这一点,但没有找到 armcc 的任何解决方案。
目标 CPU:Cortex M0+ (ARMv6-M)。
编辑: 从设备都是片上设备,其中大部分是非内存设备。对于支持地址空间的突发访问区域的非内存从属的每个寄存器都被保留(例如[0x10000..0x10100]),我不完全确定为什么,也许CPU或总线不支持固定(非增量) 地址。HW 忽略该区域内的偏移量。例如,完整请求可以是 16 个字节,完整请求的第一个字是写入的第一个字(即使偏移量非零)。