Ура! Вопрос по компиляторам! С удовольствием отвечаю! :)
Предположим, что мы уже получили IR в виде кода для стековой машины. Далее можно было бы заняться простейшим видом генерации x64-кода на основе макроподстановки. Основная проблема, однако в том, что работу со стеком придется постоянно имитировать -- то есть получится нечто в духе подпрограммного шитого кода, если говорить в терминах Форта. Ситуацию можно немного улучшить с помощью peephole-замен, но это явно не самое эффективное решение.
С другой стороны, можно было бы представить, что стек у нас виртуальный, на вершине его находятся аппаратные регистры, а далее идут ячейки стековой памяти. Тогда мы могли бы заняться интерпретацией стекового IR таким образом, чтобы при появлении push или pop определять, где у нас реальные операнды и соответствующим образом генерировать целевые команды.
Схожая техника под названием DDCG работает за один проход и хорошо известна в компиляторной Scheme-школе. Вот, в частности, статья на тему от K. Dybvig и др. "Destination-Driven Code Generation":
https://pdfs.semanticscholar.org/16f1/89ec98c0a9bd0c672ce14799347fab8b4726.pdfНо совсем в наглядном варианте подход этот описан в презентации "One-pass Code Generation in V8":
https://github.com/eatonphil/one-pass-code-generation-in-v8/blob/master/One-pass%20Code%20Generation%20in%20V8.pdfКроме того, можно посмотреть часть лекции Булычева под названием "Интерпретатор стековой машины с символическим стеком как генератор кода". Я сразу для удобства перемотал до нужного места:
https://youtu.be/XFjXmYFu3Ik?t=2958