From 740415246e9472fe488a7f7d2918010096fed21b Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Tue, 14 Aug 2018 18:32:17 +0100 Subject: [PATCH 1/2] - added exact floating point comparison opcodes --- src/scripting/vm/jit.cpp | 124 +++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 12 deletions(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 341ce7c96b..6f70213ff6 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -226,8 +226,6 @@ template void emitComparisonOpcode(asmjit::X86Compiler& cc, const TArray& labels, const VMOP* pc, int i, Func compFunc) { using namespace asmjit; - Label elseLabel = cc.newLabel(); - auto tmp0 = cc.newInt32(); auto tmp1 = cc.newInt32(); @@ -237,12 +235,9 @@ void emitComparisonOpcode(asmjit::X86Compiler& cc, const TArray& cc.and_(tmp1, CMP_CHECK); cc.cmp(tmp0, tmp1); - cc.jne(elseLabel); + cc.jne(labels[i + 2]); cc.jmp(labels[i + 2 + JMPOFS(pc + 1)]); - - cc.bind(elseLabel); - cc.jmp(labels[i + 2]); } JitFuncPtr JitCompile(VMScriptFunction *sfunc) @@ -979,8 +974,8 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) { auto compLambda = [&](X86Gp& result) { auto tmp = cc.newIntPtr(); - cc.mov(tmp, reinterpret_cast(&(konstd[C]))); - cc.cmp(x86::ptr(tmp), regD[B]); + cc.mov(tmp, reinterpret_cast(&(konstd[B]))); + cc.cmp(x86::ptr(tmp), regD[C]); cc.setl(result); }; emitComparisonOpcode(cc, labels, pc, i, compLambda); @@ -1011,8 +1006,8 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) { auto compLambda = [&](X86Gp& result) { auto tmp = cc.newIntPtr(); - cc.mov(tmp, reinterpret_cast(&(konstd[C]))); - cc.cmp(x86::ptr(tmp), regD[B]); + cc.mov(tmp, reinterpret_cast(&(konstd[B]))); + cc.cmp(x86::ptr(tmp), regD[C]); cc.setle(result); }; emitComparisonOpcode(cc, labels, pc, i, compLambda); @@ -1043,8 +1038,8 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) { auto compLambda = [&](X86Gp& result) { auto tmp = cc.newIntPtr(); - cc.mov(tmp, reinterpret_cast(&(konstd[C]))); - cc.cmp(x86::ptr(tmp), regD[B]); + cc.mov(tmp, reinterpret_cast(&(konstd[B]))); + cc.cmp(x86::ptr(tmp), regD[C]); cc.setb(result); }; emitComparisonOpcode(cc, labels, pc, i, compLambda); @@ -1162,13 +1157,118 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) case OP_ATAN2: // fA = atan2(fB,fC), result is in degrees case OP_FLOP: // fA = f(fB), where function is selected by C 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); + }; + emitComparisonOpcode(cc, labels, pc, i, compLambda); + + break; + } 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); + }; + emitComparisonOpcode(cc, labels, pc, i, compLambda); + + break; + } case OP_LTF_RR: // if ((fkB < fkC) != (A & 1)) then pc++ + { + auto compLambda = [&](X86Gp& result) { + cc.ucomisd(regF[C], regF[B]); + cc.seta(result); + cc.and_(result, 1); + }; + emitComparisonOpcode(cc, labels, pc, i, compLambda); + + break; + } case OP_LTF_RK: + { + auto compLambda = [&](X86Gp& result) { + auto constTmp = cc.newIntPtr(); + auto xmmTmp = cc.newXmmSd(); + cc.mov(constTmp, reinterpret_cast(&(konstf[C]))); + cc.movsd(xmmTmp, x86::qword_ptr(constTmp)); + + cc.ucomisd(xmmTmp, regF[B]); + cc.seta(result); + cc.and_(result, 1); + }; + emitComparisonOpcode(cc, labels, pc, i, compLambda); + + break; + } case OP_LTF_KR: + { + auto compLambda = [&](X86Gp& result) { + auto tmp = cc.newIntPtr(); + cc.mov(tmp, reinterpret_cast(&(konstf[B]))); + + cc.ucomisd(regF[C], x86::qword_ptr(tmp)); + cc.seta(result); + cc.and_(result, 1); + }; + emitComparisonOpcode(cc, labels, pc, i, compLambda); + + break; + } case OP_LEF_RR: // if ((fkb <= fkC) != (A & 1)) then pc++ + { + auto compLambda = [&](X86Gp& result) { + cc.ucomisd(regF[C], regF[B]); + cc.setae(result); + cc.and_(result, 1); + }; + emitComparisonOpcode(cc, labels, pc, i, compLambda); + + break; + } case OP_LEF_RK: + { + auto compLambda = [&](X86Gp& result) { + auto constTmp = cc.newIntPtr(); + auto xmmTmp = cc.newXmmSd(); + cc.mov(constTmp, reinterpret_cast(&(konstf[C]))); + cc.movsd(xmmTmp, x86::qword_ptr(constTmp)); + + cc.ucomisd(xmmTmp, regF[B]); + cc.setae(result); + cc.and_(result, 1); + }; + emitComparisonOpcode(cc, labels, pc, i, compLambda); + + break; + } case OP_LEF_KR: + { + auto compLambda = [&](X86Gp& result) { + auto tmp = cc.newIntPtr(); + cc.mov(tmp, reinterpret_cast(&(konstf[B]))); + + cc.ucomisd(regF[C], x86::qword_ptr(tmp)); + cc.setae(result); + cc.and_(result, 1); + }; + emitComparisonOpcode(cc, labels, pc, i, compLambda); + + break; + } break; // Vector math. (2D) From dc03cb7a80cc282efba7658fb4b211c86eb8023d Mon Sep 17 00:00:00 2001 From: Jonathan Russell Date: Tue, 14 Aug 2018 20:50:32 +0100 Subject: [PATCH 2/2] - made CMP_CHECK checking compile time --- src/scripting/vm/jit.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 6f70213ff6..8a5018596c 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -226,16 +226,15 @@ template void emitComparisonOpcode(asmjit::X86Compiler& cc, const TArray& labels, const VMOP* pc, int i, Func compFunc) { using namespace asmjit; - auto tmp0 = cc.newInt32(); - auto tmp1 = cc.newInt32(); + auto tmp = cc.newInt32(); - compFunc(tmp0); + compFunc(tmp); - cc.mov(tmp1, A); - cc.and_(tmp1, CMP_CHECK); + bool check = static_cast(A & CMP_CHECK); - cc.cmp(tmp0, tmp1); - cc.jne(labels[i + 2]); + cc.test(tmp, tmp); + if (check) cc.je (labels[i + 2]); + else cc.jne(labels[i + 2]); cc.jmp(labels[i + 2 + JMPOFS(pc + 1)]); }