diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index c922d81596..17f6c11edc 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -49,9 +49,6 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) #if defined(DEBUG_JIT) if (strcmp(sfunc->PrintableName.GetChars(), "StatusScreen.drawNum") != 0) return nullptr; -#else - if (!JitCompiler::CanJit(sfunc)) - return nullptr; #endif //Printf("Jitting function: %s\n", sfunc->PrintableName.GetChars()); @@ -141,28 +138,6 @@ void JitCompiler::EmitOpcode() } } -bool JitCompiler::CanJit(VMScriptFunction *sfunc) -{ - int size = sfunc->CodeSize; - for (int i = 0; i < size; i++) - { - // Partially implemented functions: - - auto pc = sfunc->Code + i; - if (sfunc->Code[i].op == OP_PARAM) - { - if (!!(B & REGT_MULTIREG3) || !!(B & REGT_MULTIREG2)) - return false; - } - else if (sfunc->Code[i].op == OP_RESULT) - { - if (!!(B & REGT_MULTIREG3) || !!(B & REGT_MULTIREG2)) - return false; - } - } - return true; -} - void JitCompiler::Setup() { using namespace asmjit; diff --git a/src/scripting/vm/jit_call.cpp b/src/scripting/vm/jit_call.cpp index f89fb6a220..1747477952 100644 --- a/src/scripting/vm/jit_call.cpp +++ b/src/scripting/vm/jit_call.cpp @@ -260,6 +260,18 @@ void JitCompiler::StoreInOuts(int b) cc.mov(stackPtr, frameF); cc.add(stackPtr, (int)(C * sizeof(double))); cc.movsd(x86::qword_ptr(stackPtr), regF[C]); + + // When passing the address to a float we don't know if the receiving function will treat it as float, vec2 or vec3. + if ((unsigned int)C + 1 < regF.Size()) + { + cc.add(stackPtr, (int)sizeof(double)); + cc.movsd(x86::qword_ptr(stackPtr), regF[C + 1]); + } + if ((unsigned int)C + 2 < regF.Size()) + { + cc.add(stackPtr, (int)sizeof(double)); + cc.movsd(x86::qword_ptr(stackPtr), regF[C + 2]); + } break; default: break; @@ -274,7 +286,7 @@ void JitCompiler::LoadInOuts(int b) const VMOP ¶m = *ParamOpcodes[i]; if (param.op == OP_PARAM && (param.b & REGT_ADDROF)) { - LoadCallResult(param); + LoadCallResult(param, true); } } } @@ -286,11 +298,11 @@ void JitCompiler::LoadReturns(const VMOP *retval, int numret) if (retval[i].op != OP_RESULT) I_FatalError("Expected OP_RESULT to follow OP_CALL\n"); - LoadCallResult(retval[i]); + LoadCallResult(retval[i], false); } } -void JitCompiler::LoadCallResult(const VMOP &opdata) +void JitCompiler::LoadCallResult(const VMOP &opdata, bool addrof) { int type = opdata.b; int regnum = opdata.c; @@ -302,6 +314,23 @@ void JitCompiler::LoadCallResult(const VMOP &opdata) break; case REGT_FLOAT: cc.movsd(regF[regnum], asmjit::x86::qword_ptr(frameF, regnum * sizeof(double))); + if (addrof) + { + // When passing the address to a float we don't know if the receiving function will treat it as float, vec2 or vec3. + if ((unsigned int)regnum + 1 < regF.Size()) + cc.movsd(regF[regnum + 1], asmjit::x86::qword_ptr(frameF, (regnum + 1) * sizeof(double))); + if ((unsigned int)regnum + 2 < regF.Size()) + cc.movsd(regF[regnum + 2], asmjit::x86::qword_ptr(frameF, (regnum + 2) * sizeof(double))); + } + else if (type & REGT_MULTIREG2) + { + cc.movsd(regF[regnum + 1], asmjit::x86::qword_ptr(frameF, (regnum + 1) * sizeof(double))); + } + else if (type & REGT_MULTIREG3) + { + cc.movsd(regF[regnum + 1], asmjit::x86::qword_ptr(frameF, (regnum + 1) * sizeof(double))); + cc.movsd(regF[regnum + 2], asmjit::x86::qword_ptr(frameF, (regnum + 2) * sizeof(double))); + } break; case REGT_STRING: // We don't have to do anything in this case. String values are never moved to virtual registers. diff --git a/src/scripting/vm/jit_store.cpp b/src/scripting/vm/jit_store.cpp index 9f69aad963..3ae500a1ad 100644 --- a/src/scripting/vm/jit_store.cpp +++ b/src/scripting/vm/jit_store.cpp @@ -111,9 +111,9 @@ void JitCompiler::EmitSP_R() void JitCompiler::EmitSV2() { - EmitNullPointerThrow(B, X_WRITE_NIL); + EmitNullPointerThrow(A, X_WRITE_NIL); auto tmp = newTempIntPtr(); - cc.mov(tmp, regA[B]); + cc.mov(tmp, regA[A]); cc.add(tmp, konstd[C]); cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]); cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]); @@ -121,9 +121,9 @@ void JitCompiler::EmitSV2() void JitCompiler::EmitSV2_R() { - EmitNullPointerThrow(B, X_WRITE_NIL); + EmitNullPointerThrow(A, X_WRITE_NIL); auto tmp = newTempIntPtr(); - cc.mov(tmp, regA[B]); + cc.mov(tmp, regA[A]); cc.add(tmp, regD[C]); cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]); cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]); @@ -131,9 +131,9 @@ void JitCompiler::EmitSV2_R() void JitCompiler::EmitSV3() { - EmitNullPointerThrow(B, X_WRITE_NIL); + EmitNullPointerThrow(A, X_WRITE_NIL); auto tmp = newTempIntPtr(); - cc.mov(tmp, regA[B]); + cc.mov(tmp, regA[A]); cc.add(tmp, konstd[C]); cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]); cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]); @@ -142,9 +142,9 @@ void JitCompiler::EmitSV3() void JitCompiler::EmitSV3_R() { - EmitNullPointerThrow(B, X_WRITE_NIL); + EmitNullPointerThrow(A, X_WRITE_NIL); auto tmp = newTempIntPtr(); - cc.mov(tmp, regA[B]); + cc.mov(tmp, regA[A]); cc.add(tmp, regD[C]); cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]); cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]); @@ -153,7 +153,7 @@ void JitCompiler::EmitSV3_R() void JitCompiler::EmitSBIT() { - EmitNullPointerThrow(B, X_WRITE_NIL); + EmitNullPointerThrow(A, X_WRITE_NIL); auto tmp1 = newTempInt32(); auto tmp2 = newTempInt32(); cc.mov(tmp1, asmjit::x86::byte_ptr(regA[A])); diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index 28f9ff4694..f49b05f01c 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -31,8 +31,6 @@ public: void Codegen(); - static bool CanJit(VMScriptFunction *sfunc); - private: // Declare EmitXX functions for the opcodes: #define xx(op, name, mode, alt, kreg, ktype) void Emit##op(); @@ -48,7 +46,7 @@ private: void LoadInOuts(int b); void LoadReturns(const VMOP *retval, int numret); void FillReturns(const VMOP *retval, int numret); - void LoadCallResult(const VMOP &opdata); + void LoadCallResult(const VMOP &opdata, bool addrof); static int DoCall(VMFrameStack *stack, VMFunction *call, int b, int c, VMValue *param, VMReturn *returns, JitExceptionInfo *exceptinfo); template