From a422c72ab03bf214448f22af740417d59588f10c Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Thu, 16 Jan 2020 00:00:47 -0500 Subject: [PATCH] Add ISA version 0.2 This changes the registers to 16-bit registers in order to solve the code and data addressing problems in the first revision. Having registers be address-sized means that we don't need to use register pairs or segments. Some of these changes open up new encoding space, or invalidate some previous design decisions. For instance, registers are 16 bits now, so AND/OR/XOR can no longer have a full-size immediate in one byte. With this, we free up encoding space for other options. Major additions include a "load upper/lower immediate" instruction. --- isa.txt | 66 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/isa.txt b/isa.txt index 4c77802..58fbdd3 100644 --- a/isa.txt +++ b/isa.txt @@ -1,27 +1,39 @@ -ALU2: add sub and lsl rol or xor bic -ALU1: inc dec neg compl -ALUI: add7 sub6 lsl lsr asr rot and or xor - -76543210 --------- -0000aabb => MOVE: a = b # when a != b -0000aabb => CALL: call a # when a == b, r0 <- ret -0001aaoo => ALU1: a = op a -001faa00 0iiiiiii => LDST: a <-> [imm] -001faa00 1iiiiibb => LDST: a <-> [b + imm] -001faa10 => LDST: a <-> [r2] -001faabb => LDST: a <-> [b-1:b] -0100aabb iiiiiiii => JMPR: jump aa # when a == b -01010000 iiiiiiii => JMPI: jump offset -01010101 iiiiiiii => CALI: call offset -01010101 iiiiiiii => CALI: call offset -010oaabb oiiiiiii => BRNC: branch if a op b -0110aa00 0iiiiiii => ALUI: a = a + imm -0110aa00 10iiiiii => ALUI: a = a - imm -0110aa00 11oooiii => ALUI: a = a op imm -0110aaoo iiiiiiii => ALUI: a = a {and, or, xor} imm -0111aabb => SKIP: skip if a ule b -1oooaabb => ALU2: a = a op b +4 16-bit general-purpose registers r0, r1, r2, r3 + +ALU2: trap nope add sub and or xor +ALU1: inc dec neg comp +ALUA: add +ALUI: lsl lsr asr rol clr set tog ext + +7654_3210 +--------- -------- +0000_0000 => HALT: halt +0001_0000 => NOPE: nope +0ooo_aabb => ALU2: a = a op b +1000_aabb => JALR: jalr ra # when a == b +1000_aabb => MOVE: a = b # when a != b +1001_aaoo => ALU1: a = op a +101f_aabb => LDST: a <-> [b] +110o_aabb oiiiiiii => BRNC: branch if a op b # when a != b +1100_0000 iiiiiiii => JMPI: jump offset +1101_aabb fiiiiiii => LSI0: a <-> [imm * 2] +1110_aa00 iiiiiiii => ALUA: a = a + imm +1110_aa01 ooooiiii => ALUI: a = a op imm +1110_aa10 iiiiiiii => LDLI: lo(a) = imm +1110_aa11 iiiiiiii => LDUI: hi(a) = imm +1111_aabb wpsiiiii => MEM2 + + +7654_3210 wps (write | push/pop | size) +--------- -------- +1111_aabb 000iiiii => LDBI +1111_aabb 001iiiii => LDWI +1111_aabb 100iiiii => STBI +1111_aabb 101iiiii => STWI +1111_aabb 010iiiii => POPB +1111_aabb 011iiiii => POPW +1111_aabb 110iiiii => PSHB +1111_aabb 111iiiii => PSHW Encoding branch conditions: @@ -32,12 +44,12 @@ This is natural for lt/gt, and the comparison for eq/ne etc. just needs 1 LUT4. Load/store should use register pairs, and then specific registers numbers can encode whether it should use the larger instructions. -Skip is valuable because it lets you implement wider add/sub with a relatively short instruction sequence. +Skip is valuable because it lets you implement wider add/sub with a relatively short instruction sequence, in particular this wide add is 4 bytes not 5. For instance, you can do: a1 = a1 + b1 a2 = a2 + b2 -skip if b1 ule a1 -a2 = inc a2 +branch if b1 ule a1 +a2 = a2 + 1 to compute [a2:a1] + [b2:b1] -- 2.47.0