Implemented Missing instructions from Logic, stack and math

This commit is contained in:
Jeremiah Orians 2016-05-30 12:38:02 -04:00
parent 56543ca5c6
commit 63d9d2fb54
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
3 changed files with 216 additions and 28 deletions

View File

@ -81,8 +81,9 @@
09 00 06 xx # Reserved 09 00 06 xx # Reserved
... ...
09 00 FF xx # Reserved 09 00 FF xx # Reserved
09 01 00 ab # BRANCH a b :: Mem[b] = PC; PC = a 09 01 00 ab # BRANCH a b :: MEM[b] = PC; PC = a
09 01 01 xx # Reserved 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 09 FF FF xx # Reserved
0A nn nn ab # 2OP Floating group 0A nn nn ab # 2OP Floating group
@ -99,7 +100,13 @@
... ...
0D 00 FF Fx # Reserved 0D 00 FF Fx # Reserved
0D 01 00 0a # JSR_COROUTINE a; PC = a 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 0D FF FF Fx # Reserved

199
vm.c
View File

@ -114,50 +114,98 @@ bool eval_3OP_Int(struct lilith* vm, struct Instruction* c)
} }
case 0x006: /* MUL */ case 0x006: /* MUL */
{ {
int64_t sum = tmp1 * tmp2;
/* We only want the bottom 32bits */
vm->reg[c->reg0] = sum % 0x100000000;
break; break;
} }
case 0x007: /* MULH */ case 0x007: /* MULH */
{ {
int64_t sum = tmp1 * tmp2;
/* We only want the top 32bits */
vm->reg[c->reg0] = sum / 0x100000000;
break; break;
} }
case 0x008: /* MULU */ case 0x008: /* MULU */
{ {
uint64_t sum = tmp1 * tmp2;
/* We only want the bottom 32bits */
vm->reg[c->reg0] = sum % 0x100000000;
break; break;
} }
case 0x009: /* MULUH */ case 0x009: /* MULUH */
{ {
uint64_t sum = tmp1 * tmp2;
/* We only want the top 32bits */
vm->reg[c->reg0] = sum / 0x100000000;
break; break;
} }
case 0x00A: /* DIV */ case 0x00A: /* DIV */
{ {
vm->reg[c->reg0] = tmp1 / tmp2;
break; break;
} }
case 0x00B: /* MOD */ case 0x00B: /* MOD */
{ {
vm->reg[c->reg0] = tmp1 % tmp2;
break; break;
} }
case 0x00C: /* DIVU */ case 0x00C: /* DIVU */
{ {
vm->reg[c->reg0] = utmp1 / utmp2;
break; break;
} }
case 0x00D: /* MODU */ case 0x00D: /* MODU */
{ {
vm->reg[c->reg0] = utmp1 % utmp2;
break; break;
} }
case 0x010: /* MAX */ case 0x010: /* MAX */
{ {
if(tmp1 > tmp2)
{
vm->reg[c->reg0] = tmp1;
}
else
{
vm->reg[c->reg0] = tmp2;
}
break; break;
} }
case 0x011: /* MAXU */ case 0x011: /* MAXU */
{ {
if(utmp1 > utmp2)
{
vm->reg[c->reg0] = utmp1;
}
else
{
vm->reg[c->reg0] = utmp2;
}
break; break;
} }
case 0x012: /* MIN */ case 0x012: /* MIN */
{ {
if(tmp1 < tmp2)
{
vm->reg[c->reg0] = tmp1;
}
else
{
vm->reg[c->reg0] = tmp2;
}
break; break;
} }
case 0x013: /* MINU */ case 0x013: /* MINU */
{ {
if(utmp1 < utmp2)
{
vm->reg[c->reg0] = utmp1;
}
else
{
vm->reg[c->reg0] = utmp2;
}
break; break;
} }
case 0x014: /* PACK */ case 0x014: /* PACK */
@ -194,42 +242,52 @@ bool eval_3OP_Int(struct lilith* vm, struct Instruction* c)
} }
case 0x020: /* AND */ case 0x020: /* AND */
{ {
vm->reg[c->reg0] = utmp1 & utmp2;
break; break;
} }
case 0x021: /* OR */ case 0x021: /* OR */
{ {
vm->reg[c->reg0] = utmp1 | utmp2;
break; break;
} }
case 0x022: /* XOR */ case 0x022: /* XOR */
{ {
vm->reg[c->reg0] = utmp1 ^ utmp2;
break; break;
} }
case 0x023: /* NAND */ case 0x023: /* NAND */
{ {
vm->reg[c->reg0] = ~(utmp1 & utmp2);
break; break;
} }
case 0x024: /* NOR */ case 0x024: /* NOR */
{ {
vm->reg[c->reg0] = ~(utmp1 | utmp2);
break; break;
} }
case 0x025: /* XNOR */ case 0x025: /* XNOR */
{ {
vm->reg[c->reg0] = ~(utmp1 ^ utmp2);
break; break;
} }
case 0x026: /* MPQ */ case 0x026: /* MPQ */
{ {
vm->reg[c->reg0] = (~utmp1) & utmp2;
break; break;
} }
case 0x027: /* LPQ */ case 0x027: /* LPQ */
{ {
vm->reg[c->reg0] = utmp1 & (~utmp2);
break; break;
} }
case 0x028: /* CPQ */ case 0x028: /* CPQ */
{ {
vm->reg[c->reg0] = (~utmp1) | utmp2;
break; break;
} }
case 0x029: /* BPQ */ case 0x029: /* BPQ */
{ {
vm->reg[c->reg0] = utmp1 | (~utmp2);
break; break;
} }
case 0x030: /* SAL */ case 0x030: /* SAL */
@ -272,34 +330,91 @@ bool eval_3OP_Int(struct lilith* vm, struct Instruction* c)
/* Process 2OP Integer instructions */ /* Process 2OP Integer instructions */
bool eval_2OP_Int(struct lilith* vm, struct Instruction* c) 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) switch(c->raw_XOP)
{ {
case 0x0000: /* NEG */ case 0x0000: /* NEG */
{ {
vm->reg[c->reg0] = tmp1*-1;
break; break;
} }
case 0x0001: /* ABS */ case 0x0001: /* ABS */
{ {
if(0 <= tmp1)
{
vm->reg[c->reg0] = tmp1;
}
else
{
vm->reg[c->reg0] = tmp1*-1;
}
break; break;
} }
case 0x0002: /* NABS */ case 0x0002: /* NABS */
{ {
if(0 > tmp1)
{
vm->reg[c->reg0] = tmp1;
}
else
{
vm->reg[c->reg0] = tmp1*-1;
}
break; break;
} }
case 0x0003: /* SWAP */ case 0x0003: /* SWAP */
{ {
vm->reg[c->reg1] = vm->reg[c->reg0];
vm->reg[c->reg0] = utmp1;
break; break;
} }
case 0x0004: /* COPY */ case 0x0004: /* COPY */
{ {
vm->reg[c->reg0] = utmp1;
break; break;
} }
case 0x0005: /* MOVE */ case 0x0005: /* MOVE */
{ {
vm->reg[c->reg0] = utmp1;
vm->reg[c->reg1] = 0;
break; break;
} }
case 0x0100: /* BRANCH */ 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; break;
} }
default: return true; default: return true;
@ -314,22 +429,69 @@ bool eval_1OP_Int(struct lilith* vm, struct Instruction* c)
{ {
case 0x00000: /* READPC */ case 0x00000: /* READPC */
{ {
vm->reg[c->reg0] = vm->ip;
break; break;
} }
case 0x00001: /* READSCID */ case 0x00001: /* READSCID */
{ {
/* We only support Base 8,16 and 32*/
vm->reg[c->reg0] = 0x00000007;
break; break;
} }
case 0x00002: /* FALSE */ case 0x00002: /* FALSE */
{ {
vm->reg[c->reg0] = 0;
break; break;
} }
case 0x00003: /* TRUE */ case 0x00003: /* TRUE */
{ {
vm->reg[c->reg0] = 0xFFFFFFFF;
break; break;
} }
case 0x01000: /* JSR_COROUTINE */ 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; break;
} }
default: return true; default: return true;
@ -388,6 +550,11 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
} }
break; break;
} }
case 0x13: /* LOAD */
{
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0);
break;
}
case 0x14: /* LOAD8 */ case 0x14: /* LOAD8 */
{ {
raw0 = vm->memory[utmp1 + c->raw_Immediate]; 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 0x18: /* LOAD32 */
case 0x19: /* LOADU32 */ case 0x19: /* LOADU32 */
case 0x13: /* LOAD */
{ {
raw0 = vm->memory[utmp1 + c->raw_Immediate]; readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0);
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;
break; break;
} }
case 0x1F: /* CMPUI */ case 0x1F: /* CMPUI */
@ -459,6 +617,11 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
} }
break; break;
} }
case 0x20: /* STORE */
{
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0);
break;
}
case 0x21: /* STORE8 */ case 0x21: /* STORE8 */
{ {
int32_t tmp = (int8_t)(vm->reg[c->reg0]); 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 0x25: /* STORE32 */
case 0x26: /* STOREU32 */ case 0x26: /* STOREU32 */
case 0x20: /* STORE */
{ {
uint32_t tmp = vm->reg[c->reg0]; writeout_Reg(vm, (utmp1 + c->raw_Immediate), 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;
break; break;
} }
default: return true; default: return true;

32
vm.h
View File

@ -179,3 +179,35 @@ void unpack_instruction(struct Instruction* c)
c->opcode[0] = c->operation[0]; c->opcode[0] = c->operation[0];
c->opcode[1] = c->operation[1]; 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;
}