From d137b3c94ee794a547e353a10e65ce29c77493e4 Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Fri, 17 Aug 2018 19:08:19 +0100 Subject: [PATCH 1/3] - implemented CMP_APPROX for OP_EQF_*, making ~== work for doubles --- src/scripting/vm/jit.cpp | 77 ++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 15 deletions(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index cdf874327ed..104184bf184 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -1166,12 +1166,34 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) case OP_EQF_R: // if ((fB == fkC) != (A & 1)) then pc++ { auto compLambda = [&](X86Gp& result) { - auto tmp = cc.newInt32(); - cc.ucomisd(regF[B], regF[C]); - cc.sete(result); - cc.setnp(tmp); - cc.and_(result, tmp); - cc.and_(result, 1); + bool approx = static_cast(A & CMP_APPROX); + if (!approx) { + auto tmp = cc.newInt32(); + cc.ucomisd(regF[B], regF[C]); + cc.sete(result); + cc.setnp(tmp); + cc.and_(result, tmp); + cc.and_(result, 1); + } + else { + auto tmp = cc.newXmmSd(); + + int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF; + auto absMask = cc.newDoubleConst(kConstScopeLocal, reinterpret_cast(absMaskInt)); + auto absMaskXmm = cc.newXmmPd(); + + auto epsilon = cc.newDoubleConst(kConstScopeLocal, VM_EPSILON); + auto epsilonXmm = cc.newXmmSd(); + + cc.movsd(tmp, regF[B]); + cc.subsd(tmp, regF[C]); + cc.movsd(absMaskXmm, absMask); + cc.andpd(tmp, absMaskXmm); + cc.movsd(epsilonXmm, epsilon); + cc.ucomisd(epsilonXmm, tmp); + cc.seta(result); + cc.and_(result, 1); + } }; emitComparisonOpcode(cc, labels, pc, i, compLambda); @@ -1180,15 +1202,40 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) case OP_EQF_K: { auto compLambda = [&](X86Gp& result) { - auto konstTmp = cc.newIntPtr(); - auto parityTmp = cc.newInt32(); - cc.mov(konstTmp, reinterpret_cast(&(konstf[C]))); - - cc.ucomisd(regF[B], x86::qword_ptr(konstTmp)); - cc.sete(result); - cc.setnp(parityTmp); - cc.and_(result, parityTmp); - cc.and_(result, 1); + bool approx = static_cast(A & CMP_APPROX); + if (!approx) { + auto konstTmp = cc.newIntPtr(); + auto parityTmp = cc.newInt32(); + cc.mov(konstTmp, reinterpret_cast(&(konstf[C]))); + + cc.ucomisd(regF[B], x86::qword_ptr(konstTmp)); + cc.sete(result); + cc.setnp(parityTmp); + cc.and_(result, parityTmp); + cc.and_(result, 1); + } + else { + auto konstTmp = cc.newIntPtr(); + auto subTmp = cc.newXmmSd(); + + int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF; + auto absMask = cc.newDoubleConst(kConstScopeLocal, reinterpret_cast(absMaskInt)); + auto absMaskXmm = cc.newXmmPd(); + + auto epsilon = cc.newDoubleConst(kConstScopeLocal, VM_EPSILON); + auto epsilonXmm = cc.newXmmSd(); + + cc.mov(konstTmp, reinterpret_cast(&(konstf[C]))); + + cc.movsd(subTmp, regF[B]); + cc.subsd(subTmp, x86::qword_ptr(konstTmp)); + cc.movsd(absMaskXmm, absMask); + cc.andpd(subTmp, absMaskXmm); + cc.movsd(epsilonXmm, epsilon); + cc.ucomisd(epsilonXmm, subTmp); + cc.seta(result); + cc.and_(result, 1); + } }; emitComparisonOpcode(cc, labels, pc, i, compLambda); From 08c0ac541f33237b2d2ac924c13d955f5c6d6e56 Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Fri, 17 Aug 2018 19:14:31 +0100 Subject: [PATCH 2/3] - made absMaskInt const --- src/scripting/vm/jit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 104184bf184..6325b64493d 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -270,7 +270,7 @@ void emitComparisonOpcode(asmjit::X86Compiler& cc, const TArray& JitFuncPtr JitCompile(VMScriptFunction *sfunc) { -#if 0 // For debugging +#if 1 // For debugging if (strcmp(sfunc->Name.GetChars(), "EmptyFunction") != 0) return nullptr; #else @@ -1178,7 +1178,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) else { auto tmp = cc.newXmmSd(); - int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF; + const int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF; auto absMask = cc.newDoubleConst(kConstScopeLocal, reinterpret_cast(absMaskInt)); auto absMaskXmm = cc.newXmmPd(); @@ -1218,7 +1218,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) auto konstTmp = cc.newIntPtr(); auto subTmp = cc.newXmmSd(); - int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF; + const int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF; auto absMask = cc.newDoubleConst(kConstScopeLocal, reinterpret_cast(absMaskInt)); auto absMaskXmm = cc.newXmmPd(); From 758ee5cbfbff014f9b17fb10aa6f470068952548 Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Fri, 17 Aug 2018 19:15:27 +0100 Subject: [PATCH 3/3] - forgot to turn off debug switch in last commit --- src/scripting/vm/jit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 6325b64493d..c0a9d672166 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -270,7 +270,7 @@ void emitComparisonOpcode(asmjit::X86Compiler& cc, const TArray& JitFuncPtr JitCompile(VMScriptFunction *sfunc) { -#if 1 // For debugging +#if 0 // For debugging if (strcmp(sfunc->Name.GetChars(), "EmptyFunction") != 0) return nullptr; #else