-
Notifications
You must be signed in to change notification settings - Fork 16
Description
The current instruction set is, for lack of a better word, limited, in many areas:
- Addressing modes
- Control flows
- Arithmetic and logical operations
Let's see how we can improve it:
Addressing modes
As we're starting to add memory support to do-core, we're hitting a few limitations and inefficiency related to the addressing modes that the architecture supports: Register and base addressing.
ADD R3, R4; is equivalent to $R3 = $R3 + $R4, this is the register addressing mode.
LD R3, R4; is equivalent to $R3 = [$R4], this is a base addressing mode, as the second operand is used as an index (a base) into the memory array.
What we're missing is a third addressing mode, that would allow us to load or add a value directly, a.k.a. immediate addressing:
ADDI R3, 0x100 would be equivalent to $R3 = $R3 + 0x100
LDI R3, 0x100 would be equivalent to $R3 = 0x100
Instruction format changes
In order to efficiently access memory, in one instruction, across the whole 4K address space, we ideally should be able to do immediate addressing across the whole address space which spans across 12 bits.
With the current instruction format, allocating 8 bits for the opcode, 4 for op0 and 4 for op1, immediate addressing is only left with 4 bits. So here we propose to change the instruction format in the following way:
- Increase the instruction size to 32 bits (2 words)
- Decrease the opcode size to 6 bits (a maximum of 64 instructions)
- Increase the register index to 5 bits (32 registers at most,
do-core1will still be an 8 generic registers architecture)
Immediate addressing instructions (ADDI, LDI) would then be left with 21 bits for immediate values.
Word aligned memory accesses
Moreover, the LD instruction loads 8 bits (1 byte) into do-core1 16-bit (2 bytes) registers. This is a limitation as loading a machine word (16-bit) would involve multiple instructions and more than 1 clock cycle.
To overcome that limitation, we thus propose to rename LD and ST and redefine their semantics:
LDwould becomeLDW(Load Word).STwould becomeSTW(Store Word)LDW R3, R4;would be equivalent to loading the 2 bytes at$R4into$R3. The lower 8 bits of$R3would be loaded with the 8 bits at$R4and the upper 8 bits of$R3would be loaded with the 8 bits at$R4+1. A similar logic would apply toSTW.- The second operand of both
LDWandSTW(The memory address) must be 16-bit aligned.
Control flow
The current instruction set does not allow for branching and jumping, which is a mandatory requirements for efficient loop implementation and function calls.
We propose to add 4 branches and jump instructions:
JMP addr: Jump toaddrJMPR R1: Jump to$R1BEQ R1, R2, addrIf$R1 == $R2, branch to$RIP + addrBNE R1, R2, addrIf$R1 != $R2, branch to$RIP + addr
Arithmetic and logical operations
In order to facilitate generating code for the do-core architecture, we propose to add the following instructions:
SUB R1, R2:$R1=$R1-$R2AND R1, R2:$R1=$R1&$R2(bitwise AND)OR R1, R2:$R1=$R1|$R2(bitwise OR)SHL R1, imm:$R1=$R1<<imm(Shift Left)SHR R1, imm:$R1=$R1>>imm(Shift Right)CMP R1, R2:if $R1 == $R2 then RFLAGS[0] = 1. Set first bit ofRFLAGSto 1 when both operands are equal