- removed CanJit as all opcodes are now implemented

- fix some store bugs
This commit is contained in:
Magnus Norddahl 2018-10-07 22:21:48 +02:00
parent 47bcf318a5
commit d643fbd077
4 changed files with 42 additions and 40 deletions

View file

@ -49,9 +49,6 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
#if defined(DEBUG_JIT)
if (strcmp(sfunc->PrintableName.GetChars(), "StatusScreen.drawNum") != 0)
return nullptr;
#else
if (!JitCompiler::CanJit(sfunc))
return nullptr;
#endif
//Printf("Jitting function: %s\n", sfunc->PrintableName.GetChars());
@ -141,28 +138,6 @@ void JitCompiler::EmitOpcode()
}
}
bool JitCompiler::CanJit(VMScriptFunction *sfunc)
{
int size = sfunc->CodeSize;
for (int i = 0; i < size; i++)
{
// Partially implemented functions:
auto pc = sfunc->Code + i;
if (sfunc->Code[i].op == OP_PARAM)
{
if (!!(B & REGT_MULTIREG3) || !!(B & REGT_MULTIREG2))
return false;
}
else if (sfunc->Code[i].op == OP_RESULT)
{
if (!!(B & REGT_MULTIREG3) || !!(B & REGT_MULTIREG2))
return false;
}
}
return true;
}
void JitCompiler::Setup()
{
using namespace asmjit;

View file

@ -260,6 +260,18 @@ void JitCompiler::StoreInOuts(int b)
cc.mov(stackPtr, frameF);
cc.add(stackPtr, (int)(C * sizeof(double)));
cc.movsd(x86::qword_ptr(stackPtr), regF[C]);
// When passing the address to a float we don't know if the receiving function will treat it as float, vec2 or vec3.
if ((unsigned int)C + 1 < regF.Size())
{
cc.add(stackPtr, (int)sizeof(double));
cc.movsd(x86::qword_ptr(stackPtr), regF[C + 1]);
}
if ((unsigned int)C + 2 < regF.Size())
{
cc.add(stackPtr, (int)sizeof(double));
cc.movsd(x86::qword_ptr(stackPtr), regF[C + 2]);
}
break;
default:
break;
@ -274,7 +286,7 @@ void JitCompiler::LoadInOuts(int b)
const VMOP &param = *ParamOpcodes[i];
if (param.op == OP_PARAM && (param.b & REGT_ADDROF))
{
LoadCallResult(param);
LoadCallResult(param, true);
}
}
}
@ -286,11 +298,11 @@ void JitCompiler::LoadReturns(const VMOP *retval, int numret)
if (retval[i].op != OP_RESULT)
I_FatalError("Expected OP_RESULT to follow OP_CALL\n");
LoadCallResult(retval[i]);
LoadCallResult(retval[i], false);
}
}
void JitCompiler::LoadCallResult(const VMOP &opdata)
void JitCompiler::LoadCallResult(const VMOP &opdata, bool addrof)
{
int type = opdata.b;
int regnum = opdata.c;
@ -302,6 +314,23 @@ void JitCompiler::LoadCallResult(const VMOP &opdata)
break;
case REGT_FLOAT:
cc.movsd(regF[regnum], asmjit::x86::qword_ptr(frameF, regnum * sizeof(double)));
if (addrof)
{
// When passing the address to a float we don't know if the receiving function will treat it as float, vec2 or vec3.
if ((unsigned int)regnum + 1 < regF.Size())
cc.movsd(regF[regnum + 1], asmjit::x86::qword_ptr(frameF, (regnum + 1) * sizeof(double)));
if ((unsigned int)regnum + 2 < regF.Size())
cc.movsd(regF[regnum + 2], asmjit::x86::qword_ptr(frameF, (regnum + 2) * sizeof(double)));
}
else if (type & REGT_MULTIREG2)
{
cc.movsd(regF[regnum + 1], asmjit::x86::qword_ptr(frameF, (regnum + 1) * sizeof(double)));
}
else if (type & REGT_MULTIREG3)
{
cc.movsd(regF[regnum + 1], asmjit::x86::qword_ptr(frameF, (regnum + 1) * sizeof(double)));
cc.movsd(regF[regnum + 2], asmjit::x86::qword_ptr(frameF, (regnum + 2) * sizeof(double)));
}
break;
case REGT_STRING:
// We don't have to do anything in this case. String values are never moved to virtual registers.

View file

@ -111,9 +111,9 @@ void JitCompiler::EmitSP_R()
void JitCompiler::EmitSV2()
{
EmitNullPointerThrow(B, X_WRITE_NIL);
EmitNullPointerThrow(A, X_WRITE_NIL);
auto tmp = newTempIntPtr();
cc.mov(tmp, regA[B]);
cc.mov(tmp, regA[A]);
cc.add(tmp, konstd[C]);
cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]);
cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]);
@ -121,9 +121,9 @@ void JitCompiler::EmitSV2()
void JitCompiler::EmitSV2_R()
{
EmitNullPointerThrow(B, X_WRITE_NIL);
EmitNullPointerThrow(A, X_WRITE_NIL);
auto tmp = newTempIntPtr();
cc.mov(tmp, regA[B]);
cc.mov(tmp, regA[A]);
cc.add(tmp, regD[C]);
cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]);
cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]);
@ -131,9 +131,9 @@ void JitCompiler::EmitSV2_R()
void JitCompiler::EmitSV3()
{
EmitNullPointerThrow(B, X_WRITE_NIL);
EmitNullPointerThrow(A, X_WRITE_NIL);
auto tmp = newTempIntPtr();
cc.mov(tmp, regA[B]);
cc.mov(tmp, regA[A]);
cc.add(tmp, konstd[C]);
cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]);
cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]);
@ -142,9 +142,9 @@ void JitCompiler::EmitSV3()
void JitCompiler::EmitSV3_R()
{
EmitNullPointerThrow(B, X_WRITE_NIL);
EmitNullPointerThrow(A, X_WRITE_NIL);
auto tmp = newTempIntPtr();
cc.mov(tmp, regA[B]);
cc.mov(tmp, regA[A]);
cc.add(tmp, regD[C]);
cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]);
cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]);
@ -153,7 +153,7 @@ void JitCompiler::EmitSV3_R()
void JitCompiler::EmitSBIT()
{
EmitNullPointerThrow(B, X_WRITE_NIL);
EmitNullPointerThrow(A, X_WRITE_NIL);
auto tmp1 = newTempInt32();
auto tmp2 = newTempInt32();
cc.mov(tmp1, asmjit::x86::byte_ptr(regA[A]));

View file

@ -31,8 +31,6 @@ public:
void Codegen();
static bool CanJit(VMScriptFunction *sfunc);
private:
// Declare EmitXX functions for the opcodes:
#define xx(op, name, mode, alt, kreg, ktype) void Emit##op();
@ -48,7 +46,7 @@ private:
void LoadInOuts(int b);
void LoadReturns(const VMOP *retval, int numret);
void FillReturns(const VMOP *retval, int numret);
void LoadCallResult(const VMOP &opdata);
void LoadCallResult(const VMOP &opdata, bool addrof);
static int DoCall(VMFrameStack *stack, VMFunction *call, int b, int c, VMValue *param, VMReturn *returns, JitExceptionInfo *exceptinfo);
template <typename Func>