Hacker News new | ask | show | jobs
by londons_explore 2254 days ago
It would be interesting to compare this project to simply converting 6502 assembly into LLVM IR, and letting clangs optimization passes work their magic.

Obviously self modifying code would be hard to handle, but every other case ought to work, and the auto-vectorization ought to do amazing things to some loop-heavy code.

7 comments

I was wondering about this. Does LLVM offer facilities expressive enough to model things like self-modification and arbitrary interruptability?

I agree it'd be wonderful to see auto-vectorization! Obviously, 6502 code does things 1 byte at a time so even adding 32-bit integers is painful. Auto-upgrade of those loops to 32-bit variants would be amazing.

Self modifying code was the norm. I hated the loss of optimizations you could do when going to a system on non-self-modifying code. I ended up just giving up on assembly.
I remember thinking, "oh? this was made by people who can't code!?" then I quit entirely.

Before, stuff would reduce to nothing after use. Will this condition continue to change? Will it stay true? (Remove the check) Will it stay false? (remove that chunk of code) and then remove this.

Sure, it was fun. More important: People wrote things that were truly impressive. Writing something that worked was only the beginning.

Until compilers know which buttons are used most frequently they cant fully optimize. Who knows, maybe one day windos will give me a start menu and allow me to reboot when the application freezes up? Maybe one day text input will have some priority? The bare basics basically?

a 6502 backend for LLVM has been attempted a couple times[1][2], but the fact that the 6502 only has three registers imposes severe limitations w.r.t. LLVM's calling conventions.

[1] https://github.com/c64scene-ar/llvm-6502

[2] https://github.com/beholdnec/llvm-m6502

Other way around - the idea is to create an LLVM frontend for 6502 machine code, and then transpile that code to run on a modern CPU architecture.
That sounds like an interesting project!

You would probably want to add some tricks directly there, maybe register renaming (I don't know if LLVM does "variable renaming", let's put it this way)

That's the approach taken by https://github.com/libcpu/libcpu. It supports 6502 and several other CPUs.
I would think you’d need to write a couple of new optimization passes, for example to detect multiplications (in various variants, such as “signed 8 bit to 16 bit, multiplier is 13” or “unsigned 16 bit times 8 bit”) and convert them to LLVM multiplication instructions.

There also is the trick where “BIT” instructions are used to give a function multiple entry points, and that BIT instruction can also be a LDA# (https://retrocomputing.stackexchange.com/a/11132)

I’m not sure that can “simply” be converted to LLVM IR.

Is this what you're (roughly) referring to?:

  https://andrewkelley.me/post/jamulator.html
Although the programmer's target is an entire system, the conclusion may still apply:

  > There is a constant struggle between correctness and optimized code. Nearly all
  > optimizations must be tossed out the window in the interest of correctness
This but at runtime.
I’m not sure: LLVM’s optimizer is fairly slow and there’s a lot of bad things going on that will constantly cause deoptimizations. Maybe for some of the hottest paths?