NeverBugFree
8 hours ago
For the last few months I've been researching how C compilers work, as I'd like to be able to write programs/games for the 16-bit ISA I designed and implemented. It was a rabbit hole nobody could've prepared me for: optimizations, DAGs, instruction selection, CFGs and everything in between. After asking around, I was told to try making a backend for either PCC, GCC or LLVM. I knew PCC was the simplest of the three, so naturally I attempted it first. Boy, what a mistake. PCC is archaic and so is its documentation. After a few days of "monkey see, monkey do" and imitating concepts I saw other 16-bit PCC targets implement, I tried compiling with my own target... And got a segfault. Nothing I could change anywhere in the codebase would make it budge and compile, so I tried compiling one of the existing targets. You can imagine I wanted to eat my can of Monster when that threw a segfault as well. I tried to tackle GCC and LLVM, but being the behemoths they are, the task was unapproachable by someone with little to no experience in compilers like me.
I was about to give up when I was looking around github and found out that clang has C# bindings in the form of the ClangSharp nuget package. Given the rest of my project is written in C# as well, I thought it couldn't hurt to give it a go, and I was right: within a day I was compiling simple C programs to my ISA.
Now, after a lot of research and work, I have a working compiler complete with peephole optimizations, implementations of C standard library functions such as alloca and memcpy via my project's firmware layer, and a fast C -> ROM file workflow. I'd love if you checked it out.