Clean up VM and Lua loading functions

This commit is contained in:
Simon Robertshaw 2013-02-02 14:46:45 +00:00
parent 487647645e
commit 316e940e53
7 changed files with 153 additions and 121 deletions

View File

@ -950,6 +950,20 @@ void LuaScriptInterface::initElementsAPI()
} }
pim::VirtualMachine * LuaScriptInterface::updateVirtualMachines[PT_NUM]; pim::VirtualMachine * LuaScriptInterface::updateVirtualMachines[PT_NUM];
NativeUpdateFunc LuaScriptInterface::updateNativeCode[PT_NUM];
int LuaScriptInterface::updateNative(UPDATE_FUNC_ARGS)
{
/*void (*nativeFunction)(int, int, int) = updateNativeCode[parts[i].type];//(void(*)(int, int, int))nativeRom;
//int arg3 = CSPop().Integer;
//int arg2 = CSPop().Integer;
//int arg1 = CSPop().Integer;
//std::cout << arg1 << std::endl;
//std::cout << arg2 << std::endl;
//std::cout << arg3 << std::endl;
nativeFunction(i, x, y);*/
updateNativeCode[parts[i].type](i, x, y);
return 0;
}
int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS) int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS)
{ {
@ -959,7 +973,7 @@ int LuaScriptInterface::updateVM(UPDATE_FUNC_ARGS)
machine->CSPush(x); machine->CSPush(x);
machine->CSPush(y); machine->CSPush(y);
//machine->Call(0); //machine->Call(0);
machine->CallCompiled(0); machine->Run(0);
/*vm::VirtualMachine * vMachine = updateVirtualMachines[parts[i].type]; /*vm::VirtualMachine * vMachine = updateVirtualMachines[parts[i].type];
@ -1318,7 +1332,15 @@ int LuaScriptInterface::elements_property(lua_State * l)
else if(lua_type(l, 3) == LUA_TLIGHTUSERDATA) else if(lua_type(l, 3) == LUA_TLIGHTUSERDATA)
{ {
updateVirtualMachines[id] = (pim::VirtualMachine*)lua_touserdata(l, 3); updateVirtualMachines[id] = (pim::VirtualMachine*)lua_touserdata(l, 3);
luacon_sim->elements[id].Update = &updateVM; if(updateVirtualMachines[id]->IsCompiled())
{
updateNativeCode[id] = (NativeUpdateFunc)updateVirtualMachines[id]->GetNativeEntryPoint(0);
luacon_sim->elements[id].Update = &updateNative;
}
else
{
luacon_sim->elements[id].Update = &updateVM;
}
} }
else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3)) else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
{ {
@ -1467,7 +1489,10 @@ int LuaScriptInterface::virtualMachine_loadProgram(lua_State * l)
pim::VirtualMachine * machine = new pim::VirtualMachine(luacon_sim); pim::VirtualMachine * machine = new pim::VirtualMachine(luacon_sim);
machine->LoadProgram(programData); machine->LoadProgram(programData);
#if defined(X86) && !defined(_64BIT)
machine->Compile(); machine->Compile();
#endif
lua_pushlightuserdata(l, machine); lua_pushlightuserdata(l, machine);
return 1; return 1;

View File

@ -45,6 +45,8 @@ class Tool;
#define LUACON_EL_MODIFIED_MENUS 0x4 #define LUACON_EL_MODIFIED_MENUS 0x4
class TPTScriptInterface; class TPTScriptInterface;
class LuaScriptInterface;
typedef void (*NativeUpdateFunc)(int, int, int);
class LuaScriptInterface: public CommandInterface class LuaScriptInterface: public CommandInterface
{ {
int luacon_mousex, luacon_mousey, luacon_mousebutton, luacon_brushx, luacon_brushy; int luacon_mousex, luacon_mousey, luacon_mousebutton, luacon_brushx, luacon_brushy;
@ -75,6 +77,8 @@ class LuaScriptInterface: public CommandInterface
//Elements //Elements
static pim::VirtualMachine * updateVirtualMachines[PT_NUM]; static pim::VirtualMachine * updateVirtualMachines[PT_NUM];
static NativeUpdateFunc updateNativeCode[PT_NUM];
static int updateNative(UPDATE_FUNC_ARGS);
static int updateVM(UPDATE_FUNC_ARGS); static int updateVM(UPDATE_FUNC_ARGS);
// //
void initElementsAPI(); void initElementsAPI();

View File

@ -23,7 +23,8 @@ namespace pim
VirtualMachine::VirtualMachine(Simulation * simulation) : VirtualMachine::VirtualMachine(Simulation * simulation) :
rom(NULL), rom(NULL),
ram(NULL), ram(NULL),
sim(simulation) sim(simulation),
nativeRom(0)
{ {
} }
@ -193,7 +194,7 @@ namespace pim
int argSize = 0; int argSize = 0;
Instruction instruction; Instruction instruction;
instruction.Opcode = programData[programPosition++]; instruction.Opcode = programData[programPosition++];
if(argSize = OpcodeArgSize(instruction.Opcode)) if(argSize = opcodeArgSize(instruction.Opcode))
{ {
if(argSize == 4 && programPosition+3 < programData.size()) if(argSize == 4 && programPosition+3 < programData.size())
{ {
@ -236,7 +237,7 @@ namespace pim
callStack += WORDSIZE; //Since there's nothing on the stack, it shouldn't point to the item on the bottom callStack += WORDSIZE; //Since there's nothing on the stack, it shouldn't point to the item on the bottom
} }
int VirtualMachine::OpcodeArgSize(int opcode) int VirtualMachine::opcodeArgSize(int opcode)
{ {
switch(opcode) switch(opcode)
{ {
@ -276,7 +277,7 @@ namespace pim
} }
} }
void VirtualMachine::Run() void VirtualMachine::run()
{ {
//std::cout << "CS: " << callStack << " PS: " << programStack << std::endl; //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"}; //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"};
@ -423,43 +424,38 @@ namespace pim
void VirtualMachine::Compile() void VirtualMachine::Compile()
{ {
Native * native = new X86Native(); Native * native = new X86Native();
std::vector<unsigned char> executableCode = native->Compile(sim, rom, romSize); if(nativeRom)
Client::Ref().WriteFile(executableCode, "code.x"); delete[] nativeRom;
if(nativeStack)
delete[] nativeStack;
unsigned char * romAddress = new unsigned char[executableCode.size()+8]; nativeStack = new unsigned char [1024*1024];
std::fill(romAddress, romAddress+executableCode.size()+8, 0x90); //Fill with NOP for debugging
std::copy(executableCode.begin(), executableCode.end(), romAddress+4); std::vector<unsigned char> executableCode = native->Compile(sim, nativeStack + (1024*512), rom, romSize);
nativeRom = (intptr_t)romAddress; nativeRom = new unsigned char[executableCode.size()];
printf("%p\n", romAddress);
fflush(stdout); std::copy(executableCode.begin(), executableCode.end(), nativeRom);
delete native; delete native;
} }
void VirtualMachine::CallCompiled(std::string entryPoint) void * VirtualMachine::GetNativeEntryPoint(std::string entryPoint)
{ {
} }
void VirtualMachine::CallCompiled(int entryPoint) void * VirtualMachine::GetNativeEntryPoint(intptr_t entryPoint)
{ {
void (*nativeFunction)(int, int, int) = (void(*)(int, int, int))nativeRom; return nativeRom+entryPoint;
int arg3 = CSPop().Integer;
int arg2 = CSPop().Integer;
int arg1 = CSPop().Integer;
//std::cout << arg1 << std::endl;
//std::cout << arg2 << std::endl;
//std::cout << arg3 << std::endl;
nativeFunction(arg1, arg2, arg3);
} }
void VirtualMachine::Call(std::string entryPoint) void VirtualMachine::Run(std::string entryPoint)
{ {
} }
void VirtualMachine::Call(int entryPoint) void VirtualMachine::Run(int entryPoint)
{ {
programCounter = entryPoint; programCounter = entryPoint;
Run(); run();
} }
} }

View File

@ -59,7 +59,8 @@ namespace pim
int romSize; int romSize;
int romMask; int romMask;
intptr_t nativeRom; unsigned char * nativeRom;
unsigned char * nativeStack;
unsigned char * compiledRom; unsigned char * compiledRom;
int compiledRomSize; int compiledRomSize;
@ -80,16 +81,20 @@ namespace pim
//Instruction * instructions; //Instruction * instructions;
int programCounter; int programCounter;
void run();
int opcodeArgSize(int opcode);
public: public:
VirtualMachine(Simulation * sim); VirtualMachine(Simulation * sim);
int OpcodeArgSize(int opcode);
void LoadProgram(std::vector<unsigned char> programData); void LoadProgram(std::vector<unsigned char> programData);
void Run();
void Compile(); void Compile();
void CallCompiled(std::string entryPoint); void * GetNativeEntryPoint(std::string entryPoint);
void CallCompiled(int entryPoint); void * GetNativeEntryPoint(intptr_t entryPoint);
void Call(std::string entryPoint); void Run(std::string entryPoint);
void Call(int entryPoint); void Run(int entryPoint);
inline bool IsCompiled()
{
return nativeRom != 0;
}
inline void PSPush(Word word) inline void PSPush(Word word)
{ {
programStack -= WORDSIZE; programStack -= WORDSIZE;

View File

@ -4,8 +4,49 @@ namespace pim
{ {
class Native class Native
{ {
protected:
std::vector<unsigned char> nativeRom;
void emit(std::string opcode)
{
unsigned char c1, c2;
unsigned char v;
const char * string = opcode.c_str();
while (true)
{
c1 = string[0];
c2 = string[1];
v = (hex( c1 ) << 4) | hex(c2);
nativeRom.push_back(v);
if (!string[2])
{
break;
}
string += 3;
}
}
unsigned char hex(char 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';
return 0;
}
virtual void emitConstantS(short int constant) {} //Single
virtual void emitConstantD(long int constant) {} //Double
virtual void emitConstantP(intptr_t constant) {} //Pointer
virtual void emitConstantQ(long long int constant) {} //Quad
virtual void emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize) {}
virtual void emitPlaceholder(int virtualAddress) {}
public: public:
Native() {} Native() : nativeRom() {}
virtual std::vector<unsigned char> Compile(Simulation * sim, Instruction * rom, int romSize) {} virtual std::vector<unsigned char> Compile(Simulation * sim, unsigned char * machineStack, Instruction * rom, int romSize) {}
}; };
} }

View File

@ -4,19 +4,16 @@
namespace pim namespace pim
{ {
std::vector<unsigned char> X86Native::Compile(Simulation * sim, Instruction * rom, int romSize) std::vector<unsigned char> X86Native::Compile(Simulation * sim, unsigned char * machineStack, Instruction * rom, int romSize)
{ {
#if defined(X86) && !defined(_64BIT) #if defined(X86) && !defined(_64BIT)
int programCounter = 0; int programCounter = 0;
nativeRom.clear(); nativeRom.clear();
unsigned char * esi = new unsigned char[1024*1024];//malloc(1024*1024);
esi += 512;
//emit("52"); //push edx for(int i = 0; i < 8; i++) { emit("90"); } //nop, helps find the code in memory with a debugger
//emit("56"); //push esi
emit("BE"); //mov esi, machineStack emit("BE"); //mov esi, machineStack
emit((intptr_t)esi); emitConstantP((intptr_t)machineStack);
while(programCounter < romSize) while(programCounter < romSize)
{ {
@ -29,7 +26,7 @@ namespace pim
//Load value at base stack + offset into eax //Load value at base stack + offset into eax
//emit("8B 85"); //mov eax, [ebp+offset] //emit("8B 85"); //mov eax, [ebp+offset]
emit("8B 84 24"); //mov eax, [esp+offset] emit("8B 84 24"); //mov eax, [esp+offset]
emit((int) (argument.Integer)); emitConstantP(argument.Integer);
//Store value in eax onto top of program stack //Store value in eax onto top of program stack
emit("89 06"); //mov [esi], eax emit("89 06"); //mov [esi], eax
break; break;
@ -37,23 +34,22 @@ namespace pim
//Load value on top of the program stack into eax //Load value on top of the program stack into eax
emit("8B 06"); //mov eax, [esi] emit("8B 06"); //mov eax, [esi]
//Load value in eax into memory //Load value in eax into memory
//emit("89 85"); //mov [ebp+offset], eax
emit("89 84 24"); //mov [esp+offset], eax emit("89 84 24"); //mov [esp+offset], eax
emit((int) (argument.Integer)); emitConstantD(argument.Integer);
emit("83 C6 04"); //add esi, 4 emit("83 C6 04"); //add esi, 4
break; break;
case Opcode::Constant: case Opcode::Constant:
emit("83 EE 04"); //sub esi, 4 emit("83 EE 04"); //sub esi, 4
emit("C7 06"); //mov [esi], dword ptr constant emit("C7 06"); //mov [esi], dword ptr constant
emit((int) (argument.Integer)); emitConstantD(argument.Integer);
break; break;
case Opcode::Increment: case Opcode::Increment:
if(argument.Integer > 0) { if(argument.Integer > 0) {
emit("81 06"); //add [esi], dword ptr constant emit("81 06"); //add [esi], dword ptr constant
emit((int) (argument.Integer)); emitConstantD(argument.Integer);
} else { } else {
emit("81 2E"); //sub [esi], dword ptr constant emit("81 2E"); //sub [esi], dword ptr constant
emit((int) (-argument.Integer)); emitConstantD(-argument.Integer);
} }
break; break;
case Opcode::Discard: case Opcode::Discard:
@ -112,10 +108,6 @@ namespace pim
emit("83 C6 08"); //add esi, 8 emit("83 C6 08"); //add esi, 8
emitCall((intptr_t)sim, (intptr_t)((void*)&Simulation::create_part), 16); emitCall((intptr_t)sim, (intptr_t)((void*)&Simulation::create_part), 16);
emit("89 06"); //mov [esi], eax emit("89 06"); //mov [esi], eax
//temp1 = PSPop();
//temp2 = PSPop();
//temp3 = PSPop();
//PSPush(sim->create_part(PSPop().Integer, temp3.Integer, temp2.Integer, temp1.Integer));
break; break;
case Opcode::Transform: case Opcode::Transform:
//PSPop(); //PSPop();
@ -127,21 +119,19 @@ namespace pim
intptr_t partsArray = (intptr_t)sim->pmap; intptr_t partsArray = (intptr_t)sim->pmap;
emit("8B 06"); //mov eax, [esi] emit("8B 06"); //mov eax, [esi]
emit("8B 4E 04"); //mov ecx, [esi+4] emit("8B 4E 04"); //mov ecx, [esi+4]
emit("81 F9"); //cmp ecx, XRES emit("81 F9"); //cmp ecx, XRES
emit((int)XRES); emitConstantD((int)XRES);
emit("7D 22"); //|--< //jge 34 emit("7D 22"); //|--< //jge 34
emit("74 20"); //|--< //jz 32 emit("74 20"); //|--< //jz 32
emit("3D"); //| //cmp eax, YRES emit("3D"); //| //cmp eax, YRES
emit((int)YRES); //| emitConstantD((int)YRES); //|
emit("7D 19"); //|--< //jge 25 emit("7D 19"); //|--< //jge 25
emit("74 17"); //|--< //jz 23 emit("74 17"); //|--< //jz 23
//|
emit("69 C0"); //| //imul eax, 612 emit("69 C0"); //| //imul eax, 612
emit((int)XRES); //| emitConstantD((int)XRES); //|
emit("01 C8"); //| //add eax, ecx emit("01 C8"); //| //add eax, ecx
emit("8B 04 85"); //| //mov eax, [eax*4+pmap] emit("8B 04 85"); //| //mov eax, [eax*4+pmap]
emit((int)partsArray); //| emitConstantP((int)partsArray); //|
emit("C1 F8 08"); //| //sar eax, 8 emit("C1 F8 08"); //| //sar eax, 8
emit("89 46 04"); //| //mov [esi+4], eax #Copy eax onto stack emit("89 46 04"); //| //mov [esi+4], eax #Copy eax onto stack
emit("EB 07"); //| |-< //jmp +7 emit("EB 07"); //| |-< //jmp +7
@ -153,26 +143,20 @@ namespace pim
{ {
intptr_t partsArray = (intptr_t)sim->parts; intptr_t partsArray = (intptr_t)sim->parts;
emit("8B 06"); //mov eax, [esi] #Load index from stack emit("8B 06"); //mov eax, [esi] #Load index from stack
emit("3D"); //cmp eax, NPART emit("3D"); //cmp eax, NPART
emit((int)NPART); emitConstantD((int)NPART);
emit("7D 23"); //|--< //jge 31 emit("7D 23"); //|--< //jge 31
emit("74 21"); //|--< //jz 29 emit("74 21"); //|--< //jz 29
//|
emit("C1 E0 03"); //| //sal eax, 3 #Shift index left (multiply by 8) emit("C1 E0 03"); //| //sal eax, 3 #Shift index left (multiply by 8)
emit("8D 14 C5 00 00 00 00"); //| //lea edx, [eax*8] #Mutiply by 8 again and copy into edx //Size of 56 is represented by (1*(8^2))-(1*8) emit("8D 14 C5 00 00 00 00"); //| //lea edx, [eax*8] #Mutiply by 8 again and copy into edx //Size of 56 is represented by (1*(8^2))-(1*8)
emit("89 D1"); //| //mov ecx, edx emit("89 D1"); //| //mov ecx, edx
emit("29 C1"); //| //sub ecx, eax #Subtract index*8^2 by index*8 to get the index*56 emit("29 C1"); //| //sub ecx, eax #Subtract index*8^2 by index*8 to get the index*56
//emit("8B 81"); //| //mov eax, [ecx+xOffset+partsArray] #Copy value at index+baseAddress+propertyOffset into eax
emit("D9 81"); //| //fld [ecx+xOffset+partsArray] emit("D9 81"); //| //fld [ecx+xOffset+partsArray]
emit(partsArray+offsetof(Particle, x)); emitConstantP(partsArray+offsetof(Particle, x));
emit("DB 1E"); //| //fistp [esi] emit("DB 1E"); //| //fistp [esi]
//emit("89 06"); //| //mov [esi], eax #Copy eax onto stack
//emit("89 81"); //| //mov eax, [ecx+yOffset+partsArray] #Copy value at index+baseAddress+propertyOffset into eax
emit("D9 81"); //| //fld [ecx+xOffset+partsArray] emit("D9 81"); //| //fld [ecx+xOffset+partsArray]
emit(partsArray+offsetof(Particle, y)); emitConstantP(partsArray+offsetof(Particle, y));
emit("DB 5E FC"); //| //fistp [esi-4], eax #Copy eax onto stack emit("DB 5E FC"); //| //fistp [esi-4], eax #Copy eax onto stack
//emit("89 46 FC"); //| //mov [esi-4], eax #Copy eax onto stack
emit("EB 0D"); //| |-< //jmp +13 emit("EB 0D"); //| |-< //jmp +13
emit("C7 06 FF FF FF FF"); //L-+-> //mov [esi], -1 emit("C7 06 FF FF FF FF"); //L-+-> //mov [esi], -1
emit("C7 46 FC FF FF FF FF"); // | //mov [esi-4] -1 emit("C7 46 FC FF FF FF FF"); // | //mov [esi-4] -1
@ -193,7 +177,7 @@ namespace pim
emit("89 D1"); //mov ecx, edx emit("89 D1"); //mov ecx, edx
emit("29 C1"); //sub ecx, eax #Subtract index*8^2 by index*8 to get the index*56 emit("29 C1"); //sub ecx, eax #Subtract index*8^2 by index*8 to get the index*56
emit("8B 81"); //mov eax, [ecx+propertyOffset+partsArray] #Copy value at index+baseAddress+propertyOffset into eax emit("8B 81"); //mov eax, [ecx+propertyOffset+partsArray] #Copy value at index+baseAddress+propertyOffset into eax
emit(partsArray+propertyOffset); emitConstantP(partsArray+propertyOffset);
emit("89 06"); //mov [esi], eax #Copy eax onto stack emit("89 06"); //mov [esi], eax #Copy eax onto stack
} }
break; break;
@ -208,7 +192,7 @@ namespace pim
emit("29 C1"); //sub ecx, eax emit("29 C1"); //sub ecx, eax
emit("8B 46 04"); //mov eax, [esi+4] emit("8B 46 04"); //mov eax, [esi+4]
emit("89 81"); //mov [ecx+propertyOffset+partsArray], eax emit("89 81"); //mov [ecx+propertyOffset+partsArray], eax
emit(partsArray+propertyOffset); emitConstantP(partsArray+propertyOffset);
emit("83 C6 08"); //add esi, 8 emit("83 C6 08"); //add esi, 8
} }
break; break;
@ -273,25 +257,22 @@ namespace pim
emitPlaceholder(argument.Integer); emitPlaceholder(argument.Integer);
break; break;
case Opcode::Return: case Opcode::Return:
//emit("5E"); //pop esi
//emit("5A"); //pop edx
emit("C3"); //ret emit("C3"); //ret
break; break;
case Opcode::Leave: case Opcode::Leave:
//emit("81 C7"); //add edi, constant
emit("81 C4"); //add esp, constant emit("81 C4"); //add esp, constant
emit(argument.Integer); emitConstantD(argument.Integer);
break; break;
case Opcode::LocalEnter: case Opcode::LocalEnter:
//emit("81 EF"); //sub edi constant
emit("81 EC"); //sub esp constant emit("81 EC"); //sub esp constant
emit(argument.Integer); emitConstantD(argument.Integer);
break; break;
} }
//std::cout << programStack << std::endl; //std::cout << programStack << std::endl;
programCounter++; programCounter++;
} }
for(int i = 0; i < 8; i++) { emit("90"); } //nop, helps find the code in memory with a debugger
for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter) for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
{ {
@ -315,39 +296,27 @@ namespace pim
void X86Native::emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize) void X86Native::emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize)
{ {
//emit("B9"); //mov ecx, instancePointer #ifdef _MSC_VER
emit("68"); //push instancePointer //MSVC puts the instance pointer in ecx, not on the stack
emit((int) objectPtr); emit("B9"); //mov ecx, instancePointer
emitConstantP(objectPtr);
emit("B8"); //mov eax, functionAddress emit("B8"); //mov eax, functionAddress
emit((int)functionAddress); emitConstantP(functionAddress);
emit("FF D0"); //call eax emit("FF D0"); //call eax
emit("81 C4"); //add esp, stacksize emit("81 C4"); //add esp, stacksize
emit((int)stackSize+sizeof(intptr_t)); emitConstantD(stackSize);
#else
emit("68"); //push instancePointer
emitConstantP(objectPtr);
emit("B8"); //mov eax, functionAddress
emitConstantP(functionAddress);
emit("FF D0"); //call eax
emit("81 C4"); //add esp, stacksize
emitConstantD(stackSize+sizeof(intptr_t));
#endif
} }
void X86Native::emit(std::string opcode) void X86Native::emitConstantD(long int constant)
{
unsigned char c1, c2;
unsigned char v;
const char * string = opcode.c_str();
while (true)
{
c1 = string[0];
c2 = string[1];
v = (hex( c1 ) << 4) | hex(c2);
nativeRom.push_back(v);
if (!string[2])
{
break;
}
string += 3;
}
}
void X86Native::emit(int constant)
{ {
nativeRom.push_back(constant & 0xFF); nativeRom.push_back(constant & 0xFF);
nativeRom.push_back((constant >> 8) & 0xFF); nativeRom.push_back((constant >> 8) & 0xFF);
@ -355,15 +324,9 @@ namespace pim
nativeRom.push_back((constant >> 24) & 0xFF); nativeRom.push_back((constant >> 24) & 0xFF);
} }
unsigned char X86Native::hex(char c) void X86Native::emitConstantP(intptr_t constant)
{ {
if (c >= 'a' && c <= 'f') emitConstantD(constant);
return 10 + c - 'a';
if (c >= 'A' && c <= 'F')
return 10 + c - 'A';
if (c >= '0' && c <= '9')
return c - '0';
return 0;
} }
} }

View File

@ -7,15 +7,13 @@ namespace pim
class X86Native : public Native class X86Native : public Native
{ {
public: public:
X86Native() : Native(), nativeRom() {} X86Native() : Native() {}
virtual std::vector<unsigned char> Compile(Simulation * sim, Instruction * rom, int romSize); virtual std::vector<unsigned char> Compile(Simulation * sim, unsigned char * machineStack, Instruction * rom, int romSize);
private: protected:
void emit(std::string opcode); virtual void emitConstantD(long int constant);
void emit(int constant); virtual void emitConstantP(intptr_t constant);
void emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize); virtual void emitCall(intptr_t objectPtr, intptr_t functionAddress, int stackSize);
void emitPlaceholder(int virtualAddress); virtual void emitPlaceholder(int virtualAddress);
unsigned char hex(char c);
std::vector<unsigned char> nativeRom;
std::map<int, int> virtualToNative; std::map<int, int> virtualToNative;
std::map<int, int> placeholders; std::map<int, int> placeholders;
}; };