diff options
Diffstat (limited to 'src/pim/Machine.cpp')
| -rw-r--r-- | src/pim/Machine.cpp | 637 |
1 files changed, 0 insertions, 637 deletions
diff --git a/src/pim/Machine.cpp b/src/pim/Machine.cpp deleted file mode 100644 index a954d31..0000000 --- a/src/pim/Machine.cpp +++ /dev/null @@ -1,637 +0,0 @@ -//Virtual machine - -#include <iostream> -#include "Machine.h" -#include "Opcodes.h" -#include "simulation/Simulation.h" -namespace pim -{ - /*unsigned char * rom; - int romSize; - int romMask; - - unsigned char * ram; - int ramSize; - int ramMask; - - int programStack; - int callStack;*/ - - VirtualMachine::VirtualMachine(Simulation * simulation) : - rom(NULL), - ram(NULL), - sim(simulation) - { - - } - - void VirtualMachine::LoadProgram(std::vector<unsigned char> fileData) - { - int lastBit = 0; - - if(!(fileData[0] == 'P' && fileData[1] == 'V' && fileData[2] == 'M' && fileData[3] == '1' && fileData.size() >= 16)) - { - throw InvalidProgramException(); - } - - int macroSize = 0, propSize = 0, codeSize = 0; - macroSize = fileData[4]; - macroSize |= fileData[5] << 8; - macroSize |= fileData[6] << 16; - macroSize |= fileData[7] << 24; - - propSize = fileData[8]; - propSize |= fileData[9] << 8; - propSize |= fileData[10] << 16; - propSize |= fileData[11] << 24; - - codeSize = fileData[12]; - codeSize |= fileData[13] << 8; - codeSize |= fileData[14] << 16; - codeSize |= fileData[15] << 24; - - if(fileData.size() < 16 + macroSize + propSize + codeSize) - { - throw InvalidProgramException(); - } - - //std::vector<std::pair<int, int> > insertions; - - int macroOffset = 16; - int propOffset = macroOffset+macroSize; - int codeOffset = propOffset+propSize; - - - int filePosition = macroOffset; - while(filePosition + 4 < macroSize + macroOffset) - { - std::string macro; - int macroPosition; - int macroValue; - - macroPosition = fileData[filePosition++]; - macroPosition |= fileData[filePosition++] << 8; - macroPosition |= fileData[filePosition++] << 16; - macroPosition |= fileData[filePosition++] << 24; - - int stringLength = fileData[filePosition++]; - if(filePosition + stringLength > macroSize + macroOffset) - { - throw InvalidProgramException(); - } - - macro.insert(macro.begin(), fileData.begin()+filePosition, fileData.begin()+filePosition+stringLength); - filePosition += stringLength; - - bool resolved = false; - for(int i = 0; i < PT_NUM; i++) - { - if(sim->elements[i].Enabled && sim->elements[i].Identifier == macro) - { - macroValue = i; - resolved = true; - } - } - if(!resolved) - { - throw UnresolvedValueException(macro); - } - - if(macroPosition + 3 >= codeSize) - { - throw InvalidProgramException(); - } - - std::cout << "Macro insertion [" << macro << "] at " << macroPosition << " with " << macroValue << std::endl; - - fileData[codeOffset+macroPosition] = macroValue & 0xFF; - fileData[codeOffset+macroPosition+1] = (macroValue >> 8) & 0xFF; - fileData[codeOffset+macroPosition+2] = (macroValue >> 16) & 0xFF; - fileData[codeOffset+macroPosition+3] = (macroValue >> 24) & 0xFF; - //insertions.push_back(std::pair<int, int>(macroPosition, macroValue)); - } - - filePosition = propOffset; - while(filePosition + 4 < propSize + propOffset) - { - std::string prop; - int propPosition; - int propValue; - - propPosition = fileData[filePosition++]; - propPosition |= fileData[filePosition++] << 8; - propPosition |= fileData[filePosition++] << 16; - propPosition |= fileData[filePosition++] << 24; - - int stringLength = fileData[filePosition++]; - if(filePosition + stringLength > propSize + propOffset) - { - throw InvalidProgramException(); - } - - prop.insert(prop.begin(), fileData.begin()+filePosition, fileData.begin()+filePosition+stringLength); - filePosition += stringLength; - - bool resolved = false; - - std::vector<StructProperty> properties = Particle::GetProperties(); - for(std::vector<StructProperty>::iterator iter = properties.begin(), end = properties.end(); iter != end; ++iter) - { - StructProperty property = *iter; - std::cout << property.Offset << std::endl; - if(property.Name == prop && - (property.Type == StructProperty::ParticleType || - property.Type == StructProperty::Colour || - property.Type == StructProperty::Integer || - property.Type == StructProperty::UInteger || - property.Type == StructProperty::Float) - ) - { - propValue = property.Offset; - resolved = true; - break; - } - } - if(!resolved) - { - throw UnresolvedValueException(prop); - } - - if(propPosition + 3 >= codeSize) - { - throw InvalidProgramException(); - } - - std::cout << "Property insertion [" << prop << "] at " << propPosition << " with " << propValue << std::endl; - - fileData[codeOffset+propPosition] = propValue & 0xFF; - fileData[codeOffset+propPosition+1] = (propValue >> 8) & 0xFF; - fileData[codeOffset+propPosition+2] = (propValue >> 16) & 0xFF; - fileData[codeOffset+propPosition+3] = (propValue >> 24) & 0xFF; - //insertions.push_back(std::pair<int, int>(macroPosition, macroValue)); - } - - std::vector<unsigned char> programData; - programData.insert(programData.begin(), fileData.begin()+codeOffset, fileData.begin()+codeOffset+codeSize); - - romSize = programData.size(); - - for (lastBit = 0; romSize > (1 << lastBit); lastBit++ ) { } - romSize = 1 << lastBit; - romMask = romSize - 1; - - rom = new Instruction[romSize]; - - int pc = 0; - int programPosition = 0; - - while(programPosition < programData.size()) - { - int argSize = 0; - Instruction instruction; - instruction.Opcode = programData[programPosition++]; - if(argSize = OpcodeArgSize(instruction.Opcode)) - { - if(argSize == 4 && programPosition+3 < programData.size()) - { - int tempInt = 0; - tempInt |= programData[programPosition]; - tempInt |= programData[programPosition+1] << 8; - tempInt |= programData[programPosition+2] << 16; - tempInt |= programData[programPosition+3] << 24; - - - std::cout << "Got integer " << tempInt << std::endl; - - if(instruction.Opcode == Opcode::LoadProperty || instruction.Opcode == Opcode::StoreProperty) - { - if(tempInt > offsetof(Particle, dcolour)) - throw InvalidProgramException(); - } - - instruction.Parameter.Integer = tempInt; - - programPosition += 4; - } - } - else - { - instruction.Parameter.Integer = 0; - } - rom[pc++] = instruction; - } - romSize = pc; - - ramSize = 1024; - ramMask = ramSize - 1; - - ram = new unsigned char[ramSize]; - programStack = ramSize-1; - callStack = ramSize-260; - - framePointer = callStack; - callStack += WORDSIZE; //Since there's nothing on the stack, it shouldn't point to the item on the bottom - } - - int VirtualMachine::OpcodeArgSize(int opcode) - { - switch(opcode) - { - case Opcode::Load: - case Opcode::Store: - case Opcode::Constant: - case Opcode::Increment: - case Opcode::JumpEqual: - case Opcode::JumpNotEqual: - case Opcode::JumpGreater: - case Opcode::JumpGreaterEqual: - case Opcode::JumpLess: - case Opcode::JumpLessEqual: - case Opcode::Jump: - case Opcode::Return: - case Opcode::LocalEnter: - case Opcode::LoadProperty: - case Opcode::StoreProperty: - return 4; - case Opcode::Discard: - case Opcode::Duplicate: - case Opcode::Add: - case Opcode::Subtract: - case Opcode::Multiply: - case Opcode::Divide: - case Opcode::Modulus: - case Opcode::Negate: - case Opcode::Create: - case Opcode::Transform: - case Opcode::Get: - case Opcode::Position: - case Opcode::Kill: - return 0; - } - } - - void VirtualMachine::Run() - { - //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl; - //std::string names[] = { "Load", "Store", "Constant", "Increment", "Discard", "Duplicate", "Add", "Subtract", "Multiply", "Divide", "Modulus", "Negate", "Create", "Transform", "Get", "Position", "Kill", "JumpEqual", "JumpNotEqual", "JumpGreater", "JumpGreaterEqual", "JumpLess", "JumpLessEqual", "Jump", "Return", "LocalEnter"}; - - Word temp1; - Word temp2; - Word temp3; - Word temp4; - int temp; - while(programCounter < romSize) - { - Word argument = rom[programCounter].Parameter; - //std::cerr << programCounter << "\t" << names[rom[programCounter].Opcode] << "\t" << argument.Integer << std::endl;//"\t"; - switch(rom[programCounter].Opcode) - { - case Opcode::Load: - PSPush(CSA(argument.Integer)); - break; - case Opcode::Store: - CSA(argument.Integer) = PSPop(); - break; - case Opcode::Constant: - PSPush(argument); - break; - case Opcode::Increment: - PS().Integer += argument.Integer; - break; - case Opcode::Discard: - programStack += WORDSIZE; - break; - case Opcode::Duplicate: - PSPush(PS()); - break; - case Opcode::Add: - PSPush(PSPop().Integer + PSPop().Integer); - break; - case Opcode::Subtract: - temp1 = PSPop(); - PSPush(PSPop().Integer - temp1.Integer); - break; - case Opcode::Multiply: - PSPush(PSPop().Integer * PSPop().Integer); - break; - case Opcode::Divide: - temp1 = PSPop(); - PSPush(PSPop().Integer / temp1.Integer); - break; - case Opcode::Modulus: - temp1 = PSPop(); - PSPush(PSPop().Integer % temp1.Integer); - break; - case Opcode::Negate: - PS().Integer = -PS().Integer; - break; - case Opcode::Create: - temp1 = PSPop(); - temp2 = PSPop(); - temp3 = PSPop(); - PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer)); - break; - case Opcode::Transform: - PSPop(); - PSPop(); - PSPush((Word)-1); - break; - case Opcode::Get: - temp1 = PSPop(); - temp2 = PSPop(); - if(temp1.Integer < 0 || temp1.Integer >= YRES || temp2.Integer < 0 || temp2.Integer >= XRES || !(temp = sim->pmap[temp1.Integer][temp2.Integer])) - { - PSPush(-1); - break; - } - PSPush(temp>>8); - break; - case Opcode::Position: - temp1 = PSPop(); - if(temp1.Integer < 0 || temp1.Integer >= NPART || !sim->parts[temp1.Integer].type) - { - PSPush(-1); - PSPush(-1); - break; - } - PSPush((int)sim->parts[temp1.Integer].x); - PSPush((int)sim->parts[temp1.Integer].y); - break; - case Opcode::Kill: - sim->kill_part(PSPop().Integer); - PSPush((Word)0); - break; - case Opcode::LoadProperty: - PSPush(PPROP(PSPop().Integer, argument.Integer)); - break; - case Opcode::StoreProperty: - temp1 = PSPop(); - PPROP(temp1.Integer, argument.Integer) = PSPop(); - break; - case Opcode::JumpEqual: - if(PSPop().Integer == PSPop().Integer) - programCounter = argument.Integer-1; - break; - case Opcode::JumpNotEqual: - if(PSPop().Integer != PSPop().Integer) - programCounter = argument.Integer-1; - break; - case Opcode::JumpGreater: - temp1 = PSPop(); - if(PSPop().Integer > temp1.Integer) - programCounter = argument.Integer-1; - break; - case Opcode::JumpGreaterEqual: - temp1 = PSPop(); - if(PSPop().Integer >= temp1.Integer) - programCounter = argument.Integer-1; - break; - case Opcode::JumpLess: - temp1 = PSPop(); - if(PSPop().Integer < temp1.Integer) - programCounter = argument.Integer-1; - break; - case Opcode::JumpLessEqual: - temp1 = PSPop(); - if(PSPop().Integer <= temp1.Integer) - programCounter = argument.Integer-1; - break; - case Opcode::Jump: - programCounter = argument.Integer-1; - break; - case Opcode::Return: - callStack += argument.Integer; - break; - case Opcode::LocalEnter: - callStack -= argument.Integer; - break; - } - //std::cout << programStack << std::endl; - programCounter++; - } - //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl; - } - - void VirtualMachine::Compile() - { - while(programCounter < romSize) - { - Word argument = rom[programCounter].Parameter; - switch(rom[programCounter].Opcode) - { - case Opcode::Load: - emit("83 EF 04"); //sub edi 4 - - //Load value at base stack + offset into eax - emit("8B 85"); //mov eax [ebp+ram+offset] - emit((intptr_t) (ram - argument.Integer)); - - //Store value in eax onto top of program stack - emit("89 07"); //mov [edi], eax - emit((intptr_t) (ram)); - break; - case Opcode::Store: - //Load value on top of the program stack into eax - emit("8B 07"); //mov eax [edi] - emit((intptr_t) (ram)); - - //Load value in eax onto top of program stack - emit("89 85"); //mov [ebp+ram+offset], eax - emit((intptr_t) (ram - argument.Integer)); - - emit("83 C7 04"); //add edi 4 - break; - case Opcode::Constant: - emit("83 EF 04"); //sub edi 4 - - emit("C7 07"); //mov [edi] constant - emit((int) (argument.Integer)); - break; - case Opcode::Increment: - emit("81 07"); //add [edi] constant - emit((int) (argument.Integer)); - break; - case Opcode::Discard: - emit("83 C7 04"); //add edi 4 - break; - case Opcode::Duplicate: - //Copy value on stack into register - emit("8B 07"); //mov eax [edi] - //Adjust program stack pointer - emit("83 EF 04"); //sub edi 4 - //Move value in eax into program stack - emit("89 07"); //mov [edi], eax - break; - case Opcode::Add: - emit("8B 07"); //mov eax [edi] - emit("01 47 04"); //add [edi+4] eax - emit("83 C7 04"); //add edi 4 - break; - case Opcode::Subtract: - emit("8B 07"); //mov eax [edi] - emit("29 47 04"); //sub [edi+4] eax - emit("83 C7 04"); //add edi 4 - break; - case Opcode::Multiply: - emit("8B 47 04"); //mov eax [edi+4] - emit("F7 2F"); //imul [edi] - emit("89 47 04"); //mov [edi+4] eax - emit("83 C7 04"); //add edi 4 - break; - case Opcode::Divide: - emit("8B 47 04");//mov eax [edi+4] - emit("99"); //cdq - emit("F7 3F"); //idiv [edi] - emit("89 47 04"); //mov [edi+4] eax - emit("83 C7 04"); //add edi 4 - break; - case Opcode::Modulus: - emit("8B 47 04"); // mov eax [edi+4] - emit("99"); // cdq - emit("F7 3F"); // idiv [edi] - emit("89 57 04"); // mov [edi+4] edx - emit("83 C7 04"); //add edi 4 - break; - case Opcode::Negate: - emit("F7 1F"); //neg [edi] - break; - case Opcode::Create: - //temp1 = PSPop(); - //temp2 = PSPop(); - //temp3 = PSPop(); - //PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer)); - break; - case Opcode::Transform: - //PSPop(); - //PSPop(); - //PSPush((Word)-1); - break; - case Opcode::Get: - //temp1 = PSPop(); - //temp2 = PSPop(); - //if(temp1.Integer < 0 || temp1.Integer >= YRES || temp2.Integer < 0 || temp2.Integer >= XRES || !(temp = sim->pmap[temp1.Integer][temp2.Integer])) - //{ - // PSPush(-1); - // break; - //} - //PSPush(temp>>8); - break; - case Opcode::Position: - //temp1 = PSPop(); - //if(temp1.Integer < 0 || temp1.Integer >= NPART || !sim->parts[temp1.Integer].type) - //{ - // PSPush(-1); - // PSPush(-1); - // break; - //} - //PSPush((int)sim->parts[temp1.Integer].x); - //PSPush((int)sim->parts[temp1.Integer].y); - break; - case Opcode::Kill: - //sim->kill_part(PSPop().Integer); - //PSPush((Word)0); - break; - case Opcode::LoadProperty: - //PSPush(PPROP(PSPop().Integer, argument.Integer)); - break; - case Opcode::StoreProperty: - //temp1 = PSPop(); - //PPROP(temp1.Integer, argument.Integer) = PSPop(); - break; - case Opcode::JumpEqual: - emit("83 C7 04"); //add edi 8 - emit("8B 47 FC"); //mov eax, dword ptr [edi-4] - emit("3B 47 F7"); //cmp eax, dword ptr [edi-8] - emit("75 06"); //jne +6 - emit("FF 25"); //jmp [0x12345678] - emit(0); - break; - case Opcode::JumpNotEqual: - emit("83 C7 04"); //add edi 8 - emit("8B 47 FC"); //mov eax, dword ptr [edi-4] - emit("3B 47 F7"); //cmp eax, dword ptr [edi-8] - emit("74 06"); //je +6 - emit("FF 25"); //jmp [0x12345678] - emit(0); - break; - case Opcode::JumpGreater: - emit("83 C7 04"); //add edi 8 - emit("8B 47 FC"); //mov eax, dword ptr [edi-4] - emit("3B 47 F7"); //cmp eax, dword ptr [edi-8] - emit("7E 06"); //jng +6 - emit("FF 25"); //jmp [0x12345678] - emit(0); - break; - case Opcode::JumpGreaterEqual: - emit("83 C7 04"); //add edi 8 - emit("8B 47 FC"); //mov eax, dword ptr [edi-4] - emit("3B 47 F7"); //cmp eax, dword ptr [edi-8] - emit("7C 06"); //jnge +6 - emit("FF 25"); //jmp [0x12345678] - emit(0); - break; - case Opcode::JumpLess: - emit("83 C7 04"); //add edi 8 - emit("8B 47 FC"); //mov eax, dword ptr [edi-4] - emit("3B 47 F7"); //cmp eax, dword ptr [edi-8] - emit("7D 06"); //jnl +6 - emit("FF 25"); //jmp [0x12345678] - emit(0); - break; - case Opcode::JumpLessEqual: - emit("83 C7 04"); //add edi 8 - emit("8B 47 FC"); //mov eax, dword ptr [edi-4] - emit("3B 47 F7"); //cmp eax, dword ptr [edi-8] - emit("7F 06"); //jnle +6 - emit("FF 25"); //jmp [0x12345678] - emit(0); - break; - case Opcode::Jump: - //programCounter = argument.Integer-1; - break; - case Opcode::Return: - emit("81 C6"); //add esi constant - emit(argument.Integer); - break; - case Opcode::LocalEnter: - emit("81 EE"); //sub esi constant - emit(argument.Integer); - break; - } - //std::cout << programStack << std::endl; - programCounter++; - } - //std::cout << "CS: " << callStack << " PS: " << programStack << std::endl; - } - - void VirtualMachine::emit(std::string opcode) - { - - } - - void VirtualMachine::emit(int constant) - { - - } - - void VirtualMachine::CallCompiled(std::string entryPoint) - { - - } - - void VirtualMachine::CallCompiled(int entryPoint) - { - - } - - void VirtualMachine::Call(std::string entryPoint) - { - - } - - void VirtualMachine::Call(int entryPoint) - { - programCounter = entryPoint; - Run(); - } -} |
