- create CreateCall helper to get rid of a lot of the cc.call boilerplate

This commit is contained in:
Magnus Norddahl 2018-09-17 12:00:25 +02:00
parent f61df60240
commit 61735ddd8b
7 changed files with 97 additions and 175 deletions

View file

@ -170,12 +170,12 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
}
auto result = cc.newInt32();
auto call = cc.call(ToMemAddress(reinterpret_cast<const void*>(&JitCompiler::DoCall)), FuncSignature7<int, void*, void*, int, int, void*, void*, void*>());
auto call = CreateCall<int, VMFrameStack*, VMFunction*, int, int, VMValue*, VMReturn*, JitExceptionInfo*>(&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<const void*>(&JitCompiler::DoCall)), FuncSignature7<int, void*, void*, int, int, void*, void*, void*>());
auto call = CreateCall<int, VMFrameStack*, VMFunction*, int, int, VMValue*, VMReturn*, JitExceptionInfo*>(&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);

View file

@ -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<const void*>(static_cast<FuncPtr>([](DObject *o, int c) -> VMFunction* {
auto call = CreateCall<VMFunction*, DObject*, int>([](DObject *o, int c) -> VMFunction* {
auto p = o->GetClass();
assert(c < (int)p->Virtuals.Size());
return p->Virtuals[c];
}))), asmjit::FuncSignature2<void*, void*, int>());
});
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<const void*>(static_cast<FuncPtr>([](DObject *o, VMFunction *f, int b) -> int {
auto call = CreateCall<int, DObject*, VMFunction*, int>([](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<int, void*, void*, int>());
});
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<void*>(static_cast<void(*)(VMReturn*, FString*)>(setRetStringLamdba))),
asmjit::FuncSignature2<void, VMReturn*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, VMReturn*, FString*>([](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<const void*>(static_cast<FuncPtr>([](PClass *cls, int c) -> DObject* {
auto call = CreateCall<DObject*, PClass*, int>([](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<void*, void*, int>());
});
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<const void*>(static_cast<FuncPtr>([](PClass *cls, int c) -> DObject* {
auto call = CreateCall<DObject*, PClass*, int>([](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<void*, void*, int>());
});
call->setRet(0, result);
call->setArg(0, regcls);
call->setArg(1, asmjit::Imm(C));

View file

@ -23,8 +23,7 @@ void JitCompiler::EmitLKF()
void JitCompiler::EmitLKS()
{
auto call = cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<void(*)(FString*, FString*)>(CallAssignString))),
asmjit::FuncSignature2<void, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, FString*>(&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<void*>(static_cast<void(*)(FString*, FString*)>(CallAssignString))),
asmjit::FuncSignature2<void, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, FString*>(&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<const void*>(static_cast<FuncPtr>([](void *o) -> void*
{
return static_cast<DObject*>(o)->GetClass()->Meta;
}))), asmjit::FuncSignature1<void*, void*>());
auto call = CreateCall<uint8_t*, DObject*>([](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<const void*>(static_cast<FuncPtr>([](void *o) -> void*
{
return static_cast<DObject*>(o)->GetClass();
}))), asmjit::FuncSignature1<void*, void*>());
auto call = CreateCall<PClass*, DObject*>([](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<void*>(static_cast<void(*)(FString*, FString*)>(CallAssignString))),
asmjit::FuncSignature2<void, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, FString*>(&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<void*>(static_cast<void(*)(FString*, FString*)>(CallAssignString))),
asmjit::FuncSignature2<void, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, FString*>(&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<const void*>(static_cast<FuncPtr>([](void *ptr) -> void*
{
DObject *p = static_cast<DObject *>(ptr);
return GC::ReadBarrier(p);
}))), asmjit::FuncSignature1<void*, void*>());
auto call = CreateCall<DObject*,DObject*>([](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<const void*>(static_cast<FuncPtr>([](void *ptr) -> void*
{
DObject *p = static_cast<DObject *>(ptr);
return GC::ReadBarrier(p);
}))), asmjit::FuncSignature1<void*, void*>());
auto call = CreateCall<DObject*, DObject*>([](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<void*>(static_cast<void(*)(FString*, char**)>(loadLambda))),
asmjit::FuncSignature2<void, FString*, char**>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, char**>([](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<void*>(static_cast<void(*)(FString*, char**)>(loadLambda))),
asmjit::FuncSignature2<void, FString*, char**>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, char**>([](FString* to, char** from) { *to = *from; });
call->setArg(0, regS[A]);
call->setArg(1, ptr);
}

View file

@ -7,11 +7,9 @@
void JitCompiler::EmitCONCAT()
{
auto rc = CheckRegS(C, A);
auto concatLambda = [](FString* to, FString* first, FString* second) -> void {
auto call = CreateCall<void, FString*, FString*, FString*>([](FString* to, FString* first, FString* second) {
*to = *first + *second;
};
auto call = cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<void(*)(FString*, FString*, FString*)>(concatLambda))),
asmjit::FuncSignature3<void, FString*, FString*, FString*>(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<int, FString*>([](FString* str) -> int {
return static_cast<int>(str->Len());
};
auto call = cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<int(*)(FString*)>(lenLambda))),
asmjit::FuncSignature1<int, FString*>(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<bool>(A & CMP_APPROX) ?
cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<int(*)(FString*, FString*)>(compareNoCaseLambda))),
asmjit::FuncSignature2<int, FString*, FString*>(asmjit::CallConv::kIdHostCDecl)) :
cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<int(*)(FString*, FString*)>(compareLambda))),
asmjit::FuncSignature2<int, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = static_cast<bool>(A & CMP_APPROX) ?
CreateCall<int, FString*, FString*>(compareNoCaseLambda) :
CreateCall<int, FString*, FString*>(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<const void*>(static_cast<FuncPtr>([](double a, double b) -> double
auto call = CreateCall<double, double, double>([](double a, double b) -> double
{
return a - floor(a / b) * b;
}))), FuncSignature2<double, double, double>());
});
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<const void*>(static_cast<FuncPtr>([](double a, double b) -> double {
auto call = CreateCall<double, double, double>([](double a, double b) -> double {
return a - floor(a / b) * b;
}))), FuncSignature2<double, double, double>());
});
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<const void*>(static_cast<FuncPtr>([](double a, double b) -> double {
auto call = CreateCall<double, double, double>([](double a, double b) -> double {
return a - floor(a / b) * b;
}))), FuncSignature2<double, double, double>());
});
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<const void*>(static_cast<FuncPtr>(g_pow))), FuncSignature2<double, double, double>());
auto call = CreateCall<double, double, double>(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<const void*>(static_cast<FuncPtr>(g_pow))), FuncSignature2<double, double, double>());
auto call = CreateCall<double, double, double>(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<const void*>(static_cast<FuncPtr>(g_pow))), FuncSignature2<double, double, double>());
auto call = CreateCall<double, double, double>(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<const void*>(static_cast<FuncPtr>(g_atan2))), FuncSignature2<double, double, double>());
auto call = CreateCall<double, double, double>(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<const void*>(func)), asmjit::FuncSignature1<double, double>());
auto call = CreateCall<double, double>(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<const void*>(static_cast<FuncPtr>(g_sqrt))), FuncSignature1<double, double>());
auto call = CreateCall<double, double>(g_sqrt);
call->setRet(0, a);
call->setArg(0, b);
}

View file

@ -15,8 +15,7 @@ void JitCompiler::EmitMOVEF()
void JitCompiler::EmitMOVES()
{
auto call = cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<void(*)(FString*, FString*)>(CallAssignString))),
asmjit::FuncSignature2<void, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, FString*>(&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<void, FString*, int> FuncI2S, FuncU2S, FuncN2S, FuncCo2S, FuncSo2S, FuncSid2S, FuncTid2S;
typedef asmjit::FuncSignature2<void, FString*, double> FuncF2S;
typedef asmjit::FuncSignature3<void, FString*, double, double> FuncV22S;
typedef asmjit::FuncSignature4<void, FString*, double, double, double> FuncV32S;
typedef asmjit::FuncSignature2<void, FString*, void*> FuncP2S;
typedef asmjit::FuncSignature1<int, FString*> FuncS2I, FuncS2N, FuncS2Co, FuncS2So;
typedef asmjit::FuncSignature1<double, FString*> 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<const void*>(i2s)), FuncI2S());
call = CreateCall<void, FString*, int>([](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<const void*>(u2s)), FuncU2S());
call = CreateCall<void, FString*, int>([](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<const void*>(f2s)), FuncF2S());
call = CreateCall<void, FString*, double>([](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<const void*>(v22s)), FuncV22S());
call = CreateCall<void, FString*, double, double>([](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<const void*>(v32s)), FuncV32S());
call = CreateCall<void, FString*, double, double, double>([](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<const void*>(p2s)), FuncP2S());
call = CreateCall<void, FString*, void*>([](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<const void*>(s2i)), FuncS2I());
call = CreateCall<int, FString*>([](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<const void*>(s2f)), FuncS2F());
call = CreateCall<double, FString*>([](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<const void*>(s2n)), FuncS2N());
call = CreateCall<int, FString*>([](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<const void*>(n2s)), FuncN2S());
call = CreateCall<void, FString*, int>([](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<const void*>(s2co)), FuncS2Co());
call = CreateCall<int, FString*>([](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<const void*>(co2s)), FuncCo2S());
call = CreateCall<void, FString*, int>([](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<const void*>(s2so)), FuncS2So());
call = CreateCall<int, FString*>([](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<const void*>(so2s)), FuncSo2S());
call = CreateCall<void, FString*, int>([](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<const void*>(sid2s)), FuncSid2S());
call = CreateCall<void, FString*, unsigned int>([](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<const void*>(tid2s)), FuncTid2S());
call = CreateCall<void, FString*, int>([](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<const void*>(static_cast<FuncPtr>([](FString *s) -> int {
return s->Len() > 0;
}))), FuncSignature1<int, void*>());
auto call = CreateCall<int, FString*>([](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<const void*>(static_cast<FuncPtr>([](DObject *obj, PClass *cls) -> DObject* {
auto call = CreateCall<DObject*, DObject*, PClass*>([](DObject *obj, PClass *cls) -> DObject* {
return (obj && obj->IsKindOf(cls)) ? obj : nullptr;
}))), FuncSignature2<void*, void*, void*>());
});
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<const void*>(static_cast<FuncPtr>([](DObject *obj, PClass *cls) -> DObject* {
auto call = CreateCall<DObject*, DObject*, PClass*>([](DObject *obj, PClass *cls) -> DObject* {
return (obj && obj->IsKindOf(cls)) ? obj : nullptr;
}))), FuncSignature2<void*, void*, void*>());
});
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<const void*>(static_cast<FuncPtr>([](PClass *cls1, PClass *cls2) -> PClass* {
auto call = CreateCall<PClass*, PClass*, PClass*>([](PClass *cls1, PClass *cls2) -> PClass* {
return (cls1 && cls1->IsDescendantOf(cls2)) ? cls1 : nullptr;
}))), FuncSignature2<void*, void*, void*>());
});
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<const void*>(static_cast<FuncPtr>([](PClass *cls1, PClass *cls2) -> PClass* {
auto call = CreateCall<PClass*, PClass*, PClass*>([](PClass *cls1, PClass *cls2) -> PClass* {
return (cls1 && cls1->IsDescendantOf(cls2)) ? cls1 : nullptr;
}))), FuncSignature2<void*, void*, void*>());
});
call->setRet(0, regA[A]);
call->setArg(0, regA[B]);
call->setArg(1, c);

View file

@ -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<void*>(static_cast<void(*)(FString*, FString*)>(CallAssignString))),
asmjit::FuncSignature2<void, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, FString*>(&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<void*>(static_cast<void(*)(FString*, FString*)>(CallAssignString))),
asmjit::FuncSignature2<void, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
auto call = CreateCall<void, FString*, FString*>(&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<const void*>(static_cast<FuncPtr>(GC::WriteBarrier))), asmjit::FuncSignature1<void, void*>());
auto call = CreateCall<void, DObject*>(static_cast<FuncPtr>(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<const void*>(static_cast<FuncPtr>(GC::WriteBarrier))), asmjit::FuncSignature1<void, void*>());
auto call = CreateCall<void, DObject*>(static_cast<FuncPtr>(GC::WriteBarrier));
call->setArg(0, regA[B]);
}

View file

@ -79,6 +79,27 @@ private:
*to = *from;
}
template<typename RetType, typename P1>
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1)) { return cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<RetType(*)(P1)>(func))), asmjit::FuncSignature1<RetType, P1>()); }
template<typename RetType, typename P1, typename P2>
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2)) { return cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2)>(func))), asmjit::FuncSignature2<RetType, P1, P2>()); }
template<typename RetType, typename P1, typename P2, typename P3>
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3)) { return cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3)>(func))), asmjit::FuncSignature3<RetType, P1, P2, P3>()); }
template<typename RetType, typename P1, typename P2, typename P3, typename P4>
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4)) { return cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4)>(func))), asmjit::FuncSignature4<RetType, P1, P2, P3, P4>()); }
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5>
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)) { return cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5)>(func))), asmjit::FuncSignature5<RetType, P1, P2, P3, P4, P5>()); }
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)) { return cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6)>(func))), asmjit::FuncSignature6<RetType, P1, P2, P3, P4, P5, P6>()); }
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
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<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6, P7)>(func))), asmjit::FuncSignature7<RetType, P1, P2, P3, P4, P5, P6, P7>()); }
void EmitNullPointerThrow(int index, EVMAbortException reason);
void EmitThrowException(EVMAbortException reason);
void EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg1);