Small Instruction Set Computing

polprog, 06.2024

From time to time I like to experiment with various computing machines and architectures. Since a computer is just a very complicated state machine, it should be possible to make one that uses a simpler instruction set. After all, single instruction set computers and languages like Brainf*ck exist and work.

The size of an instruction set is a tradeoff between code size, execution speed and how complicated the underlying hardware is. Reduced Instruction Set Computer (RISC) and Complex Instruction Set Computer (CISC) was the first division of instruction set architectures as more and more CPUs were designed.

RISC CPUs were historically faster (in instructions per second) than CISC because they had less instructions, so the hardware could be made simpler and clock speeds faster. The performance was however variable as what RISC had to do in several instructions, a CISC could do in one. That distioction is very symbolic these days with ARM, a typycal RISC, implementing more and more instructions, and x86, a typical CISC (8086, the "Mainframe on a chip"), gaining more RISC-like features with the introduction of amd64 over 20 years ago.

8ball, the 8 instruction ISA

For a few projects I am doing I need a small instruction set, so I am trying co come up with a round number of instructions. Currently 8 is a nice round number as each instruction can be coded in just 3 bits. The ISA is targeted to be ran as a virtual machine, but there is nothing to prevent implementing it in some HDL. Why 3 bytes? It's a secret :)

There are 5 registers

a     Accumulator
d     Data pointer/second register
tmp   hidden temporary register for SWAP
sp    Stack pointer
ip    Instruction pointer

Only the accumulator and stack pointer can be directly modified. These are the 8 instructions:

opcode    instruction
-------------------------
0         ZERO         a <- 0;
1         INC          a++;
2         ROL          rotate a left
3         SWAP         tmp <- a; a <- d; d <- tmp;
4         PUSH         sp++; stack[sp] <- a;
5         POP          a <- stack[sp]; sp--;
6         JZ           iff a == 0 then ip <- d - 1;
7         JP           ip <- d - 1;

There are a few groups. You may notice there is no constant loadin instruction, there is simply no way to encode a sensible constant and an instruction in 3 bits. Instead, loading a constant into a register is done using the ZERO, INC and ROL instructions:

Example: Load 13 (0b1101) into register a:

ZERO INC ROL INC ROL ROL INC

The ROL instruction is there so that constants can be formed easily. Otherwise loading a constant would need a lot INC instructions. This way constants are formed bit-by-bit. SWAP is used to access the d register.

PUSH and POP are the usual instructions for running the stack.

The VM can interface to the outside world by a SYSCALL. This is not a real instruction, but rather a call gate. When the program jumps to address zero, the VM will execute a system call using the stack for arguments. The system call can be anything, it can even be mapped to the underlying OS (eg. Linux) syscall. the SYSCALL is an idiom for ZERO SWAP JP. You have to save the accumulator yourself at the right moment.

Jumps and calls are hard. I only wrote a few programs in this ISA, so this part is not well thought out. Two instructions are provided, a JZ (jump if zero) and JP (unconditional jump). There is no call instruction, that is, a jump with saving the return address. In this version of the ISA there is no way to save the instruction pointer, so I might replace the unconditional jump with a CALL instruction that saves the ip to stack and jumps to address in d. In that case, an uncoditional jump would be PUSH ZERO JZ. The function return RET would become POP SWAP ZERO JZ. The stack would be used to return a value, however it would need some more instructions to swap the place of the return address and the return value on the stack. This could become a part of the RET idiom.

Arithmetic operations are still to be done. Some programs simply don't need them, but they should be possible. This is still work in progress.

Back to homepage...