diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index e60a783548..01b949c2cc 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -169,8 +169,6 @@ bool JitCompiler::CanJit(VMScriptFunction *sfunc) if (B != REGT_NIL) { int regtype = B; - if ((regtype & REGT_TYPE) == REGT_STRING) - return false; } } else if (sfunc->Code[i].op == OP_CAST) @@ -198,10 +196,6 @@ bool JitCompiler::CanJit(VMScriptFunction *sfunc) switch (B) { - case REGT_STRING: - case REGT_STRING | REGT_ADDROF: - case REGT_STRING | REGT_KONST: - return false; default: break; } @@ -210,9 +204,6 @@ bool JitCompiler::CanJit(VMScriptFunction *sfunc) { if (!!(B & REGT_MULTIREG3) || !!(B & REGT_MULTIREG2)) return false; - - if ((B & REGT_TYPE) == REGT_STRING) - return false; } } return true; diff --git a/src/scripting/vm/jit_call.cpp b/src/scripting/vm/jit_call.cpp index a3df4187d6..5d036dcea6 100644 --- a/src/scripting/vm/jit_call.cpp +++ b/src/scripting/vm/jit_call.cpp @@ -32,9 +32,41 @@ void JitCompiler::EmitPARAM() cc.mov(x86::dword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, i)), konstd[C]); cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_INT); break; - //case REGT_STRING: - //case REGT_STRING | REGT_ADDROF: - //case REGT_STRING | REGT_KONST: + case REGT_STRING: + { + auto setStringLambda = [](VMValue* val, FString* str) -> void { + ::new(val) VMValue(str); + }; + auto ptr = cc.newIntPtr(); + cc.mov(ptr, params); + cc.add(ptr, index * sizeof(VMValue)); + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(setStringLambda))), + asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + call->setArg(0, ptr); + call->setArg(1, regS[C]); + break; + } + case REGT_STRING | REGT_ADDROF: + stackPtr = cc.newIntPtr(); + cc.mov(stackPtr, frameS); + cc.add(stackPtr, C * sizeof(FString)); + cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), stackPtr); + cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER); + break; + case REGT_STRING | REGT_KONST: + { + auto setStringLambda = [](VMValue* val, FString* str) -> void { + ::new(val) VMValue(str); + }; + auto ptr = cc.newIntPtr(); + cc.mov(ptr, params); + cc.add(ptr, index * sizeof(VMValue)); + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(setStringLambda))), + asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + call->setArg(0, ptr); + call->setArg(1, asmjit::imm_ptr(&konsts[C])); + break; + } case REGT_POINTER: cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), regA[C]); cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER); @@ -245,8 +277,10 @@ void JitCompiler::LoadReturns(const VMOP *retval, int numret, bool inout) case REGT_FLOAT: cc.movsd(regF[regnum], asmjit::x86::qword_ptr(frameF, regnum * sizeof(double))); break; - /*case REGT_STRING: - break;*/ + case REGT_STRING: + cc.mov(regS[regnum], frameS); + cc.add(regS[regnum], regnum * sizeof(FString)); + break; case REGT_POINTER: cc.mov(regA[regnum], asmjit::x86::ptr(frameA, regnum * sizeof(void*))); break; @@ -288,10 +322,10 @@ void JitCompiler::FillReturns(const VMOP *retval, int numret) cc.mov(regPtr, frameF); cc.add(regPtr, (int)(regnum * sizeof(double))); break; - /*case REGT_STRING: + case REGT_STRING: cc.mov(regPtr, frameS); cc.add(regPtr, regnum * sizeof(FString)); - break;*/ + break; case REGT_POINTER: cc.mov(regPtr, frameA); cc.add(regPtr, (int)(regnum * sizeof(void*))); diff --git a/src/scripting/vm/jit_flow.cpp b/src/scripting/vm/jit_flow.cpp index cbe2e93bda..f5d76d575b 100644 --- a/src/scripting/vm/jit_flow.cpp +++ b/src/scripting/vm/jit_flow.cpp @@ -168,7 +168,20 @@ void JitCompiler::EmitRET() } break; case REGT_STRING: + { + auto setRetStringLamdba = [](VMReturn* ret, FString* str) -> void { + ret->SetString(*str); + }; + auto ptr = cc.newIntPtr(); + cc.mov(ptr, ret); + cc.add(ptr, retnum * sizeof(VMReturn)); + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(setRetStringLamdba))), + asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + call->setArg(0, ptr); + if (regtype & REGT_KONST) call->setArg(1, asmjit::imm_ptr(&konsts[regnum])); + else call->setArg(1, regS[regnum]); break; + } case REGT_POINTER: #ifdef ASMJIT_ARCH_X64 if (regtype & REGT_KONST) diff --git a/src/scripting/vm/jit_load.cpp b/src/scripting/vm/jit_load.cpp index 718f511c23..43a6e183bd 100644 --- a/src/scripting/vm/jit_load.cpp +++ b/src/scripting/vm/jit_load.cpp @@ -23,10 +23,7 @@ void JitCompiler::EmitLKF() void JitCompiler::EmitLKS() { - auto loadLambda = [] (FString* to, FString* from) -> void { - *to = *from; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); call->setArg(0, regS[A]); call->setArg(1, asmjit::imm(ToMemAddress(konsts + BC))); @@ -193,10 +190,7 @@ void JitCompiler::EmitLS() auto ptr = cc.newIntPtr(); cc.mov(ptr, regA[B]); cc.add(ptr, konstd[C]); - auto loadLambda = [](FString* to, FString* from) -> void { - *to = *from; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); call->setArg(0, regS[A]); call->setArg(1, ptr); @@ -210,10 +204,7 @@ void JitCompiler::EmitLS_R() auto tmp = cc.newIntPtr(); cc.mov(tmp, regD[C]); cc.add(ptr, tmp); - auto loadLambda = [](FString* to, FString* from) -> void { - *to = *from; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); call->setArg(0, regS[A]); call->setArg(1, ptr); diff --git a/src/scripting/vm/jit_move.cpp b/src/scripting/vm/jit_move.cpp index fb51649265..00cecf47ac 100644 --- a/src/scripting/vm/jit_move.cpp +++ b/src/scripting/vm/jit_move.cpp @@ -12,10 +12,7 @@ void JitCompiler::EmitMOVEF() void JitCompiler::EmitMOVES() { - auto loadLambda = [](FString* to, FString* from) -> void { - *to = *from; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); call->setArg(0, regS[A]); call->setArg(1, regS[B]); diff --git a/src/scripting/vm/jit_store.cpp b/src/scripting/vm/jit_store.cpp index 036fe82b3c..1584d0afe3 100644 --- a/src/scripting/vm/jit_store.cpp +++ b/src/scripting/vm/jit_store.cpp @@ -67,10 +67,7 @@ void JitCompiler::EmitSS() auto ptr = cc.newIntPtr(); cc.mov(ptr, regA[A]); cc.add(ptr, konstd[C]); - auto loadLambda = [](FString* to, FString* from) -> void { - *to = *from; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); call->setArg(0, ptr); call->setArg(1, regS[B]); @@ -84,10 +81,7 @@ void JitCompiler::EmitSS_R() auto tmp = cc.newIntPtr(); cc.mov(tmp, regD[C]); cc.add(ptr, tmp); - auto loadLambda = [](FString* to, FString* from) -> void { - *to = *from; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); call->setArg(0, ptr); call->setArg(1, regS[B]); diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index b596a5edcb..be8abec7ff 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -72,6 +72,10 @@ private: void CallSqrt(const asmjit::X86Xmm &a, const asmjit::X86Xmm &b); + static void CallAssignString(FString* to, FString* from) { + *to = *from; + } + void EmitNullPointerThrow(int index, EVMAbortException reason); void EmitThrowException(EVMAbortException reason); void EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg1);