From 9b55ee0f549490eda5032b7fac6719edcaa9c7ad Mon Sep 17 00:00:00 2001 From: hellerve Date: Tue, 16 Jun 2015 10:47:01 +0200 Subject: [PATCH] updated virtual machine routines --- src/opcode.c | 66 +++++++++++++++++++++++++++++++++++++++++++------ src/opcode.h | 26 +++++++++---------- src/vm.c | 38 +++++++++++++++++----------- test/factorial | 16 ++++++------ test/helloworld | 28 ++++++++++----------- 5 files changed, 117 insertions(+), 57 deletions(-) diff --git a/src/opcode.c b/src/opcode.c index f9f2552..afae0eb 100644 --- a/src/opcode.c +++ b/src/opcode.c @@ -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]; } diff --git a/src/opcode.h b/src/opcode.h index 83ecc74..b6835a3 100644 --- a/src/opcode.h +++ b/src/opcode.h @@ -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 }; /** diff --git a/src/vm.c b/src/vm.c index 584e9f7..ee220d4 100644 --- a/src/vm.c +++ b/src/vm.c @@ -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; diff --git a/test/factorial b/test/factorial index 46ce3e4..ee3f0b4 100644 --- a/test/factorial +++ b/test/factorial @@ -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 diff --git a/test/helloworld b/test/helloworld index c50d04e..a4ead10 100644 --- a/test/helloworld +++ b/test/helloworld @@ -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