From 63d9d2fb541f85d5505803429787a021b33bb1c2 Mon Sep 17 00:00:00 2001 From: Jeremiah Orians Date: Mon, 30 May 2016 12:38:02 -0400 Subject: [PATCH] Implemented Missing instructions from Logic, stack and math --- ISA_HEX_Map.txt | 13 +++- vm.c | 199 ++++++++++++++++++++++++++++++++++++++++++------ vm.h | 32 ++++++++ 3 files changed, 216 insertions(+), 28 deletions(-) diff --git a/ISA_HEX_Map.txt b/ISA_HEX_Map.txt index a620bde..8794a9b 100644 --- a/ISA_HEX_Map.txt +++ b/ISA_HEX_Map.txt @@ -81,8 +81,9 @@ 09 00 06 xx # Reserved ... 09 00 FF xx # Reserved -09 01 00 ab # BRANCH a b :: Mem[b] = PC; PC = a -09 01 01 xx # Reserved +09 01 00 ab # BRANCH a b :: MEM[b] = PC; PC = a +09 01 01 ab # CALL a b :: MEM[b] = PC; b = b + (register size in bytes); PC = a +09 01 02 xx # Reserved ... 09 FF FF xx # Reserved 0A nn nn ab # 2OP Floating group @@ -99,7 +100,13 @@ ... 0D 00 FF Fx # Reserved 0D 01 00 0a # JSR_COROUTINE a; PC = a -0D 01 00 1x # Reserved +0D 01 00 1a # RET a :: PC = MEM[a]; a = a - (register size in bytes) +0D 01 00 2x # Reserved +... +0D 01 FF Fx # Reserved +0D 02 00 0a # PUSHPC a :: MEM[a] = PC; a = a + (register size in bytes) +0D 02 00 1a # POPPC a :: PC = MEM[a]; a = a - (register size in bytes) +0D 02 00 2x # Reserved ... 0D FF FF Fx # Reserved diff --git a/vm.c b/vm.c index 3190c0d..cf70bc2 100644 --- a/vm.c +++ b/vm.c @@ -114,50 +114,98 @@ bool eval_3OP_Int(struct lilith* vm, struct Instruction* c) } case 0x006: /* MUL */ { + int64_t sum = tmp1 * tmp2; + /* We only want the bottom 32bits */ + vm->reg[c->reg0] = sum % 0x100000000; break; } case 0x007: /* MULH */ { + int64_t sum = tmp1 * tmp2; + /* We only want the top 32bits */ + vm->reg[c->reg0] = sum / 0x100000000; break; } case 0x008: /* MULU */ { + uint64_t sum = tmp1 * tmp2; + /* We only want the bottom 32bits */ + vm->reg[c->reg0] = sum % 0x100000000; break; } case 0x009: /* MULUH */ { + uint64_t sum = tmp1 * tmp2; + /* We only want the top 32bits */ + vm->reg[c->reg0] = sum / 0x100000000; break; } case 0x00A: /* DIV */ { + vm->reg[c->reg0] = tmp1 / tmp2; break; } case 0x00B: /* MOD */ { + vm->reg[c->reg0] = tmp1 % tmp2; break; } case 0x00C: /* DIVU */ { + vm->reg[c->reg0] = utmp1 / utmp2; break; } case 0x00D: /* MODU */ { + vm->reg[c->reg0] = utmp1 % utmp2; break; } case 0x010: /* MAX */ { + if(tmp1 > tmp2) + { + vm->reg[c->reg0] = tmp1; + } + else + { + vm->reg[c->reg0] = tmp2; + } break; } case 0x011: /* MAXU */ { + if(utmp1 > utmp2) + { + vm->reg[c->reg0] = utmp1; + } + else + { + vm->reg[c->reg0] = utmp2; + } break; } case 0x012: /* MIN */ { + if(tmp1 < tmp2) + { + vm->reg[c->reg0] = tmp1; + } + else + { + vm->reg[c->reg0] = tmp2; + } break; } case 0x013: /* MINU */ { + if(utmp1 < utmp2) + { + vm->reg[c->reg0] = utmp1; + } + else + { + vm->reg[c->reg0] = utmp2; + } break; } case 0x014: /* PACK */ @@ -194,42 +242,52 @@ bool eval_3OP_Int(struct lilith* vm, struct Instruction* c) } case 0x020: /* AND */ { + vm->reg[c->reg0] = utmp1 & utmp2; break; } case 0x021: /* OR */ { + vm->reg[c->reg0] = utmp1 | utmp2; break; } case 0x022: /* XOR */ { + vm->reg[c->reg0] = utmp1 ^ utmp2; break; } case 0x023: /* NAND */ { + vm->reg[c->reg0] = ~(utmp1 & utmp2); break; } case 0x024: /* NOR */ { + vm->reg[c->reg0] = ~(utmp1 | utmp2); break; } case 0x025: /* XNOR */ { + vm->reg[c->reg0] = ~(utmp1 ^ utmp2); break; } case 0x026: /* MPQ */ { + vm->reg[c->reg0] = (~utmp1) & utmp2; break; } case 0x027: /* LPQ */ { + vm->reg[c->reg0] = utmp1 & (~utmp2); break; } case 0x028: /* CPQ */ { + vm->reg[c->reg0] = (~utmp1) | utmp2; break; } case 0x029: /* BPQ */ { + vm->reg[c->reg0] = utmp1 | (~utmp2); break; } case 0x030: /* SAL */ @@ -272,34 +330,91 @@ bool eval_3OP_Int(struct lilith* vm, struct Instruction* c) /* Process 2OP Integer instructions */ bool eval_2OP_Int(struct lilith* vm, struct Instruction* c) { + int32_t tmp1 = (int32_t)(vm->reg[c->reg1]); + uint32_t utmp1 = vm->reg[c->reg1]; + switch(c->raw_XOP) { case 0x0000: /* NEG */ { + vm->reg[c->reg0] = tmp1*-1; break; } case 0x0001: /* ABS */ { + if(0 <= tmp1) + { + vm->reg[c->reg0] = tmp1; + } + else + { + vm->reg[c->reg0] = tmp1*-1; + } break; } case 0x0002: /* NABS */ { + if(0 > tmp1) + { + vm->reg[c->reg0] = tmp1; + } + else + { + vm->reg[c->reg0] = tmp1*-1; + } break; } case 0x0003: /* SWAP */ { + vm->reg[c->reg1] = vm->reg[c->reg0]; + vm->reg[c->reg0] = utmp1; break; } case 0x0004: /* COPY */ { + vm->reg[c->reg0] = utmp1; break; } case 0x0005: /* MOVE */ { + vm->reg[c->reg0] = utmp1; + vm->reg[c->reg1] = 0; break; } case 0x0100: /* BRANCH */ { + /* Preserve index */ + uint32_t utmp1 = vm->reg[c->reg1]; + + /* Use the index register to store the PC for upload to MEM */ + vm->reg[c->reg1] = vm->ip; + + /* Write out the PC */ + writeout_Reg(vm, utmp1, c->reg1); + + /* Restore our index */ + vm->reg[c->reg1] = utmp1; + + /* Update PC */ + vm->ip = vm->reg[c->reg0]; + break; + } + case 0x0101: /* CALL */ + { + /* Preserve index */ + uint32_t utmp1 = vm->reg[c->reg1]; + + /* Use the index register to store the PC for upload to MEM */ + vm->reg[c->reg1] = vm->ip; + + /* Write out the PC */ + writeout_Reg(vm, utmp1, c->reg1); + + /* Update our index */ + vm->reg[c->reg1] = utmp1 + 4; + + /* Update PC */ + vm->ip = vm->reg[c->reg0]; break; } default: return true; @@ -314,22 +429,69 @@ bool eval_1OP_Int(struct lilith* vm, struct Instruction* c) { case 0x00000: /* READPC */ { + vm->reg[c->reg0] = vm->ip; break; } case 0x00001: /* READSCID */ { + /* We only support Base 8,16 and 32*/ + vm->reg[c->reg0] = 0x00000007; break; } case 0x00002: /* FALSE */ { + vm->reg[c->reg0] = 0; break; } case 0x00003: /* TRUE */ { + vm->reg[c->reg0] = 0xFFFFFFFF; break; } case 0x01000: /* JSR_COROUTINE */ { + vm->ip = vm->reg[c->reg0]; + break; + } + case 0x01001: /* RET */ + { + /* Preserve index */ + uint32_t utmp1 = vm->reg[c->reg0]; + + /* Read in the new PC */ + readin_Reg(vm, utmp1, c->reg0); + vm->ip = vm->reg[c->reg0]; + + /* Update our index */ + vm->reg[c->reg0] = utmp1 - 4; + break; + } + case 0x02000: /* PUSHPC */ + { + /* Preserve index */ + uint32_t utmp1 = vm->reg[c->reg0]; + + /* Use the index register to store the PC for upload to MEM */ + vm->reg[c->reg0] = vm->ip; + + /* Write out the PC */ + writeout_Reg(vm, utmp1, c->reg0); + + /* Update our index */ + vm->reg[c->reg0] = utmp1 + 4; + break; + } + case 0x02001: /* POPPC */ + { + /* Preserve index */ + uint32_t utmp1 = vm->reg[c->reg0]; + + /* Read in the new PC */ + readin_Reg(vm, utmp1, c->reg0); + vm->ip = vm->reg[c->reg0]; + + /* Update our index */ + vm->reg[c->reg0] = utmp1 - 4; break; } default: return true; @@ -388,6 +550,11 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c) } break; } + case 0x13: /* LOAD */ + { + readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0); + break; + } case 0x14: /* LOAD8 */ { raw0 = vm->memory[utmp1 + c->raw_Immediate]; @@ -428,17 +595,8 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c) } case 0x18: /* LOAD32 */ case 0x19: /* LOADU32 */ - case 0x13: /* LOAD */ { - raw0 = vm->memory[utmp1 + c->raw_Immediate]; - raw1 = vm->memory[utmp1 + c->raw_Immediate + 1]; - raw2 = vm->memory[utmp1 + c->raw_Immediate + 2]; - raw3 = vm->memory[utmp1 + c->raw_Immediate + 3]; - - vm->reg[c->reg0] = raw0*0x1000000 + - raw1*0x10000 + - raw2*0x100 + - raw3; + readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0); break; } case 0x1F: /* CMPUI */ @@ -459,6 +617,11 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c) } break; } + case 0x20: /* STORE */ + { + writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0); + break; + } case 0x21: /* STORE8 */ { int32_t tmp = (int8_t)(vm->reg[c->reg0]); @@ -499,22 +662,8 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c) } case 0x25: /* STORE32 */ case 0x26: /* STOREU32 */ - case 0x20: /* STORE */ { - uint32_t tmp = vm->reg[c->reg0]; - raw3 = tmp%0x100; - tmp = tmp/0x100; - raw2 = tmp%0x100; - tmp = tmp/0x100; - raw1 = tmp%0x100; - tmp = tmp/0x100; - raw0 = tmp%0x100; - - vm->memory[utmp1 + c->raw_Immediate] = raw0; - vm->memory[utmp1 + c->raw_Immediate + 1] = raw1; - vm->memory[utmp1 + c->raw_Immediate + 2] = raw2; - vm->memory[utmp1 + c->raw_Immediate + 3] = raw3; - + writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0); break; } default: return true; diff --git a/vm.h b/vm.h index 90463de..3a1349b 100644 --- a/vm.h +++ b/vm.h @@ -179,3 +179,35 @@ void unpack_instruction(struct Instruction* c) c->opcode[0] = c->operation[0]; c->opcode[1] = c->operation[1]; } + +void writeout_Reg(struct lilith* vm, uint32_t p, uint8_t r) +{ + uint8_t raw0, raw1, raw2, raw3; + uint32_t tmp = vm->reg[r]; + raw3 = tmp%0x100; + tmp = tmp/0x100; + raw2 = tmp%0x100; + tmp = tmp/0x100; + raw1 = tmp%0x100; + tmp = tmp/0x100; + raw0 = tmp%0x100; + + vm->memory[p] = raw0; + vm->memory[p + 1] = raw1; + vm->memory[p + 2] = raw2; + vm->memory[p + 3] = raw3; +} + +void readin_Reg(struct lilith* vm, uint32_t p, uint8_t r) +{ + uint8_t raw0, raw1, raw2, raw3; + raw0 = vm->memory[p]; + raw1 = vm->memory[p + 1]; + raw2 = vm->memory[p + 2]; + raw3 = vm->memory[p + 3]; + + vm->reg[r] = raw0*0x1000000 + + raw1*0x10000 + + raw2*0x100 + + raw3; +}