From 61735ddd8b23f8ac2605e2dae78b019bd68ddfeb Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 17 Sep 2018 12:00:25 +0200 Subject: [PATCH] - create CreateCall helper to get rid of a lot of the cc.call boilerplate --- src/scripting/vm/jit_call.cpp | 10 ++-- src/scripting/vm/jit_flow.cpp | 27 +++++------ src/scripting/vm/jit_load.cpp | 52 ++++---------------- src/scripting/vm/jit_math.cpp | 64 ++++++++----------------- src/scripting/vm/jit_move.cpp | 88 ++++++++++------------------------ src/scripting/vm/jit_store.cpp | 10 ++-- src/scripting/vm/jitintern.h | 21 ++++++++ 7 files changed, 97 insertions(+), 175 deletions(-) diff --git a/src/scripting/vm/jit_call.cpp b/src/scripting/vm/jit_call.cpp index 154e41c288..98cdf7d069 100644 --- a/src/scripting/vm/jit_call.cpp +++ b/src/scripting/vm/jit_call.cpp @@ -170,12 +170,12 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp ptr) } auto result = cc.newInt32(); - auto call = cc.call(ToMemAddress(reinterpret_cast(&JitCompiler::DoCall)), FuncSignature7()); + auto call = CreateCall(&JitCompiler::DoCall); call->setRet(0, result); call->setArg(0, stack); call->setArg(1, ptr); - call->setArg(2, asmjit::Imm(B)); - call->setArg(3, asmjit::Imm(C)); + call->setArg(2, Imm(B)); + call->setArg(3, Imm(C)); call->setArg(4, paramsptr); call->setArg(5, callReturns); call->setArg(6, exceptInfo); @@ -223,11 +223,11 @@ void JitCompiler::EmitDoTail(asmjit::X86Gp ptr) } auto result = cc.newInt32(); - auto call = cc.call(ToMemAddress(reinterpret_cast(&JitCompiler::DoCall)), FuncSignature7()); + auto call = CreateCall(&JitCompiler::DoCall); call->setRet(0, result); call->setArg(0, stack); call->setArg(1, ptr); - call->setArg(2, asmjit::Imm(B)); + call->setArg(2, Imm(B)); call->setArg(3, numret); call->setArg(4, paramsptr); call->setArg(5, ret); diff --git a/src/scripting/vm/jit_flow.cpp b/src/scripting/vm/jit_flow.cpp index 72677f846a..8641c2da89 100644 --- a/src/scripting/vm/jit_flow.cpp +++ b/src/scripting/vm/jit_flow.cpp @@ -36,12 +36,11 @@ void JitCompiler::EmitVTBL() EmitThrowException(X_READ_NIL); cc.bind(notnull); - typedef VMFunction*(*FuncPtr)(DObject*, int); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](DObject *o, int c) -> VMFunction* { + auto call = CreateCall([](DObject *o, int c) -> VMFunction* { auto p = o->GetClass(); assert(c < (int)p->Virtuals.Size()); return p->Virtuals[c]; - }))), asmjit::FuncSignature2()); + }); call->setRet(0, regA[A]); call->setArg(0, regA[B]); call->setArg(1, asmjit::Imm(C)); @@ -60,7 +59,7 @@ void JitCompiler::EmitSCOPE() auto result = cc.newInt32(); typedef int(*FuncPtr)(DObject*, VMFunction*, int); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](DObject *o, VMFunction *f, int b) -> int { + auto call = CreateCall([](DObject *o, VMFunction *f, int b) -> int { try { FScopeBarrier::ValidateCall(o->GetClass(), f, b - 1); @@ -71,7 +70,7 @@ void JitCompiler::EmitSCOPE() // To do: pass along the exception info return 0; } - }))), asmjit::FuncSignature3()); + }); call->setRet(0, result); call->setArg(0, regA[A]); call->setArg(1, f); @@ -168,14 +167,12 @@ void JitCompiler::EmitRET() break; case REGT_STRING: { - auto setRetStringLamdba = [](VMReturn* ret, FString* str) -> void { - ret->SetString(*str); - }; auto ptr = cc.newIntPtr(); cc.mov(ptr, ret); cc.add(ptr, (int)(retnum * sizeof(VMReturn))); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(setRetStringLamdba))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall([](VMReturn* ret, FString* str) -> void { + ret->SetString(*str); + }); call->setArg(0, ptr); if (regtype & REGT_KONST) call->setArg(1, asmjit::imm_ptr(&konsts[regnum])); else call->setArg(1, regS[regnum]); @@ -240,8 +237,7 @@ void JitCompiler::EmitRETI() void JitCompiler::EmitNEW() { auto result = cc.newIntPtr(); - typedef DObject*(*FuncPtr)(PClass*, int); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](PClass *cls, int c) -> DObject* { + auto call = CreateCall([](PClass *cls, int c) -> DObject* { try { if (!cls->ConstructNative) @@ -266,7 +262,7 @@ void JitCompiler::EmitNEW() // To do: pass along the exception info return nullptr; } - }))), asmjit::FuncSignature2()); + }); call->setRet(0, result); call->setArg(0, regA[B]); call->setArg(1, asmjit::Imm(C)); @@ -299,8 +295,7 @@ void JitCompiler::EmitNEW_K() auto result = cc.newIntPtr(); auto regcls = cc.newIntPtr(); cc.mov(regcls, ToMemAddress(konsta[B].v)); - typedef DObject*(*FuncPtr)(PClass*, int); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](PClass *cls, int c) -> DObject* { + auto call = CreateCall([](PClass *cls, int c) -> DObject* { try { if (c) FScopeBarrier::ValidateNew(cls, c - 1); @@ -311,7 +306,7 @@ void JitCompiler::EmitNEW_K() // To do: pass along the exception info return nullptr; } - }))), asmjit::FuncSignature2()); + }); call->setRet(0, result); call->setArg(0, regcls); call->setArg(1, asmjit::Imm(C)); diff --git a/src/scripting/vm/jit_load.cpp b/src/scripting/vm/jit_load.cpp index 3bf07393f5..50ab180dd3 100644 --- a/src/scripting/vm/jit_load.cpp +++ b/src/scripting/vm/jit_load.cpp @@ -23,8 +23,7 @@ void JitCompiler::EmitLKF() void JitCompiler::EmitLKS() { - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall(&JitCompiler::CallAssignString); call->setArg(0, regS[A]); call->setArg(1, asmjit::imm(ToMemAddress(konsts + BC))); } @@ -60,8 +59,7 @@ void JitCompiler::EmitLKS_R() static_assert(sizeof(FString) == 4, "sizeof(FString) needs to be 4"); cc.lea(ptr, asmjit::x86::ptr(base, regD[B], 2)); #endif - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall(&JitCompiler::CallAssignString); call->setArg(0, regS[A]); call->setArg(1, ptr); } @@ -86,36 +84,26 @@ void JitCompiler::EmitLFP() void JitCompiler::EmitMETA() { - typedef void*(*FuncPtr)(void*); - auto label = cc.newLabel(); cc.test(regA[B], regA[B]); cc.jne(label); EmitThrowException(X_READ_NIL); cc.bind(label); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](void *o) -> void* - { - return static_cast(o)->GetClass()->Meta; - }))), asmjit::FuncSignature1()); + auto call = CreateCall([](DObject *o) { return o->GetClass()->Meta; }); call->setRet(0, regA[A]); call->setArg(0, regA[B]); } void JitCompiler::EmitCLSS() { - typedef void*(*FuncPtr)(void*); - auto label = cc.newLabel(); cc.test(regA[B], regA[B]); cc.jne(label); EmitThrowException(X_READ_NIL); cc.bind(label); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](void *o) -> void* - { - return static_cast(o)->GetClass(); - }))), asmjit::FuncSignature1()); + auto call = CreateCall([](DObject *o) { return o->GetClass(); }); call->setRet(0, regA[A]); call->setArg(0, regA[B]); } @@ -212,8 +200,7 @@ void JitCompiler::EmitLS() EmitNullPointerThrow(B, X_READ_NIL); auto ptr = cc.newIntPtr(); cc.lea(ptr, asmjit::x86::ptr(regA[B], konstd[C])); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall(&JitCompiler::CallAssignString); call->setArg(0, regS[A]); call->setArg(1, ptr); } @@ -223,8 +210,7 @@ void JitCompiler::EmitLS_R() EmitNullPointerThrow(B, X_READ_NIL); auto ptr = cc.newIntPtr(); cc.lea(ptr, asmjit::x86::ptr(regA[B], regD[C])); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall(&JitCompiler::CallAssignString); call->setArg(0, regS[A]); call->setArg(1, ptr); } @@ -236,12 +222,7 @@ void JitCompiler::EmitLO() auto ptr = cc.newIntPtr(); cc.mov(ptr, asmjit::x86::ptr(regA[B], konstd[C])); - typedef void*(*FuncPtr)(void*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](void *ptr) -> void* - { - DObject *p = static_cast(ptr); - return GC::ReadBarrier(p); - }))), asmjit::FuncSignature1()); + auto call = CreateCall([](DObject *p) { return GC::ReadBarrier(p); }); call->setRet(0, regA[A]); call->setArg(0, ptr); } @@ -253,12 +234,7 @@ void JitCompiler::EmitLO_R() auto ptr = cc.newIntPtr(); cc.mov(ptr, asmjit::x86::ptr(regA[B], regD[C])); - typedef void*(*FuncPtr)(void*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](void *ptr) -> void* - { - DObject *p = static_cast(ptr); - return GC::ReadBarrier(p); - }))), asmjit::FuncSignature1()); + auto call = CreateCall([](DObject *p) { return GC::ReadBarrier(p); }); call->setRet(0, regA[A]); call->setArg(0, ptr); } @@ -322,11 +298,7 @@ void JitCompiler::EmitLCS() EmitNullPointerThrow(B, X_READ_NIL); auto ptr = cc.newIntPtr(); cc.lea(ptr, asmjit::x86::ptr(regA[B], konstd[C])); - auto loadLambda = [](FString* to, char** from) -> void { - *to = *from; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall([](FString* to, char** from) { *to = *from; }); call->setArg(0, regS[A]); call->setArg(1, ptr); } @@ -336,11 +308,7 @@ void JitCompiler::EmitLCS_R() EmitNullPointerThrow(B, X_READ_NIL); auto ptr = cc.newIntPtr(); cc.lea(ptr, asmjit::x86::ptr(regA[B], regD[C])); - auto loadLambda = [](FString* to, char** from) -> void { - *to = *from; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(loadLambda))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall([](FString* to, char** from) { *to = *from; }); call->setArg(0, regS[A]); call->setArg(1, ptr); } diff --git a/src/scripting/vm/jit_math.cpp b/src/scripting/vm/jit_math.cpp index 5ef70eff6f..b3f04ed7a7 100644 --- a/src/scripting/vm/jit_math.cpp +++ b/src/scripting/vm/jit_math.cpp @@ -7,11 +7,9 @@ void JitCompiler::EmitCONCAT() { auto rc = CheckRegS(C, A); - auto concatLambda = [](FString* to, FString* first, FString* second) -> void { + auto call = CreateCall([](FString* to, FString* first, FString* second) { *to = *first + *second; - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(concatLambda))), - asmjit::FuncSignature3(asmjit::CallConv::kIdHostCDecl)); + }); call->setArg(0, regS[A]); call->setArg(1, regS[B]); call->setArg(2, rc); @@ -19,11 +17,9 @@ void JitCompiler::EmitCONCAT() void JitCompiler::EmitLENS() { - auto lenLambda = [](FString* str) -> int { + auto call = CreateCall([](FString* str) -> int { return static_cast(str->Len()); - }; - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(lenLambda))), - asmjit::FuncSignature1(asmjit::CallConv::kIdHostCDecl)); + }); call->setRet(0, regD[A]); call->setArg(0, regS[B]); } @@ -38,12 +34,9 @@ void JitCompiler::EmitCMPS() return first->Compare(*second); }; - auto call = - static_cast(A & CMP_APPROX) ? - cc.call(ToMemAddress(reinterpret_cast(static_cast(compareNoCaseLambda))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)) : - cc.call(ToMemAddress(reinterpret_cast(static_cast(compareLambda))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = static_cast(A & CMP_APPROX) ? + CreateCall(compareNoCaseLambda) : + CreateCall(compareLambda); auto result = cc.newInt32(); call->setRet(0, result); @@ -758,19 +751,16 @@ void JitCompiler::EmitDIVF_KR() void JitCompiler::EmitMODF_RR() { - using namespace asmjit; - typedef double(*FuncPtr)(double, double); - auto label = cc.newLabel(); cc.ptest(regF[C], regF[C]); cc.jne(label); EmitThrowException(X_DIVISION_BY_ZERO); cc.bind(label); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](double a, double b) -> double + auto call = CreateCall([](double a, double b) -> double { return a - floor(a / b) * b; - }))), FuncSignature2()); + }); call->setRet(0, regF[A]); call->setArg(0, regF[B]); call->setArg(1, regF[C]); @@ -778,9 +768,6 @@ void JitCompiler::EmitMODF_RR() void JitCompiler::EmitMODF_RK() { - using namespace asmjit; - typedef double(*FuncPtr)(double, double); - auto label = cc.newLabel(); cc.ptest(regF[C], regF[C]); cc.jne(label); @@ -788,11 +775,11 @@ void JitCompiler::EmitMODF_RK() cc.bind(label); auto tmp = cc.newXmm(); - cc.movsd(tmp, x86::ptr(ToMemAddress(&konstf[C]))); + cc.movsd(tmp, asmjit::x86::ptr(ToMemAddress(&konstf[C]))); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](double a, double b) -> double { + auto call = CreateCall([](double a, double b) -> double { return a - floor(a / b) * b; - }))), FuncSignature2()); + }); call->setRet(0, regF[A]); call->setArg(0, regF[B]); call->setArg(1, tmp); @@ -801,7 +788,6 @@ void JitCompiler::EmitMODF_RK() void JitCompiler::EmitMODF_KR() { using namespace asmjit; - typedef double(*FuncPtr)(double, double); auto label = cc.newLabel(); cc.ptest(regF[C], regF[C]); @@ -812,9 +798,9 @@ void JitCompiler::EmitMODF_KR() auto tmp = cc.newXmm(); cc.movsd(tmp, x86::ptr(ToMemAddress(&konstf[B]))); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](double a, double b) -> double { + auto call = CreateCall([](double a, double b) -> double { return a - floor(a / b) * b; - }))), FuncSignature2()); + }); call->setRet(0, regF[A]); call->setArg(0, tmp); call->setArg(1, regF[C]); @@ -822,9 +808,7 @@ void JitCompiler::EmitMODF_KR() void JitCompiler::EmitPOWF_RR() { - using namespace asmjit; - typedef double(*FuncPtr)(double, double); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(g_pow))), FuncSignature2()); + auto call = CreateCall(g_pow); call->setRet(0, regF[A]); call->setArg(0, regF[B]); call->setArg(1, regF[C]); @@ -837,9 +821,7 @@ void JitCompiler::EmitPOWF_RK() cc.mov(tmp, ToMemAddress(&konstf[C])); cc.movsd(tmp2, asmjit::x86::qword_ptr(tmp)); - using namespace asmjit; - typedef double(*FuncPtr)(double, double); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(g_pow))), FuncSignature2()); + auto call = CreateCall(g_pow); call->setRet(0, regF[A]); call->setArg(0, regF[B]); call->setArg(1, tmp2); @@ -852,9 +834,7 @@ void JitCompiler::EmitPOWF_KR() cc.mov(tmp, ToMemAddress(&konstf[B])); cc.movsd(tmp2, asmjit::x86::qword_ptr(tmp)); - using namespace asmjit; - typedef double(*FuncPtr)(double, double); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(g_pow))), FuncSignature2()); + auto call = CreateCall(g_pow); call->setRet(0, regF[A]); call->setArg(0, tmp2); call->setArg(1, regF[C]); @@ -896,9 +876,7 @@ void JitCompiler::EmitMAXF_RK() void JitCompiler::EmitATAN2() { - using namespace asmjit; - typedef double(*FuncPtr)(double, double); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(g_atan2))), FuncSignature2()); + auto call = CreateCall(g_atan2); call->setRet(0, regF[A]); call->setArg(0, regF[B]); call->setArg(1, regF[C]); @@ -962,7 +940,7 @@ void JitCompiler::EmitFLOP() case FLOP_TANH: func = g_tanh; break; } - auto call = cc.call(ToMemAddress(reinterpret_cast(func)), asmjit::FuncSignature1()); + auto call = CreateCall(func); call->setRet(0, regF[A]); call->setArg(0, v); @@ -1537,9 +1515,7 @@ void JitCompiler::EmitEQA_K() void JitCompiler::CallSqrt(const asmjit::X86Xmm &a, const asmjit::X86Xmm &b) { - using namespace asmjit; - typedef double(*FuncPtr)(double); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(g_sqrt))), FuncSignature1()); + auto call = CreateCall(g_sqrt); call->setRet(0, a); call->setArg(0, b); } diff --git a/src/scripting/vm/jit_move.cpp b/src/scripting/vm/jit_move.cpp index 9a7bfbc795..ece9930f8d 100644 --- a/src/scripting/vm/jit_move.cpp +++ b/src/scripting/vm/jit_move.cpp @@ -15,8 +15,7 @@ void JitCompiler::EmitMOVEF() void JitCompiler::EmitMOVES() { - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall(&JitCompiler::CallAssignString); call->setArg(0, regS[A]); call->setArg(1, regS[B]); } @@ -41,31 +40,6 @@ void JitCompiler::EmitMOVEV3() void JitCompiler::EmitCAST() { - static void (*i2s)(FString *a, int b) = [](FString *a, int b) { a->Format("%d", b); }; - static void (*u2s)(FString *a, int b) = [](FString *a, int b) { a->Format("%u", b); }; - static void (*f2s)(FString *a, double b) = [](FString *a, double b) { a->Format("%.5f", b); }; - static void (*v22s)(FString *a, double b, double b1) = [](FString *a, double b, double b1) { a->Format("(%.5f, %.5f)", b, b1); }; - static void (*v32s)(FString *a, double b, double b1, double b2) = [](FString *a, double b, double b1, double b2) { a->Format("(%.5f, %.5f, %.5f)", b, b1, b2); }; - static void (*p2s)(FString *a, void *b) = [](FString *a, void *b) { if (b == nullptr) *a = "null"; else a->Format("%p", b); }; - static int (*s2i)(FString *b) = [](FString *b) -> int { return (VM_SWORD)b->ToLong(); }; - static double (*s2f)(FString *b) = [](FString *b) -> double { return b->ToDouble(); }; - static int (*s2n)(FString *b) = [](FString *b) -> int { return b->Len() == 0 ? FName(NAME_None) : FName(*b); }; - static void (*n2s)(FString *a, int b) = [](FString *a, int b) { FName name = FName(ENamedName(b)); *a = name.IsValidName() ? name.GetChars() : ""; }; - static int (*s2co)(FString *b) = [](FString *b) -> int { return V_GetColor(nullptr, *b); }; - static void (*co2s)(FString *a, int b) = [](FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); }; - static int (*s2so)(FString *b) = [](FString *b) -> int { return FSoundID(*b); }; - static void (*so2s)(FString *a, int b) = [](FString *a, int b) { *a = S_sfx[b].name; }; - static void (*sid2s)(FString *a, unsigned int b) = [](FString *a, unsigned int b) { *a = (b >= sprites.Size()) ? "TNT1" : sprites[b].name; }; - static void (*tid2s)(FString *a, int b) = [](FString *a, int b) { auto tex = TexMan[*(FTextureID*)&b]; *a = (tex == nullptr) ? "(null)" : tex->Name.GetChars(); }; - - typedef asmjit::FuncSignature2 FuncI2S, FuncU2S, FuncN2S, FuncCo2S, FuncSo2S, FuncSid2S, FuncTid2S; - typedef asmjit::FuncSignature2 FuncF2S; - typedef asmjit::FuncSignature3 FuncV22S; - typedef asmjit::FuncSignature4 FuncV32S; - typedef asmjit::FuncSignature2 FuncP2S; - typedef asmjit::FuncSignature1 FuncS2I, FuncS2N, FuncS2Co, FuncS2So; - typedef asmjit::FuncSignature1 FuncS2F; - asmjit::X86Gp tmp; asmjit::CCFuncCall *call = nullptr; @@ -89,85 +63,85 @@ void JitCompiler::EmitCAST() cc.mov(regD[A], tmp.r32()); break; case CAST_I2S: - call = cc.call(ToMemAddress(reinterpret_cast(i2s)), FuncI2S()); + call = CreateCall([](FString *a, int b) { a->Format("%d", b); }); call->setArg(0, regS[A]); call->setArg(1, regD[B]); break; case CAST_U2S: - call = cc.call(ToMemAddress(reinterpret_cast(u2s)), FuncU2S()); + call = CreateCall([](FString *a, int b) { a->Format("%u", b); }); call->setArg(0, regS[A]); call->setArg(1, regD[B]); break; case CAST_F2S: - call = cc.call(ToMemAddress(reinterpret_cast(f2s)), FuncF2S()); + call = CreateCall([](FString *a, double b) { a->Format("%.5f", b); }); call->setArg(0, regS[A]); call->setArg(1, regF[B]); break; case CAST_V22S: - call = cc.call(ToMemAddress(reinterpret_cast(v22s)), FuncV22S()); + call = CreateCall([](FString *a, double b, double b1) { a->Format("(%.5f, %.5f)", b, b1); }); call->setArg(0, regS[A]); call->setArg(1, regF[B]); call->setArg(2, regF[B + 1]); break; case CAST_V32S: - call = cc.call(ToMemAddress(reinterpret_cast(v32s)), FuncV32S()); + call = CreateCall([](FString *a, double b, double b1, double b2) { a->Format("(%.5f, %.5f, %.5f)", b, b1, b2); }); call->setArg(0, regS[A]); call->setArg(1, regF[B]); call->setArg(2, regF[B + 1]); call->setArg(3, regF[B + 2]); break; case CAST_P2S: - call = cc.call(ToMemAddress(reinterpret_cast(p2s)), FuncP2S()); + call = CreateCall([](FString *a, void *b) { if (b == nullptr) *a = "null"; else a->Format("%p", b); }); call->setArg(0, regS[A]); call->setArg(1, regA[B]); break; case CAST_S2I: - call = cc.call(ToMemAddress(reinterpret_cast(s2i)), FuncS2I()); + call = CreateCall([](FString *b) -> int { return (VM_SWORD)b->ToLong(); }); call->setRet(0, regD[A]); call->setArg(0, regS[B]); break; case CAST_S2F: - call = cc.call(ToMemAddress(reinterpret_cast(s2f)), FuncS2F()); + call = CreateCall([](FString *b) -> double { return b->ToDouble(); }); call->setRet(0, regF[A]); call->setArg(0, regS[B]); break; case CAST_S2N: - call = cc.call(ToMemAddress(reinterpret_cast(s2n)), FuncS2N()); + call = CreateCall([](FString *b) -> int { return b->Len() == 0 ? FName(NAME_None) : FName(*b); }); call->setRet(0, regD[A]); call->setArg(0, regS[B]); break; case CAST_N2S: - call = cc.call(ToMemAddress(reinterpret_cast(n2s)), FuncN2S()); + call = CreateCall([](FString *a, int b) { FName name = FName(ENamedName(b)); *a = name.IsValidName() ? name.GetChars() : ""; }); call->setArg(0, regS[A]); call->setArg(1, regD[B]); break; case CAST_S2Co: - call = cc.call(ToMemAddress(reinterpret_cast(s2co)), FuncS2Co()); + call = CreateCall([](FString *b) -> int { return V_GetColor(nullptr, *b); }); call->setRet(0, regD[A]); call->setArg(0, regS[B]); break; case CAST_Co2S: - call = cc.call(ToMemAddress(reinterpret_cast(co2s)), FuncCo2S()); + call = CreateCall([](FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); }); call->setArg(0, regS[A]); call->setArg(1, regD[B]); break; case CAST_S2So: - call = cc.call(ToMemAddress(reinterpret_cast(s2so)), FuncS2So()); + call = CreateCall([](FString *b) -> int { return FSoundID(*b); }); call->setRet(0, regD[A]); call->setArg(0, regS[B]); break; case CAST_So2S: - call = cc.call(ToMemAddress(reinterpret_cast(so2s)), FuncSo2S()); + call = CreateCall([](FString *a, int b) { *a = S_sfx[b].name; }); call->setArg(0, regS[A]); call->setArg(1, regD[B]); break; case CAST_SID2S: - call = cc.call(ToMemAddress(reinterpret_cast(sid2s)), FuncSid2S()); + call = CreateCall([](FString *a, unsigned int b) { *a = (b >= sprites.Size()) ? "TNT1" : sprites[b].name; }); call->setArg(0, regS[A]); call->setArg(1, regD[B]); break; case CAST_TID2S: - call = cc.call(ToMemAddress(reinterpret_cast(tid2s)), FuncTid2S()); + call = CreateCall([](FString *a, int b) { auto tex = TexMan[*(FTextureID*)&b]; *a = (tex == nullptr) ? "(null)" : tex->Name.GetChars(); }); call->setArg(0, regS[A]); call->setArg(1, regD[B]); break; @@ -200,11 +174,7 @@ void JitCompiler::EmitCASTB() } else { - using namespace asmjit; - typedef int(*FuncPtr)(FString*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](FString *s) -> int { - return s->Len() > 0; - }))), FuncSignature1()); + auto call = CreateCall([](FString *s) -> int { return s->Len() > 0; }); call->setRet(0, regD[A]); call->setArg(0, regS[B]); } @@ -212,11 +182,9 @@ void JitCompiler::EmitCASTB() void JitCompiler::EmitDYNCAST_R() { - using namespace asmjit; - typedef DObject*(*FuncPtr)(DObject*, PClass*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](DObject *obj, PClass *cls) -> DObject* { + auto call = CreateCall([](DObject *obj, PClass *cls) -> DObject* { return (obj && obj->IsKindOf(cls)) ? obj : nullptr; - }))), FuncSignature2()); + }); call->setRet(0, regA[A]); call->setArg(0, regA[B]); call->setArg(1, regA[C]); @@ -224,13 +192,11 @@ void JitCompiler::EmitDYNCAST_R() void JitCompiler::EmitDYNCAST_K() { - using namespace asmjit; auto c = cc.newIntPtr(); cc.mov(c, ToMemAddress(konsta[C].o)); - typedef DObject*(*FuncPtr)(DObject*, PClass*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](DObject *obj, PClass *cls) -> DObject* { + auto call = CreateCall([](DObject *obj, PClass *cls) -> DObject* { return (obj && obj->IsKindOf(cls)) ? obj : nullptr; - }))), FuncSignature2()); + }); call->setRet(0, regA[A]); call->setArg(0, regA[B]); call->setArg(1, c); @@ -238,11 +204,9 @@ void JitCompiler::EmitDYNCAST_K() void JitCompiler::EmitDYNCASTC_R() { - using namespace asmjit; - typedef PClass*(*FuncPtr)(PClass*, PClass*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](PClass *cls1, PClass *cls2) -> PClass* { + auto call = CreateCall([](PClass *cls1, PClass *cls2) -> PClass* { return (cls1 && cls1->IsDescendantOf(cls2)) ? cls1 : nullptr; - }))), FuncSignature2()); + }); call->setRet(0, regA[A]); call->setArg(0, regA[B]); call->setArg(1, regA[C]); @@ -254,9 +218,9 @@ void JitCompiler::EmitDYNCASTC_K() auto c = cc.newIntPtr(); cc.mov(c, ToMemAddress(konsta[C].o)); typedef PClass*(*FuncPtr)(PClass*, PClass*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast([](PClass *cls1, PClass *cls2) -> PClass* { + auto call = CreateCall([](PClass *cls1, PClass *cls2) -> PClass* { return (cls1 && cls1->IsDescendantOf(cls2)) ? cls1 : nullptr; - }))), FuncSignature2()); + }); call->setRet(0, regA[A]); call->setArg(0, regA[B]); call->setArg(1, c); diff --git a/src/scripting/vm/jit_store.cpp b/src/scripting/vm/jit_store.cpp index 2ea845801d..4e37b05972 100644 --- a/src/scripting/vm/jit_store.cpp +++ b/src/scripting/vm/jit_store.cpp @@ -66,8 +66,7 @@ void JitCompiler::EmitSS() EmitNullPointerThrow(A, X_WRITE_NIL); auto ptr = cc.newIntPtr(); cc.lea(ptr, asmjit::x86::ptr(regA[A], konstd[C])); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall(&JitCompiler::CallAssignString); call->setArg(0, ptr); call->setArg(1, regS[B]); } @@ -77,8 +76,7 @@ void JitCompiler::EmitSS_R() EmitNullPointerThrow(A, X_WRITE_NIL); auto ptr = cc.newIntPtr(); cc.lea(ptr, asmjit::x86::ptr(regA[A], regD[C])); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(CallAssignString))), - asmjit::FuncSignature2(asmjit::CallConv::kIdHostCDecl)); + auto call = CreateCall(&JitCompiler::CallAssignString); call->setArg(0, ptr); call->setArg(1, regS[B]); } @@ -88,7 +86,7 @@ void JitCompiler::EmitSO() cc.mov(asmjit::x86::ptr(regA[A], konstd[C]), regA[B]); typedef void(*FuncPtr)(DObject*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(GC::WriteBarrier))), asmjit::FuncSignature1()); + auto call = CreateCall(static_cast(GC::WriteBarrier)); call->setArg(0, regA[B]); } @@ -97,7 +95,7 @@ void JitCompiler::EmitSO_R() cc.mov(asmjit::x86::ptr(regA[A], regD[C]), regA[B]); typedef void(*FuncPtr)(DObject*); - auto call = cc.call(ToMemAddress(reinterpret_cast(static_cast(GC::WriteBarrier))), asmjit::FuncSignature1()); + auto call = CreateCall(static_cast(GC::WriteBarrier)); call->setArg(0, regA[B]); } diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index 83bacdfa02..af1f6bd350 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -79,6 +79,27 @@ private: *to = *from; } + template + asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1)) { return cc.call(ToMemAddress(reinterpret_cast(static_cast(func))), asmjit::FuncSignature1()); } + + template + asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2)) { return cc.call(ToMemAddress(reinterpret_cast(static_cast(func))), asmjit::FuncSignature2()); } + + template + asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3)) { return cc.call(ToMemAddress(reinterpret_cast(static_cast(func))), asmjit::FuncSignature3()); } + + template + asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4)) { return cc.call(ToMemAddress(reinterpret_cast(static_cast(func))), asmjit::FuncSignature4()); } + + template + asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)) { return cc.call(ToMemAddress(reinterpret_cast(static_cast(func))), asmjit::FuncSignature5()); } + + template + asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)) { return cc.call(ToMemAddress(reinterpret_cast(static_cast(func))), asmjit::FuncSignature6()); } + + template + asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)) { return cc.call(ToMemAddress(reinterpret_cast(static_cast(func))), asmjit::FuncSignature7()); } + void EmitNullPointerThrow(int index, EVMAbortException reason); void EmitThrowException(EVMAbortException reason); void EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg1);