Made the VM turing complete, lots more to add

This commit is contained in:
Jeremiah Orians 2016-05-29 18:08:58 -04:00
parent eff07ba783
commit 277f7db7e1
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
2 changed files with 220 additions and 22 deletions

208
vm.c
View File

@ -46,11 +46,70 @@ bool eval_4OP_Int(struct lilith* vm, struct Instruction* c)
/* Process 3OP Integer instructions */
bool eval_3OP_Int(struct lilith* vm, struct Instruction* c)
{
int64_t tmp1, tmp2;
uint64_t utmp1, utmp2;
tmp1 = (int64_t)(vm->reg[c->reg1]);
tmp2 = (int64_t)(vm->reg[c->reg2]);
utmp1 = vm->reg[c->reg1];
utmp2 = vm->reg[c->reg2];
switch(c->raw_XOP)
{
case 0x000: /* ADD */
{
vm->reg[c->reg0] = vm->reg[c->reg1] + vm->reg[c->reg2];
vm->reg[c->reg0] = (int64_t)(tmp1 + tmp2);
break;
}
case 0x001: /* ADDU */
{
vm->reg[c->reg0] = utmp1 + utmp2;
break;
}
case 0x002: /* SUB */
{
vm->reg[c->reg0] = (int64_t)(tmp1 - tmp2);
break;
}
case 0x003: /* SUBU */
{
vm->reg[c->reg0] = utmp1 - utmp2;
break;
}
case 0x004: /* CMP */
{
/* Clear bottom 3 bits of condition register */
vm->reg[c->reg0] = vm->reg[c->reg0] & 0xFFFFFFFFFFFFFFF8;
if(tmp1 > tmp2)
{
vm->reg[c->reg0] = vm->reg[c->reg0] | GreaterThan;
}
else if(tmp1 == tmp2)
{
vm->reg[c->reg0] = vm->reg[c->reg0] | EQual;
}
else
{
vm->reg[c->reg0] = vm->reg[c->reg0] | LessThan;
}
break;
}
case 0x005: /* CMPU */
{
/* Clear bottom 3 bits of condition register */
vm->reg[c->reg0] = vm->reg[c->reg0] & 0xFFFFFFFFFFFFFFF8;
if(utmp1 > utmp2)
{
vm->reg[c->reg0] = vm->reg[c->reg0] | GreaterThan;
}
else if(utmp1 == utmp2)
{
vm->reg[c->reg0] = vm->reg[c->reg0] | EQual;
}
else
{
vm->reg[c->reg0] = vm->reg[c->reg0] | LessThan;
}
break;
}
default: return true;
@ -73,17 +132,138 @@ bool eval_1OP_Int(struct lilith* vm, struct Instruction* c)
/* Process 2OPI Integer instructions */
bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
{
int64_t tmp1;
uint64_t utmp1;
tmp1 = (int64_t)(vm->reg[c->reg1]);
utmp1 = vm->reg[c->reg1];
/* 0x0E ... 0x2B */
switch(c->raw0)
{
case 0x0E: /* ADDI */
{
vm->reg[c->reg0] = (int8_t)(vm->reg[c->reg1] + c->raw_Immediate);
vm->reg[c->reg0] = (int64_t)(tmp1 + c->raw_Immediate);
break;
}
case 0x0F: /* ADDUI */
{
vm->reg[c->reg0] = vm->reg[c->reg1] + c->raw_Immediate; break;
vm->reg[c->reg0] = utmp1 + c->raw_Immediate;
break;
}
case 0x10: /* SUB */
{
vm->reg[c->reg0] = (int64_t)(tmp1 - c->raw_Immediate);
break;
}
case 0x11: /* SUBU */
{
vm->reg[c->reg0] = utmp1 + c->raw_Immediate;
break;
}
default: return true;
}
return false;
}
/* Process 1OPI instructions */
bool eval_1OPI(struct lilith* vm, struct Instruction* c)
{
bool C, B, O, GT, EQ, LT;
uint64_t tmp;
tmp = vm->reg[c->reg0];
C = tmp & Carry;
B = tmp & Borrow;
O = tmp & Overflow;
GT = tmp & GreaterThan;
EQ = tmp & EQual;
LT = tmp & LessThan;
/* 0x2C ... 0x3B */
switch(c->raw0)
{
case 0x2C: /*JMP.C*/
{
if(1 == C)
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
case 0x2D: /*JMP.B*/
{
if(1 == B)
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
case 0x2E: /*JMP.O*/
{
if(1 == O)
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
case 0x2F: /*JMP.G*/
{
if(1 == GT)
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
case 0x30: /*JMP.GE*/
{
if((1 == GT) || (1 == EQ))
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
case 0x31: /*JMP.E*/
{
if(1 == EQ)
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
case 0x32: /*JMP.NE*/
{
if(1 != EQ)
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
case 0x33: /*JMP.LE*/
{
if((1 == EQ) || (1 == LT))
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
case 0x34: /*JMP.L*/
{
if(1 == LT)
{
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + c->raw_Immediate - 4;
}
break;
}
default: return true;
}
@ -99,7 +279,6 @@ void eval_instruction(struct lilith* vm, struct Instruction* current)
{
case 0x00: /* Deal with NOPs */
{
vm->halted = true;
return;
}
case 0x01:
@ -137,17 +316,30 @@ void eval_instruction(struct lilith* vm, struct Instruction* current)
if ( invalid) goto fail;
break;
}
case 0x2C:
case 0x2C ... 0x3B:
{
decode_1OPI(current);
invalid = eval_1OPI(vm, current);
if ( invalid) goto fail;
break;
}
case 0x3C:
case 0x3C: /* JUMP */
{
decode_0OPI(current);
/* Adust the IP relative the the start of this instruction*/
vm->ip = vm->ip + current->raw_Immediate - 4;
break;
}
case 0x42:
{
}
case 0xFF: /* Deal with illegal instruction */
default:
case 0xFF: /* Deal with HALT */
{
vm->halted = true;
fprintf(stderr, "Computer Program has Halted\n");
break;
}
default: /* Deal with illegal instruction */
{
fail:
fprintf(stderr, "Unable to execute the following instruction:\n%c %c %c %c\n", current->raw0, current->raw1, current->raw2, current->raw3);

34
vm.h
View File

@ -23,7 +23,7 @@ struct Instruction
uint32_t raw_XOP;
char XOP[6];
char operation[9];
uint32_t raw_Immediate;
int32_t raw_Immediate;
char Immediate[7];
uint32_t HAL_CODE;
uint8_t reg0;
@ -36,11 +36,11 @@ struct Instruction
/* Condition Codes */
enum condition
{
Carry = 1 << 5,
Borrow = 1 << 4,
Overflow = 1 << 3,
GreaterThan = 1 << 2,
EQual = 1 << 1,
Carry = (1 << 5),
Borrow = (1 << 4),
Overflow = (1 << 3),
GreaterThan = (1 << 2),
EQual = (1 << 1),
LessThan = 1
};
@ -78,7 +78,7 @@ void decode_4OP(struct Instruction* c)
/* Deal with 3OP */
void decode_3OP(struct Instruction* c)
{
c->raw_XOP = c->raw1*16 + c->raw2/16;
c->raw_XOP = c->raw1*0x10 + c->raw2/16;
c->XOP[0] = c->operation[2];
c->XOP[1] = c->operation[3];
c->XOP[2] = c->operation[4];
@ -91,7 +91,7 @@ void decode_3OP(struct Instruction* c)
/* Deal with 2OP */
void decode_2OP(struct Instruction* c)
{
c->raw_XOP = c->raw1*256 + c->raw2;
c->raw_XOP = c->raw1*0x100 + c->raw2;
c->XOP[0] = c->operation[2];
c->XOP[1] = c->operation[3];
c->XOP[2] = c->operation[4];
@ -104,7 +104,7 @@ void decode_2OP(struct Instruction* c)
/* Deal with 1OP */
void decode_1OP(struct Instruction* c)
{
c->raw_XOP = c->raw1*4096 + c->raw2*16 + c->raw3/16;
c->raw_XOP = c->raw1*0x1000 + c->raw2*0x10 + c->raw3/16;
c->XOP[0] = c->operation[2];
c->XOP[1] = c->operation[3];
c->XOP[2] = c->operation[4];
@ -117,7 +117,7 @@ void decode_1OP(struct Instruction* c)
/* Deal with 2OPI */
void decode_2OPI(struct Instruction* c)
{
c->raw_Immediate = c->raw2*256 + c->raw3;
c->raw_Immediate = c->raw2*0x100 + c->raw3;
c->Immediate[0] = c->operation[4];
c->Immediate[1] = c->operation[5];
c->Immediate[2] = c->operation[6];
@ -129,19 +129,25 @@ void decode_2OPI(struct Instruction* c)
/* Deal with 1OPI */
void decode_1OPI(struct Instruction* c)
{
c->raw_Immediate = (c->raw1%16)*4096 + c->raw2*256 + c->raw3;
c->raw_Immediate = (c->raw1%16)*0x10000 + c->raw2*0x100 + c->raw3;
/* Sign extend immediate*/
c->raw_Immediate = c->raw_Immediate << 12;
c->raw_Immediate = c->raw_Immediate >> 12;
c->Immediate[0] = c->operation[3];
c->Immediate[1] = c->operation[4];
c->Immediate[2] = c->operation[5];
c->Immediate[3] = c->operation[6];
c->Immediate[4] = c->operation[7];
c->HAL_CODE = 0;
c->reg0 = c->raw1/16;
c->reg0 = c->raw3/16;
}
/* Deal with 0OPI */
void decode_0OPI(struct Instruction* c)
{
c->raw_Immediate = c->raw1*4096 + c->raw2*256 + c->raw3;
c->raw_Immediate = c->raw1*0x10000 + c->raw2*0x100 + c->raw3;
/* Sign extend immediate*/
c->raw_Immediate = c->raw_Immediate << 8;
c->raw_Immediate = c->raw_Immediate >> 8;
c->Immediate[0] = c->operation[2];
c->Immediate[1] = c->operation[3];
c->Immediate[2] = c->operation[4];
@ -153,7 +159,7 @@ void decode_0OPI(struct Instruction* c)
/* Deal with Halcode */
void decode_HALCODE(struct Instruction* c)
{
c->HAL_CODE = c->raw1*4096 + c->raw2*256 + c->raw3;
c->HAL_CODE = c->raw1*0x10000 + c->raw2*0x100 + c->raw3;
}
/* Useful unpacking functions */