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;

View File

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

View File

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