updated virtual machine routines
This commit is contained in:
66
src/opcode.c
66
src/opcode.c
@@ -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];
|
||||||
}
|
}
|
||||||
|
26
src/opcode.h
26
src/opcode.h
@@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
38
src/vm.c
38
src/vm.c
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user