summaryrefslogtreecommitdiff
path: root/src/virtualmachine
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2013-10-20 14:33:06 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2013-10-20 14:33:06 (GMT)
commite8c53dc3e8d293ef750f3780b999783ae3537ba9 (patch)
treed9158731234905b36cae9991f49bbe99f82cd56a /src/virtualmachine
parenteea006ad6f63083782a3decda51b6bf80caa47af (diff)
downloadpowder-e8c53dc3e8d293ef750f3780b999783ae3537ba9.zip
powder-e8c53dc3e8d293ef750f3780b999783ae3537ba9.tar.gz
Remove old unfinished virtual machine and Lua bindings for it
Diffstat (limited to 'src/virtualmachine')
-rw-r--r--src/virtualmachine/Exceptions.h100
-rw-r--r--src/virtualmachine/JustInTime.cpp1144
-rw-r--r--src/virtualmachine/Operations.cpp356
-rw-r--r--src/virtualmachine/Operations.inl60
-rw-r--r--src/virtualmachine/Syscalls.cpp99
-rw-r--r--src/virtualmachine/Syscalls.inl14
-rw-r--r--src/virtualmachine/VirtualMachine.cpp405
-rw-r--r--src/virtualmachine/VirtualMachine.h282
8 files changed, 0 insertions, 2460 deletions
diff --git a/src/virtualmachine/Exceptions.h b/src/virtualmachine/Exceptions.h
deleted file mode 100644
index 3a25e87..0000000
--- a/src/virtualmachine/Exceptions.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#pragma once
-#include <stdexcept>
-#include <cstring>
-#include "Format.h"
-
-namespace vm
-{
- class RuntimeException: public std::exception
- {
- char * error;
- public:
- RuntimeException() : error(NULL) {}
- RuntimeException(char * message) : error(strdup(message)) {}
- const char * what() const throw()
- {
- if(error)
- return error;
- else
- return "VirtualMachine runtime exception";
- }
- ~RuntimeException() throw() {};
- };
-
- class StackOverflowException: public RuntimeException
- {
- public:
- StackOverflowException() {}
- const char * what() const throw()
- {
- return "VirtualMachine Stack overflow";
- }
- ~StackOverflowException() throw() {};
- };
-
- class StackUnderflowException: public RuntimeException
- {
- public:
- StackUnderflowException() {}
- const char * what() const throw()
- {
- return "VirtualMachine Stack underflow";
- }
- ~StackUnderflowException() throw() {};
- };
-
- class AccessViolationException: public RuntimeException
- {
- int address;
- char * _what;
- public:
- AccessViolationException(int address = 0) : address(address)
- {
- _what = strdup(std::string("VirtualMachine Access violation at "+format::NumberToString<int>(address)).c_str());
- }
- const char * what() const throw()
- {
- if(address)
- return _what;
- return "VirtualMachine Access violation";
- }
- ~AccessViolationException() throw() {};
- };
-
- class JITException: public RuntimeException
- {
- char * _what;
- public:
- JITException(const char * what2)
- {
- _what = strdup(what2);
- }
- const char * what() const throw()
- {
- return _what;
- }
- ~JITException() throw() {};
- };
-
- class OutOfMemoryException: public RuntimeException
- {
- public:
- OutOfMemoryException() {}
- const char * what() const throw()
- {
- return "VirtualMachine Out of memory";
- }
- ~OutOfMemoryException() throw() {};
- };
-
- class InvalidProgramException: public RuntimeException
- {
- public:
- InvalidProgramException() {}
- const char * what() const throw()
- {
- return "Could not load program";
- }
- ~InvalidProgramException() throw() {};
- };
-}
diff --git a/src/virtualmachine/JustInTime.cpp b/src/virtualmachine/JustInTime.cpp
deleted file mode 100644
index 9f6fe57..0000000
--- a/src/virtualmachine/JustInTime.cpp
+++ /dev/null
@@ -1,1144 +0,0 @@
-#ifdef VMJIT
-
-#include <cstdio>
-#include "VirtualMachine.h"
-
-#ifdef WIN32
-#include "Windows.h"
-#endif
-
-namespace vm
-{
- #define OP(n) OP##n
- /*
-
- eax scratch
- ebx scratch
- ecx scratch (required for shifts)
- edx scratch (required for divisions)
- esi RP
- edi DP
-
- */
-
- // TTimo: initialised the statics, this fixes a crash when entering a compiled VM
- static unsigned char *buf = NULL;
- static unsigned char *jused = NULL;
- static int compiledOfs = 0;
- static int pc = 0;
-
- //static int callMask = 0; // bk001213 - init
- static int eDP;
- static int eRP;
- static int instruction, pass;
- static int lastConst = 0;
- static int oc0, oc1, pop0, pop1;
-
- static int eRamMask = 0;
- static int eRomMask = 0;
- static int * eInstructionPointers = NULL;
-
- static int eSyscallNum;
- static void * eRam = NULL;
- static VirtualMachine * eVM = NULL;
-
- static int callFromCompiledPtr = (int)VirtualMachine::callFromCompiled;
- static int callSyscallPtr = (int)VirtualMachine::callSyscall;
-
- typedef enum
- {
- LAST_COMMAND_NONE = 0,
- LAST_COMMAND_MOV_EDI_EAX,
- LAST_COMMAND_SUB_DI_4,
- LAST_COMMAND_SUB_DI_8,
- } ELastCommand;
-
- static ELastCommand LastCommand;
-
- void VirtualMachine::callSyscall()
- {
- //throw RuntimeException("Turd");
-
- /*VirtualMachine * savedVM;
- int * callOpStack2;
-
- savedVM = eVM;
- callOpStack2 = (int*)eOpStack;
-
- // save the stack to allow recursive VM entry
- eVM->DP = eDP - 4;
- *(int *)((byte *)eVM->ram + eDP + 4) = eSyscallNum;
- //VM_LogSyscalls( (int *)((byte *)currentVM->dataBase + programStack + 4) );
- *(callOpStack2+1) = eVM->syscall( *(int *)((unsigned char *)eVM->ram + eDP + 4) );
-
- eVM = savedVM;*/
- }
-
- void VirtualMachine::callFromCompiled()
- {
- /*__asm__("doAsmCall: \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " subl $4,%%edi \n\t" \
- " orl %%eax,%%eax \n\t" \
- " jl systemCall \n\t" \
- " shll $2,%%eax \n\t" \
- " addl %3,%%eax \n\t" \
- " call *(%%eax) \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " andl %5, %%eax \n\t" \
- " jmp doret \n\t" \
- "systemCall: \n\t" \
- " negl %%eax \n\t" \
- " decl %%eax \n\t" \
- " movl %%eax,%0 \n\t" \
- " movl %%esi,%1 \n\t" \
- " movl %%edi,%2 \n\t" \
- " pushl %%ecx \n\t" \
- " pushl %%esi \n\t" \
- " pushl %%edi \n\t" \
- " call *%4 \n\t" \
- " popl %%edi \n\t" \
- " popl %%esi \n\t" \
- " popl %%ecx \n\t" \
- " addl $4,%%edi \n\t" \
- "doret: \n\t" \
- " ret \n\t" \
- : "=rm" (eSyscallNum), "=rm" (eDP), "=rm" (eOpStack) \
- : "rm" (eInstructionPointers), "r" (callSyscall), "m" (eRomMask) \
- : "ax", "di", "si", "cx" \
- );*/
- //" call *%4 \n\t"
-
- //" negl %%eax \n\t"
- // " decl %%eax \n\t"
- __asm__ volatile ("doAsmCall: \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " subl $4,%%edi \n\t" \
- " orl %%eax,%%eax \n\t" \
- " jl systemCall \n\t" \
- " shll $2,%%eax \n\t" \
- " addl %3,%%eax \n\t" \
- " call *(%%eax) \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " andl %5, %%eax \n\t" \
- " ret \n\t" \
- "systemCall: \n\t" \
- " movl %%eax,%0 \n\t" \
- " movl %%esi,%1 \n\t" \
- " movl %%edi,%2 \n\t" \
- " pushl %%ecx \n\t" \
- " pushl %%esi \n\t" \
- " pushl %%edi \n\t" \
- : "=rm" (eSyscallNum), "=rm" (eRP), "=rm" (eDP) \
- : "rm" (eInstructionPointers), "r" (callSyscall), "m" (eRomMask) \
- : "ax", "di", "si", "cx" \
- );
- //printf("Syscall: %d\n", eSyscallNum);
- //throw RuntimeException("Turd");
-
- eVM->DP = eDP-((int)eRam);
- eVM->syscall(eSyscallNum);
- eDP = eVM->DP+((int)eRam)-4;
-
- //" addl $4,%edi \n\t"
- // " ret \n\t"
- __asm__ volatile ("popl %edi \n\t" \
- " popl %esi \n\t" \
- " popl %ecx \n\t" \
- "doret: \n\t" \
- );
- }
-
- int VirtualMachine::CallCompiled(int address)
- {
- //int stack[1024];
- //int stack[100];
- int programStack;
- int stackOnEntry;
- unsigned char * image;
- void * entryPoint;
- int * oldInstructionPointers;
- void * oldDataStack;
-
- oldDataStack = eRam;
- oldInstructionPointers = eInstructionPointers;
-
- eVM = this;
- eInstructionPointers = instructionPointers;
-
- eRomMask = romMask;
- eRamMask = ramMask;
-
- // we might be called recursively, so this might not be the very top
- eDP = ((int)ram)+DP;
- stackOnEntry = DP;
-
- // set up the stack frame
- image = (unsigned char *)ram;//vm->dataBase;
-
- eDP -= 48;
-
- //*(int *)&image[ programStack + 44] = args[9];
- //*(int *)&image[ programStack + 40] = args[8];
- //*(int *)&image[ programStack + 36] = args[7];
- //*(int *)&image[ programStack + 32] = args[6];
- //*(int *)&image[ programStack + 28] = args[5];
- //*(int *)&image[ programStack + 24] = args[4];
- //*(int *)&image[ programStack + 20] = args[3];
- //*(int *)&image[ programStack + 16] = args[2];
- //*(int *)&image[ programStack + 12] = args[1];
- //*(int *)&image[ programStack + 8 ] = args[0];
- //*(int *)&image[ programStack + 4 ] = 0; // return stack
- //*(int *)&image[ programStack ] = -1; // will terminate the loop on return
-
- // off we go into generated code...
- entryPoint = compiledRom;//0;//vm->codeBase;
- eRam = ram+dataStack;
-
- #if defined(_MSC_VER)
- __asm {
- pushad
- mov esi, DP;
- mov edi, opStack
- call entryPoint
- mov DP, esi
- mov opStack, edi
- popad
- }
- #else
- {
- static int memDP;
- static int memRP;
- static void *memEntryPoint;
-
- memDP = DP+((int)ram);
- memRP = RP;
- memEntryPoint = entryPoint;
-
- __asm__(" pushal \r\n" \
- " movl %0,%%esi \r\n" \
- " movl %1,%%edi \r\n" \
- " call *%2 \r\n" \
- " movl %%esi,%0 \r\n" \
- " movl %%edi,%1 \r\n" \
- " popal \r\n" \
- : "=m" (memRP), "=m" (memDP) \
- : "m" (memEntryPoint), "0" (memRP), "1" (memDP) \
- : "si", "di" \
- );
-
- DP = memDP-((int)ram);
- RP = memRP;
- }
- #endif
-
- if ( eRam != ram+dataStack ) {
- throw RuntimeException("opStack corrupted in compiled code");
- }
- if ( DP != stackOnEntry+4 ) {
- printf("DP: %d, stackOnEntry: %d\n", DP, stackOnEntry);
- throw RuntimeException("programStack corrupted in compiled code");
- }
-
- DP = stackOnEntry;
-
- // in case we were recursively called by another vm
- eInstructionPointers = oldInstructionPointers;
- eRam = oldDataStack;
-
- return 0;//*(int *)eOpStack;
- }
-
- bool VirtualMachine::Compile()
- {
- Instruction op;
- int maxLength;
- int v;
- int i;
- bool opt;
-
- // allocate a very large temp buffer, we will shrink it later
- maxLength = romSize * 8;
- buf = new unsigned char[maxLength];
- jused = new unsigned char[romSize + 2];
- instructionPointers = new int[romSize];
- std::fill(jused, jused+romSize+2, 0);
-
- for(pass=0; pass<2; pass++) {
- oc0 = -23423;
- oc1 = -234354;
- pop0 = -43435;
- pop1 = -545455;
-
- // translate all instructions
- pc = 0;
- instruction = 0;
- compiledOfs = 0;
-
- LastCommand = LAST_COMMAND_NONE;
-
- while (instruction < romSize)
- {
- if (compiledOfs > maxLength - 16)
- {
- throw JITException("Compile: maxLength exceeded");
- }
-
- instructionPointers[instruction] = compiledOfs;
- instruction++;
-
- if (pc > romSize)
- {
- throw JITException("Compile: program counter run off the edge");
- }
-
- op = rom[pc];
- pc++;
- switch ( op.Operation )
- {
- case 0:
- break;
- case OP(BREAK):
- emitInstruction( "CC" ); // int 3
- break;
- case OP(ENTER):
- //emitInstruction( "CC" ); // int 3
- emitInstruction( "81 EE" ); // sub esi, 0x12345678
- emit4( constant4() );
- break;
- case OP(CONST):
- if (rom[pc].Operation == OP(LOAD4))
- {
- emitAddEDI4();
- emitInstruction( "BB" ); // mov ebx, 0x12345678
- emit4( (constant4()&ramMask) + (int)ram);
- emitInstruction( "8B 03" ); // mov eax, dword ptr [ebx]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- pc++; // OP(LOAD4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(LOAD2))
- {
- emitAddEDI4();
- emitInstruction( "BB" ); // mov ebx, 0x12345678
- emit4( (constant4()&ramMask) + (int)ram);
- emitInstruction( "0F B7 03" ); // movzx eax, word ptr [ebx]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- pc++; // OP(LOAD4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(LOAD1))
- {
- emitAddEDI4();
- emitInstruction( "BB" ); // mov ebx, 0x12345678
- emit4( (constant4()&ramMask) + (int)ram);
- emitInstruction( "0F B6 03" ); // movzx eax, byte ptr [ebx]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- pc++; // OP(LOAD4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(STORE4))
- {
- opt = emitMovEBXEDI((ramMask & ~3));
- emitInstruction( "B8" ); // mov eax, 0x12345678
- emit4( constant4() );
- // if (!opt) {
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask & ~3 );
- // }
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(STORE4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(STORE2))
- {
- opt = emitMovEBXEDI((ramMask & ~1));
- emitInstruction( "B8" ); // mov eax, 0x12345678
- emit4( constant4() );
- // if (!opt) {
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask & ~1 );
- // }
- emitInstruction( "66 89 83" ); // mov word ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(STORE4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(STORE1))
- {
- opt = emitMovEBXEDI(ramMask);
- emitInstruction( "B8" ); // mov eax, 0x12345678
- emit4( constant4() );
- // if (!opt) {
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask );
- // }
- emitInstruction( "88 83" ); // mov byte ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(STORE4)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(ADD))
- {
- emitInstruction( "81 07" ); // add dword ptr [edi], 0x1234567
- emit4( constant4() );
- pc++; // OP(ADD)
- instruction += 1;
- break;
- }
- if (rom[pc].Operation == OP(SUB))
- {
- emitInstruction( "81 2F" ); // sub dword ptr [edi], 0x1234567
- emit4( constant4() );
- pc++; // OP(ADD)
- instruction += 1;
- break;
- }
- emitAddEDI4();
- emitInstruction( "C7 07" ); // mov dword ptr [edi], 0x12345678
- lastConst = constant4();
- emit4( lastConst );
- if (rom[pc].Operation == OP(JUMP))
- {
- jused[lastConst] = 1;
- }
- break;
- case OP(LOCAL):
- emitAddEDI4();
- emitInstruction( "8D 86" ); // lea eax, [0x12345678 + esi]
- oc0 = oc1;
- oc1 = constant4();
- emit4( oc1 );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(ARG):
- emitMovEAXEDI(); // mov eax,dword ptr [edi]
- emitInstruction( "89 86" ); // mov dword ptr [esi+ram],eax
- // FIXME: range check
- emit4( constant1() + (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(CALL):
- emitInstruction("C7 86"); // mov dword ptr [esi+ram],0x12345678
- emit4((int)ram);
- emit4(pc);
- emitInstruction("FF 15"); // call callFromCompiled
- emit4((int)&callFromCompiledPtr);
- break;
- case OP(PUSH):
- emitAddEDI4();
- break;
- case OP(POP):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(LEAVE):
- v = constant4();
- emitInstruction( "81 C6" ); // add esi, 0x12345678
- emit4( v );
- emitInstruction( "C3" ); // ret
- break;
- case OP(LOAD4):
- if (rom[pc].Operation == OP(CONST) && rom[pc+1].Operation == OP(ADD) && rom[pc+2].Operation == OP(STORE4))
- {
- if (oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- compiledOfs -= 11;
- instructionPointers[ instruction-1 ] = compiledOfs;
- }
- pc++; // OP(CONST)
- v = constant4();
- emitMovEBXEDI(ramMask);
- if (v == 1 && oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- emitInstruction( "FF 83"); // inc dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- }
- else
- {
- emitInstruction( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- emitInstruction( "05" ); // add eax, const
- emit4( v );
- if (oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- }
- else
- {
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "8B 1F" ); // mov ebx, dword ptr [edi]
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- }
- }
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(ADD)
- pc++; // OP(STORE)
- instruction += 3;
- break;
- }
-
- if (rom[pc].Operation == OP(CONST) && rom[pc+1].Operation == OP(SUB) && rom[pc+2].Operation == OP(STORE4))
- {
- if (oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL)) {
- compiledOfs -= 11;
- instructionPointers[ instruction-1 ] = compiledOfs;
- }
- emitMovEBXEDI(ramMask);
- emitInstruction( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- pc++; // OP(CONST)
- v = constant4();
- if (v == 1 && oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- emitInstruction( "FF 8B"); // dec dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- }
- else
- {
- emitInstruction( "2D" ); // sub eax, const
- emit4( v );
- if (oc0 == oc1 && pop0 == OP(LOCAL) && pop1 == OP(LOCAL))
- {
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- }
- else
- {
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "8B 1F" ); // mov ebx, dword ptr [edi]
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- }
- }
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- pc++; // OP(SUB)
- pc++; // OP(STORE)
- instruction += 3;
- break;
- }
-
- if (buf[compiledOfs-2] == 0x89 && buf[compiledOfs-1] == 0x07)
- {
- compiledOfs -= 2;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "8B 80"); // mov eax, dword ptr [eax + 0x1234567]
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- }
- emitMovEBXEDI(ramMask);
- emitInstruction( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678]
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(LOAD2):
- emitMovEBXEDI(ramMask);
- emitInstruction( "0F B7 83" ); // movzx eax, word ptr [ebx + 0x12345678]
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(LOAD1):
- emitMovEBXEDI(ramMask);
- emitInstruction( "0F B6 83" ); // movzx eax, byte ptr [ebx + 0x12345678]
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(STORE4):
- emitMovEAXEDI();
- emitInstruction( "8B 5F FC" ); // mov ebx, dword ptr [edi-4]
- // if (pop1 != OP(CALL)) {
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask & ~3 );
- // }
- emitInstruction( "89 83" ); // mov dword ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- break;
- case OP(STORE2):
- emitMovEAXEDI();
- emitInstruction( "8B 5F FC" ); // mov ebx, dword ptr [edi-4]
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask & ~1 );
- emitInstruction( "66 89 83" ); // mov word ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- break;
- case OP(STORE1):
- emitMovEAXEDI();
- emitInstruction( "8B 5F FC" ); // mov ebx, dword ptr [edi-4]
- // emitInstruction( "81 E3" ); // and ebx, 0x12345678
- // emit4( ramMask );
- emitInstruction( "88 83" ); // mov byte ptr [ebx+0x12345678], eax
- emit4( (int)ram );
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- break;
-
- case OP(EQ):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "75 06" ); // jne +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(NE):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "74 06" ); // je +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LTI):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "7D 06" ); // jnl +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LEI):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "7F 06" ); // jnle +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GTI):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "7E 06" ); // jng +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GEI):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "7C 06" ); // jnge +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LTU):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "73 06" ); // jnb +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LEU):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "77 06" ); // jnbe +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GTU):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "76 06" ); // jna +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GEU):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "8B 47 04" ); // mov eax, dword ptr [edi+4]
- emitInstruction( "3B 47 08" ); // cmp eax, dword ptr [edi+8]
- emitInstruction( "72 06" ); // jnae +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(EQF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 40" ); // test ah,0x40
- emitInstruction( "74 06" ); // je +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(NEF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 40" ); // test ah,0x40
- emitInstruction( "75 06" ); // jne +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LTF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 01" ); // test ah,0x01
- emitInstruction( "74 06" ); // je +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(LEF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 41" ); // test ah,0x41
- emitInstruction( "74 06" ); // je +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GTF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 41" ); // test ah,0x41
- emitInstruction( "75 06" ); // jne +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(GEF):
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- emitInstruction( "D9 47 04" ); // fld dword ptr [edi+4]
- emitInstruction( "D8 5F 08" ); // fcomp dword ptr [edi+8]
- emitInstruction( "DF E0" ); // fnstsw ax
- emitInstruction( "F6 C4 01" ); // test ah,0x01
- emitInstruction( "75 06" ); // jne +6
- emitInstruction( "FF 25" ); // jmp [0x12345678]
- v = constant4();
- jused[v] = 1;
- emit4( (int)instructionPointers + v*4 );
- break;
- case OP(NEGI):
- emitInstruction( "F7 1F" ); // neg dword ptr [edi]
- break;
- case OP(ADD):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "01 47 FC" ); // add dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(SUB):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "29 47 FC" ); // sub dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(DIVI):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "99" ); // cdq
- emitInstruction( "F7 3F" ); // idiv dword ptr [edi]
- emitInstruction( "89 47 FC" ); // mov dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(DIVU):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "33 D2" ); // xor edx, edx
- emitInstruction( "F7 37" ); // div dword ptr [edi]
- emitInstruction( "89 47 FC" ); // mov dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(MODI):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "99" ); // cdq
- emitInstruction( "F7 3F" ); // idiv dword ptr [edi]
- emitInstruction( "89 57 FC" ); // mov dword ptr [edi-4],edx
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(MODU):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "33 D2" ); // xor edx, edx
- emitInstruction( "F7 37" ); // div dword ptr [edi]
- emitInstruction( "89 57 FC" ); // mov dword ptr [edi-4],edx
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(MULI):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "F7 2F" ); // imul dword ptr [edi]
- emitInstruction( "89 47 FC" ); // mov dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(MULU):
- emitInstruction( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
- emitInstruction( "F7 27" ); // mul dword ptr [edi]
- emitInstruction( "89 47 FC" ); // mov dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(BAND):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "21 47 FC" ); // and dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(BOR):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "09 47 FC" ); // or dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(BXOR):
- emitMovEAXEDI(); // mov eax, dword ptr [edi]
- emitInstruction( "31 47 FC" ); // xor dword ptr [edi-4],eax
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(BCOM):
- emitInstruction( "F7 17" ); // not dword ptr [edi]
- break;
- case OP(LSH):
- emitInstruction( "8B 0F" ); // mov ecx, dword ptr [edi]
- emitInstruction( "D3 67 FC" ); // shl dword ptr [edi-4], cl
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(RSHI):
- emitInstruction( "8B 0F" ); // mov ecx, dword ptr [edi]
- emitInstruction( "D3 7F FC" ); // sar dword ptr [edi-4], cl
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(RSHU):
- emitInstruction( "8B 0F" ); // mov ecx, dword ptr [edi]
- emitInstruction( "D3 6F FC" ); // shr dword ptr [edi-4], cl
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(NEGF):
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "D9 E0" ); // fchs
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(ADDF):
- emitInstruction( "D9 47 FC" ); // fld dword ptr [edi-4]
- emitInstruction( "D8 07" ); // fadd dword ptr [edi]
- emitInstruction( "D9 5F FC" ); // fstp dword ptr [edi-4]
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- break;
- case OP(SUBF):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "D8 67 04" ); // fsub dword ptr [edi+4]
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(DIVF):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "D8 77 04" ); // fdiv dword ptr [edi+4]
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(MULF):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "D8 4f 04" ); // fmul dword ptr [edi+4]
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(CVIF):
- emitInstruction( "DB 07" ); // fild dword ptr [edi]
- emitInstruction( "D9 1F" ); // fstp dword ptr [edi]
- break;
- case OP(CVFI):
- #ifndef FTOL_PTR // WHENHELLISFROZENOVER // bk001213 - was used in 1.17
- // not IEEE complient, but simple and fast
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "DB 1F" ); // fistp dword ptr [edi]
- #else // FTOL_PTR
- // call the library conversion function
- emitInstruction( "D9 07" ); // fld dword ptr [edi]
- emitInstruction( "FF 15" ); // call ftolPtr
- emit4( (int)&ftolPtr );
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- #endif
- break;
- case OP(SEX8):
- emitInstruction( "0F BE 07" ); // movsx eax, byte ptr [edi]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
- case OP(SEX16):
- emitInstruction( "0F BF 07" ); // movsx eax, word ptr [edi]
- emitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax
- break;
-
- case OP(BLOCK_COPY):
- // FIXME: range check
- emitInstruction( "56" ); // push esi
- emitInstruction( "57" ); // push edi
- emitInstruction( "8B 37" ); // mov esi,[edi]
- emitInstruction( "8B 7F FC" ); // mov edi,[edi-4]
- emitInstruction( "B9" ); // mov ecx,0x12345678
- emit4( constant4() >> 2 );
- emitInstruction( "B8" ); // mov eax, ramMask
- emit4( ramMask );
- emitInstruction( "BB" ); // mov ebx, ram
- emit4( (int)ram );
- emitInstruction( "23 F0" ); // and esi, eax
- emitInstruction( "03 F3" ); // add esi, ebx
- emitInstruction( "23 F8" ); // and edi, eax
- emitInstruction( "03 FB" ); // add edi, ebx
- emitInstruction( "F3 A5" ); // rep movsd
- emitInstruction( "5F" ); // pop edi
- emitInstruction( "5E" ); // pop esi
- emitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8
- break;
-
- case OP(JUMP):
- emitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
- emitInstruction( "8B 47 04" ); // mov eax,dword ptr [edi+4]
- // FIXME: range check
- emitInstruction( "FF 24 85" ); // jmp dword ptr [instructionPointers + eax * 4]
- emit4( (int)instructionPointers );
- break;
- default:
- throw JITException("Compile: bad opcode");
- }
- pop0 = pop1;
- pop1 = op.Operation;
- }
- }
-
- // copy to an exact size buffer on the hunk
- //codeLength = compiledOfs;
- //codeBase = Hunk_Alloc( compiledOfs, h_low );
-
- //Com_Memcpy( codeBase, buf, compiledOfs );
-
- compiledRom = new char[compiledOfs];
- std::copy(buf, buf+compiledOfs, compiledRom);
- compiledRomSize = compiledOfs;
- compiledRomMask = compiledOfs;
-
- delete[] buf;
- delete[] jused;
-
- //printf( "VM file %s compiled to %i bytes of code\n", name, compiledOfs);
-
- // offset all the instruction pointers for the new location
- for ( i = 0 ; i < /*header->instructionCount*/ romSize ; i++ ) {
- instructionPointers[i] += (int)rom;
- }
-
-#ifdef WIN32
- VirtualProtect(compiledRom, compiledRomSize, PAGE_EXECUTE, NULL);
-#endif
- #if 0 // ndef _WIN32
- // Must make the newly generated code executable
- {
- int r;
- unsigned long addr;
- int psize = getpagesize();
-
- addr = ((int)codeBase & ~(psize-1)) - psize;
-
- r = mprotect((char*)addr, codeLength + (int)codeBase - addr + psize,
- PROT_READ | PROT_WRITE | PROT_EXEC );
-
- if (r < 0)
- Com_Error( ERR_FATAL, "mprotect failed to change PROT_EXEC" );
- }
- #endif
- return true;
-
- }
-
- int VirtualMachine::constant4()
- {
- int v;
-
- v = rom[pc-1].Parameter.int4;// | (rom[pc-1].Parameter<<8) | (rom[pc-1].Parameter<<16) | (rom[pc-1].Parameter<<24);
- return v;
- }
-
- int VirtualMachine::constant1()
- {
- int v;
-
- v = rom[pc-1].Parameter.uint1;
- return v;
- }
-
- void VirtualMachine::emit1(int v)
- {
- buf[compiledOfs] = v;
- compiledOfs++;
-
- LastCommand = LAST_COMMAND_NONE;
- }
-
- void VirtualMachine::emit4(int v)
- {
- emit1(v & 255);
- emit1((v >> 8) & 255);
- emit1((v >> 16) & 255);
- emit1((v >> 24) & 255);
- }
-
- void VirtualMachine::emitInstruction(const char *string)
- {
- int c1, c2;
- int v;
-
- while (true)
- {
- c1 = string[0];
- c2 = string[1];
-
- v = (hex( c1 ) << 4) | hex(c2);
- emit1( v );
-
- if (!string[2])
- {
- break;
- }
- string += 3;
- }
- }
-
- void VirtualMachine::emitCommand(int command_)
- {
- ELastCommand command = (ELastCommand)command_;
- switch(command)
- {
- case LAST_COMMAND_MOV_EDI_EAX:
- emitInstruction( "89 07" ); // mov dword ptr [edi], eax
- break;
- case LAST_COMMAND_SUB_DI_4:
- emitInstruction( "83 EF 04" ); // sub edi, 4
- break;
- case LAST_COMMAND_SUB_DI_8:
- emitInstruction( "83 EF 08" ); // sub edi, 8
- break;
- default:
- break;
- }
- LastCommand = command;
- }
-
- void VirtualMachine::emitAddEDI4()
- {
- if (LastCommand == LAST_COMMAND_SUB_DI_4 && jused[instruction-1] == 0)
- { // sub di,4
- compiledOfs -= 3;
- instructionPointers[ instruction-1 ] = compiledOfs;
- return;
- }
- if (LastCommand == LAST_COMMAND_SUB_DI_8 && jused[instruction-1] == 0)
- { // sub di,8
- compiledOfs -= 3;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "83 EF 04" ); // sub edi,4
- return;
- }
- emitInstruction( "83 C7 04" ); // add edi,4
- }
-
- void VirtualMachine::emitMovEAXEDI()
- {
- if (LastCommand == LAST_COMMAND_MOV_EDI_EAX)
- { // mov [edi], eax
- compiledOfs -= 2;
- instructionPointers[ instruction-1 ] = compiledOfs;
- return;
- }
- if (pop1 == OP(DIVI) || pop1 == OP(DIVU) || pop1 == OP(MULI) || pop1 == OP(MULU) || pop1 == OP(STORE4) || pop1 == OP(STORE2) || pop1 == OP(STORE1) )
- {
- return;
- }
- if (pop1 == OP(CONST) && buf[compiledOfs-6] == 0xC7 && buf[compiledOfs-5] == 0x07)
- { // mov edi, 0x123456
- compiledOfs -= 6;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "B8" ); // mov eax, 0x12345678
- emit4( lastConst );
- return;
- }
- emitInstruction( "8B 07" ); // mov eax, dword ptr [edi]
- }
-
- bool VirtualMachine::emitMovEBXEDI(int andit)
- {
- if (LastCommand == LAST_COMMAND_MOV_EDI_EAX)
- { // mov [edi], eax
- compiledOfs -= 2;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "8B D8"); // mov bx, eax
- return false;
- }
- if (pop1 == OP(DIVI) || pop1 == OP(DIVU) || pop1 == OP(MULI) || pop1 == OP(MULU) || pop1 == OP(STORE4) || pop1 == OP(STORE2) || pop1 == OP(STORE1) )
- {
- emitInstruction( "8B D8"); // mov bx, eax
- return false;
- }
- if (pop1 == OP(CONST) && buf[compiledOfs-6] == 0xC7 && buf[compiledOfs-5] == 0x07 )
- { // mov edi, 0x123456
- compiledOfs -= 6;
- instructionPointers[ instruction-1 ] = compiledOfs;
- emitInstruction( "BB" ); // mov ebx, 0x12345678
- if (andit) {
- emit4( lastConst & andit );
- } else {
- emit4( lastConst );
- }
- return true;
- }
-
- emitInstruction( "8B 1F" ); // mov ebx, dword ptr [edi]
- return false;
- }
-
- int VirtualMachine::hex(int c)
- {
- if (c >= 'a' && c <= 'f')
- return 10 + c - 'a';
- if (c >= 'A' && c <= 'F')
- return 10 + c - 'A';
- if (c >= '0' && c <= '9')
- return c - '0';
-
- throw JITException("hex: bad character");
-
- return 0;
- }
-
- #undef OP
-}
-
-#endif
diff --git a/src/virtualmachine/Operations.cpp b/src/virtualmachine/Operations.cpp
deleted file mode 100644
index 0c998a8..0000000
--- a/src/virtualmachine/Operations.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-#include "VirtualMachine.h"
-
-namespace vm
-{
- #define OPDEF(n) &VirtualMachine::Op##n,
- OperationFunction VirtualMachine::operations[] =
- {
- #include "Operations.inl"
- };
- #undef OPDEF
-
- #define OPDEF(n) int VirtualMachine::Op##n(word parameter)
-
- #define R0 (r[0])
- #define R1 (r[1])
- #define R2 (r[2])
-
-
- OPDEF(UNDEF)
- {
- /* Die horribly. */
- throw RuntimeException();
- return -1;
- }
-
- OPDEF(IGNORE)
- {
- /* NOP */
- throw RuntimeException();
- return 0;
- }
-
- OPDEF(BREAK)
- {
- /* Usage never spotted. */
- /* Die horribly? */
- throw RuntimeException();
- return -1;
- }
-
- /*
- Stack on entering...
-
- no locals: ENTER 8
- 1 words locals: ENTER 16
- 2 words locals: ENTER 20
- 3 words locals: ENTER 24
- etc.
-
- address of argument:
- ADDRFP4 v => OP_LOCAL (16 + currentLocals + currentArgs + v)
- address of local:
- ADDRLP4 v => OP_LOCAL (8 + currentArgs + v)
-
- RP [ ] ??? (oldPC?)
- [ ] ???
- [ ] \
- ... > locals (args marshalling)
- [ ] /
- [ ] \
- ... > locals
- [ ] / (ADDRLP4 v => OP_LOCAL (8 + currentArgs + v))
- (oldRP?) [ ] ???
- [ ] ???
- [ ] (my args?)
- ...
- [ ]
- */
-
- OPDEF(ENTER) /* ??? */
- {
- while (parameter.int4 > (2 * sizeof(word)))
- {
- RPush<int4_t>(0); /* init zero */
- parameter.int4 -= sizeof(word);
- }
- RPush(Pop()); //Program Counter
- RPush<int4_t>(0); //Unknown
- return 0;
- }
-
- OPDEF(LEAVE) /* ??? */
- {
- RPop(); //Unknown
- parameter.int4 -= sizeof(word);
- PC = RPop<int4_t>(); //Program counter
- parameter.int4 -= sizeof(word);
- while (parameter.int4 > 0)
- {
- RPop();
- parameter.int4 -= sizeof(word);
- }
- return 0;
- }
-
- OPDEF(CALL) /* Call subroutine. */
- {
- R0 = Pop();
- Push<int4_t>(PC);
- PC = R0.int4;
- return 0;
- }
-
- OPDEF(PUSH) /* [DP] <- 0; DP++ */
- {
- Push(0);
- return 0;
- }
-
- OPDEF(POP) /* DP-- */
- {
- Pop();
- return 0;
- }
-
- OPDEF(CONST) /* [DP] <- parm; DP++ */
- {
- Push(parameter);
- return 0;
- }
-
- OPDEF(LOCAL) /* [DP] <- [RP-n] */
- {
- Push<int4_t>(RP + parameter.int4);
- return 0;
- }
-
- OPDEF(JUMP) /* PC <- [DP] */
- {
- PC = Pop<int4_t>();
- return 0;
- }
-
- #define CMP(type, op) \
- { \
- R0 = Pop(); \
- cm = (Pop<type##_t>() op R0.type); \
- if (cm) \
- PC = parameter.uint4; \
- return 0; \
- }
-
- OPDEF(EQ) /* if [DP] == [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, ==)
-
- OPDEF(NE) /* if [DP] == [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, !=)
-
- OPDEF(LTI) /* if [DP] < [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, <)
-
- OPDEF(LEI) /* if [DP] <= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, <=)
-
- OPDEF(GTI) /* if [DP] > [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, >)
-
- OPDEF(GEI) /* if [DP] >= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(int4, >=)
-
- OPDEF(LTU) /* if [DP] < [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(uint4, <)
-
- OPDEF(LEU) /* if [DP] <= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(uint4, <=)
-
- OPDEF(GTU) /* if [DP] > [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(uint4, >)
-
- OPDEF(GEU) /* if [DP] >= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(uint4, >=)
-
- OPDEF(EQF) /* if [DP] == [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, ==)
-
- OPDEF(NEF) /* if [DP] != [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, !=)
-
- OPDEF(LTF) /* if [DP] < [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, <)
-
- OPDEF(LEF) /* if [DP] <= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, <=)
-
- OPDEF(GTF) /* if [DP] > [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, >)
-
- OPDEF(GEF) /* if [DP] >= [DP-1] then PC <- parm; DP <- DP-2 */
- CMP(float4, >=)
-
-
- OPDEF(LOAD1) /* [DP] <- [[DP]] */
- {
- Push<uint1_t>(Get<uint1_t>(Pop<uint4_t>()));
- return 0;
- }
-
- OPDEF(LOAD2) /* [DP] <- [[DP]] */
- {
- Push<uint2_t>(Get<uint2_t>(Pop<uint4_t>()));
- return 0;
- }
-
- OPDEF(LOAD4) /* [DP] <- [[DP]] */
- {
- Push<uint4_t>(Get<uint4_t>(Pop<uint4_t>()));
- return 0;
- }
-
- OPDEF(STORE1) /* [DP-1] <- [DP]; DP <- DP-2 */
- {
- Set<uint1_t>(Pop<uint4_t>(), Pop<uint1_t>());
- return 0;
- }
-
- OPDEF(STORE2) /* [DP-1] <- [DP]; DP <- DP-2 */
- {
- Set<uint2_t>(Pop<uint4_t>(), Pop<uint2_t>());
- return 0;
- }
-
- OPDEF(STORE4) /* [DP-1] <- [DP]; DP <- DP-2 */
- {
- Set<uint4_t>(Pop<uint4_t>(), Pop<uint4_t>());
- return 0;
- }
-
- OPDEF(ARG) /* Marshal TOS to to-call argument list */
- {
- Marshal(parameter.uint1, Pop());
- return 0;
- }
-
- OPDEF(BLOCK_COPY) /* XXX */
- {
- R1 = Pop();
- R0 = Pop();
- if(R0.int4 >= 0 && R0.int4 + parameter.int4 < ramSize && R1.int4 >= 0 && R1.int4 + parameter.int4 < ramSize)
- memcpy(ram + R0.int4, ram + R1.int4, parameter.int4);
- else
- throw AccessViolationException();
- return -1;
- }
-
- OPDEF(SEX8) /* Sign-extend 8-bit */
- {
- R0 = Pop();
- if(R0.uint4 & 0x80)
- R0.uint4 |= 0xFFFFFF80;
- Push(R0);
- return 0;
- }
-
- OPDEF(SEX16) /* Sign-extend 16-bit */
- {
- R0 = Pop();
- if(R0.uint4 & 0x8000)
- R0.uint4 |= 0xFFFF8000;
- Push(R0);
- return 0;
- }
-
- #define UNOP(type, op) \
- { \
- Push<type##_t>(op Pop<type##_t>()); \
- return 0; \
- }
-
- #define BINOP(type, op) \
- { \
- R0 = Pop(); \
- Push<type##_t>(Pop<type##_t>() op R0.type); \
- return 0; \
- }
-
- OPDEF(NEGI) /* [DP] <- -[DP] */
- UNOP(int4, -)
-
- OPDEF(ADD) /* [DP-1] <- [DP-1] + [DP]; DP <- DP-1 */
- BINOP(int4, +)
-
- OPDEF(SUB) /* [DP-1] <- [DP-1] - [DP]; DP <- DP-1 */
- BINOP(int4, -)
-
- OPDEF(DIVI) /* [DP-1] <- [DP-1] / [DP]; DP <- DP-1 */
- BINOP(int4, /)
-
- OPDEF(DIVU) /* [DP-1] <- [DP-1] / [DP]; DP <- DP-1 */
- BINOP(uint4, /)
-
- OPDEF(MODI) /* [DP-1] <- [DP-1] % [DP]; DP <- DP-1 */
- BINOP(int4, %)
-
- OPDEF(MODU) /* [DP-1] <- [DP-1] % [DP]; DP <- DP-1 */
- BINOP(uint4, %)
-
- OPDEF(MULI) /* [DP-1] <- [DP-1] * [DP]; DP <- DP-1 */
- BINOP(int4, *)
-
- OPDEF(MULU) /* [DP-1] <- [DP-1] * [DP]; DP <- OP-1 */
- BINOP(uint4, *)
-
- OPDEF(BAND) /* [DP-1] <- [DP-1] & [DP]; DP <- DP-1 */
- BINOP(uint4, &)
-
- OPDEF(BOR) /* [DP-1] <- [DP-1] | [DP]; DP <- DP-1 */
- BINOP(uint4, |)
-
- OPDEF(BXOR) /* [DP-1] <- [DP-1] ^ [DP]; DP <- DP-1 */
- BINOP(uint4, ^)
-
- OPDEF(BCOM) /* [DP] <- ~[DP] */
- UNOP(uint4, ~)
-
- OPDEF(LSH) /* [DP-1] <- [DP-1] << [DP]; DP <- DP-1 */
- BINOP(uint4, <<)
-
- OPDEF(RSHI) /* [DP-1] <- [DP-1] >> [DP]; DP <- DP-1 */
- {
- R1.int4 = Pop<int4_t>();
- R0.int4 = Pop<int4_t>();
- R2.int4 = R0.int4 >> R1.int4;
- Push(R2);
- return 0;
- }
-
- OPDEF(RSHU) /* [DP-1] <- [DP-1] >> [DP]; DP <- DP-1 */
- BINOP(uint4, >>)
-
- OPDEF(NEGF) /* [DP] <- -[DP] */
- UNOP(float4, -)
-
- OPDEF(ADDF) /* [DP-1] <- [DP-1] + [DP]; DP <- DP-1 */
- BINOP(float4, +)
-
- OPDEF(SUBF) /* [DP-1] <- [DP-1] - [DP]; DP <- DP-1 */
- BINOP(float4, -)
-
- OPDEF(DIVF) /* [DP-1] <- [DP-1] / [DP]; DP <- DP-1 */
- BINOP(float4, /)
-
- OPDEF(MULF) /* [DP-1] <- [DP-1] / [DP]; DP <- DP-1 */
- BINOP(float4, *)
-
- OPDEF(CVIF) /* [DP] <- [DP] */
- {
- Push<float4_t>(Pop<int4_t>());
- return 0;
- }
-
- OPDEF(CVFI) /* [DP] <- [DP] */
- {
- Push<int4_t>(Pop<float4_t>());
- return 0;
- }
-}
diff --git a/src/virtualmachine/Operations.inl b/src/virtualmachine/Operations.inl
deleted file mode 100644
index a1d4b43..0000000
--- a/src/virtualmachine/Operations.inl
+++ /dev/null
@@ -1,60 +0,0 @@
-OPDEF(UNDEF)
-OPDEF(IGNORE) /* no-op */
-OPDEF(BREAK) /* ??? */
-OPDEF(ENTER) /* Begin subroutine. */
-OPDEF(LEAVE) /* End subroutine. */
-OPDEF(CALL) /* Call subroutine. */
-OPDEF(PUSH) /* push to stack. */
-OPDEF(POP) /* discard top-of-stack. */
-OPDEF(CONST) /* load constant to stack. */
-OPDEF(LOCAL) /* get local variable. */
-OPDEF(JUMP) /* unconditional jump. */
-OPDEF(EQ) /* compare integers, jump if equal. */
-OPDEF(NE) /* compare integers, jump if not equal. */
-OPDEF(LTI) /* compare integers, jump if less-than. */
-OPDEF(LEI) /* compare integers, jump if less-than-or-equal. */
-OPDEF(GTI) /* compare integers, jump if greater-than. */
-OPDEF(GEI) /* compare integers, jump if greater-than-or-equal. */
-OPDEF(LTU) /* compare unsigned integers, jump if less-than */
-OPDEF(LEU) /* compare unsigned integers, jump if less-than-or-equal */
-OPDEF(GTU) /* compare unsigned integers, jump if greater-than */
-OPDEF(GEU) /* compare unsigned integers, jump if greater-than-or-equal */
-OPDEF(EQF) /* compare floats, jump if equal */
-OPDEF(NEF) /* compare floats, jump if not-equal */
-OPDEF(LTF) /* compare floats, jump if less-than */
-OPDEF(LEF) /* compare floats, jump if less-than-or-equal */
-OPDEF(GTF) /* compare floats, jump if greater-than */
-OPDEF(GEF) /* compare floats, jump if greater-than-or-equal */
-OPDEF(LOAD1) /* load 1-byte from memory */
-OPDEF(LOAD2) /* load 2-byte from memory */
-OPDEF(LOAD4) /* load 4-byte from memory */
-OPDEF(STORE1) /* store 1-byte to memory */
-OPDEF(STORE2) /* store 2-byte to memory */
-OPDEF(STORE4) /* store 4-byte to memory */
-OPDEF(ARG) /* marshal argument */
-OPDEF(BLOCK_COPY) /* block copy... */
-OPDEF(SEX8) /* Pedophilia */
-OPDEF(SEX16) /* Sign-Extend 16-bit */
-OPDEF(NEGI) /* Negate integer. */
-OPDEF(ADD) /* Add integers (two's complement). */
-OPDEF(SUB) /* Subtract integers (two's complement). */
-OPDEF(DIVI) /* Divide signed integers. */
-OPDEF(DIVU) /* Divide unsigned integers. */
-OPDEF(MODI) /* Modulus (signed). */
-OPDEF(MODU) /* Modulus (unsigned). */
-OPDEF(MULI) /* Multiply signed integers. */
-OPDEF(MULU) /* Multiply unsigned integers. */
-OPDEF(BAND) /* Bitwise AND */
-OPDEF(BOR) /* Bitwise OR */
-OPDEF(BXOR) /* Bitwise eXclusive-OR */
-OPDEF(BCOM) /* Bitwise COMplement */
-OPDEF(LSH) /* Left-shift */
-OPDEF(RSHI) /* Right-shift (algebraic; preserve sign) */
-OPDEF(RSHU) /* Right-shift (bitwise; ignore sign) */
-OPDEF(NEGF) /* Negate float */
-OPDEF(ADDF) /* Add floats */
-OPDEF(SUBF) /* Subtract floats */
-OPDEF(DIVF) /* Divide floats */
-OPDEF(MULF) /* Multiply floats */
-OPDEF(CVIF) /* Convert to integer from float */
-OPDEF(CVFI) /* Convert to float from integer */ \ No newline at end of file
diff --git a/src/virtualmachine/Syscalls.cpp b/src/virtualmachine/Syscalls.cpp
deleted file mode 100644
index e4ca7ca..0000000
--- a/src/virtualmachine/Syscalls.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#include <cstdio>
-#include <cstdlib>
-#include <cmath>
-#include "VirtualMachine.h"
-#include "simulation/Simulation.h"
-#include "graphics/Renderer.h"
-
-namespace vm
-{
- #define ARG(n) (Get(RP + ((2 + n) * sizeof(word))))
-
- #define TRAPDEF(f) int VirtualMachine::trap##f()
-
- TRAPDEF(sin)
- {
- Push<float4_t>(sin(ARG(0).float4));
- return 0;
- }
-
- TRAPDEF(cos)
- {
- Push<float4_t>(cos(ARG(0).float4));
- return 0;
- }
-
- TRAPDEF(atan2)
- {
- Push<float4_t>(atan2(ARG(0).float4, ARG(1).float4));
- return 0;
- }
-
- TRAPDEF(sqrt)
- {
- Push<float4_t>(sqrt(ARG(0).float4));
- return 0;
- }
-
- TRAPDEF(floor)
- {
- Push<float4_t>(floor(ARG(0).float4));
- return 0;
- }
-
- TRAPDEF(ceil)
- {
- Push<float4_t>(ceil(ARG(0).float4));
- return 0;
- }
-
-
- TRAPDEF(print)
- {
- char *text;
- text = (char*)(ram) + ARG(0).int4;
- printf("%s", text);
- return 0;
- }
-
-
- TRAPDEF(error)
- {
- char *msg;
- msg = (char*)(ram) + ARG(0).int4;
- printf("%s", msg);
- End();
- return 0;
- }
-
-
- TRAPDEF(partCreate)
- {
- Push<int4_t>(sim->create_part(ARG(0).int4, ARG(1).int4, ARG(2).int4, ARG(3).int4));
- return 0;
- }
-
- TRAPDEF(partChangeType)
- {
- sim->part_change_type(ARG(0).int4, ARG(1).int4, ARG(2).int4, ARG(3).int4);
- return 0;
- }
-
- TRAPDEF(pmapData)
- {
- Push<int4_t>(sim->pmap[ARG(1).int4][ARG(0).int4]);
- return 0;
- }
-
- TRAPDEF(deletePart)
- {
- sim->delete_part(ARG(0).int4, ARG(1).int4);
- return 0;
- }
-
- TRAPDEF(killPart)
- {
- sim->kill_part(ARG(0).int4);
- return 0;
- }
-}
diff --git a/src/virtualmachine/Syscalls.inl b/src/virtualmachine/Syscalls.inl
deleted file mode 100644
index 75455c1..0000000
--- a/src/virtualmachine/Syscalls.inl
+++ /dev/null
@@ -1,14 +0,0 @@
-TRAPDEF(-1, sin)
-TRAPDEF(-2, cos)
-TRAPDEF(-3, atan2)
-TRAPDEF(-4, sqrt)
-TRAPDEF(-5, floor)
-TRAPDEF(-6, ceil)
-
-TRAPDEF(-7, error)
-TRAPDEF(-8, print)
-TRAPDEF(-9, partCreate)
-TRAPDEF(-10, partChangeType)
-TRAPDEF(-11, pmapData)
-TRAPDEF(-12, deletePart)
-TRAPDEF(-13, killPart)
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;
- }
-}
diff --git a/src/virtualmachine/VirtualMachine.h b/src/virtualmachine/VirtualMachine.h
deleted file mode 100644
index b295d02..0000000
--- a/src/virtualmachine/VirtualMachine.h
+++ /dev/null
@@ -1,282 +0,0 @@
-#pragma once
-
-#include "Exceptions.h"
-
-class Simulation;
-class Renderer;
-
-namespace vm
-{
-
- class VirtualMachine;
-
- typedef char ram_t;
-
-
-
- typedef unsigned int uint4_t;
- typedef signed int int4_t;
-
- typedef unsigned short uint2_t;
- typedef signed short int2_t;
-
- typedef unsigned char uint1_t;
- typedef signed char int1_t;
-
- typedef float float4_t;
-
- union word
- {
- uint4_t uint4;
- int4_t int4;
- uint2_t uint2;
- int2_t int2;
- uint1_t uint1;
- int1_t int1;
- float4_t float4;
- };
-
- typedef int (VirtualMachine::*OperationFunction)(word parameter);
-
- struct Instruction
- {
- int Operation;
- word Parameter;
- //opfunc opfunc;
- };
-
- enum
- {
- QVM_MAGIC = 0x12721444,
- };
-
- struct qvm_header_t
- {
- int magic;
- /* not-entirely-RISC ISA, so instruction count != codelen */
- int inscount; /* instruction count. */
- int codeoff; /* file offset of code segment. */
- int codelen; /* length of code segment, in octets. */
- int dataoff; /* file offset of data segment. */
- int datalen; /* length of data segment, in octets. */
- int litlen; /* length of lit segment (which is embedded in data segment). */
- int bsslen; /* length of bss segment. */
- };
-
- class VirtualMachine
- {
-
- int * instructionPointers;
-
- bool bigEndian; /* host is big-endian (requires byte-swapping). */
-
- /* Memory spaces. */
- char * hunk; /* hunk space (malloc'd). */
- int hunkSize; /* total hunk size. */
- int hunkFree; /* free pointer. */
-
- /* Read-Only Memory (code). */
- Instruction * rom;
- int romSize;
- int romMask;
-
- char * compiledRom;
- int compiledRomSize;
- int compiledRomMask;
-
- /* Random-Access Memory (data). */
- ram_t *ram;
- int ramSize;
- int ramMask;
-
- int dataStack;
- int returnStack;
-
- word r[4]; /* registers. */
- int DP; /* Datastack pointer. */
- int RP; /* Return stack pointer. */
- int PC; /* Program Counter. */
- // int AP; /* Argument pointer. (hrm...) */
-
- /* various flags. */
- int cm:1;
-
- /* Execution time */
- int cycles;
-
- #define TRAPDEF(n, f) int trap##f();
- #include "Syscalls.inl"
- #undef TRAPDEF
-
- static OperationFunction operations[];
-
-
- #define OPDEF(n) OP##n,
- enum {
- #include "Operations.inl"
- };
- #undef OPDEF
-
- int readProgram(std::istream & input);
- int readByte(std::istream & input);
- int readInt(std::istream & input);
- int opcodeParameterSize(int opcode);
- int syscall(int programCounter);
-
- //Used by the JIT
- #ifdef VMJIT
- int constant4();
- int constant1();
- void emit1(int v);
- void emit4(int v);
- void emitInstruction(const char *string);
- void emitCommand(int command);
- void emitAddEDI4();
- void emitMovEAXEDI();
- bool emitMovEBXEDI(int andit);
- static int hex(int c);
- #endif
-public:
- #ifdef VMJIT
- static void callFromCompiled();
- static void callSyscall();
- bool Compile();
- int CallCompiled(int address);
- #endif
- Simulation * sim;
- Renderer * ren;
-
- #define OPDEF(n) int Op##n(word parameter);
- #include "Operations.inl"
- #undef OPDEF
-
- VirtualMachine(int hunkMbytes);
- virtual ~VirtualMachine();
-
- int LoadProgram(char * filename);
- int LoadProgram(std::vector<char> fileData);
- int Run();
- int CallInterpreted(int address);
- void End();
- void Marshal(int address, word element)
- {
- ram_t * ptr = ram+RP+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(RP+address);
- *((word*)ptr) = element;
- }
-
- template <typename T> T Get(int address)
- {
- ram_t * ptr = ram+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(address);
- return *((T*)ptr);
- }
-
- template <typename T> void Set(int address, T value)
- {
- ram_t * ptr = ram+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(address);
- *((T*)ptr) = value;
- }
-
- template <typename T> T Pop ()
- {
- ram_t * ptr = ram+DP;
- if(DP + sizeof(word) < hunkSize)
- DP += sizeof(word);
- else
- throw StackUnderflowException();
- return *((T*)ptr);
- };
-
- template <typename T> T RPop ()
- {
- ram_t * ptr = ram+RP;
- if(RP + sizeof(word) < hunkSize)
- RP += sizeof(word);
- else
- throw StackUnderflowException();
- return *((T*)ptr);
- };
-
- template <typename T> void Push(T value)
- {
- if(DP - sizeof(word) >= 0)
- DP -= sizeof(word);
- else
- throw StackOverflowException();
- ram_t * ptr = ram+DP;
- *((T*)ptr) = value;
- };
-
- template <typename T> void RPush(T value)
- {
- if(RP - sizeof(word) >= 0)
- RP -= sizeof(word);
- else
- throw StackOverflowException();
- ram_t * ptr = ram+RP;
- *((T*)ptr) = value;
- };
-
- word Get(int address)
- {
- ram_t * ptr = ram+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(address);
- return *((word*)ptr);
- }
-
- void Set(int address, word value)
- {
- ram_t * ptr = ram+address;
- if(ptr < ram || ptr > ram+ramSize - sizeof(word))
- throw AccessViolationException(address);
- *((word*)ptr) = value;
- }
-
- word Pop()
- {
- ram_t * ptr = ram+DP;
- if(DP + sizeof(word) < hunkSize)
- DP += sizeof(word);
- else
- throw StackUnderflowException();
- return *((word*)ptr);
- };
-
- void Push(word value)
- {
- if(DP - sizeof(word) >= 0)
- DP -= sizeof(word);
- else
- throw StackOverflowException();
- ram_t * ptr = ram+DP;
- *((word*)ptr) = value;
- };
-
- word RPop()
- {
- ram_t * ptr = ram+RP;
- if(RP + sizeof(word) < hunkSize)
- RP += sizeof(word);
- else
- throw StackUnderflowException();
- return *((word*)ptr);
- };
-
- void RPush(word value)
- {
- if(RP - sizeof(word) >= 0)
- RP -= sizeof(word);
- else
- throw StackOverflowException();
- ram_t * ptr = ram+RP;
- *((word*)ptr) = value;
- };
- };
-
-}