Close

Log #6: Accidentally wrote a C backend

A project log for DIP-8 TTL Computer

Digital Information Processor - an 8-bit computer made out of 7400 series logic and some EEPROMs.

kaimackaimac 08/08/2022 at 21:210 Comments

Getting C programs running on this machine was never one of my goals, but I was looking idly at the documentation for LLVM and GCC, wondering how hard it would be to write a code generator. It seemed like far too big a task and I was happy to let it go, and then I stumbled across the vbcc compiler. It has many different backends, including some small 8-bit processors and a clean "generic" 32-bit RISC. Each backend is basically a single 1000-2000 line C file. Those examples, coupled with this useful document were enough to get me hacking together a DIP8 backend. It is quite a complicated and frustrating process, but the nice thing is you can add functionality bit by bit, and before you know it you can compile some fairly interesting C programs.

I haven't got function calls, structs or arrays working properly yet, but I can compile the C version of the Byte sieve test that I previously wrote in assembly:

#define size 8191

int main(void) {

    unsigned int count;
    unsigned int prime;
    unsigned int k;
    unsigned char *flags = 0x1000;

    count = 0;
    for (unsigned int i=0; i<size; i++) {
        flags[i] = 1;
    }
    for (unsigned int i=0; i<size; i++) {
        if (flags[i]) {
            prime = i + i + 3;
            k = i + prime;
            while (k < size) {
                flags[k] = 0;
                k += prime;
            }
            count = count + 1;
        }
    }

    return count;

}

This works, and to my amazement it's actually quite fast - only 20% slower (and 50% bigger in size) than my hand-crafted assembly. 

In the process of doing this, I added some more instructions that C likes to use a lot and were otherwise a bit difficult - signed comparisons, rotate right, some more 16-bit arithmetic and a way to do arithmetic on variables in memory, without loading into a register. I'll go through those in another log.

I would like to at some point write a tutorial on how to write a vbcc backend for a homebrew CPU, as the vbcc code isn't very easy to read and the docs are a bit lacking in places. Actually the most useful backend to look at is for the "Z-machine", a VM used for Infocom text adventure games, as it's well commented - link here.

Discussions