5 ms·
LLVM-MOS – Clang LLVM fork targeting the 6502
- mtklein 11mo agoThis was a nice surprise when learning to code for NES, that I could write pretty much normal C and have it work on the 6502. A lot of tutorials warn you, "prepare for weird code" and this pretty much moots that.
- cmrdporcupine 11mo agoIt's been amazing to see the progress on this project over the last 5 years. As someone who poked around looking at the feasibility of this myself, and gave up thinking it'd never be practical, I'm super happy to see how far they've gotten. Maybe someday the 65816 target will get out there, a challenge in itself.
- jacquesm 11mo agoInstead of the 65816 we got the ARM, which I think was the better thing to happen in the longer term.
- self_awareness 11mo agoRust fork that works on this LLVM fork, for 6502, genering code that can be executed on a Commodore-64: https://github.com/mrk-its/rust-mos https://github.com/mrk-its/rust-mos
- michalpleban 11mo agoHow does it compare to cc65 with regard to code size and speed?
- asiekierka 11mo agoHere's a benchmark of all modern 6502 C compilers: https://thred.github.io/c-bench-64/ https://thred.github.io/c-bench-64/ - do note that binary sizes also include the size of the standard libraries, which means it is not a full picture of the code generation density of the compilers themselves.
- michalpleban 11mo agoThank you, that's really helpful.
- gregsadetsky 11mo agoI don't know this world well (I know what llvm is) but - does anyone know why this was made as a fork vs. contributing to llvm? I suppose it's harder to contribute code to the real llvm..? Thanks
- jjmarr 11mo agoLLVM has very high quality standards in my experience. Much higher than I've ever had even at work. It might be a challenge to get this upstreamed. LLVM is also very modular which makes it easy to maintain forks for a specific backend that don't touch core functionality.
- gregsadetsky 11mo agoSuper interesting, thanks. I specifically thought that its modular aspect made it possible to just "load" architectures or parsers as ... "plugins" But I'm sure it's more complicated than that. :-) Thanks again
- zozbot234 11mo agoLLVM backends are indeed modular, and the LLVM project does allow for experimental backends. Some of the custom optimization passes introduced by this MOS backend are also of broader interest for the project, especially the automated static allocation for provably non-reentrant functions, which might turn out to be highly applicable to GPU-targeting backends. It would be interesting to also have a viable backend for the Z80 architecture, which also seems to have a highly interested community of potential maintainers.
- codebje 11mo agohttps://github.com/jacobly0/llvm-project https://github.com/jacobly0/llvm-project ... but now three years out of date, because it's hard to maintain :-)
- codebje 11mo agoMy experience is that while LLVM is very modular, it also has a pretty high amount of change in the boundaries, both in where they're drawn and in the interfaces between them. Maintaining a fork of LLVM with a new back-end is very hard.
- HarHarVeryFunny 11mo agoAccording to this page, LLVM-MOS seems to be pretty soundly beaten in performance of generated code by Oscar64. https://thred.github.io/c-bench-64/ https://thred.github.io/c-bench-64/ I think the ideal compiler for 6502, and maybe any of the memory-poor 8-bit systems would be one that supported both native code generation where speed is needed as well as virtual machine code for compactness. Ideally would also support inline assembler. The LLVM-MOS approach of reserving some of zero page as registers is a good start, but given how valuable zero page is, it would also be useful to be able to designate static/global variables as zero page or not.
- zozbot234 11mo agoAIUI, Oscar64 does not aim to implement a standard C/C++ compiler as LLVM does, so the LLVM-MOS approach is still very much worthwhile. You can help by figuring out which relevant optimizations LLVM-MOS seems to be missing compared to SOTA (compiled or human-written) 6502 code, and filing issues.
- deleted 11mo ago[deleted]
- djmips 11mo agoI feel like no amount of optimizations will close the gap - it's an intractable problem.
- fooker 11mo agoIt's performance of generated code, not performance of the compiler.
- djmips 10mo agomhm
- HarHarVeryFunny 11mo agoI wouldn't say intractable, but it's not clear whether LLVM's optimization framework is flexible enough for it. From mysterymath's (LLVM-MOS) description, presenting some of zero page as 16 bit registers (to make up for lack thereof, and perhaps due to LLVM not having any other support for preferred/faster memory regions), while beneficial, still had limitations since LLVM just assumes that there will be FAST register-register transfer operations available, and that is not even true for the 6502's real registers (no TXY), let alone these ZP "registers" which would require using the accumulator to copy. A code generation/optimization approach that would seem more guaranteed to do well on the 6502 might be to treat it more as tree search (with pruning) - generate multiple branching alternatives and then select the best based on whatever is being optimized for (clock cycles or code size). Coding for the 6502 by hand was always a bit like that ... you had some ideas of alternate ways things could be coded, but there was also an iterative phase of optimization (cf search) to tweak it and save a byte here, a couple of cycles there ... I've mentioned elsewhere I used to work for Acorn back in the day, developing for the BBC micro, with me and a buddy developing the ISO-Pascal system which was delivered in 2 16KB ROMs. Putting code in ROM gives you an absolute hard size budget, and putting a full Pascal compiler, interpreter, runtime library and programmers editor into a total 32KB was no joke! I remember at the end of the project we were still a few hundred bytes over what would fit in the ROMs, and had to fight for every byte to make it fit!
- iberator 11mo agoSlightly off-topic. If you want to learn low level assembly programming in the XXI century, 6502 is still an EXCELLENT choice! Simple architecture and really really joyful to use even for casual programmers born a decade, or two later :)
- 1000100_1000101 11mo agoI'd argue that 68K is simpler to learn and use. You get a similar instruction set, but 32-bit registers, many of them. It's even got a relocatable stack so it can handle threading when you get to that point.
- chihuahua 11mo agoI agree, I feel like the 68k architecture was a dream for assembly programming. each register is large enough to store useful values, there are lots of them, there are instructions for multiply and divide. This allows you to focus on the essence of what you want to accomplish, and not have to get side-tracked into how to represent the X-coordinate of some object because it's just over 8 bits wide, or how to multiply to integers. Both of these seemingly trivial things already require thought on the 6502.
- monocasa 11mo agoAnd registers are actually pointer width, so you don't have to go through memory just to do arbitrary pointer arithmetic.
- jacquesm 11mo agoIf 8 bit: 6809. If 32 bit: 68K. Those are miles ahead of the 6502. Otoh if you want to see a fun quirky chip the 6502 is definitely great, and I'd recommend you use a (virtual) BBC Micro to start you off with.
- bsder 11mo agoYeah, the 6809 is just ridiculously good to learn assembly language on. Motorola cleaned up all the idiocies from the 6800 on the 6809. The attention the 6502 get is just because of history. The advantage the 6502 had was that it was cheap--on every other axis the 6502 sucked.
- bbbbbr 11mo agoThere is a similar project for the Game Boy (sm83 cpu) with a fork of LLVM. https://github.com/DaveDuck321/gb-llvm https://github.com/DaveDuck321/gb-llvm https://github.com/DaveDuck321/libgbxx https://github.com/DaveDuck321/libgbxx It seems to be first reasonably successful attempt (can actually be used) among a handful of previous abandoned llvm Game Boy attempts.
- retrac 11mo agoPresumably it would be straightforward to port the GB code generation to the Intel 8080 / Z80. There have been a few attempts for LLVM for those CPUs over the years. But none which panned out, I think?
- zozbot234 11mo agoMost attempts at developing new LLVM downstream architectures simply fail at keeping up with upstream LLVM, especially across major releases. Perhaps these projects should focus a bit more on getting at least some of their simpler self-contained changes to be adopted upstream, such as custom optimization passes. Once that is done successfully, it might be easier to make an argument for also including support for a newly added ISA, especially a well-known ISA that can act as convenient reference code for the project as a whole.
- codebje 11mo agoThe CE-dev community's LLVM back-end for the (e)Z80 'panned out' in that it produced pretty decent Z80 assembly code, but like most hobby-level back-ends the effort to keep up to date with LLVM's changes overwhelmed the few contributors active and it's now three years since the last release. It still works, so long as you're OK using the older LLVM (and clang). This is why these back-ends aren't accepted by the LLVM project: without a significant commitment to supporting them, they're a liability for LLVM.
- avadodin 11mo agoA lot of people try to write backends for LLVM to support obscure architectures but these guys are the only ones I know that have ever been successful to any degree. Portable assembly has a nice ring to it but reality is a harsh mistress and she only speaks C++. Even the hobby underdog qbe seems ill-suited to 6502 repurposing.