From 51cccf9afd2b84f22d0798422275f693281535e5 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 10 May 2020 21:40:53 +0200 Subject: [PATCH] Implement rest of jit_flow --- src/common/scripting/jit/jit.cpp | 38 +++++++- src/common/scripting/jit/jit_flow.cpp | 126 +++++++++----------------- src/common/scripting/jit/jitintern.h | 24 +++-- 3 files changed, 92 insertions(+), 96 deletions(-) diff --git a/src/common/scripting/jit/jit.cpp b/src/common/scripting/jit/jit.cpp index 0f261195258..d78722d85af 100644 --- a/src/common/scripting/jit/jit.cpp +++ b/src/common/scripting/jit/jit.cpp @@ -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 diff --git a/src/common/scripting/jit/jit_flow.cpp b/src/common/scripting/jit/jit_flow.cpp index bab125f1c72..6c9f68326b9 100644 --- a/src/common/scripting/jit/jit_flow.cpp +++ b/src/common/scripting/jit/jit_flow.cpp @@ -64,8 +64,6 @@ void JitCompiler::EmitSCOPE() cc.CreateCall(GetNativeFunc("__ValidateCall", ValidateCall), { LoadA(A), ConstA(C), ConstValueD(B) }); } -#if 0 - static void SetString(VMReturn* ret, FString* str) { ret->SetString(*str); @@ -73,28 +71,23 @@ static void SetString(VMReturn* ret, FString* 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; @@ -102,148 +95,113 @@ void JitCompiler::EmitRET() { 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(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("__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() { diff --git a/src/common/scripting/jit/jitintern.h b/src/common/scripting/jit/jitintern.h index 9d0f0b1ef0b..038d07cf517 100644 --- a/src/common/scripting/jit/jitintern.h +++ b/src/common/scripting/jit/jitintern.h @@ -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); @@ -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(); @@ -133,14 +134,12 @@ class JitCompiler template 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(A & CMP_CHECK), failLabel, successLabel); - cc.bind(successLabel); + IRBasicBlock* successbb = irfunc->createBasicBlock({}); + IRBasicBlock* failbb = GetLabel(i + 2 + JMPOFS(pc + 1)); + jmpFunc(static_cast(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); @@ -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); } @@ -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;