Skip to content

Commit

Permalink
Implement rest of jit_flow
Browse files Browse the repository at this point in the history
  • Loading branch information
dpjudas committed May 10, 2020
1 parent 48618b1 commit 51cccf9
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 96 deletions.
38 changes: 35 additions & 3 deletions src/common/scripting/jit/jit.cpp
Expand Up @@ -18,9 +18,41 @@ void JitDumpLog(FILE* file, VMScriptFunction* sfunc)
{
}

void JitCompiler::EmitNullPointerThrow(int index, EVMAbortException reason) { }
void JitCompiler::EmitThrowException(EVMAbortException reason) { }
IRBasicBlock* JitCompiler::EmitThrowExceptionLabel(EVMAbortException reason) { return irfunc->createBasicBlock(""); }
void JitCompiler::EmitNullPointerThrow(int index, EVMAbortException reason)
{
}

void JitCompiler::EmitThrowException(EVMAbortException reason)
{
}

void JitCompiler::ThrowException(int reason)
{
ThrowAbortException((EVMAbortException)reason, nullptr);
}

IRBasicBlock* JitCompiler::EmitThrowExceptionLabel(EVMAbortException reason)
{
return irfunc->createBasicBlock("");
}

void JitCompiler::CheckVMFrame()
{
}

void JitCompiler::EmitPopFrame()
{
}

IRValue* JitCompiler::GetCallReturns()
{
return nullptr;
}

IRBasicBlock* JitCompiler::GetLabel(size_t pos)
{
return nullptr;
}

#else
Expand Down
126 changes: 42 additions & 84 deletions src/common/scripting/jit/jit_flow.cpp
Expand Up @@ -64,186 +64,144 @@ void JitCompiler::EmitSCOPE()
cc.CreateCall(GetNativeFunc<void, DObject*, VMFunction*, int>("__ValidateCall", ValidateCall), { LoadA(A), ConstA(C), ConstValueD(B) });
}

#if 0

static void SetString(VMReturn* ret, FString* str)
{
ret->SetString(*str);
}

void JitCompiler::EmitRET()
{
using namespace asmjit;
if (B == REGT_NIL)
{
EmitPopFrame();
X86Gp vReg = newTempInt32();
cc.mov(vReg, 0);
cc.ret(vReg);
cc.CreateRet(ConstValueD(0));
}
else
{
int a = A;
int retnum = a & ~RET_FINAL;

X86Gp reg_retnum = newTempInt32();
X86Gp location = newTempIntPtr();
Label L_endif = cc.newLabel();
IRBasicBlock* ifbb = irfunc->createBasicBlock({});
IRBasicBlock* endifbb = irfunc->createBasicBlock({});

cc.mov(reg_retnum, retnum);
cc.cmp(reg_retnum, numret);
cc.jge(L_endif);
cc.CreateCondBr(cc.CreateICmpSLE(ConstValueD(retnum), numret), ifbb, endifbb);
cc.SetInsertPoint(ifbb);

cc.mov(location, x86::ptr(ret, retnum * sizeof(VMReturn)));
IRValue* location = Load(ToPtrPtr(ret, retnum * sizeof(VMReturn)));

int regtype = B;
int regnum = C;
switch (regtype & REGT_TYPE)
{
case REGT_INT:
if (regtype & REGT_KONST)
cc.mov(x86::dword_ptr(location), konstd[regnum]);
Store32(ConstD(regnum), ToInt32Ptr(location));
else
cc.mov(x86::dword_ptr(location), regD[regnum]);
Store32(LoadD(regnum), ToInt32Ptr(location));
break;
case REGT_FLOAT:
if (regtype & REGT_KONST)
{
auto tmp = newTempInt64();
if (regtype & REGT_MULTIREG3)
{
cc.mov(tmp, (((int64_t *)konstf)[regnum]));
cc.mov(x86::qword_ptr(location), tmp);

cc.mov(tmp, (((int64_t *)konstf)[regnum + 1]));
cc.mov(x86::qword_ptr(location, 8), tmp);

cc.mov(tmp, (((int64_t *)konstf)[regnum + 2]));
cc.mov(x86::qword_ptr(location, 16), tmp);
StoreDouble(ConstF(regnum), ToDoublePtr(location));
StoreDouble(ConstF(regnum + 1), ToDoublePtr(location, 8));
StoreDouble(ConstF(regnum + 2), ToDoublePtr(location, 16));
}
else if (regtype & REGT_MULTIREG2)
{
cc.mov(tmp, (((int64_t *)konstf)[regnum]));
cc.mov(x86::qword_ptr(location), tmp);

cc.mov(tmp, (((int64_t *)konstf)[regnum + 1]));
cc.mov(x86::qword_ptr(location, 8), tmp);
StoreDouble(ConstF(regnum), ToDoublePtr(location));
StoreDouble(ConstF(regnum + 1), ToDoublePtr(location, 8));
}
else
{
cc.mov(tmp, (((int64_t *)konstf)[regnum]));
cc.mov(x86::qword_ptr(location), tmp);
StoreDouble(ConstF(regnum), ToDoublePtr(location));
}
}
else
{
if (regtype & REGT_MULTIREG3)
{
cc.movsd(x86::qword_ptr(location), regF[regnum]);
cc.movsd(x86::qword_ptr(location, 8), regF[regnum + 1]);
cc.movsd(x86::qword_ptr(location, 16), regF[regnum + 2]);
StoreDouble(LoadF(regnum), ToDoublePtr(location));
StoreDouble(LoadF(regnum + 1), ToDoublePtr(location, 8));
StoreDouble(LoadF(regnum + 2), ToDoublePtr(location, 16));
}
else if (regtype & REGT_MULTIREG2)
{
cc.movsd(x86::qword_ptr(location), regF[regnum]);
cc.movsd(x86::qword_ptr(location, 8), regF[regnum + 1]);
StoreDouble(LoadF(regnum), ToDoublePtr(location));
StoreDouble(LoadF(regnum + 1), ToDoublePtr(location, 8));
}
else
{
cc.movsd(x86::qword_ptr(location), regF[regnum]);
StoreDouble(LoadF(regnum), ToDoublePtr(location));
}
}
break;
case REGT_STRING:
{
auto ptr = newTempIntPtr();
cc.mov(ptr, ret);
cc.add(ptr, (int)(retnum * sizeof(VMReturn)));
auto call = CreateCall<void, VMReturn*, FString*>(SetString);
call->setArg(0, ptr);
if (regtype & REGT_KONST) call->setArg(1, asmjit::imm_ptr(&konsts[regnum]));
else call->setArg(1, regS[regnum]);
cc.CreateCall(GetNativeFunc<void, VMReturn*, FString*>("__SetString", SetString), { location, (regtype & REGT_KONST) ? ConstS(regnum) : LoadS(regnum) });
break;
}
case REGT_POINTER:
if (cc.is64Bit())
if (regtype & REGT_KONST)
{
if (regtype & REGT_KONST)
{
auto ptr = newTempIntPtr();
cc.mov(ptr, asmjit::imm_ptr(konsta[regnum].v));
cc.mov(x86::qword_ptr(location), ptr);
}
else
{
cc.mov(x86::qword_ptr(location), regA[regnum]);
}
StorePtr(ConstA(regnum), ToPtrPtr(location));
}
else
{
if (regtype & REGT_KONST)
{
auto ptr = newTempIntPtr();
cc.mov(ptr, asmjit::imm_ptr(konsta[regnum].v));
cc.mov(x86::dword_ptr(location), ptr);
}
else
{
cc.mov(x86::dword_ptr(location), regA[regnum]);
}
StorePtr(LoadA(regnum), ToPtrPtr(location));
}
break;
}

if (a & RET_FINAL)
{
cc.add(reg_retnum, 1);
EmitPopFrame();
cc.ret(reg_retnum);
cc.CreateRet(ConstValueD(retnum + 1));
}

cc.bind(L_endif);
cc.SetInsertPoint(endifbb);

if (a & RET_FINAL)
{
EmitPopFrame();
cc.ret(numret);
cc.CreateRet(numret);
}
}
}

void JitCompiler::EmitRETI()
{
using namespace asmjit;

int a = A;
int retnum = a & ~RET_FINAL;

X86Gp reg_retnum = newTempInt32();
X86Gp location = newTempIntPtr();
Label L_endif = cc.newLabel();
IRBasicBlock* ifbb = irfunc->createBasicBlock({});
IRBasicBlock* endifbb = irfunc->createBasicBlock({});

cc.mov(reg_retnum, retnum);
cc.cmp(reg_retnum, numret);
cc.jge(L_endif);
cc.CreateCondBr(cc.CreateICmpSLE(ConstValueD(retnum), numret), ifbb, endifbb);
cc.SetInsertPoint(ifbb);

cc.mov(location, x86::ptr(ret, retnum * sizeof(VMReturn)));
cc.mov(x86::dword_ptr(location), BCs);
IRValue* location = Load(ToPtrPtr(ret, retnum * sizeof(VMReturn)));
Store32(ConstValueD(BCs), ToInt32Ptr(location));

if (a & RET_FINAL)
{
cc.add(reg_retnum, 1);
EmitPopFrame();
cc.ret(reg_retnum);
cc.CreateRet(ConstValueD(retnum + 1));
}
else
{
cc.CreateBr(endifbb);
}

cc.SetInsertPoint(endifbb);

cc.bind(L_endif);
if (a & RET_FINAL)
{
EmitPopFrame();
cc.ret(numret);
cc.CreateRet(numret);
}
}
#endif

void JitCompiler::EmitTHROW()
{
Expand Down
24 changes: 15 additions & 9 deletions src/common/scripting/jit/jitintern.h
Expand Up @@ -33,7 +33,7 @@ class JitCompiler
#include "vmops.h"
#undef xx

IRBasicBlock* GetLabel(size_t pos) { return nullptr; }
IRBasicBlock* GetLabel(size_t pos);

void EmitNativeCall(VMNativeFunction* target);
void EmitVMCall(IRValue* ptr, VMFunction* target);
Expand All @@ -53,8 +53,9 @@ class JitCompiler
static void ThrowArrayOutOfBounds(int index, int size);
static void ThrowException(int reason);

void CheckVMFrame() { }
IRValue* GetCallReturns() { return nullptr; }
void CheckVMFrame();
void EmitPopFrame();
IRValue* GetCallReturns();

IRFunctionType* GetFuncSignature();

Expand Down Expand Up @@ -133,14 +134,12 @@ class JitCompiler
template <typename Func>
void EmitComparisonOpcode(Func jmpFunc)
{
/*
int i = (int)(ptrdiff_t)(pc - sfunc->Code);
auto successLabel = cc.newLabel();
auto failLabel = GetLabel(i + 2 + JMPOFS(pc + 1));
jmpFunc(static_cast<bool>(A & CMP_CHECK), failLabel, successLabel);
cc.bind(successLabel);
IRBasicBlock* successbb = irfunc->createBasicBlock({});
IRBasicBlock* failbb = GetLabel(i + 2 + JMPOFS(pc + 1));
jmpFunc(static_cast<bool>(A & CMP_CHECK), failbb, successbb);
cc.SetInsertPoint(successbb);
pc++; // This instruction uses two instruction slots - skip the next one
*/
}

void EmitVectorComparison(int N, bool check, IRBasicBlock* fail, IRBasicBlock* success);
Expand Down Expand Up @@ -172,8 +171,10 @@ class JitCompiler
IRValue* ToFloatPtr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getFloatPtrTy()); }
IRValue* ToDoublePtr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getDoublePtrTy()); }
IRValue* ToDoublePtr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getDoublePtrTy()); }
IRValue* ToDoublePtr(IRValue* ptr) { return cc.CreateBitCast(ptr, ircontext->getDoublePtrTy()); }
IRValue* ToPtrPtr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt8PtrTy()->getPointerTo(ircontext)); }
IRValue* ToPtrPtr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt8PtrTy()->getPointerTo(ircontext)); }
IRValue* ToPtrPtr(IRValue* ptr) { return cc.CreateBitCast(ptr, ircontext->getInt8PtrTy()->getPointerTo(ircontext)); }
void Store8(IRValue* value, IRValue* ptr) { cc.CreateStore(cc.CreateTrunc(value, ircontext->getInt8Ty()), ptr); }
void Store16(IRValue* value, IRValue* ptr) { cc.CreateStore(cc.CreateTrunc(value, ircontext->getInt16Ty()), ptr); }
void Store32(IRValue* value, IRValue* ptr) { cc.CreateStore(value, ptr); }
Expand All @@ -193,6 +194,11 @@ class JitCompiler
IRFunction* irfunc;
IRBuilder cc;

IRValue* args;
IRValue* numargs;
IRValue* ret;
IRValue* numret;

const int* konstd;
const double* konstf;
const FString* konsts;
Expand Down

0 comments on commit 51cccf9

Please sign in to comment.