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" #include "opcode.h"
/*The opcodes as chars*/ /*The opcodes as chars*/
const char* opcodes[] = {"IADD", "ISUB", "IMULT", "IDIV", "IMOD", const char* opcodes[] = { "ADD",
"ILT", "IEQ", "IGT", "BR", "BRT", "BRF", "ICONST", "LOAD", "GLOAD", "SUB",
"STORE", "GSTORE", "PRINT", "POP", "HALT", "ILEQ", "IGEQ", "CALL", "RET", "MULT",
"IPRINT", "FETCH", "IINC", "IDEC" }; "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*/ /*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, int nargs[] = { 0,
0, 2, 0, 0, 0, 0, 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(){ instruction* setup_instructions(){
int i; int i;
static instruction ins[IDEC+1]; static instruction ins[DEC+1];
ins[0].operands = 0; ins[0].operands = 0;
ins[0].name = "\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].operands = nargs[i-1];
ins[i].name = opcodes[i-1]; ins[i].name = opcodes[i-1];
} }

View File

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

View File

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

View File

@@ -1,21 +1,21 @@
ENTRY 22 ENTRY 22
LOAD -3 LOAD -3
ICONST 2 CONST 2
ILT LT
BRF 10 BRF 10
ICONST 1 CONST 1
RET RET
LOAD -3 LOAD -3
LOAD -3 LOAD -3
ICONST 1 CONST 1
ISUB SUB
CALL 0 1 CALL 0 1
IMULT MULT
RET RET
ICONST 12 CONST 12
CALL 0 1 CALL 0 1
IPRINT IPRINT
ICONST 10 CONST 10
PRINT PRINT
HALT HALT

View File

@@ -1,31 +1,31 @@
ICONST 72 CONST 72
PRINT PRINT
ICONST 101 CONST 101
PRINT PRINT
ICONST 108 CONST 108
PRINT PRINT
ICONST 108 CONST 108
PRINT PRINT
ICONST 111 CONST 111
PRINT PRINT
ICONST 44 CONST 44
PRINT PRINT
ICONST 32 CONST 32
PRINT PRINT
ICONST 119 CONST 119
PRINT PRINT
ICONST 111 CONST 111
PRINT PRINT
ICONST 114 CONST 114
PRINT PRINT
ICONST 108 CONST 108
PRINT PRINT
ICONST 100 CONST 100
PRINT PRINT
ICONST 33 CONST 33
GSTORE 0 GSTORE 0
GLOAD 0 GLOAD 0
PRINT PRINT
ICONST 10 CONST 10
PRINT PRINT
HALT HALT