diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 1e6e172e6..19780d829 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -45,9 +45,9 @@ static asmjit::JitRuntime jit; #define ABCs (pc[0].i24) #define JMPOFS(x) ((x)->i24) #define KC (konstd[C]) -#define RC (reg.d[C]) -#define PA (reg.a[A]) -#define PB (reg.a[B]) +#define RC (regD[C]) +#define PA (regA[A]) +#define PB (regA[B]) #define ASSERTD(x) assert((unsigned)(x) < sfunc->NumRegD) #define ASSERTF(x) assert((unsigned)(x) < sfunc->NumRegF) @@ -153,8 +153,8 @@ static bool CanJit(VMScriptFunction *sfunc) JitFuncPtr JitCompile(VMScriptFunction *sfunc) { -#if 0 // For debugging - if (strcmp(sfunc->Name.GetChars(), "EmptyFunction") != 0 && !CanJit(sfunc)) +#if 1 // For debugging + if (strcmp(sfunc->Name.GetChars(), "EmptyFunction") != 0) return nullptr; #else if (!CanJit(sfunc)) @@ -174,13 +174,15 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) X86Compiler cc(&code); X86Gp stack = cc.newIntPtr("stack"); // VMFrameStack *stack + X86Gp vmregs = cc.newIntPtr("vmregs"); // void *vmregs X86Gp ret = cc.newIntPtr("ret"); // VMReturn *ret X86Gp numret = cc.newInt32("numret"); // int numret - cc.addFunc(FuncSignature3()); + cc.addFunc(FuncSignature4()); cc.setArg(0, stack); - cc.setArg(1, ret); - cc.setArg(2, numret); + cc.setArg(1, vmregs); + cc.setArg(2, ret); + cc.setArg(3, numret); const int *konstd = sfunc->KonstD; const double *konstf = sfunc->KonstF; @@ -189,13 +191,52 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) TArray regD(sfunc->NumRegD, true); TArray regF(sfunc->NumRegF, true); - //TArray regA(sfunc->NumRegA, true); + TArray regA(sfunc->NumRegA, true); //TArray regS(sfunc->NumRegS, true); - for (int i = 0; i < sfunc->NumRegD; i++) regD[i] = cc.newInt32(); - for (int i = 0; i < sfunc->NumRegF; i++) regF[i] = cc.newXmm(); - //for (int i = 0; i < sfunc->NumRegA; i++) regA[i] = cc.newIntPtr(); - //for (int i = 0; i < sfunc->NumRegS; i++) regS[i] = cc.newGpd(); + X86Gp initreg = cc.newIntPtr(); + if (sfunc->NumRegD > 0) + { + cc.mov(initreg, x86::ptr(vmregs, 0)); + for (int i = 0; i < sfunc->NumRegD; i++) + { + regD[i] = cc.newInt32(); + cc.mov(regD[i], x86::dword_ptr(initreg, i * 4)); + } + } + if (sfunc->NumRegF > 0) + { + cc.mov(initreg, x86::ptr(vmregs, sizeof(void*))); + for (int i = 0; i < sfunc->NumRegF; i++) + { + regF[i] = cc.newXmm(); + cc.movsd(regF[i], x86::qword_ptr(initreg, i * 4)); + } + } + /*if (sfunc->NumRegS > 0) + { + cc.mov(initreg, x86::ptr(vmregs, sizeof(void*) * 2)); + for (int i = 0; i < sfunc->NumRegS; i++) + { + regS[i] = cc.newGpd(); + } + }*/ + if (sfunc->NumRegA > 0) + { + cc.mov(initreg, x86::ptr(vmregs, sizeof(void*) * 3)); + for (int i = 0; i < sfunc->NumRegA; i++) + { + regA[i] = cc.newIntPtr(); + cc.mov(regA[i], x86::ptr(initreg, i * 4)); + } + } + + /* + typedef void(*FuncPtr)(); + cc.call((ptrdiff_t)(FuncPtr)[] { + Printf("c++ from asmjit\n"); + }, FuncSignature0()); + */ int size = sfunc->CodeSize; for (int i = 0; i < size; i++) @@ -280,11 +321,23 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) // Store instructions. *(rA + rkC) = rB case OP_SB: // store byte + //if (PA == NULL) { ThrowAbortException(X_WRITE_NIL, nullptr); return 0; } + cc.mov(x86::byte_ptr(PA, KC), regD[B]); + break; case OP_SB_R: + //if (PA == NULL) { ThrowAbortException(X_WRITE_NIL, nullptr); return 0; } + cc.mov(x86::byte_ptr(PA, RC), regD[B]); + break; case OP_SH: // store halfword case OP_SH_R: case OP_SW: // store word + //if (PA == NULL) { ThrowAbortException(X_WRITE_NIL, nullptr); return 0; } + cc.mov(x86::dword_ptr(PA, KC), regD[B]); + break; case OP_SW_R: + //if (PA == NULL) { ThrowAbortException(X_WRITE_NIL, nullptr); return 0; } + cc.mov(x86::dword_ptr(PA, RC), regD[B]); + break; case OP_SSP: // store single-precision fp case OP_SSP_R: case OP_SDP: // store double-precision fp @@ -361,7 +414,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) Label L_endif = cc.newLabel(); cc.mov(reg_retnum, retnum); - cc.test(reg_retnum, numret); // Operand size mismatch: test eax, rcx + cc.test(reg_retnum, numret); cc.jg(L_endif); cc.mov(location, x86::ptr(ret, retnum * sizeof(VMReturn))); @@ -695,8 +748,20 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) // Pointer math. case OP_ADDA_RR: // pA = pB + dkC + cc.mov(regA[a], regA[B]); + cc.add(regA[a], regD[C]); + break; + case OP_ADDA_RK: + cc.mov(regA[a], regA[B]); + cc.add(regA[a], konstd[C]); + break; + case OP_SUBA: // dA = pB - pC + cc.mov(regA[a], regA[B]); + cc.sub(regA[a], regD[C]); + break; + case OP_EQA_R: // if ((pB == pkC) != A) then pc++ case OP_EQA_K: break; diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index ae0fc76f4..8df0fb70b 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -81,7 +81,7 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) sfunc->JitCompiled = true; } if (sfunc->JitFunc) - return sfunc->JitFunc(stack, ret, numret); + return sfunc->JitFunc(stack, ®, ret, numret); } void *ptr; diff --git a/src/scripting/vm/vmintern.h b/src/scripting/vm/vmintern.h index a01629f7b..379ad7c5f 100644 --- a/src/scripting/vm/vmintern.h +++ b/src/scripting/vm/vmintern.h @@ -437,7 +437,7 @@ extern thread_local VMFrameStack GlobalVMStack; typedef std::pair FTypeAndOffset; -typedef int(*JitFuncPtr)(VMFrameStack *stack, VMReturn *ret, int numret); +typedef int(*JitFuncPtr)(VMFrameStack *stack, const void *vmregs, VMReturn *ret, int numret); class VMScriptFunction : public VMFunction {