From 0b6c514067cb53322ef7d8fad4e4bb4f549b6426 Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Thu, 13 Sep 2018 20:31:06 +0100 Subject: [PATCH] - added OP_MOVES, OP_CONCAT, OP_LENS, OP_CMPS --- src/scripting/vm/jit.cpp | 18 +++++++--- src/scripting/vm/jit_math.cpp | 60 ++++++++++++++++++++++++++++++++-- src/scripting/vm/jit_move.cpp | 8 ++++- src/scripting/vm/jit_store.cpp | 4 +-- src/scripting/vm/jitintern.h | 1 + 5 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 6d2fd7d765..78e6f6849f 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -154,14 +154,10 @@ bool JitCompiler::CanJit(VMScriptFunction *sfunc) case OP_LFP: case OP_LCS_R: case OP_SS_R: - case OP_MOVES: case OP_IJMP: case OP_CALL: // this one is implemented but crashes currently case OP_TAIL: case OP_TAIL_K: - case OP_CONCAT: - case OP_LENS: - case OP_CMPS: return false; } @@ -417,6 +413,20 @@ asmjit::X86Xmm JitCompiler::CheckRegF(int r0, int r1, int r2, int r3) } } +asmjit::X86Gp JitCompiler::CheckRegS(int r0, int r1) +{ + if (r0 != r1) + { + return regS[r0]; + } + else + { + auto copy = cc.newIntPtr(); + cc.mov(copy, regS[r0]); + return copy; + } +} + asmjit::X86Gp JitCompiler::CheckRegA(int r0, int r1) { if (r0 != r1) diff --git a/src/scripting/vm/jit_math.cpp b/src/scripting/vm/jit_math.cpp index 47413c0872..5ef70eff6f 100644 --- a/src/scripting/vm/jit_math.cpp +++ b/src/scripting/vm/jit_math.cpp @@ -6,17 +6,71 @@ void JitCompiler::EmitCONCAT() { - I_FatalError("EmitCONCAT not implemented\n"); + auto rc = CheckRegS(C, A); + auto concatLambda = [](FString* to, FString* first, FString* second) -> void { + *to = *first + *second; + }; + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(concatLambda))), + asmjit::FuncSignature3(asmjit::CallConv::kIdHostCDecl)); + call->setArg(0, regS[A]); + call->setArg(1, regS[B]); + call->setArg(2, rc); } void JitCompiler::EmitLENS() { - I_FatalError("EmitLENS not implemented\n"); + auto lenLambda = [](FString* str) -> int { + return static_cast(str->Len()); + }; + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(lenLambda))), + asmjit::FuncSignature1(asmjit::CallConv::kIdHostCDecl)); + call->setRet(0, regD[A]); + call->setArg(0, regS[B]); } void JitCompiler::EmitCMPS() { - I_FatalError("EmitCMPS not implemented\n"); + EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) { + auto compareNoCaseLambda = [](FString* first, FString* second) -> int { + return first->CompareNoCase(*second); + }; + auto compareLambda = [](FString* first, FString* second) -> int { + return first->Compare(*second); + }; + + auto call = + static_cast(A & CMP_APPROX) ? + cc.call(ToMemAddress(reinterpret_cast(static_cast(compareNoCaseLambda))), + asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)) : + cc.call(ToMemAddress(reinterpret_cast(static_cast(compareLambda))), + asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + + auto result = cc.newInt32(); + call->setRet(0, result); + + if (static_cast(A & CMP_BK)) call->setArg(0, asmjit::imm_ptr(&konsts[B])); + else call->setArg(0, regS[B]); + + if (static_cast(A & CMP_CK)) call->setArg(1, asmjit::imm_ptr(&konsts[C])); + else call->setArg(1, regS[C]); + + int method = A & CMP_METHOD_MASK; + if (method == CMP_EQ) { + cc.test(result, result); + if (check) cc.jz(fail); + else cc.jnz(fail); + } + else if (method == CMP_LT) { + cc.cmp(result, 0); + if (check) cc.jl(fail); + else cc.jnl(fail); + } + else { + cc.cmp(result, 0); + if (check) cc.jle(fail); + else cc.jnle(fail); + } + }); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/scripting/vm/jit_move.cpp b/src/scripting/vm/jit_move.cpp index 8d5e8cc3a0..fb51649265 100644 --- a/src/scripting/vm/jit_move.cpp +++ b/src/scripting/vm/jit_move.cpp @@ -12,7 +12,13 @@ void JitCompiler::EmitMOVEF() void JitCompiler::EmitMOVES() { - I_FatalError("EmitMOVES not implemented\n"); + auto loadLambda = [](FString* to, FString* from) -> void { + *to = *from; + }; + auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), + asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + call->setArg(0, regS[A]); + call->setArg(1, regS[B]); } void JitCompiler::EmitMOVEA() diff --git a/src/scripting/vm/jit_store.cpp b/src/scripting/vm/jit_store.cpp index 4a3aa0e2af..036fe82b3c 100644 --- a/src/scripting/vm/jit_store.cpp +++ b/src/scripting/vm/jit_store.cpp @@ -63,7 +63,7 @@ void JitCompiler::EmitSDP_R() void JitCompiler::EmitSS() { - EmitNullPointerThrow(B, X_WRITE_NIL); + EmitNullPointerThrow(A, X_WRITE_NIL); auto ptr = cc.newIntPtr(); cc.mov(ptr, regA[A]); cc.add(ptr, konstd[C]); @@ -78,7 +78,7 @@ void JitCompiler::EmitSS() void JitCompiler::EmitSS_R() { - EmitNullPointerThrow(B, X_WRITE_NIL); + EmitNullPointerThrow(A, X_WRITE_NIL); auto ptr = cc.newIntPtr(); cc.mov(ptr, regA[A]); auto tmp = cc.newIntPtr(); diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index ffbc8d9544..b596a5edcb 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -80,6 +80,7 @@ private: asmjit::X86Xmm CheckRegF(int r0, int r1); asmjit::X86Xmm CheckRegF(int r0, int r1, int r2); asmjit::X86Xmm CheckRegF(int r0, int r1, int r2, int r3); + asmjit::X86Gp CheckRegS(int r0, int r1); asmjit::X86Gp CheckRegA(int r0, int r1); asmjit::X86Compiler cc;