Expanded Instruction set

This commit is contained in:
Jeremiah Orians 2016-06-05 22:08:28 -04:00
parent 14e4c6746a
commit 7ce6a98931
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
5 changed files with 130 additions and 62 deletions

View File

@ -236,23 +236,28 @@
1OPI i ii ii is the Immediate, a = a OP i ii ii
*** Conditional Integer Jumps
2C 0a ii ii # JUMP.C a i ii ii :: Carry? a; PC = PC + i ii ii
2C 1a ii ii # JUMP.B a i ii ii :: Borrow? a; PC = PC + i ii ii
2C 2a ii ii # JUMP.O a i ii ii :: Overflow? a; PC = PC + i ii ii
2C 3a ii ii # JUMP.G a i ii ii :: GT? a; PC = PC + i ii ii
2C 4a ii ii # JUMP.GE a i ii ii :: GT? a | EQ? a; PC = PC + i ii ii
2C 5a ii ii # JUMP.E a i ii ii :: EQ? a; PC = PC + i ii ii
2C 6a ii ii # JUMP.NE a i ii ii :: NEQ? a; PC = PC + i ii ii
2C 7a ii ii # JUMP.LE a i ii ii :: LT? a | EQ? a; PC = PC + i ii ii
2C 8a ii ii # JUMP.L a i ii ii :: LT? a; PC = PC + i ii ii
2C 9a ii ii # JUMP.Z a i ii ii :: ZERO? a; PC = PC + i ii ii
2C Aa ii ii # JUMP.NZ a i ii ii :: NZERO? a; PC = PC + i ii ii
2C 0a ii ii # JUMP.C a ii ii :: Carry? a; PC = PC + i ii ii
2C 1a ii ii # JUMP.B a ii ii :: Borrow? a; PC = PC + i ii ii
2C 2a ii ii # JUMP.O a ii ii :: Overflow? a; PC = PC + i ii ii
2C 3a ii ii # JUMP.G a ii ii :: GT? a; PC = PC + i ii ii
2C 4a ii ii # JUMP.GE a ii ii :: GT? a | EQ? a; PC = PC + i ii ii
2C 5a ii ii # JUMP.E a ii ii :: EQ? a; PC = PC + i ii ii
2C 6a ii ii # JUMP.NE a ii ii :: NEQ? a; PC = PC + i ii ii
2C 7a ii ii # JUMP.LE a ii ii :: LT? a | EQ? a; PC = PC + i ii ii
2C 8a ii ii # JUMP.L a ii ii :: LT? a; PC = PC + i ii ii
2C 9a ii ii # JUMP.Z a ii ii :: ZERO? a; PC = PC + i ii ii
2C Aa ii ii # JUMP.NZ a ii ii :: NZERO? a; PC = PC + i ii ii
2C Bx xx xx # Reserved
2C Cx xx xx # Reserved
2C Dx xx xx # Reserved
2C Ex xx xx # Reserved
2C Fx xx xx # Reserved
*** Branch Immediates
2D 0a ii ii # CALLI a ii ii :: MEM[a] = PC; a = a + (register size in bytes); PC = PC + ii ii
2D 1a ii ii # LOADI a ii ii :: a = ii ii (signed)
2D 2a ii ii # LOADUI a ii ii :: a = ii ii (unsigned)
** 0OPI group
0OPI ii ii is the Immediate, OP ii ii

3
asm.c
View File

@ -287,6 +287,9 @@ void assemble(struct Token* p)
setExpression(p, "JUMP.L", "2C8", 4);
setExpression(p, "JUMP.Z", "2C9", 4);
setExpression(p, "JUMP.NZ", "2CA", 4);
setExpression(p, "CALLI", "2D0", 4);
setExpression(p, "LOADI", "2D1", 4);
setExpression(p, "LOADUI", "2D2", 4);
/* 0OPI Group */
setExpression(p, "JUMP", "3C00", 4);

View File

@ -653,7 +653,7 @@ void decode_Integer_2OPI(struct Instruction* c)
}
case 0x12: /* CMPI */
{
strncpy(Name, "", 19);
strncpy(Name, "CMPI", 19);
break;
}
case 0x13: /* LOAD */
@ -824,6 +824,49 @@ void decode_1OPI(struct Instruction* c)
fprintf(stdout, "# %s\n", c->operation);
}
void decode_Branch_1OPI(struct Instruction* c)
{
/* Parse Raw Data */
c->raw_Immediate = c->raw2*0x100 + c->raw3;
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->raw_XOP = c->raw1/16;
c->reg0 = c->raw1%16;
char Name[20] = "ILLEGAL_1OPI";
/* Convert to Human readable form */
switch(c->raw_XOP)
{
case 0x0: /* CALLI */
{
strncpy(Name, "CALLI", 19);
break;
}
case 0x1: /* LOADI */
{
strncpy(Name, "LOADI", 19);
break;
}
case 0x2: /* LOADUI */
{
strncpy(Name, "LOADUI", 19);
break;
}
default: /* Unknown 1OPI*/
{
break;
}
}
fprintf(stdout, "%s reg%o %d\t", Name, c->reg0, c->raw_Immediate);
fprintf(stdout, "# %s\n", c->operation);
}
void decode_0OPI(struct Instruction* c)
{
/* Parse Raw Data */
@ -941,6 +984,11 @@ void eval_instruction(struct Instruction* c)
decode_1OPI(c);
break;
}
case 0x2D: /* Branch 1OPI*/
{
decode_Branch_1OPI(c);
break;
}
case 0x3C: /* Core 0OPI */
{
decode_0OPI(c);

94
vm.c
View File

@ -838,17 +838,8 @@ bool eval_2OP_Int(struct lilith* vm, struct Instruction* c)
}
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;
writeout_Reg(vm, vm->reg[c->reg1], vm->ip);
/* Update PC */
vm->ip = vm->reg[c->reg0];
@ -856,17 +847,11 @@ bool eval_2OP_Int(struct lilith* vm, struct Instruction* c)
}
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);
writeout_Reg(vm, vm->reg[c->reg1], vm->ip);
/* Update our index */
vm->reg[c->reg1] = utmp1 + 4;
vm->reg[c->reg1] = vm->reg[c->reg1] + 4;
/* Update PC */
vm->ip = vm->reg[c->reg0];
@ -910,43 +895,29 @@ bool eval_1OP_Int(struct lilith* vm, struct Instruction* c)
}
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];
vm->ip = readin_Reg(vm, vm->reg[c->reg0]);
/* Update our index */
vm->reg[c->reg0] = utmp1 - 4;
vm->reg[c->reg0] = vm->reg[c->reg0] - 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);
writeout_Reg(vm, vm->reg[c->reg0], vm->ip);
/* Update our index */
vm->reg[c->reg0] = utmp1 + 4;
vm->reg[c->reg0] = vm->reg[c->reg0] + 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];
vm->ip = readin_Reg(vm, vm->reg[c->reg0]);
/* Update our index */
vm->reg[c->reg0] = utmp1 - 4;
vm->reg[c->reg0] = vm->reg[c->reg0] - 4;
break;
}
default: return true;
@ -1007,7 +978,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
}
case 0x13: /* LOAD */
{
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0);
vm->reg[c->reg0] = readin_Reg(vm, (utmp1 + c->raw_Immediate));
break;
}
case 0x14: /* LOAD8 */
@ -1051,7 +1022,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
case 0x18: /* LOAD32 */
case 0x19: /* LOADU32 */
{
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0);
vm->reg[c->reg0] = readin_Reg(vm, (utmp1 + c->raw_Immediate));
break;
}
case 0x1F: /* CMPUI */
@ -1074,7 +1045,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
}
case 0x20: /* STORE */
{
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0);
writeout_Reg(vm, (utmp1 + c->raw_Immediate), vm->reg[c->reg0]);
break;
}
case 0x21: /* STORE8 */
@ -1118,7 +1089,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
case 0x25: /* STORE32 */
case 0x26: /* STOREU32 */
{
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0);
writeout_Reg(vm, (utmp1 + c->raw_Immediate), vm->reg[c->reg0]);
break;
}
default: return true;
@ -1248,6 +1219,38 @@ bool eval_Integer_1OPI(struct lilith* vm, struct Instruction* c)
return false;
}
bool eval_branch_1OPI(struct lilith* vm, struct Instruction* c)
{
switch(c->raw_XOP)
{
case 0x0: /* CALLI */
{
/* Write out the PC */
writeout_Reg(vm, vm->reg[c->reg0], vm->ip);
/* Update our index */
vm->reg[c->reg0] = vm->reg[c->reg0] + 4;
/* Update PC */
vm->ip = vm->ip + c->raw_Immediate - 4;
break;
}
case 0x1: /* LOADI */
{
vm->reg[c->reg0] = (int16_t)c->raw_Immediate;
break;
}
case 0x2: /* LOADUI*/
{
vm->reg[c->reg0] = c->raw_Immediate;
break;
}
default: return true;
}
return false;
}
/* Process 0OPI Integer instructions */
bool eval_Integer_0OPI(struct lilith* vm, struct Instruction* c)
{
@ -1316,6 +1319,13 @@ void eval_instruction(struct lilith* vm, struct Instruction* current)
if ( invalid) goto fail;
break;
}
case 0x2D:
{
decode_1OPI(current);
invalid = eval_branch_1OPI(vm, current);
if ( invalid) goto fail;
break;
}
case 0x3C: /* JUMP */
{
decode_0OPI(current);

18
vm.h
View File

@ -177,10 +177,10 @@ void unpack_instruction(struct Instruction* c)
c->opcode[1] = c->operation[1];
}
void writeout_Reg(struct lilith* vm, uint32_t p, uint8_t r)
void writeout_Reg(struct lilith* vm, uint32_t p, uint32_t value)
{
uint8_t raw0, raw1, raw2, raw3;
uint32_t tmp = vm->reg[r];
uint32_t tmp = value;
raw3 = tmp%0x100;
tmp = tmp/0x100;
raw2 = tmp%0x100;
@ -195,16 +195,18 @@ void writeout_Reg(struct lilith* vm, uint32_t p, uint8_t r)
vm->memory[p + 3] = raw3;
}
void readin_Reg(struct lilith* vm, uint32_t p, uint8_t r)
uint32_t readin_Reg(struct lilith* vm, uint32_t p)
{
uint8_t raw0, raw1, raw2, raw3;
uint8_t raw0, raw1, raw2, raw3, sum;
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;
sum = raw0*0x1000000 +
raw1*0x10000 +
raw2*0x100 +
raw3;
return sum;
}