В попытке сделать GCC не генерированием операцию загрузки-изменение-магазин каждый раз, когда я делаю |=
или &=
, я определил следующие макросы:Получение 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) автоматически оптимизировать избыточные операции стека?
Не удивительно, что вы его не нашли; Поддержка m68hc11 была устарела в 4.6 и удалена в 4.7. Мне не нужна ценность 'X' после того, как я закончу; 'bset' (бит SET) и' bclr' (бит CLeaR) имеют только нулевые страницы и индексированные режимы адресации, поэтому сохраняются, загружаются и восстанавливаются индексный регистр. Я проверю документы, спасибо. –
После нескольких экспериментов я теперь убежден, что это правильное решение. У меня проблемы с индексированной адресацией, но я отправлю это как отдельный вопрос. –