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 1OPI i ii ii is the Immediate, a = a OP i ii ii
*** Conditional Integer Jumps *** Conditional Integer Jumps
2C 0a ii ii # JUMP.C a i ii ii :: Carry? 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 i ii ii :: Borrow? 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 i ii ii :: Overflow? 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 i ii ii :: GT? 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 i ii ii :: GT? a | EQ? 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 i ii ii :: 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 i ii ii :: NEQ? 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 i ii ii :: LT? a | EQ? 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 i ii ii :: LT? 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 i ii ii :: ZERO? 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 i ii ii :: NZERO? 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 Bx xx xx # Reserved
2C Cx xx xx # Reserved 2C Cx xx xx # Reserved
2C Dx xx xx # Reserved 2C Dx xx xx # Reserved
2C Ex xx xx # Reserved 2C Ex xx xx # Reserved
2C Fx 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 group
0OPI ii ii is the Immediate, OP ii ii 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.L", "2C8", 4);
setExpression(p, "JUMP.Z", "2C9", 4); setExpression(p, "JUMP.Z", "2C9", 4);
setExpression(p, "JUMP.NZ", "2CA", 4); setExpression(p, "JUMP.NZ", "2CA", 4);
setExpression(p, "CALLI", "2D0", 4);
setExpression(p, "LOADI", "2D1", 4);
setExpression(p, "LOADUI", "2D2", 4);
/* 0OPI Group */ /* 0OPI Group */
setExpression(p, "JUMP", "3C00", 4); setExpression(p, "JUMP", "3C00", 4);

View File

@ -653,7 +653,7 @@ void decode_Integer_2OPI(struct Instruction* c)
} }
case 0x12: /* CMPI */ case 0x12: /* CMPI */
{ {
strncpy(Name, "", 19); strncpy(Name, "CMPI", 19);
break; break;
} }
case 0x13: /* LOAD */ case 0x13: /* LOAD */
@ -824,6 +824,49 @@ void decode_1OPI(struct Instruction* c)
fprintf(stdout, "# %s\n", c->operation); 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) void decode_0OPI(struct Instruction* c)
{ {
/* Parse Raw Data */ /* Parse Raw Data */
@ -941,6 +984,11 @@ void eval_instruction(struct Instruction* c)
decode_1OPI(c); decode_1OPI(c);
break; break;
} }
case 0x2D: /* Branch 1OPI*/
{
decode_Branch_1OPI(c);
break;
}
case 0x3C: /* Core 0OPI */ case 0x3C: /* Core 0OPI */
{ {
decode_0OPI(c); 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 */ 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 */ /* Write out the PC */
writeout_Reg(vm, utmp1, c->reg1); writeout_Reg(vm, vm->reg[c->reg1], vm->ip);
/* Restore our index */
vm->reg[c->reg1] = utmp1;
/* Update PC */ /* Update PC */
vm->ip = vm->reg[c->reg0]; vm->ip = vm->reg[c->reg0];
@ -856,17 +847,11 @@ bool eval_2OP_Int(struct lilith* vm, struct Instruction* c)
} }
case 0x0101: /* CALL */ 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 */ /* Write out the PC */
writeout_Reg(vm, utmp1, c->reg1); writeout_Reg(vm, vm->reg[c->reg1], vm->ip);
/* Update our index */ /* Update our index */
vm->reg[c->reg1] = utmp1 + 4; vm->reg[c->reg1] = vm->reg[c->reg1] + 4;
/* Update PC */ /* Update PC */
vm->ip = vm->reg[c->reg0]; vm->ip = vm->reg[c->reg0];
@ -910,43 +895,29 @@ bool eval_1OP_Int(struct lilith* vm, struct Instruction* c)
} }
case 0x01001: /* RET */ case 0x01001: /* RET */
{ {
/* Preserve index */
uint32_t utmp1 = vm->reg[c->reg0];
/* Read in the new PC */ /* Read in the new PC */
readin_Reg(vm, utmp1, c->reg0); vm->ip = readin_Reg(vm, vm->reg[c->reg0]);
vm->ip = vm->reg[c->reg0];
/* Update our index */ /* Update our index */
vm->reg[c->reg0] = utmp1 - 4; vm->reg[c->reg0] = vm->reg[c->reg0] - 4;
break; break;
} }
case 0x02000: /* PUSHPC */ 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 */ /* Write out the PC */
writeout_Reg(vm, utmp1, c->reg0); writeout_Reg(vm, vm->reg[c->reg0], vm->ip);
/* Update our index */ /* Update our index */
vm->reg[c->reg0] = utmp1 + 4; vm->reg[c->reg0] = vm->reg[c->reg0] + 4;
break; break;
} }
case 0x02001: /* POPPC */ case 0x02001: /* POPPC */
{ {
/* Preserve index */
uint32_t utmp1 = vm->reg[c->reg0];
/* Read in the new PC */ /* Read in the new PC */
readin_Reg(vm, utmp1, c->reg0); vm->ip = readin_Reg(vm, vm->reg[c->reg0]);
vm->ip = vm->reg[c->reg0];
/* Update our index */ /* Update our index */
vm->reg[c->reg0] = utmp1 - 4; vm->reg[c->reg0] = vm->reg[c->reg0] - 4;
break; break;
} }
default: return true; default: return true;
@ -1007,7 +978,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
} }
case 0x13: /* LOAD */ case 0x13: /* LOAD */
{ {
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0); vm->reg[c->reg0] = readin_Reg(vm, (utmp1 + c->raw_Immediate));
break; break;
} }
case 0x14: /* LOAD8 */ case 0x14: /* LOAD8 */
@ -1051,7 +1022,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
case 0x18: /* LOAD32 */ case 0x18: /* LOAD32 */
case 0x19: /* LOADU32 */ case 0x19: /* LOADU32 */
{ {
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0); vm->reg[c->reg0] = readin_Reg(vm, (utmp1 + c->raw_Immediate));
break; break;
} }
case 0x1F: /* CMPUI */ case 0x1F: /* CMPUI */
@ -1074,7 +1045,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
} }
case 0x20: /* STORE */ case 0x20: /* STORE */
{ {
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0); writeout_Reg(vm, (utmp1 + c->raw_Immediate), vm->reg[c->reg0]);
break; break;
} }
case 0x21: /* STORE8 */ case 0x21: /* STORE8 */
@ -1118,7 +1089,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
case 0x25: /* STORE32 */ case 0x25: /* STORE32 */
case 0x26: /* STOREU32 */ case 0x26: /* STOREU32 */
{ {
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0); writeout_Reg(vm, (utmp1 + c->raw_Immediate), vm->reg[c->reg0]);
break; break;
} }
default: return true; default: return true;
@ -1248,6 +1219,38 @@ bool eval_Integer_1OPI(struct lilith* vm, struct Instruction* c)
return false; 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 */ /* Process 0OPI Integer instructions */
bool eval_Integer_0OPI(struct lilith* vm, struct Instruction* c) 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; if ( invalid) goto fail;
break; break;
} }
case 0x2D:
{
decode_1OPI(current);
invalid = eval_branch_1OPI(vm, current);
if ( invalid) goto fail;
break;
}
case 0x3C: /* JUMP */ case 0x3C: /* JUMP */
{ {
decode_0OPI(current); decode_0OPI(current);

12
vm.h
View File

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