Added PC relative instruction load and store to make position independent code more efficient

This commit is contained in:
Jeremiah Orians 2016-06-19 22:31:30 -04:00
parent 114cc0b388
commit 08e24c4ccc
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
5 changed files with 383 additions and 0 deletions

View File

@ -363,6 +363,46 @@
| 2D 7a ii ii | SL1I a ii ii | a = a << ii ii [Fill with ones] |
| 2D 8a ii ii | SR1I a ii ii | a = a >> ii ii [Fill with ones] |
*** Relative Loads
| Hex | Name | Comment |
|-------------+------------------+----------------------------------------|
| 2E 0a ii ii | LOADR a ii ii | a = MEM[ip + ii ii] |
| 2E 1a ii ii | LOADR8 a ii ii | a = MEM[ip + ii ii] [signed 8 bits] |
| 2E 2a ii ii | LOADRU8 a ii ii | a = MEM[ip + ii ii] [unsigned 8 bits] |
| 2E 3a ii ii | LOADR16 a ii ii | a = MEM[ip + ii ii] [signed 16 bits] |
| 2E 4a ii ii | LOADRU16 a ii ii | a = MEM[ip + ii ii] [unsigned 16 bits] |
| 2E 5a ii ii | LOADR32 a ii ii | a = MEM[ip + ii ii] [signed 32 bits] |
| 2E 6a ii ii | LOADRU32 a ii ii | a = MEM[ip + ii ii] [unsigned 32 bits] |
| 2E 7a ii ii | Reserved | |
| 2E 8a ii ii | Reserved | |
| 2E 9a ii ii | Reserved | |
| 2E Aa ii ii | Reserved | |
| 2E Ba ii ii | Reserved | |
| 2E Ca ii ii | Reserved | |
| 2E Da ii ii | Reserved | |
| 2E Ea ii ii | Reserved | |
| 2E Fa ii ii | Reserved | |
*** Relative Stores
| Hex | Name | Comment |
|-------------+------------------+--------------------------------------|
| 2F 0a ii ii | STORER a ii ii | MEM[ip + ii ii] = a |
| 2F 1a ii ii | STORER8 a ii ii | MEM[ip + ii ii] = a [signed 8 bits] |
| 2F 2a ii ii | STORER16 a ii ii | MEM[ip + ii ii] = a [signed 16 bits] |
| 2F 3a ii ii | STORER32 a ii ii | MEM[ip + ii ii] = a [signed 32 bits] |
| 2F 4a ii ii | Reserved | |
| 2F 5a ii ii | Reserved | |
| 2F 6a ii ii | Reserved | |
| 2F 7a ii ii | Reserved | |
| 2F 8a ii ii | Reserved | |
| 2F 9a ii ii | Reserved | |
| 2F Aa ii ii | Reserved | |
| 2F Ba ii ii | Reserved | |
| 2F Ca ii ii | Reserved | |
| 2F Da ii ii | Reserved | |
| 2F Ea ii ii | Reserved | |
| 2F Fa ii ii | Reserved | |
** 0OPI group
0OPI ii ii is the Immediate, OP ii ii

11
asm.c
View File

@ -304,6 +304,17 @@ void assemble(struct Token* p)
setExpression(p, "SR0I", "2D6", 4);
setExpression(p, "SL1I", "2D7", 4);
setExpression(p, "SR1I", "2D8", 4);
setExpression(p, "LOADR", "2E0", 4);
setExpression(p, "LOADR8", "2E1", 4);
setExpression(p, "LOADRU8", "2E2", 4);
setExpression(p, "LOADR16", "2E3", 4);
setExpression(p, "LOADRU16", "2E4", 4);
setExpression(p, "LOADR32", "2E5", 4);
setExpression(p, "LOADRU32", "2E6", 4);
setExpression(p, "STORER", "2F0", 4);
setExpression(p, "STORER8", "2F1", 4);
setExpression(p, "STORER16", "2F2", 4);
setExpression(p, "STORER32", "2F3", 4);
/* 0OPI Group */
setExpression(p, "JUMP", "3C00", 4);

121
disasm.c
View File

@ -937,6 +937,117 @@ void decode_Branch_1OPI(struct Instruction* c)
fprintf(stdout, "# %s\n", c->operation);
}
void decode_Load_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: /* LOADR */
{
strncpy(Name, "LOADR", 19);
break;
}
case 0x1: /* LOADR8 */
{
strncpy(Name, "LOADR8", 19);
break;
}
case 0x2: /* LOADRU8 */
{
strncpy(Name, "LOADRU8", 19);
break;
}
case 0x3: /* LOADR16 */
{
strncpy(Name, "LOADR16", 19);
break;
}
case 0x4: /* LOADRU16 */
{
strncpy(Name, "LOADRU16", 19);
break;
}
case 0x5: /* LOADR32 */
{
strncpy(Name, "LOADR32", 19);
break;
}
case 0x6: /* LOADRU32 */
{
strncpy(Name, "LOADRU32", 19);
break;
}
default: /* Unknown 1OPI*/
{
break;
}
}
fprintf(stdout, "%s reg%u %d\t", Name, c->reg0, c->raw_Immediate);
fprintf(stdout, "# %s\n", c->operation);
}
void decode_Store_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: /* STORER */
{
strncpy(Name, "STORER", 19);
break;
}
case 0x1: /* STORER8 */
{
strncpy(Name, "STORER8", 19);
break;
}
case 0x2: /* STORER16 */
{
strncpy(Name, "STORER16", 19);
break;
}
case 0x3: /* STORER32 */
{
strncpy(Name, "STORER32", 19);
break;
}
default: /* Unknown 1OPI*/
{
break;
}
}
fprintf(stdout, "%s reg%u %d\t", Name, c->reg0, c->raw_Immediate);
fprintf(stdout, "# %s\n", c->operation);
}
void decode_0OPI(struct Instruction* c)
{
/* Parse Raw Data */
@ -1064,6 +1175,16 @@ void eval_instruction(struct Instruction* c)
decode_Branch_1OPI(c);
break;
}
case 0x2E: /* LOADR 1OPI */
{
decode_Load_1OPI(c);
break;
}
case 0x2F: /* STORER 1OPI*/
{
decode_Store_1OPI(c);
break;
}
case 0x3C: /* Core 0OPI */
{
decode_0OPI(c);

158
vm.c
View File

@ -138,6 +138,17 @@ void SL0I(struct lilith* vm, struct Instruction* c);
void SR0I(struct lilith* vm, struct Instruction* c);
void SL1I(struct lilith* vm, struct Instruction* c);
void SR1I(struct lilith* vm, struct Instruction* c);
void LOADR(struct lilith* vm, struct Instruction* c);
void LOADR8(struct lilith* vm, struct Instruction* c);
void LOADRU8(struct lilith* vm, struct Instruction* c);
void LOADR16(struct lilith* vm, struct Instruction* c);
void LOADRU16(struct lilith* vm, struct Instruction* c);
void LOADR32(struct lilith* vm, struct Instruction* c);
void LOADRU32(struct lilith* vm, struct Instruction* c);
void STORER(struct lilith* vm, struct Instruction* c);
void STORER8(struct lilith* vm, struct Instruction* c);
void STORER16(struct lilith* vm, struct Instruction* c);
void STORER32(struct lilith* vm, struct Instruction* c);
void JUMP(struct lilith* vm, struct Instruction* c);
/* Allocate and intialize memory/state */
@ -1663,6 +1674,139 @@ bool eval_branch_1OPI(struct lilith* vm, struct Instruction* c)
return false;
}
/* LOAD 1OPI */
bool eval_Load_1OPI(struct lilith* vm, struct Instruction* c)
{
#ifdef DEBUG
char Name[20] = "ILLEGAL_1OPI";
#endif
switch(c->raw_XOP)
{
case 0x0: /* LOADR */
{
#ifdef DEBUG
strncpy(Name, "LOADR", 19);
#endif
LOADR(vm, c);
break;
}
case 0x1: /* LOADR8 */
{
#ifdef DEBUG
strncpy(Name, "LOADR8", 19);
#endif
LOADR8(vm, c);
break;
}
case 0x2: /* LOADRU8 */
{
#ifdef DEBUG
strncpy(Name, "LOADRU8", 19);
#endif
LOADRU8(vm, c);
break;
}
case 0x3: /* LOADR16 */
{
#ifdef DEBUG
strncpy(Name, "LOADR16", 19);
#endif
LOADR16(vm, c);
break;
}
case 0x4: /* LOADRU16 */
{
#ifdef DEBUG
strncpy(Name, "LOADRU16", 19);
#endif
LOADRU16(vm, c);
break;
}
case 0x5: /* LOADR32 */
{
#ifdef DEBUG
strncpy(Name, "LOADR32", 19);
#endif
LOADR32(vm, c);
break;
}
case 0x6: /* LOADRU32 */
{
#ifdef DEBUG
strncpy(Name, "LOADRU32", 19);
#endif
LOADRU32(vm, c);
break;
}
default: return true;
}
#ifdef DEBUG
fprintf(stdout, "# %s reg%u %d\n", Name, c->reg0, c->raw_Immediate);
#endif
return false;
}
/* STORE 1OPI */
bool eval_Store_1OPI(struct lilith* vm, struct Instruction* c)
{
#ifdef DEBUG
char Name[20] = "ILLEGAL_1OPI";
#endif
switch(c->raw_XOP)
{
case 0x0: /* STORER */
{
#ifdef DEBUG
strncpy(Name, "STORER", 19);
#endif
STORER(vm, c);
break;
}
case 0x1: /* STORER8 */
{
#ifdef DEBUG
strncpy(Name, "STORER8", 19);
#endif
STORER8(vm, c);
break;
}
case 0x2: /* STORER16 */
{
#ifdef DEBUG
strncpy(Name, "STORER16", 19);
#endif
STORER16(vm, c);
break;
}
case 0x3: /* STORER32 */
{
#ifdef DEBUG
strncpy(Name, "STORER32", 19);
#endif
STORER32(vm, c);
break;
}
default: return true;
}
#ifdef DEBUG
fprintf(stdout, "# %s reg%u %d\n", Name, c->reg0, c->raw_Immediate);
#endif
return false;
}
/* Process 0OPI Integer instructions */
bool eval_Integer_0OPI(struct lilith* vm, struct Instruction* c)
{
@ -1760,6 +1904,20 @@ void eval_instruction(struct lilith* vm, struct Instruction* current)
if ( invalid) goto fail;
break;
}
case 0x2E:
{
decode_1OPI(current);
invalid = eval_Load_1OPI(vm, current);
if ( invalid) goto fail;
break;
}
case 0x2F:
{
decode_1OPI(current);
invalid = eval_Store_1OPI(vm, current);
if ( invalid) goto fail;
break;
}
case 0x3C: /* Integer 0OPI */
{
decode_0OPI(current);

View File

@ -1559,6 +1559,59 @@ void SR1I(struct lilith* vm, struct Instruction* c)
vm->reg[c->reg0] = shift_register(vm->reg[c->reg0], c->raw_Immediate, false, false);
}
void LOADR(struct lilith* vm, struct Instruction* c)
{
vm->reg[c->reg0] = readin_Reg(vm, (vm->ip + c->raw_Immediate -4));
}
void LOADR8(struct lilith* vm, struct Instruction* c)
{
vm->reg[c->reg0] = readin_byte(vm, (vm->ip + c->raw_Immediate -4), true);
}
void LOADRU8(struct lilith* vm, struct Instruction* c)
{
vm->reg[c->reg0] = readin_byte(vm, (vm->ip + c->raw_Immediate -4), false);
}
void LOADR16(struct lilith* vm, struct Instruction* c)
{
vm->reg[c->reg0] = readin_doublebyte(vm, (vm->ip + c->raw_Immediate -4), true);
}
void LOADRU16(struct lilith* vm, struct Instruction* c)
{
vm->reg[c->reg0] = readin_doublebyte(vm, (vm->ip + c->raw_Immediate -4), false);
}
void LOADR32(struct lilith* vm, struct Instruction* c)
{
vm->reg[c->reg0] = readin_Reg(vm, (vm->ip + c->raw_Immediate -4));
}
void LOADRU32(struct lilith* vm, struct Instruction* c)
{
vm->reg[c->reg0] = readin_Reg(vm, (vm->ip + c->raw_Immediate -4));
}
void STORER(struct lilith* vm, struct Instruction* c)
{
writeout_Reg(vm, (vm->ip + c->raw_Immediate - 4), vm->reg[c->reg0]);
}
void STORER8(struct lilith* vm, struct Instruction* c)
{
writeout_byte(vm, (vm->ip + c->raw_Immediate - 4), vm->reg[c->reg0]);
}
void STORER16(struct lilith* vm, struct Instruction* c)
{
writeout_doublebyte(vm, (vm->ip + c->raw_Immediate - 4), vm->reg[c->reg0]);
}
void STORER32(struct lilith* vm, struct Instruction* c)
{
writeout_Reg(vm, (vm->ip + c->raw_Immediate - 4), vm->reg[c->reg0]);
}
void JUMP(struct lilith* vm, struct Instruction* c)
{
vm->ip = vm->ip + c->raw_Immediate - 4;