Я недавно изучал дизайн компилятора. Мне удалось получить сильное представление о стадии синтаксического анализа, но мне немного сложно понять, как работает генерация кода.Как работает генерация кода сборки?
Из того, что я читал, кажется, есть 3 основных шага в фазе генерации кода:
- Инструкция выбора (Жадный Черепица)
- Инструкция Планирование
- Регистрация Allocation
Теперь, планирование команд немного превышает то, что я пытаюсь сделать в данный момент, и я думаю, что с немного более изучением и прототипированием, я, вероятно, могу объединить свой взгляд вокруг графика co алгоритм регистрации для распределения регистров.
Какие пни меня первый шаг, выбор инструкций. Из того, что я читал об этом, каждая инструкция на языке целевой машины представлена плиткой; и цель состоит в том, чтобы найти инструкции, которые соответствуют самым большим частям дерева (отсюда псевдоним, жадная черепица).
Вещь, с которой я смущен, заключается в том, как вы выбираете инструкции, когда они фактически не соответствуют 1: 1 с деревом синтаксиса?
Возьмите, например, архитектуру на основе накопителей, такую как архитектура с одной инструкцией Z80 или MIP. Выполнение даже 16-разрядной целочисленной арифметики на Z80 может потребовать использования накопительного или теневого регистров.
Есть также некоторые инструкции, которые могут использоваться только в определенных регистрах, несмотря на то, что они являются универсальными.
Буду ли я прав, предполагая следующее?
a) Плитка может состоять из последовательности инструкций, которые соответствуют шаблону дерева синтаксиса, а не только совпадению 1: 1.
b) Генератор кода генерирует код для архитектуры на основе стека (или архитектуры с бесконечными временными регистрами) и расширяет и заменяет инструкции по мере необходимости как-то на этапе распределения регистров.