С другой стороны отдельная утилита для peephole-оптимизации выглядит интересным решением - вот ещё:Shaos wrote:А можно пойти по пути, по которому пошли другие продвинутые компиляторы сей для 8080 - пробегание специальным оптимизатором по сгенерённому ассемблерному исходнику с заменой распознанных последовательностей инструкций на более оптимальные эквиваленты (см. https://en.wikipedia.org/wiki/Peephole_optimization) - например xm=@hibyte(xm) сейчас скомпилируется вот в такой исходный код Robby:который через Robby-байткод скомпилируется вот в такой 8080 код:Code: Select all
XM=(((XM)>>8) & #00FF)
тут например сразу же видно, что вот тут:Code: Select all
\ *0x40 _j0024: \ 0xF5 PUSH_H LXI_H, #0000 \ 0xF5 PUSH_H LXI_H, #0000 \ 0xF3 CALL _X_GET \ 0xF5 PUSH_H LXI_H, #0008 \ 0xD0 POP_D CALL SHIFTR \ 0xF5 PUSH_H LXI_H, #00FF \ 0xC0 POP_D MOV_A,D ANA_H MOV_H,A MOV_A,E ANA_L MOV_L,A \ 0xF4 POP_D XCHG LXI_B, @BASE MVI_A, #FF SUB_H JNZ _l0004 MOV_H,A LXI_B, @REGS _l0004: CALL _V_SET POP_H
можно опустить второй LXI_H, #0000 т.к. в HL уже 0 и далее:Code: Select all
LXI_H, #0000 \ 0xF5 PUSH_H LXI_H, #0000
можно заменить наCode: Select all
\ 0xF5 PUSH_H LXI_H, #00FF \ 0xC0 POP_D MOV_A,D ANA_H MOV_H,A MOV_A,E ANA_L MOV_L,A
Первый PUSH_H и последний POP_H тоже можно убрать т.к. они бессмысленны...Code: Select all
MVI_H, 0
P.S. Также можно опционально делать оптимизацию по размеру в ущерб скорости (скажем если надо утолкать большую программу Robby в небольшую память микрокомпьютера и на быстродействие наплевать), когда устойчивые конструкции типа:будут заменяться на вызов подпрограмм типа CALL HL_AND_DECode: Select all
MOV_A,D ANA_H MOV_H,A MOV_A,E ANA_L MOV_L,A
P.P.S. Хотя наверное будет проще научить ROBBYCC распознавать паттерны в длинных выражениях (коды операций не совпадают с кодами команд поэтому теоретически их можно отнести к одному классу и работать с ними единообразно), а для опциональной оптимизации по размеру добавить в __RULES условную компиляцию, чтобы для каждой команды одновременно описывались бы быстрая версия и компактная версия...
Code: Select all
LXI_H, #0000
\ 0xF3
CALL _X_GET
Code: Select all
LHLD @BASE+0 \ тут утилита может посчитать конкретный адрес и сразу вставить его в генерируемый код
Code: Select all
\ 0xF5
PUSH_H
LXI_H, #0008
\ 0xD0
POP_D
CALL SHIFTR
Code: Select all
MOV_D,H
MOV_E,L
MVI_L, 8
CALL SHIFTR
Вобщем интересно получается
P.S. По большому счёту такую оптимизацию логично применять только к длинным выражениям, которые в __RULES уже описаны отдельно от других команд RobbyVM и поэтому наверное можно этот самый peephole затолкать в ту же самую утилиту кросс-компиляции ROBBYCC, применяя оптимизацию каждый раз, когда очередное выражение готово, а правила конверсии завести в том же файле __RULES - так сказать всё в одном чтобы было (плюс эту оптимизацию можно включать специально с помощью новой опции -O).
P.P.S. Опция -O уже занята, так что пусть будет -T...