From
https://llvm-mos.org/wiki/Findings:
Several common assumptions about the MOS 6502 processor, and C compilers
targeting it, are now refuted by the current work.
First, the assumption that a modern compiler framework, such as LLVM, cannot
be targeted towards an old 8-bit CPU such as the 6502. LLVM's new GlobalISel
architecture can very well be targeted to the 6502, and it can indeed
produce superior code, if permitted to do so.
Second, the assumption that because the 6502 is "stackless," and has few
registers, it is not a good host for C.
Regarding stacks, while it's true that the standard C runtime model is quite
hostile to 6502 performance, the C standard provides broad latitude for
alternative models that behavior in all points "as if" it were the C model.
In the broad space of possible alternatives, we've found a collection of
techniques that broadly preserve C standard compatibility while emitting
very high quality code. To put it another way, we go to great lengths to
emit code that operates "as if there were stacks", without using stacks at
all. LLVM's sophistication facilitates this; the analyses required are quite
intricate, but most of them are slight modifications to data structures
already available in LLVM.
Regarding registers, the original 6502 designers were well aware of the
6502's register limitations, and so provided a bunch of zero-page addressing
modes to compensate. We present these to LLVM as registers, which takes our
backend from "alien nightmare" to "ugly duckling", not unlike x86 or AVR.
Normal register allocation techniques apply, since 6502 instructions treat
different zero page locations identically. While A, X, and Y are a bit
unusual, they're not any worse than x86, and LLVM's register is fully
capable of handling them, even if the relationship is a bit strained.
Third, that "simpler is better" for producing a performant compiler for
8-bit targets. llvm-mos's architecture and design choices are not at all
simple. I haven't counted, but I think llvm-mos is doing about 100 passes
through the code, about 8 of which are specific to the MOS 6502.
Fourth, that the 6502 is implicitly some sort of "special" architecture, and
it therefore requires special compilers, linkers, binary file formats, etc.
We treat the 6502, ultimately, as just another target within the LLVM
framework, and as such it benefits from all the industry-standard
ELF-compatible file formats.
Fifth, that because the 6502 is a small target, it requires a smaller
compiler and smaller tools. This assumption never really made sense anyway.
In fact the opposite is true: if you want to do advanced codegen for the
6502, you need a really intelligent (and large) compiler and toolchain
framework, not a small one. The state of the art of optimization has
advanced leaps and bounds in the past three decades, and the poor old 6502
has received none of those benefits, until the current work.
Sixth, that peephole optimization produces the best codegen for the 6502. In
fact, llvm-mos gets the most benefit out of 6502-specific optimizations
relatively early in the LLVM machine function pass pipeline, and the code it
produces (in small tests) is quite efficient, even without any 6502-specific
peephole optimizer at all. "The more clothes you put on during the day, the
more you have to take off at night." One high-level instruction can become a
big block of 6502, so a single high-level optimization that removes it can
prevent a thousand cases from being needed to handle it later.
Seventh, that because the 6502 is small, it requires some sort of
specialized language (in the David A. Wheeler sense
<
https://dwheeler.com/6502/> ) in order to generate performant code. As it
turns out, anything that generates LLVM IR, can be a candidate for running
on the 65xx series of processors. Making "a version of C" that is easy to
compile just shifts the burden of writing a modern compiler, back onto the
user, in the form of limited functionality. LLVM will likely be able to
handle compiling other languages to the 6502, at some point in the future.
Rust support has already been proven, but there are no problems in principle
with lowering many more languages to the 6502.