See also <a href="https://www.nordicsemi.com/News/2019/12/Rust-a-security-programming-language-could-eliminate-many-IoT-device-vulnerabilities-using-nRF9160" rel="nofollow">https://www.nordicsemi.com/News/2019/12/Rust-a-security-prog...</a><p>PS: Holy crap! For the first time in my 40+ year career I have clicked-thru from a semi-relevant article about Rust on a micro p̵r̵o̵c̵e̵s̵s̵o̵r̵ controller to a reference about the...[RCA] COSMAC VIP (in the form of this dude's effort to get CHIP-8 running on LLVM-MOS). Do you have any idea how many lawns I had to mow to buy one of those? It was a big disappointment (over my ELF and SuperELF) too! ROFL<p>[ <a href="https://youtu.be/fLVN05Jl6wA" rel="nofollow">https://youtu.be/fLVN05Jl6wA</a> ]
That is so cool. I saw some posts about LLVM-MOS a while ago, but at that point I thought it would be just another in a fairly long list of attempts to try and get LLVM to output 6502 instructions.<p>I never expected it to come together this well! Especially considering that the author of the article mentions there were so many issues with LLVM-AVR, you'd expect them to exist in LLVM-MOS as well. Apparently not! I guess the code quality will only improve from here on out, the loop at the bottom of the article does seem like it is not as optimal as it could be :)
Author of mentioned post on 6502.org forum here. In the meantime I worked a bit on implementing proper rust target-triple for 6502 (mos-unknown-none), code is here: <a href="https://github.com/mrk-its/rust/tree/mos_target" rel="nofollow">https://github.com/mrk-its/rust/tree/mos_target</a><p>Then standard cargo tool may be used to directly build 6502 executable, some examples: <a href="https://github.com/mrk-its/a800-rust-test" rel="nofollow">https://github.com/mrk-its/a800-rust-test</a> or <a href="https://github.com/mrk-its/llvm-mos-ferris-demo" rel="nofollow">https://github.com/mrk-its/llvm-mos-ferris-demo</a>
I am not sure if it is a good idea to compile code targeted to modern processors to 8-bit CPUs like 6502. For example:<p>Languages like C (or Rust) allocate variables on the stack because it is cheap with modern CPUs, but 8-bit CPUs don't have addressing modes to access them easily. (by the way, some modern CPUs like ARM also cannot add a register to a variable on the stack).<p>The solution is not to use the stack for variables and instead use zero-page locations. As there are only 256 zero-page bytes, same locations should be reused for variables in different functions. This cannot be used with recursive functions, but such code is ineffecient anyway so it is better not to use them at all and use loops instead.<p>Another thing is heap and closures (that allocate variables on the heap). Instead of heap the code for 8-bit CPUs should use static allocation.<p>The article contains an example of 6502 code compiled from Rust and this code is inefficient. It uses too much locations for variables (rc6-rc39) and it wastes time saving and restoring those locations in prologue/epilogue.<p>No wonder that programs run slowly. It would be much better to compile CHIP-8 directly to 6502 assembly.
Strange exercise because Rust and the 6502 original programming mood are totally different: a word of cleverness and the most obscure side effects in order to squeeze the last clock cycle. But everything is "hack value", I will respect.
Er... the article doesn't make it clear, but I guess we're talking about cross-compilation here? So it's not "Rust" (or, as he writes later, LLVM) running on the 6502, just the code generated by the Rust compiler.<p>Still cool though!