【发布时间】:2013-09-12 22:48:39
【问题描述】:
为了使 GCC 在我每次执行 |= 或 &= 时都不会生成加载-修改-存储操作,我定义了以下宏:
#define bset(base, offset, mask) bmanip(set, base, offset, mask)
#define bclr(base, offset, mask) bmanip(clr, base, offset, mask)
#define bmanip(op, base, offset, mask) \
asm("pshx");\
asm("ldx " #base);\
asm("b" #op " " #offset ",x " #mask);\
asm("pulx")
而且它们工作得很好;反汇编的二进制文件是完美的。
当我按顺序使用多个时,问题就来了:
inline void spi_init()
{
bset(_io_ports, M6811_DDRD, 0x38);
bset(_io_ports, M6811_PORTD, 0x20);
bset(_io_ports, M6811_SPCR, (M6811_SPE | M6811_DWOM | M6811_MSTR));
}
这会导致:
00002227 <spi_init>:
2227: 3c pshx
2228: fe 10 00 ldx 0x1000 <_io_ports>
222b: 1c 09 38 bset 0x9,x, #0x38
222e: 38 pulx
222f: 3c pshx
2230: fe 10 00 ldx 0x1000 <_io_ports>
2233: 1c 08 20 bset 0x8,x, #0x20
2236: 38 pulx
2237: 3c pshx
2238: fe 10 00 ldx 0x1000 <_io_ports>
223b: 1c 28 70 bset 0x28,x, #0x70
223e: 38 pulx
223f: 39 rts
有没有办法让 GCC (3.3.6-m68hc1x-20060122) 自动优化出冗余堆栈操作?
【问题讨论】:
-
5 年太晚了,我知道,但是为了完整起见:1. 对于即时模式,应该是
LDX #0x1000(操作码 CE 而不是 FE),2. 优化也应该保持一个 @ 987654327@ 指令,因为它们都加载了寄存器库,不需要为每条指令重复。