如何让ARM编译器生成STM指令而非多条STR指令?
如何让Cortex-M0+编译器生成STM指令替代多条STR指令?
我正在为Cortex-M0+编写一个重复读取固定内存地址并写入缓冲区的C函数,目标是让编译器生成STM指令而非多条STR指令。这款CPU没有指令预取单元和缓存,单条STM在取指周期上比多条STR效率更高。我了解-fldm-stm选项,但它仅用于启用该指令的功能支持,并非编译优化提示。
初始代码与编译选项
#include <stdint.h> #define port (0x12345678U) extern uint32_t buf[16]; void myfunc(void) { uint32_t *p = buf; for (uint8_t i=0; i<16; i++) { *(p++) = *(volatile uint32_t *)(port); } }
编译选项:-O3 -fldm-stm --target=arm-arm-none-eabi -mcpu=cortex-m0+ -mthumb
更新1:尝试循环展开与大小优化
参考建议修改了代码,添加循环展开编译指示并改用大小优化选项:
#include <stdint.h> #define port (0x12345678U) extern uint32_t buf[16]; void myfunc(void) { uint32_t *p = buf; #pragma unroll (4) for (uint8_t i=0; i<16; i++) { *(p++) = *(volatile uint32_t *)(port); } }
编译选项:-Os -fldm-stm --target=arm-arm-none-eabi -mcpu=cortex-m0+ -mthumb
但编译器仍未生成STM指令。
更新2:接近预期效果,但存在疑问
经过调整后,代码如下:
#include <stdint.h> #define port (0x12345678U) extern uint32_t buf[16]; void myfunc(void) { register uint32_t r0, r1, r2, r3; uint32_t *p = buf; for (uint8_t i=0; i<16; i+=4) { r0 = (uint32_t) (*(volatile uint32_t *)(port)); r1 = (uint32_t) (*(volatile uint32_t *)(port)); r2 = (uint32_t) (*(volatile uint32_t *)(port)); r3 = (uint32_t) (*(volatile uint32_t *)(port)); *(p++) = r0; *(p++) = r1; *(p++) = r2; *(p++) = r3; } }
生成的循环体汇编代码如下:
.LBB0_1: ldr r3, [r2] ldr r4, [r2] ldr r5, [r2] ldr r6, [r2] stm r1!, {r3, r4, r5, r6} ;; Bingo! adds r1, #0 ;; 这行指令为什么存在? adds r0, r0, #4 cmp r0, #12 blo .LBB0_1
我不清楚标记的adds r1, #0指令存在的原因,有人能解释吗?
内容的提问来源于stack exchange,提问作者ysap
相关产品推荐
相关产品推荐

