mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
- modify exception checks to jump ahead if the exception is to be thrown as it limits static misprediction
This commit is contained in:
parent
a7ef178284
commit
e6023c55a8
5 changed files with 77 additions and 93 deletions
|
@ -678,11 +678,9 @@ void JitCompiler::EmitPopFrame()
|
|||
|
||||
void JitCompiler::EmitNullPointerThrow(int index, EVMAbortException reason)
|
||||
{
|
||||
auto label = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(reason);
|
||||
cc.test(regA[index], regA[index]);
|
||||
cc.jne(label);
|
||||
EmitThrowException(reason);
|
||||
cc.bind(label);
|
||||
cc.je(label);
|
||||
}
|
||||
|
||||
void JitCompiler::ThrowException(VMScriptFunction *func, VMOP *line, int reason)
|
||||
|
@ -705,6 +703,16 @@ void JitCompiler::EmitThrowException(EVMAbortException reason)
|
|||
call->setArg(2, asmjit::imm(reason));
|
||||
}
|
||||
|
||||
asmjit::Label JitCompiler::EmitThrowExceptionLabel(EVMAbortException reason)
|
||||
{
|
||||
auto label = cc.newLabel();
|
||||
auto cursor = cc.getCursor();
|
||||
cc.bind(label);
|
||||
EmitThrowException(reason);
|
||||
cc.setCursor(cursor);
|
||||
return label;
|
||||
}
|
||||
|
||||
asmjit::X86Gp JitCompiler::CheckRegD(int r0, int r1)
|
||||
{
|
||||
if (r0 != r1)
|
||||
|
|
|
@ -50,11 +50,9 @@ void JitCompiler::EmitIJMP()
|
|||
|
||||
void JitCompiler::EmitVTBL()
|
||||
{
|
||||
auto notnull = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(X_READ_NIL);
|
||||
cc.test(regA[B], regA[B]);
|
||||
cc.jnz(notnull);
|
||||
EmitThrowException(X_READ_NIL);
|
||||
cc.bind(notnull);
|
||||
cc.jz(label);
|
||||
|
||||
auto result = newResultIntPtr();
|
||||
auto call = CreateCall<VMFunction*, DObject*, int>([](DObject *o, int c) -> VMFunction* {
|
||||
|
@ -70,11 +68,9 @@ void JitCompiler::EmitVTBL()
|
|||
|
||||
void JitCompiler::EmitSCOPE()
|
||||
{
|
||||
auto notnull = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(X_READ_NIL);
|
||||
cc.test(regA[A], regA[A]);
|
||||
cc.jnz(notnull);
|
||||
EmitThrowException(X_READ_NIL);
|
||||
cc.bind(notnull);
|
||||
cc.jz(label);
|
||||
|
||||
auto f = newTempIntPtr();
|
||||
cc.mov(f, asmjit::imm_ptr(konsta[C].v));
|
||||
|
@ -355,48 +351,50 @@ void JitCompiler::EmitTHROW()
|
|||
|
||||
void JitCompiler::EmitBOUND()
|
||||
{
|
||||
auto cursor = cc.getCursor();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
cc.cmp(regD[A], (int)BC);
|
||||
cc.jb(label);
|
||||
|
||||
cc.bind(label);
|
||||
auto call = CreateCall<void, VMScriptFunction *, VMOP *, int, int>(&JitCompiler::ThrowArrayOutOfBounds);
|
||||
call->setArg(0, asmjit::imm_ptr(sfunc));
|
||||
call->setArg(1, asmjit::imm_ptr(pc));
|
||||
call->setArg(2, regD[A]);
|
||||
call->setArg(3, asmjit::imm(BC));
|
||||
cc.setCursor(cursor);
|
||||
|
||||
cc.bind(label);
|
||||
cc.cmp(regD[A], (int)BC);
|
||||
cc.jae(label);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitBOUND_K()
|
||||
{
|
||||
auto cursor = cc.getCursor();
|
||||
auto label = cc.newLabel();
|
||||
cc.cmp(regD[A], (int)konstd[BC]);
|
||||
cc.jb(label);
|
||||
|
||||
cc.bind(label);
|
||||
auto call = CreateCall<void, VMScriptFunction *, VMOP *, int, int>(&JitCompiler::ThrowArrayOutOfBounds);
|
||||
call->setArg(0, asmjit::imm_ptr(sfunc));
|
||||
call->setArg(1, asmjit::imm_ptr(pc));
|
||||
call->setArg(2, regD[A]);
|
||||
call->setArg(3, asmjit::imm(konstd[BC]));
|
||||
cc.setCursor(cursor);
|
||||
|
||||
cc.bind(label);
|
||||
cc.cmp(regD[A], (int)konstd[BC]);
|
||||
cc.jae(label);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitBOUND_R()
|
||||
{
|
||||
auto cursor = cc.getCursor();
|
||||
auto label = cc.newLabel();
|
||||
cc.cmp(regD[A], regD[B]);
|
||||
cc.jb(label);
|
||||
|
||||
cc.bind(label);
|
||||
auto call = CreateCall<void, VMScriptFunction *, VMOP *, int, int>(&JitCompiler::ThrowArrayOutOfBounds);
|
||||
call->setArg(0, asmjit::imm_ptr(sfunc));
|
||||
call->setArg(1, asmjit::imm_ptr(pc));
|
||||
call->setArg(2, regD[A]);
|
||||
call->setArg(3, regD[B]);
|
||||
cc.setCursor(cursor);
|
||||
|
||||
cc.bind(label);
|
||||
cc.cmp(regD[A], regD[B]);
|
||||
cc.jae(label);
|
||||
}
|
||||
|
||||
void JitCompiler::ThrowArrayOutOfBounds(VMScriptFunction *func, VMOP *line, int index, int size)
|
||||
|
|
|
@ -78,11 +78,9 @@ void JitCompiler::EmitLFP()
|
|||
|
||||
void JitCompiler::EmitMETA()
|
||||
{
|
||||
auto label = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(X_READ_NIL);
|
||||
cc.test(regA[B], regA[B]);
|
||||
cc.jne(label);
|
||||
EmitThrowException(X_READ_NIL);
|
||||
cc.bind(label);
|
||||
cc.je(label);
|
||||
|
||||
auto result = newResultIntPtr();
|
||||
auto call = CreateCall<uint8_t*, DObject*>([](DObject *o) { return o->GetClass()->Meta; });
|
||||
|
@ -93,11 +91,9 @@ void JitCompiler::EmitMETA()
|
|||
|
||||
void JitCompiler::EmitCLSS()
|
||||
{
|
||||
auto label = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(X_READ_NIL);
|
||||
cc.test(regA[B], regA[B]);
|
||||
cc.jne(label);
|
||||
EmitThrowException(X_READ_NIL);
|
||||
cc.bind(label);
|
||||
cc.je(label);
|
||||
|
||||
auto result = newResultIntPtr();
|
||||
auto call = CreateCall<PClass*, DObject*>([](DObject *o) { return o->GetClass(); });
|
||||
|
|
|
@ -200,14 +200,11 @@ void JitCompiler::EmitDIV_RR()
|
|||
{
|
||||
auto tmp0 = newTempInt32();
|
||||
auto tmp1 = newTempInt32();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.test(regD[C], regD[C]);
|
||||
cc.jne(label);
|
||||
cc.je(label);
|
||||
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
|
||||
cc.bind(label);
|
||||
cc.mov(tmp0, regD[B]);
|
||||
cc.cdq(tmp1, tmp0);
|
||||
cc.idiv(tmp1, tmp0, regD[C]);
|
||||
|
@ -227,21 +224,21 @@ void JitCompiler::EmitDIV_RK()
|
|||
cc.idiv(tmp1, tmp0, asmjit::x86::ptr(konstTmp));
|
||||
cc.mov(regD[A], tmp0);
|
||||
}
|
||||
else EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
else
|
||||
{
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
void JitCompiler::EmitDIV_KR()
|
||||
{
|
||||
auto tmp0 = newTempInt32();
|
||||
auto tmp1 = newTempInt32();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.test(regD[C], regD[C]);
|
||||
cc.jne(label);
|
||||
cc.je(label);
|
||||
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
|
||||
cc.bind(label);
|
||||
cc.mov(tmp0, konstd[B]);
|
||||
cc.cdq(tmp1, tmp0);
|
||||
cc.idiv(tmp1, tmp0, regD[C]);
|
||||
|
@ -252,14 +249,11 @@ void JitCompiler::EmitDIVU_RR()
|
|||
{
|
||||
auto tmp0 = newTempInt32();
|
||||
auto tmp1 = newTempInt32();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.test(regD[C], regD[C]);
|
||||
cc.jne(label);
|
||||
cc.je(label);
|
||||
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
|
||||
cc.bind(label);
|
||||
cc.mov(tmp0, regD[B]);
|
||||
cc.mov(tmp1, 0);
|
||||
cc.div(tmp1, tmp0, regD[C]);
|
||||
|
@ -279,21 +273,21 @@ void JitCompiler::EmitDIVU_RK()
|
|||
cc.div(tmp1, tmp0, asmjit::x86::ptr(konstTmp));
|
||||
cc.mov(regD[A], tmp0);
|
||||
}
|
||||
else EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
else
|
||||
{
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
void JitCompiler::EmitDIVU_KR()
|
||||
{
|
||||
auto tmp0 = newTempInt32();
|
||||
auto tmp1 = newTempInt32();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.test(regD[C], regD[C]);
|
||||
cc.jne(label);
|
||||
cc.je(label);
|
||||
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
|
||||
cc.bind(label);
|
||||
cc.mov(tmp0, konstd[B]);
|
||||
cc.mov(tmp1, 0);
|
||||
cc.div(tmp1, tmp0, regD[C]);
|
||||
|
@ -304,14 +298,11 @@ void JitCompiler::EmitMOD_RR()
|
|||
{
|
||||
auto tmp0 = newTempInt32();
|
||||
auto tmp1 = newTempInt32();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.test(regD[C], regD[C]);
|
||||
cc.jne(label);
|
||||
cc.je(label);
|
||||
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
|
||||
cc.bind(label);
|
||||
cc.mov(tmp0, regD[B]);
|
||||
cc.cdq(tmp1, tmp0);
|
||||
cc.idiv(tmp1, tmp0, regD[C]);
|
||||
|
@ -331,21 +322,21 @@ void JitCompiler::EmitMOD_RK()
|
|||
cc.idiv(tmp1, tmp0, asmjit::x86::ptr(konstTmp));
|
||||
cc.mov(regD[A], tmp1);
|
||||
}
|
||||
else EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
else
|
||||
{
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
void JitCompiler::EmitMOD_KR()
|
||||
{
|
||||
auto tmp0 = newTempInt32();
|
||||
auto tmp1 = newTempInt32();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.test(regD[C], regD[C]);
|
||||
cc.jne(label);
|
||||
cc.je(label);
|
||||
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
|
||||
cc.bind(label);
|
||||
cc.mov(tmp0, konstd[B]);
|
||||
cc.cdq(tmp1, tmp0);
|
||||
cc.idiv(tmp1, tmp0, regD[C]);
|
||||
|
@ -356,14 +347,11 @@ void JitCompiler::EmitMODU_RR()
|
|||
{
|
||||
auto tmp0 = newTempInt32();
|
||||
auto tmp1 = newTempInt32();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.test(regD[C], regD[C]);
|
||||
cc.jne(label);
|
||||
cc.je(label);
|
||||
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
|
||||
cc.bind(label);
|
||||
cc.mov(tmp0, regD[B]);
|
||||
cc.mov(tmp1, 0);
|
||||
cc.div(tmp1, tmp0, regD[C]);
|
||||
|
@ -383,21 +371,21 @@ void JitCompiler::EmitMODU_RK()
|
|||
cc.div(tmp1, tmp0, asmjit::x86::ptr(konstTmp));
|
||||
cc.mov(regD[A], tmp1);
|
||||
}
|
||||
else EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
else
|
||||
{
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
void JitCompiler::EmitMODU_KR()
|
||||
{
|
||||
auto tmp0 = newTempInt32();
|
||||
auto tmp1 = newTempInt32();
|
||||
auto label = cc.newLabel();
|
||||
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.test(regD[C], regD[C]);
|
||||
cc.jne(label);
|
||||
cc.je(label);
|
||||
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
|
||||
cc.bind(label);
|
||||
cc.mov(tmp0, konstd[B]);
|
||||
cc.mov(tmp1, 0);
|
||||
cc.div(tmp1, tmp0, regD[C]);
|
||||
|
@ -717,11 +705,10 @@ void JitCompiler::EmitMULF_RK()
|
|||
|
||||
void JitCompiler::EmitDIVF_RR()
|
||||
{
|
||||
auto label = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.ptest(regF[C], regF[C]);
|
||||
cc.jne(label);
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
cc.bind(label);
|
||||
cc.je(label);
|
||||
|
||||
auto rc = CheckRegF(C, A);
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
cc.divsd(regF[A], rc);
|
||||
|
@ -753,11 +740,9 @@ void JitCompiler::EmitDIVF_KR()
|
|||
|
||||
void JitCompiler::EmitMODF_RR()
|
||||
{
|
||||
auto label = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.ptest(regF[C], regF[C]);
|
||||
cc.jne(label);
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
cc.bind(label);
|
||||
cc.je(label);
|
||||
|
||||
auto result = newResultXmmSd();
|
||||
auto call = CreateCall<double, double, double>([](double a, double b) -> double
|
||||
|
@ -772,11 +757,9 @@ void JitCompiler::EmitMODF_RR()
|
|||
|
||||
void JitCompiler::EmitMODF_RK()
|
||||
{
|
||||
auto label = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.ptest(regF[C], regF[C]);
|
||||
cc.jne(label);
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
cc.bind(label);
|
||||
cc.je(label);
|
||||
|
||||
auto tmp = newTempXmmSd();
|
||||
cc.movsd(tmp, asmjit::x86::ptr(ToMemAddress(&konstf[C])));
|
||||
|
@ -795,11 +778,9 @@ void JitCompiler::EmitMODF_KR()
|
|||
{
|
||||
using namespace asmjit;
|
||||
|
||||
auto label = cc.newLabel();
|
||||
auto label = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
cc.ptest(regF[C], regF[C]);
|
||||
cc.jne(label);
|
||||
EmitThrowException(X_DIVISION_BY_ZERO);
|
||||
cc.bind(label);
|
||||
cc.je(label);
|
||||
|
||||
auto tmp = newTempXmmSd();
|
||||
cc.movsd(tmp, x86::ptr(ToMemAddress(&konstf[B])));
|
||||
|
|
|
@ -146,6 +146,7 @@ private:
|
|||
|
||||
void EmitNullPointerThrow(int index, EVMAbortException reason);
|
||||
void EmitThrowException(EVMAbortException reason);
|
||||
asmjit::Label EmitThrowExceptionLabel(EVMAbortException reason);
|
||||
|
||||
static void ThrowArrayOutOfBounds(VMScriptFunction *func, VMOP *line, int index, int size);
|
||||
static void ThrowException(VMScriptFunction *func, VMOP *line, int reason);
|
||||
|
|
Loading…
Reference in a new issue