updated virtual machine routines

This commit is contained in:
hellerve
2015-06-16 10:47:01 +02:00
parent 45fd79cf16
commit 9b55ee0f54
5 changed files with 117 additions and 57 deletions

View File

@@ -1,21 +1,71 @@
#include "opcode.h"
/*The opcodes as chars*/
const char* opcodes[] = {"IADD", "ISUB", "IMULT", "IDIV", "IMOD",
"ILT", "IEQ", "IGT", "BR", "BRT", "BRF", "ICONST", "LOAD", "GLOAD",
"STORE", "GSTORE", "PRINT", "POP", "HALT", "ILEQ", "IGEQ", "CALL", "RET",
"IPRINT", "FETCH", "IINC", "IDEC" };
const char* opcodes[] = { "ADD",
"SUB",
"MULT",
"DIV",
"MOD",
"LT",
"EQ",
"GT",
"BR",
"BRT",
"BRF",
"CONST",
"LOAD",
"GLOAD",
"STORE",
"GSTORE",
"PRINT",
"POP",
"HALT",
"LEQ",
"GEQ",
"CALL",
"RET",
"IPRINT",
"FETCH",
"INC",
"DEC"
};
/*The argument counter for the opcodes*/
int nargs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 2, 0, 0, 0, 0, 0 };
int nargs[] = { 0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
0,
0,
2,
0,
0,
0,
0,
0
};
instruction* setup_instructions(){
int i;
static instruction ins[IDEC+1];
static instruction ins[DEC+1];
ins[0].operands = 0;
ins[0].name = "\0";
for(i = 1; i <= IDEC; i++){
for(i = 1; i <= DEC; i++){
ins[i].operands = nargs[i-1];
ins[i].name = opcodes[i-1];
}

View File

@@ -3,21 +3,21 @@
enum {
/*Addition operation*/
IADD = 1,
ADD = 1,
/*Subtraction operation*/
ISUB,
SUB,
/*Multiplication operation*/
IMULT,
MULT,
/*Division operation*/
IDIV,
DIV,
/*Modulo operation*/
IMOD,
MOD,
/*< operation*/
ILT,
LT,
/*== operation*/
IEQ,
EQ,
/*> operation*/
IGT,
GT,
/*branch operation*/
BR,
/*branch if true operation*/
@@ -25,7 +25,7 @@ enum {
/*branch if false operation*/
BRF,
/*put operation*/
ICONST,
CONST,
/*load variable operation*/
LOAD,
/*load global variable operation*/
@@ -41,9 +41,9 @@ enum {
/*end/halt operation*/
HALT,
/*<= operation*/
ILEQ,
LEQ,
/*>= operation*/
IGEQ,
GEQ,
/*call subroutine operation*/
CALL,
/*return from subroutine operation*/
@@ -53,9 +53,9 @@ enum {
/*fetch operation*/
FETCH,
/*++ operation*/
IINC,
INC,
/*-- operation*/
IDEC
DEC
};
/**

View File

@@ -34,6 +34,16 @@ static inline void disassemble(int sp, int fp, int ip, int opcode, instruction*
printf("\n");
}
/**
* @brief vm_execute
* @param code -> a list of opcodes
* @param ip -> the instruction pointer
* @param datasize -> the maximal standard datasize
* @param length -> the length of the program
*
* the main virtual machine loop. takes opcodes and
* metainformation and executes it.
*/
void vm_execute(int code[], int ip, int datasize, unsigned long length){
int* data = (int *) alloca((size_t)datasize * sizeof(int));
int stack[MAX_SIZE];
@@ -51,10 +61,10 @@ void vm_execute(int code[], int ip, int datasize, unsigned long length){
disassemble(sp, fp, ip, opcode, ins, code, stack);
}
switch(opcode){
case IINC:
case INC:
stack[sp]++;
break;
case IDEC:
case DEC:
stack[sp]--;
break;
case LOAD:
@@ -73,57 +83,57 @@ void vm_execute(int code[], int ip, int datasize, unsigned long length){
addr = code[ip++];
if(stack[sp--] == FALSE) ip = addr;
break;
case IADD:
case ADD:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a + b;
break;
case ISUB:
case SUB:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a - b;
break;
case IMULT:
case MULT:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a * b;
break;
case IDIV:
case DIV:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a / b;
break;
case IMOD:
case MOD:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a % b;
break;
case ILT:
case LT:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a < b ? TRUE : FALSE;
break;
case IEQ:
case EQ:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a == b;
break;
case IGT:
case GT:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a > b ? TRUE : FALSE;
break;
case ILEQ:
case LEQ:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a <= b ? TRUE : FALSE;
break;
case IGEQ:
case GEQ:
b = stack[sp--];
a = stack[sp--];
stack[++sp] = a >= b ? TRUE : FALSE;
break;
case ICONST:
case CONST:
stack[++sp] = code[ip++];
break;
case GLOAD:
@@ -181,7 +191,7 @@ program vm_compile(char *filename){
unsigned long codep = 0;
register int i;
instruction* ins = setup_instructions();
unsigned int len = IDEC;
unsigned int len = DEC;
size_t linelength = 0;
int entry = 0;
program prog;