Made the VM turing complete, lots more to add
This commit is contained in:
parent
eff07ba783
commit
277f7db7e1
208
vm.c
208
vm.c
|
@ -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
34
vm.h
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue