Выдыхаю. Краткая размышлизма о стековых процессорах. По мотивам предела процессоростроения -> и подтемы по стековым процессорам --> http://caxapa.ru/595300.html
http://caxapa.ru/595243.html
Но научному это называется concatenative programming language, а процики - MISC (англ. minimal instruction set computer)
https://ru.wikipedia.org/wiki/MISC
http://www.enet.ru …zov/forthcpu/misc.html
Очень простое и наглядное описание сути стековых процессоров и языков на основе этой идеи
http://brainslugs. …6/stack-languages.html
Вот тут про Форт - самый известный представитель этого мира
http://www.compile …rechyon-yazyk-fort.php
Общая ситуевина примерно такова.
Идея стекового процессора, реального или VM, весьма эффективна. Прежде всего тем, что реализация работающей экосистемы под силу одному человеку, не говоря уже о небольшом коллективе
* VM
* простой компилер из "стекового языка" в выбранный байткод, по сложности как хороший ассемблер
* IDE со всякими примочками
* железная реализация - в FPGA от 400 LE простенький вариант до 1200 LE на современных 6 LUT Xilinx
http://repo.or.cz/ …/zpu_arch.html;hb=HEAD
В силу этой простоты кастомизация всего хозяйства - задача несложная. Это не GCC патчить...
Но, самое главное, философия стекового подхода идеально ложится на FPGA. Если целевую задачу удается разложить в пространство примитивов, которые, в свою очередь, удается сделать блоками в FPGA, то расширение некоего минималистического FORTH ядра новыми словами, которые отображают свойства этих блоков - задача, которая под силу одному разработчику.
Стековые процы имеют сильные ограничение по наращиванию производительности - OoOE и суперскалярность там почти что невозможна, но нам это пофиг, ибо мы рассматриваем реализацию софткора в небольших недорогих плисках, до 20к LE, а в таком объеме настоящие OoOE и суперскалярность не замутить даже для самых идеальных систем команд :)
Но пусть это никого не смущает - за счет оптимальности системы команд для целевой задачи и отсутствие лишних телодвижений в части операций регистр - память какой-нибудь 30 Мгц стековый процик может вполне порвать 100 МГц микроконтроллер.
Хорошо просматриваются пути аппаратной поддержки прерываний и многопоточности - по сути, надо иметь несколько стеков операндов и переключаться между ними. Можно получить однокомандную задержку реакции на прерывание и поддержку некоторого разумного числа потоков (4 или 8, например).
Плотность кода у таких ядер просто фантастическая! eP32 (ниже) кодит в 32 бита либо одну "длинную" команду, либо 5(!) шестибитных (!).
Таким образом, с точки зрения среды исполнения некоей специализированной либы в FPGA среде стековый процессор выглядит очень даже привлекательно.
Но! В части ПО сложностей очень много.
Полноценный компилер C -> стековый процик штука невероятно сложная, и это явно не для рассматриваемой экосистемы.
Значит, эту самую супер-либу предстоит написать с нуля.
Постфиксная, или польская нотация имеет массу преимуществ для железа, но совместима с мозгом небольшого количества программеров.
Выстраивание в уме правильного порядка операндов в стеке сведет с ума 99% программеров. Пока не встретил описания правильной IDE - которая бы визуализировала стек операндов. Можно доработать принцип компиляции - расширить синтаксис виртуальными названиями промежуточных результатов, и пусть компилер разбирается - что в какой момент будет в каждой ячейке стека, и подсказывает программеру - совпадет или нет. Виртуальные имена живут только на стадии компиляции.
С отладкой вопрос неоднозначный. Вроде все плохо, но! За счет простоты написания симулятора ядра можно виртуально отладить во все щели. Можно расширить процык отладочными словами, которые соберут данные в процессе выполнения и сделают очень качественный трейс с привязкой к тикам 64 битного таймера, скажем. Мне кажется, это решаемый вопрос.
Еще раз повторю - возможности кастомизации просто безграничные. Например, у Altera Cyclone V блочная память может иметь шину 40 (!) бит. 32+8. Что дает возможность в стеке операндов реализовать аппаратный контроль типов данных (привет Эльбрусу). Т.е. когда мы в первый раз грузим значение в стек из кода (константа, например), мы ему присваиваем тип, и это фиксится в расширенном поле. Вводим слова приведения типов. А потом АЛУ просто тупо сравнивает 8 бит признака у операндов и генерит эксепшн, если мы int и float пытаемся сравнить, или указатель сложить со значением переменной. Заметим, что в супер-пупер армах и мипсах такого нет и не будет даже в теории.
Хакинг стековых процессоров тоже местами невозможен. Поскольку стек операндов и память кода физически разделены (если они даже живут в одном чипе SDRAM, легко проставить тупое адресное ограничение), и переполнение стека просто обрушит программу, но не даст возможность что-нибудь хакнуть.
Как должна выглядеть правильный кастомный камень с ядреными алгоритмами (FPGA для начала, а там, глядишь, и до ASIC можно дорасти)
* SDRAM контроллер и память
* софткор стекового процессора для реализации целевых алгоритмов. ВОзможно, несколько софткоров или софткор с поддержкой многопоточноси
* периферия
* "обычные" мелкие софткоры, которые из простой периферии делают умную с блочным интерфейсом. Чтобы было проще отлаживаться стандартными средствами.
Неоспоримые преимущества FPGA:
* выбираем хороший корпус ПЛИС, в котором живет много камней
* Для отладки берем самую быструю, самую толстую ПЛИСку с кучей набортных ресурсов, и реализуем все необходимое - память для хранения дампов и трейсов, ядро с кучей отладочных команд
* для серии компилим всю экосистему в сжатый вид.
Компиляция экосистемы:
Самый идеальный вариант - это когда экосистема собирается под выбранные параметры ядра. Т.е. есть некий мегакофигуратор, где ты задаешь все - от разрядности ядра и наличия команд в нем до доступных объемов памяти. Мегакомпилер синтезирует ассемблер, среду, целевой компилятор и проч. Потом ему скармливаешь исходники, и получаешь бинарник.
Методология управляющих слов и тут поможет. Вот стоит у тебя в исходнике нетривиальное деление. В "большом камне" делаешь опцию деления в ALU. А в целевом - это вызов подпрограммы деления. И считаешь такты в симуляторе - успеешь или нет. И размер кода, стека операндов - влезешь или нет.
Вывод: стековые процессоры - хорошее средство изготовления качественного "каменного цветка" небольшим коллективом, но не стоит пытаться сделать из них архитектуру всего - точно не получится.
В целом тема интересная, но для небыстрого вдумчивого изучения. Да, и проблему (С) на либу решит точно - сделать реверс этого стекового процессора - это надолго :)
Ресурсы.
Гнездо мира Форт
http://www.forth.org
Некоторое количество русской доки по Форту
http://www.forth.org.ru/forth/lit.html
http://wiki.forth. …0%BE%D1%80%D1%82%D0%B0
eForth - A simple model Forth system
http://www.calcentral.com/~forth/forth/
eForth and Zen - книжка, увы, на китайском (!)
http://www.ultratechnology.com/efzen.htm
Подборка информации о желеной реализации Форт-подобных процессоров
http://www.ultratechnology.com/chips.htm
Немало информации по всякому встроенному форту, есть на английском
http://jpb.forth.f …lais/introduction.html
eP32 - процик. Сайт довольно интересный.
http://www.offete. …om/eForth_academy.html
Factor - развитие идей Форта
https://ru.wikiped …0%B0%D0%BD%D0%B8%D1%8F)
http://progopedia.ru/language/factor/
http://habrahabr.ru/post/98479/
Нетривиальная тема - взаимоотношения Tcl и Forth. Tcl and Forth share a common philosophy. Both are based on words (or "commands") that implement the rules of the language. There is just one fundamental difference: Tcl uses prefix and infix notation, Forth uses postfix notation.
http://wiki.tcl.tk/1656
Народ написал компилер, который транслирует Форт в Tcl.
http://holonforth.com/holontforth.html
http://wiki.tcl.tk/21022
Демонстрационный проект - шахматы - на форте и Tcl
http://holonforth.com/chess.html
http://wiki.tcl.tk/4070
Простенький Форт на Tcl
http://wiki.tcl.tk/3274
http://wiki.tcl.tk/37199
FlashForth
http://flashforth.com/