Added PC relative instruction load and store to make position independent code more efficient
This commit is contained in:
parent
114cc0b388
commit
08e24c4ccc
|
@ -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
11
asm.c
|
@ -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
121
disasm.c
|
@ -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
158
vm.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue