summaryrefslogtreecommitdiff
path: root/src/virtualmachine/VirtualMachine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/virtualmachine/VirtualMachine.cpp')
-rw-r--r--src/virtualmachine/VirtualMachine.cpp405
1 files changed, 0 insertions, 405 deletions
diff --git a/src/virtualmachine/VirtualMachine.cpp b/src/virtualmachine/VirtualMachine.cpp
deleted file mode 100644
index a657f3c..0000000
--- a/src/virtualmachine/VirtualMachine.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-#include <string>
-#include <cstring>
-#include <stdio.h>
-#include <stdlib.h>
-#include "VirtualMachine.h"
-
-namespace vm
-{
-
- VirtualMachine::VirtualMachine(int hunkMbytes):
- bigEndian(false),
- hunk(NULL),
- hunkSize(1048576),
- hunkFree(0),
- rom(NULL),
- romSize(0),
- ram(NULL),
- ramSize(0),
- dataStack(0),
- returnStack(0),
- DP(0), /* Datastack pointer. */
- RP(0), /* Return stack pointer. */
- PC(0),
- cm(0),
- cycles(0),
- sim(NULL),
- ren(NULL)
- {
- hunk = new char[hunkSize];
- std::fill(hunk, hunk+hunkSize, 0);
- }
-
- VirtualMachine::~VirtualMachine()
- {
- delete[] hunk;
- }
-
- #define DEBUGTRACE(args, ...) printf(args);
-
- int VirtualMachine::opcodeParameterSize(int opcode)
- {
- #define OP(n) OP##n
- switch (opcode)
- {
- case OP(ENTER):
- case OP(LEAVE):
- case OP(LOCAL):
- case OP(EQ):
- case OP(NE):
- case OP(LTI):
- case OP(LEI):
- case OP(GTI):
- case OP(GEI):
- case OP(LTU):
- case OP(LEU):
- case OP(GTU):
- case OP(GEU):
- case OP(EQF):
- case OP(NEF):
- case OP(LTF):
- case OP(LEF):
- case OP(GTF):
- case OP(GEF):
- case OP(CONST):
- case OP(BLOCK_COPY):
- return sizeof(uint4_t);
- break;
- case OP(ARG):
- return sizeof(uint1_t);
- break;
- }
- return 0;
- #undef OP
- }
-
- /* Read one octet from file. */
- int VirtualMachine::readByte(std::istream & input)
- {
- int o;
- o = input.get();
- if (o < 0) o = 0; /* EOF (hack) */
- return o;
- }
-
- /* Read little-endian 32-bit integer from file. */
- int VirtualMachine::readInt(std::istream & input)
- {
- int a, b, c, d, n;
-
- a = readByte(input);
- b = readByte(input);
- c = readByte(input);
- d = readByte(input);
- n = (a) | (b << 8) | (c << 16) | (d << 24);
- return n;
- }
-
- int VirtualMachine::readProgram(std::istream & input)
- {
- qvm_header_t qvminfo;
- int i, n;
- uint1_t x[4];
- word w;
-
- DEBUGTRACE("Loading file...\n");
- qvminfo.magic = readInt(input); /* magic. */
- if (qvminfo.magic != QVM_MAGIC)
- {
- DEBUGTRACE("Invalid magic");
- throw InvalidProgramException();
- //q3vm_error("Does not appear to be a QVM file.");
- /* XXX: option to force continue. */
- return 0;
- }
- DEBUGTRACE("Magic OK\n");
- /* variable-length instructions mean instruction count != code length */
- qvminfo.inscount = readInt(input);
- qvminfo.codeoff = readInt(input);
- qvminfo.codelen = readInt(input);
- qvminfo.dataoff = readInt(input);
- qvminfo.datalen = readInt(input);
- qvminfo.litlen = readInt(input);
- qvminfo.bsslen = readInt(input);
-
- /* Code segment should follow... */
- /* XXX: use fseek with SEEK_CUR? */
- DEBUGTRACE("Searching for .code @ %d from %d\n", qvminfo.codeoff, input.tellg());
-
- // rom = (q3vm_rom_t*)(hunk); /* ROM-in-hunk */
- rom = (Instruction*)calloc(qvminfo.inscount, sizeof(rom[0]));
- while (input.tellg() < qvminfo.codeoff)
- readByte(input);
- while (romSize < qvminfo.inscount)
- {
- n = readByte(input);
- w.int4 = 0;
- if ((i = opcodeParameterSize(n)))
- {
- x[0] = x[1] = x[2] = x[3] = 0;
- input.readsome((char*)x, i);
- w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
- }
- rom[romSize].Operation = n;
- rom[romSize].Parameter = w;
- romSize++;
- }
- DEBUGTRACE("After loading code: at %d, should be %d\n", input.tellg(), qvminfo.codeoff + qvminfo.codelen);
-
- /* Then data segment. */
- // ram = hunk + ((romlen + 3) & ~3); /* RAM-in-hunk */
- ram = hunk;
- DEBUGTRACE("Searching for .data @ %d from %d\n", qvminfo.dataoff, input.tellg());
- while (input.tellg() < qvminfo.dataoff)
- readByte(input);
- for (n = 0; n < (qvminfo.datalen / sizeof(uint1_t)); n++)
- {
- i = input.readsome((char*)x, sizeof(x));
- w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
- *((word*)(ram + ramSize)) = w;
- ramSize += sizeof(word);
- }
-
- /* lit segment follows data segment. */
- /* Assembler should have already padded properly. */
- DEBUGTRACE("Loading .lit\n");
- for (n = 0; n < (qvminfo.litlen / sizeof(uint1_t)); n++)
- {
- i = input.readsome((char*)x, sizeof(x));
- memcpy(&(w.uint1), &x, sizeof(x)); /* no byte-swapping. */
- *((word*)(ram + ramSize)) = w;
- ramSize += sizeof(word);
- }
- /* bss segment. */
- DEBUGTRACE("Allocating .bss %d (%X) bytes\n", qvminfo.bsslen, qvminfo.bsslen);
- /* huge empty chunk. */
- ramSize += qvminfo.bsslen;
-
- hunkFree = hunkSize - ((ramSize * sizeof(uint1_t)) + 4);
-
- DEBUGTRACE("VM hunk has %d of %d bytes free (RAM = %d B).\n", hunkFree, hunkSize, ramSize);
- if (ramSize > hunkSize)
- {
- throw OutOfMemoryException();
- return 0;
- }
-
- /* set up stack. */
- {
- int stacksize = 0x10000;
- dataStack = ramSize - (stacksize / 2);
- returnStack = ramSize;
- //returnStack = dataStack+4;
- RP = returnStack;
- DP = dataStack;
- }
-
- /* set up PC for return-to-termination. */
- PC = romSize + 1;
-
- ramMask = ramSize;
-
- return 1;
- }
-
- int VirtualMachine::LoadProgram(std::vector<char> data)
- {
- /*class vectorwrapbuf : public std::basic_streambuf<char, std::char_traits<char> >
- {
- public:
- vectorwrapbuf(std::vector<char> &vec) {
- setg(vec.data(), vec.data(), vec.data() + vec.size());
- }
- };
- vectorwrapbuf databuf(data);
- std::istream is(&databuf);
- return readProgram(is);*/
- std::stringstream ss(std::string(data.begin(), data.end()));
- return readProgram((std::istream &)ss);
- }
-
- int VirtualMachine::LoadProgram(char * filename)
- {
- /*FILE * qvmfile = fopen(filename, "rb");
- qvm_header_t qvminfo;
- int i, n;
- uint1_t x[4];
- word w;
-
- DEBUGTRACE("Loading file...\n");
- qvminfo.magic = readInt(qvmfile);
- if (qvminfo.magic != QVM_MAGIC)
- {
- DEBUGTRACE("Invalid magic");
- return 0;
- }
- DEBUGTRACE("Magic OK\n");
-
- qvminfo.inscount = readInt(qvmfile);
- qvminfo.codeoff = readInt(qvmfile);
- qvminfo.codelen = readInt(qvmfile);
- qvminfo.dataoff = readInt(qvmfile);
- qvminfo.datalen = readInt(qvmfile);
- qvminfo.litlen = readInt(qvmfile);
- qvminfo.bsslen = readInt(qvmfile);
-
-
- DEBUGTRACE("Searching for .code @ %d from %d\n", qvminfo.codeoff, ftell(qvmfile));
-
- rom = (Instruction*)calloc(qvminfo.inscount, sizeof(rom[0]));
- while (ftell(qvmfile) < qvminfo.codeoff)
- readByte(qvmfile);
- while (romSize < qvminfo.inscount)
- {
- n = readByte(qvmfile);
- w.int4 = 0;
- if ((i = opcodeParameterSize(n)))
- {
- x[0] = x[1] = x[2] = x[3] = 0;
- fread(&x, 1, i, qvmfile);
- w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
- }
- rom[romSize].Operation = n;
- rom[romSize].Parameter = w;
- romSize++;
- }
- DEBUGTRACE("After loading code: at %d, should be %d\n", ftell(qvmfile), qvminfo.codeoff + qvminfo.codelen);
-
-
- ram = hunk;
- DEBUGTRACE("Searching for .data @ %d from %d\n", qvminfo.dataoff, ftell(qvmfile));
- while (ftell(qvmfile) < qvminfo.dataoff)
- readByte(qvmfile);
- for (n = 0; n < (qvminfo.datalen / sizeof(uint1_t)); n++)
- {
- i = fread(&x, 1, sizeof(x), qvmfile);
- w.uint4 = (x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
- *((word*)(ram + ramSize)) = w;
- ramSize += sizeof(word);
- }
-
-
- DEBUGTRACE("Loading .lit\n");
- for (n = 0; n < (qvminfo.litlen / sizeof(uint1_t)); n++)
- {
- i = fread(&x, 1, sizeof(x), qvmfile);
- memcpy(&(w.uint1), &x, sizeof(x));
- *((word*)(ram + ramSize)) = w;
- ramSize += sizeof(word);
- }
-
- DEBUGTRACE("Allocating .bss %d (%X) bytes\n", qvminfo.bsslen, qvminfo.bsslen);
- ramSize += qvminfo.bsslen;
-
- hunkFree = hunkSize - ((ramSize * sizeof(uint1_t)) + 4);
-
- DEBUGTRACE("VM hunk has %d of %d bytes free (RAM = %d B).\n", hunkFree, hunkSize, ramSize);
- if (ramSize > hunkSize)
- {
- throw OutOfMemoryException();
- return 0;
- }
-
-
- {
- int stacksize = 0x10000;
- dataStack = ramSize - (stacksize / 2);
- //returnStack = ramSize;
- returnStack = dataStack+4;
- RP = returnStack;
- DP = dataStack;
- }
-
-
- PC = romSize + 1;
-
- ramMask = ramSize;
-
- return 1;*/
- return 0; //temporary, something has to be returned for now
- }
-
- void VirtualMachine::End()
- {
- PC = romSize+1;
- }
-
- int VirtualMachine::CallInterpreted(int address)
- {
- word w;
- int i, argCount = 0;
-
- /* Set up call. */
- OpPUSH(w);
- DEBUGTRACE("Starting with PC=%d, DP=%d, RP=%d to %d\n", PC, DP, RP, address);
- w.int4 = (argCount + 2) * sizeof(word);
- OpENTER(w);
- i = 8;
- /**w.int4 = arg0; Marshal(i, w); i += 4;
- w.int4 = arg1; Marshal(i, w); i += 4;
- w.int4 = arg2; Marshal(i, w); i += 4;
- w.int4 = arg3; Marshal(i, w); i += 4;
- w.int4 = arg4; Marshal(i, w); i += 4;
- w.int4 = arg5; Marshal(i, w); i += 4;
- w.int4 = arg6; Marshal(i, w); i += 4;
- w.int4 = arg7; Marshal(i, w); i += 4;
- w.int4 = arg8; Marshal(i, w); i += 4;
- w.int4 = arg9; Marshal(i, w); i += 4;
- w.int4 = arg10; Marshal(i, w); i += 4;
- w.int4 = arg11; Marshal(i, w); i += 4;
- w.int4 = arg12; Marshal(i, w); i += 4;*/
- w.int4 = address;
- Push(w);
- OpCALL(w);
- DEBUGTRACE("Upon running PC=%d, DP=%d, RP=%d\n", PC, DP, RP);
- Run();
- DEBUGTRACE("At finish PC=%d, DP=%d, RP=%d\n", PC, DP, RP);
- w.int4 = (argCount + 2) * sizeof(word);
- OpLEAVE(w);
- OpPOP(w);
- PC = romSize + 1;
- return 0;
- }
-
- int VirtualMachine::Run()
- {
- bool running = true;
- int operation;
- word parameter;
- while(running)
- {
- cycles++;
- if(PC > romSize)
- {
- running = false;
- continue;
- }
- if (PC < 0)
- {
- syscall(PC);
- continue;
- }
- operation = rom[PC].Operation;
- parameter = rom[PC].Parameter;
- PC++;
- (this->*operations[operation])(parameter);
- }
- return 1;
- }
-
-
-
- int VirtualMachine::syscall(int trap)
- {
- PC = Pop<int4_t>();
-
- switch (trap)
- {
- #define TRAPDEF(n, f) case n: trap##f(); break;
- #include "Syscalls.inl"
- #undef TRAPDEF
- }
-
- return 1;
- }
-}