From 5375a99cf698cb0053977e1cabdadae32a488643 Mon Sep 17 00:00:00 2001 From: Chronos Ouroboros Date: Wed, 14 Nov 2018 10:22:05 -0200 Subject: [PATCH 1/3] Added support for CMP_APPROX to EQV_R and moved the code to a template. --- src/scripting/vm/jit_math.cpp | 54 ++--------------------------------- src/scripting/vm/jitintern.h | 47 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 52 deletions(-) diff --git a/src/scripting/vm/jit_math.cpp b/src/scripting/vm/jit_math.cpp index d88eae471..1fadbb362 100644 --- a/src/scripting/vm/jit_math.cpp +++ b/src/scripting/vm/jit_math.cpp @@ -1219,27 +1219,7 @@ void JitCompiler::EmitLENV2() void JitCompiler::EmitEQV2_R() { EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) { - if (static_cast(A & CMP_APPROX)) I_FatalError("CMP_APPROX not implemented for EQV2_R.\n"); - - cc.ucomisd(regF[B], regF[C]); - if (check) { - cc.jp(success); - cc.jne(success); - } - else { - cc.jp(fail); - cc.jne(fail); - } - - cc.ucomisd(regF[B + 1], regF[C + 1]); - if (check) { - cc.jp(success); - cc.je(fail); - } - else { - cc.jp(fail); - cc.jne(fail); - } + EmitVectorComparison<2> (check, fail, success); }); } @@ -1406,37 +1386,7 @@ void JitCompiler::EmitLENV3() void JitCompiler::EmitEQV3_R() { EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) { - if (static_cast(A & CMP_APPROX)) I_FatalError("CMP_APPROX not implemented for EQV3_R.\n"); - - cc.ucomisd(regF[B], regF[C]); - if (check) { - cc.jp(success); - cc.jne(success); - } - else { - cc.jp(fail); - cc.jne(fail); - } - - cc.ucomisd(regF[B + 1], regF[C + 1]); - if (check) { - cc.jp(success); - cc.jne(success); - } - else { - cc.jp(fail); - cc.jne(fail); - } - - cc.ucomisd(regF[B + 2], regF[C + 2]); - if (check) { - cc.jp(success); - cc.je(fail); - } - else { - cc.jp(fail); - cc.jne(fail); - } + EmitVectorComparison<3> (check, fail, success); }); } diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index 14a6c995d..769f03891 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -72,6 +72,53 @@ private: pc++; // This instruction uses two instruction slots - skip the next one } + template + void EmitVectorComparison(bool check, asmjit::Label& fail, asmjit::Label& success) + { + bool approx = static_cast(A & CMP_APPROX); + if (!approx) + { + for (int i = 0; i < N; i++) + { + cc.ucomisd(regF[B + i], regF[C + i]); + if (check) + { + cc.jp(success); + cc.jne(success); + } + else + { + cc.jp(fail); + cc.jne(fail); + } + } + } + else + { + auto tmp = newTempXmmSd(); + + const int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF; + auto absMask = cc.newDoubleConst(asmjit::kConstScopeLocal, reinterpret_cast(absMaskInt)); + auto absMaskXmm = newTempXmmPd(); + + auto epsilon = cc.newDoubleConst(asmjit::kConstScopeLocal, VM_EPSILON); + auto epsilonXmm = newTempXmmSd(); + + for (int i = 0; i < N; i++) + { + cc.movsd(tmp, regF[B + i]); + cc.subsd(tmp, regF[C + i]); + cc.movsd(absMaskXmm, absMask); + cc.andpd(tmp, absMaskXmm); + cc.movsd(epsilonXmm, epsilon); + cc.ucomisd(epsilonXmm, tmp); + + if (check) cc.ja(fail); + else cc.jna(fail); + } + } + } + static uint64_t ToMemAddress(const void *d) { return (uint64_t)(ptrdiff_t)d; From 566eb58000abed2a72ab6980a6e13b2ec521bae5 Mon Sep 17 00:00:00 2001 From: Chronos Ouroboros Date: Wed, 14 Nov 2018 14:11:46 -0200 Subject: [PATCH 2/3] Fixed the Vector2/3 != operator. --- src/scripting/vm/jitintern.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index 769f03891..b7348b773 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -84,7 +84,14 @@ private: if (check) { cc.jp(success); - cc.jne(success); + if (i == (N - 1)) + { + cc.je(fail); + } + else + { + cc.jne(success); + } } else { From 96b8f12a30099c02d9c70023c355f3fe5d6d9cbb Mon Sep 17 00:00:00 2001 From: Chronos Ouroboros Date: Wed, 14 Nov 2018 21:02:43 -0200 Subject: [PATCH 3/3] Fix the code for MODF_RK in the JIT compiler. --- src/scripting/vm/jit_math.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/scripting/vm/jit_math.cpp b/src/scripting/vm/jit_math.cpp index 1fadbb362..7b557cfb3 100644 --- a/src/scripting/vm/jit_math.cpp +++ b/src/scripting/vm/jit_math.cpp @@ -757,21 +757,27 @@ void JitCompiler::EmitMODF_RR() void JitCompiler::EmitMODF_RK() { - auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO); - cc.ptest(regF[C], regF[C]); - cc.je(label); + if (konstf[C] == 0.) + { + EmitThrowException(X_DIVISION_BY_ZERO); + } + else + { + auto tmpPtr = newTempIntPtr(); + cc.mov(tmpPtr, asmjit::imm_ptr(&konstf[C])); - auto tmp = newTempXmmSd(); - cc.movsd(tmp, asmjit::x86::ptr(ToMemAddress(&konstf[C]))); + auto tmp = newTempXmmSd(); + cc.movsd(tmp, asmjit::x86::qword_ptr(tmpPtr)); - auto result = newResultXmmSd(); - auto call = CreateCall([](double a, double b) -> double { - return a - floor(a / b) * b; - }); - call->setRet(0, result); - call->setArg(0, regF[B]); - call->setArg(1, tmp); - cc.movsd(regF[A], result); + auto result = newResultXmmSd(); + auto call = CreateCall([](double a, double b) -> double { + return a - floor(a / b) * b; + }); + call->setRet(0, result); + call->setArg(0, regF[B]); + call->setArg(1, tmp); + cc.movsd(regF[A], result); + } } void JitCompiler::EmitMODF_KR()