Хех, завелось-таки в связке с виртуальной машиной. Скомпилировались и работают 3d-бродилка на форте и пара сишных тестов (змейка и эффект огня), с другими тестами также проблем не будет.
Виртуальную машину сразу делал в варианте с поддержкой "аппаратного" стека, но проверил также и с ядром, в котором стек реализован программно. Бродилка при переходе от программного стека к аппаратному сразу худеет на 1Kb (примерно 3Kb до 2Kb). Точно не помню, но толщина таких же прошивок под ARM/Thumb была где-то 4-5Kb, для x86 было где-то 2Kb, а для форт-процессора 584 байта.
Позже гляну более точно.
Кстати, если планируется использовать сабж в связке с Фортом (а оно именно так и планируется), то можно провернуть такой трюк: оставить пару-тройку регистров для промежуточных вычислений, а в остальные регистры загнать адреса форт-примитивов, тогда каждый из них можно будет вызывать однобайтовой инструкцией call rx. В таком варианте бродилка худеет до 1.8K.
Интересно, какие еще фишки заложить, чтобы такой процессор был максимально forth-friendly?
upd. Как и ожидалось, все сишные тесты под r8 успешно скомпилировались и работают. Для адаптации под новый процессор транслятор си пришлось поменять буквально в паре мест, чуточку больше правок пришлось сделать в форте, который пожирает выхлоп транслятора си, упрощенный вариант ассемблера на макросах fasm делается элементарно (штатный тоже надо будет сделать, но позже), ну и небольшое ядро форт-системы на этом ассемблере пришлось набросать. Если сравнивать плотность кода, например, на бродилке, то цифры такие:
Код:
file vm size xv4 *
----- --------- ---- --- ---- --- ---------
[wolf3d.f]
arm lpc2129 4656 8.0
thumb stm32f042 3940 6.7
risc r8 2818-435=2383 4.1 sw stack
risc r8 2261-435=1826 3.1 hw stack
x86 1799 3.1
risc r8 1952-435=1517 2.6 reg calls
forth cpu16v1 1011-248= 763 1.3
forth cpu16v2 995-251= 744 1.3
forth cpu16v3 915-296= 619 1.1
forth cpu16v4 880-296= 584 1.0
Т.е. плотность кода для этого теста получается примерно на одном уровне с x86 (16 бит), но при этом раза в 3 жирнее, чем код для форт-процессора, а arm и thumb ожидаемо дают заметно более рыхлый код. Змейка под r8 примерно в 2 с лишним раза толще аналогичной под форт-процессор:
Код:
[snake.c]
risc r8 3227-435=2792 2.2 reg calls
x86 2413 1.9
forth cpu16v4 1593-296=1297 1.0
В целом, если сравнивать с плотностью кода для форт-процессоров, будет проигрыш раза в 2-4, что не смертельно. О производительности не переживаю, ибо планирую при помощи широкого машинного слова (а 8-битные команды как раз позволяют утрамбовать много таких команд в слово разумного размера) выполнять несколько команд параллельно. Эти и другие тесты тут:
http://totalvacuum.ru/density.zipИнтересный пример с "hello, world". Там версия под x86 весит меньше forth-версии (74 vs 99). Дело в том, что в x86 printc и printf реализованы на asm, а в форт-процессоре написаны на Си и компилируютя при помощи далеко не самого эффективного компилятора. Но стоит лишь переписать эти два определения хотя бы на Форте, как бинарник худеет с 99 до 72 байт. На форт-ассемблере будет еще меньше. И это при том, что в x86 сама строка весит 12 байт (без завершающего нуля), а в форт-процессоре Гарвард, память программ недоступна для чтения, поэтому строка выкладывается в RAM байт за байтом, а код, который это делает, весит 36 байт (получается 3 байта на символ, в теории может быть и до 4 с половиной), а в r8 вообще чудовищные 6 байт на символ получаются. Такая вот ахиллесова пята отросла.
В r8 может быть частично вылечено введением строковых регистров r10/r11 как в x86 es:si/ss:di для lodsb/stosb, тогда будет 3 байта на символ. Ну или фон Нейман
Кстати, на маленьких прошивках r8 начинает сильнее отставать от форт-процессора и x86, но это из-за того, что в прошивке присутствует код, который выполняет инициализацию регистров адресами форт-примитивов. Ну и сишные реализации printc и т.д. в сравнении с ассемблерными в x86 добавляют бодипозитива. Но при увеличении размера прошивки вклад этого кода уменьшается и прошивка сравнивается по размеру с x86.
upd. Сделал трансляцию в verilog варварским способом: вместо полноценного транслятора накидал простенькую утилиту, которая в com-файле пропускает реализацию виртуальной машины, а далее побайтно выводит прошивку в виде
Код:
code[16'hAAAA]=8'hBB;
Так что теперь можно приступать к реализации в ПЛИС. И выходит, что в таких простых случаях свой ассемблер не обязательно писать.