mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-16 17:21:10 +00:00
Replace the native call templates with CreateNativeFunction to make it more explicit which IR types are actually used
This commit is contained in:
parent
d3288a8dae
commit
1c9df61c5d
8 changed files with 400 additions and 339 deletions
|
@ -2,6 +2,10 @@
|
|||
#include "jit.h"
|
||||
#include "jitintern.h"
|
||||
#include "printf.h"
|
||||
#include "v_video.h"
|
||||
#include "s_soundinternal.h"
|
||||
#include "texturemanager.h"
|
||||
#include "palutil.h"
|
||||
|
||||
extern PString *TypeString;
|
||||
extern PStruct *TypeVector2;
|
||||
|
@ -158,7 +162,7 @@ void JitCompiler::CheckVMFrame()
|
|||
{
|
||||
if (!vmframe)
|
||||
{
|
||||
vmframe = irfunc->createAlloca(ircontext->getInt8Ty(), ircontext->getConstantInt(sfunc->StackSize), "vmframe");
|
||||
vmframe = irfunc->createAlloca(int8Ty, ircontext->getConstantInt(sfunc->StackSize), "vmframe");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,7 +170,7 @@ IRValue* JitCompiler::GetCallReturns()
|
|||
{
|
||||
if (!callReturns)
|
||||
{
|
||||
callReturns = irfunc->createAlloca(ircontext->getInt8Ty(), ircontext->getConstantInt(sizeof(VMReturn) * MAX_RETURNS), "callReturns");
|
||||
callReturns = irfunc->createAlloca(int8Ty, ircontext->getConstantInt(sizeof(VMReturn) * MAX_RETURNS), "callReturns");
|
||||
}
|
||||
return callReturns;
|
||||
}
|
||||
|
@ -215,6 +219,9 @@ IRBasicBlock* JitCompiler::GetLabel(size_t pos)
|
|||
|
||||
void JitCompiler::Setup()
|
||||
{
|
||||
GetTypes();
|
||||
CreateNativeFunctions();
|
||||
|
||||
//static const char *marks = "=======================================================";
|
||||
//cc.comment("", 0);
|
||||
//cc.comment(marks, 56);
|
||||
|
@ -226,7 +233,8 @@ void JitCompiler::Setup()
|
|||
//cc.comment(marks, 56);
|
||||
//cc.comment("", 0);
|
||||
|
||||
irfunc = ircontext->createFunction(GetFunctionType5<int, VMFunction*, void*, int, void*, int>(), sfunc->PrintableName.GetChars());
|
||||
IRFunctionType* functype = ircontext->getFunctionType(int32Ty, { int8PtrTy, int8PtrTy, int32Ty, int8PtrTy, int32Ty });
|
||||
irfunc = ircontext->createFunction(functype, sfunc->PrintableName.GetChars());
|
||||
irfunc->fileInfo.push_back({ sfunc->PrintableName.GetChars(), sfunc->SourceFileName.GetChars() });
|
||||
|
||||
args = irfunc->args[1];
|
||||
|
@ -323,17 +331,9 @@ void JitCompiler::SetupSimpleFrame()
|
|||
StoreA(ConstValueA(nullptr), i);
|
||||
}
|
||||
|
||||
static VMFrameStack *CreateFullVMFrame(VMScriptFunction *func, VMValue *args, int numargs)
|
||||
{
|
||||
VMFrameStack *stack = &GlobalVMStack;
|
||||
VMFrame *newf = stack->AllocFrame(func);
|
||||
VMFillParams(args, newf, numargs);
|
||||
return stack;
|
||||
}
|
||||
|
||||
void JitCompiler::SetupFullVMFrame()
|
||||
{
|
||||
vmframestack = cc.CreateCall(GetNativeFunc<VMFrameStack*, VMScriptFunction*, VMValue*, int>("__CreateFullVMFrame", CreateFullVMFrame), { ConstValueA(sfunc), args, numargs });
|
||||
vmframestack = cc.CreateCall(createFullVMFrame, { ConstValueA(sfunc), args, numargs });
|
||||
|
||||
IRValue* Blocks = Load(ToInt8PtrPtr(vmframestack)); // vmframestack->Blocks
|
||||
vmframe = Load(ToInt8PtrPtr(Blocks, VMFrameStack::OffsetLastFrame())); // Blocks->LastFrame
|
||||
|
@ -351,23 +351,18 @@ void JitCompiler::SetupFullVMFrame()
|
|||
StoreA(Load(ToInt8PtrPtr(vmframe, offsetA + i * sizeof(void*))), i);
|
||||
}
|
||||
|
||||
static void PopFullVMFrame(VMFrameStack * vmframestack)
|
||||
{
|
||||
vmframestack->PopFrame();
|
||||
}
|
||||
|
||||
void JitCompiler::EmitPopFrame()
|
||||
{
|
||||
if (sfunc->SpecialInits.Size() != 0 || sfunc->NumRegS != 0)
|
||||
{
|
||||
cc.CreateCall(GetNativeFunc<void, VMFrameStack*>("__PopFullVMFrame", PopFullVMFrame), { vmframestack });
|
||||
cc.CreateCall(popFullVMFrame, { vmframestack });
|
||||
}
|
||||
}
|
||||
|
||||
void JitCompiler::IncrementVMCalls()
|
||||
{
|
||||
// VMCalls[0]++
|
||||
IRValue* vmcallsptr = ircontext->getConstantInt(ircontext->getInt32PtrTy(), (uint64_t)VMCalls);
|
||||
IRValue* vmcallsptr = ircontext->getConstantInt(int32PtrTy, (uint64_t)VMCalls);
|
||||
cc.CreateStore(cc.CreateAdd(cc.CreateLoad(vmcallsptr), ircontext->getConstantInt(1)), vmcallsptr);
|
||||
}
|
||||
|
||||
|
@ -379,34 +374,30 @@ void JitCompiler::CreateRegisters()
|
|||
regS.Resize(sfunc->NumRegS);
|
||||
|
||||
FString regname;
|
||||
IRType* type;
|
||||
IRValue* arraySize = ircontext->getConstantInt(1);
|
||||
|
||||
type = ircontext->getInt32Ty();
|
||||
for (int i = 0; i < sfunc->NumRegD; i++)
|
||||
{
|
||||
regname.Format("regD%d", i);
|
||||
regD[i] = irfunc->createAlloca(type, arraySize, regname.GetChars());
|
||||
regD[i] = irfunc->createAlloca(int32Ty, arraySize, regname.GetChars());
|
||||
}
|
||||
|
||||
type = ircontext->getDoubleTy();
|
||||
for (int i = 0; i < sfunc->NumRegF; i++)
|
||||
{
|
||||
regname.Format("regF%d", i);
|
||||
regF[i] = irfunc->createAlloca(type, arraySize, regname.GetChars());
|
||||
regF[i] = irfunc->createAlloca(doubleTy, arraySize, regname.GetChars());
|
||||
}
|
||||
|
||||
type = ircontext->getInt8PtrTy();
|
||||
for (int i = 0; i < sfunc->NumRegS; i++)
|
||||
{
|
||||
regname.Format("regS%d", i);
|
||||
regS[i] = irfunc->createAlloca(type, arraySize, regname.GetChars());
|
||||
regS[i] = irfunc->createAlloca(int8PtrTy, arraySize, regname.GetChars());
|
||||
}
|
||||
|
||||
for (int i = 0; i < sfunc->NumRegA; i++)
|
||||
{
|
||||
regname.Format("regA%d", i);
|
||||
regA[i] = irfunc->createAlloca(type, arraySize, regname.GetChars());
|
||||
regA[i] = irfunc->createAlloca(int8PtrTy, arraySize, regname.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,15 +411,10 @@ void JitCompiler::EmitNullPointerThrow(int index, EVMAbortException reason)
|
|||
|
||||
void JitCompiler::EmitThrowException(EVMAbortException reason)
|
||||
{
|
||||
cc.CreateCall(GetNativeFunc<void, int>("__ThrowException", &JitCompiler::ThrowException), { ConstValueD(reason) });
|
||||
cc.CreateCall(throwException, { ConstValueD(reason) });
|
||||
cc.CreateRet(ConstValueD(0));
|
||||
}
|
||||
|
||||
void JitCompiler::ThrowException(int reason)
|
||||
{
|
||||
ThrowAbortException((EVMAbortException)reason, nullptr);
|
||||
}
|
||||
|
||||
IRBasicBlock* JitCompiler::EmitThrowExceptionLabel(EVMAbortException reason)
|
||||
{
|
||||
auto bb = irfunc->createBasicBlock({});
|
||||
|
@ -444,3 +430,181 @@ void JitCompiler::EmitNOP()
|
|||
{
|
||||
// The IR doesn't have a NOP instruction
|
||||
}
|
||||
|
||||
static void ValidateCall(DObject* o, VMFunction* f, int b)
|
||||
{
|
||||
FScopeBarrier::ValidateCall(o->GetClass(), f, b - 1);
|
||||
}
|
||||
|
||||
static void SetReturnString(VMReturn* ret, FString* str)
|
||||
{
|
||||
ret->SetString(*str);
|
||||
}
|
||||
|
||||
static VMFrameStack* CreateFullVMFrame(VMScriptFunction* func, VMValue* args, int numargs)
|
||||
{
|
||||
VMFrameStack* stack = &GlobalVMStack;
|
||||
VMFrame* newf = stack->AllocFrame(func);
|
||||
VMFillParams(args, newf, numargs);
|
||||
return stack;
|
||||
}
|
||||
|
||||
static void PopFullVMFrame(VMFrameStack* vmframestack)
|
||||
{
|
||||
vmframestack->PopFrame();
|
||||
}
|
||||
|
||||
static void ThrowException(int reason)
|
||||
{
|
||||
ThrowAbortException((EVMAbortException)reason, nullptr);
|
||||
}
|
||||
|
||||
static void ThrowArrayOutOfBounds(int index, int size)
|
||||
{
|
||||
if (index >= size)
|
||||
{
|
||||
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Max.index = %u, current index = %u\n", size, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Negative current index = %i\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
static DObject* ReadBarrier(DObject* p) { return GC::ReadBarrier(p); }
|
||||
static void WriteBarrier(DObject* p) { GC::WriteBarrier(p); }
|
||||
|
||||
static void StringAssignmentOperator(FString* to, FString* from) { *to = *from; }
|
||||
static void StringAssignmentOperatorCStr(FString* to, char** from) { *to = *from; }
|
||||
static void StringPlusOperator(FString* to, FString* first, FString* second) { *to = *first + *second; }
|
||||
static int StringLength(FString* str) { return static_cast<int>(str->Len()); }
|
||||
static int StringCompareNoCase(FString* first, FString* second) { return first->CompareNoCase(*second); }
|
||||
static int StringCompare(FString* first, FString* second) { return first->Compare(*second); }
|
||||
|
||||
static double DoubleModF(double a, double b) { return a - floor(a / b) * b; }
|
||||
static double DoublePow(double a, double b) { return g_pow(a, b); }
|
||||
static double DoubleAtan2(double a, double b) { return g_atan2(a, b); }
|
||||
static double DoubleFabs(double a) { return fabs(a); }
|
||||
static double DoubleExp(double a) { return g_exp(a); }
|
||||
static double DoubleLog(double a) { return g_log(a); }
|
||||
static double DoubleLog10(double a) { return g_log10(a); }
|
||||
static double DoubleSqrt(double a) { return g_sqrt(a); }
|
||||
static double DoubleCeil(double a) { return ceil(a); }
|
||||
static double DoubleFloor(double a) { return floor(a); }
|
||||
static double DoubleAcos(double a) { return g_acos(a); }
|
||||
static double DoubleAsin(double a) { return g_asin(a); }
|
||||
static double DoubleAtan(double a) { return g_atan(a); }
|
||||
static double DoubleCos(double a) { return g_cos(a); }
|
||||
static double DoubleSin(double a) { return g_sin(a); }
|
||||
static double DoubleTan(double a) { return g_tan(a); }
|
||||
static double DoubleCosDeg(double a) { return g_cosdeg(a); }
|
||||
static double DoubleSinDeg(double a) { return g_sindeg(a); }
|
||||
static double DoubleCosh(double a) { return g_cosh(a); }
|
||||
static double DoubleSinh(double a) { return g_sinh(a); }
|
||||
static double DoubleTanh(double a) { return g_tanh(a); }
|
||||
static double DoubleRound(double a) { return round(a); }
|
||||
|
||||
static void CastI2S(FString* a, int b) { a->Format("%d", b); }
|
||||
static void CastU2S(FString* a, int b) { a->Format("%u", b); }
|
||||
static void CastF2S(FString* a, double b) { a->Format("%.5f", b); }
|
||||
static void CastV22S(FString* a, double b, double b1) { a->Format("(%.5f, %.5f)", b, b1); }
|
||||
static void CastV32S(FString* a, double b, double b1, double b2) { a->Format("(%.5f, %.5f, %.5f)", b, b1, b2); }
|
||||
static void CastP2S(FString* a, void* b) { if (b == nullptr) *a = "null"; else a->Format("%p", b); }
|
||||
static int CastS2I(FString* b) { return (int)b->ToLong(); }
|
||||
static double CastS2F(FString* b) { return b->ToDouble(); }
|
||||
static int CastS2N(FString* b) { return b->Len() == 0 ? NAME_None : FName(*b).GetIndex(); }
|
||||
static void CastN2S(FString* a, int b) { FName name = FName(ENamedName(b)); *a = name.IsValidName() ? name.GetChars() : ""; }
|
||||
static int CastS2Co(FString* b) { return V_GetColor(nullptr, *b); }
|
||||
static void CastCo2S(FString* a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); }
|
||||
static int CastS2So(FString* b) { return FSoundID(*b); }
|
||||
static void CastSo2S(FString* a, int b) { *a = soundEngine->GetSoundName(b); }
|
||||
static void CastSID2S(FString* a, unsigned int b) { VM_CastSpriteIDToString(a, b); }
|
||||
static void CastTID2S(FString* a, int b) { auto tex = TexMan.GetGameTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); }
|
||||
static int CastB_S(FString* s) { return s->Len() > 0; }
|
||||
|
||||
static DObject* DynCast(DObject* obj, PClass* cls) { return (obj && obj->IsKindOf(cls)) ? obj : nullptr; }
|
||||
static PClass* DynCastC(PClass* cls1, PClass* cls2) { return (cls1 && cls1->IsDescendantOf(cls2)) ? cls1 : nullptr; }
|
||||
|
||||
void JitCompiler::GetTypes()
|
||||
{
|
||||
voidTy = ircontext->getVoidTy();
|
||||
int8Ty = ircontext->getInt8Ty();
|
||||
int8PtrTy = ircontext->getInt8PtrTy();
|
||||
int8PtrPtrTy = int8PtrTy->getPointerTo(ircontext);
|
||||
int16Ty = ircontext->getInt16Ty();
|
||||
int16PtrTy = ircontext->getInt16PtrTy();
|
||||
int32Ty = ircontext->getInt32Ty();
|
||||
int32PtrTy = ircontext->getInt32PtrTy();
|
||||
int64Ty = ircontext->getInt64Ty();
|
||||
floatTy = ircontext->getFloatTy();
|
||||
floatPtrTy = ircontext->getFloatPtrTy();
|
||||
doubleTy = ircontext->getDoubleTy();
|
||||
doublePtrTy = ircontext->getDoublePtrTy();
|
||||
}
|
||||
|
||||
void JitCompiler::CreateNativeFunctions()
|
||||
{
|
||||
validateCall = CreateNativeFunction(voidTy, { int8PtrTy, int8PtrTy, int32Ty }, "__ValidateCall", ValidateCall);
|
||||
setReturnString = CreateNativeFunction(voidTy, { int8PtrTy, int8PtrTy }, "__SetReturnString", SetReturnString);
|
||||
createFullVMFrame = CreateNativeFunction(int8PtrTy, { int8PtrTy, int8PtrTy, int32Ty }, "__CreateFullVMFrame", CreateFullVMFrame);
|
||||
popFullVMFrame = CreateNativeFunction(voidTy, { int8PtrTy }, "__PopFullVMFrame", PopFullVMFrame);
|
||||
throwException = CreateNativeFunction(voidTy, { int32Ty }, "__ThrowException", ThrowException);
|
||||
throwArrayOutOfBounds = CreateNativeFunction(voidTy, { int32Ty, int32Ty }, "__ThrowArrayOutOfBounds", ThrowArrayOutOfBounds);
|
||||
stringAssignmentOperator = CreateNativeFunction(voidTy, { int8PtrTy, int8PtrTy }, "__StringAssignmentOperator", StringAssignmentOperator);
|
||||
stringAssignmentOperatorCStr = CreateNativeFunction(voidTy, { int8PtrTy, int8PtrTy }, "__StringAssignmentOperatorCStr", StringAssignmentOperatorCStr);
|
||||
stringPlusOperator = CreateNativeFunction(voidTy, { int8PtrTy, int8PtrTy, int8PtrTy }, "__StringPlusOperator", StringPlusOperator);
|
||||
stringCompare = CreateNativeFunction(voidTy, { int8PtrTy, int8PtrTy }, "__StringCompare", StringCompare);
|
||||
stringCompareNoCase = CreateNativeFunction(voidTy, { int8PtrTy, int8PtrTy }, "__StringCompareNoCase", StringCompareNoCase);
|
||||
stringLength = CreateNativeFunction(int32Ty, { int8PtrTy }, "__StringLength", StringLength);
|
||||
readBarrier = CreateNativeFunction(int8PtrTy, { int8PtrTy }, "__ReadBarrier", ReadBarrier);
|
||||
writeBarrier = CreateNativeFunction(voidTy, { int8PtrTy }, "__WriteBarrier", WriteBarrier);
|
||||
doubleModF = CreateNativeFunction(doubleTy, { doubleTy, doubleTy }, "__DoubleModF", DoubleModF);
|
||||
doublePow = CreateNativeFunction(doubleTy, { doubleTy, doubleTy }, "__DoublePow", DoublePow);
|
||||
doubleAtan2 = CreateNativeFunction(doubleTy, { doubleTy, doubleTy }, "__DoubleAtan2", DoubleAtan2);
|
||||
doubleFabs = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleFabs", DoubleFabs);
|
||||
doubleExp = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleExp", DoubleExp);
|
||||
doubleLog = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleLog", DoubleLog);
|
||||
doubleLog10 = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleLog10", DoubleLog10);
|
||||
doubleSqrt = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleSqrt", DoubleSqrt);
|
||||
doubleCeil = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleCeil", DoubleCeil);
|
||||
doubleFloor = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleFloor", DoubleFloor);
|
||||
doubleAcos = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleAcos", DoubleAcos);
|
||||
doubleAsin = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleAsin", DoubleAsin);
|
||||
doubleAtan = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleAtan", DoubleAtan);
|
||||
doubleCos = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleCos", DoubleCos);
|
||||
doubleSin = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleSin", DoubleSin);
|
||||
doubleTan = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleTan", DoubleTan);
|
||||
doubleCosDeg = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleCosDeg", DoubleCosDeg);
|
||||
doubleSinDeg = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleSinDeg", DoubleSinDeg);
|
||||
doubleCosh = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleCosh", DoubleCosh);
|
||||
doubleSinh = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleSinh", DoubleSinh);
|
||||
doubleTanh = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleTanh", DoubleTanh);
|
||||
doubleRound = CreateNativeFunction(doubleTy, { doubleTy }, "__DoubleRound", DoubleRound);
|
||||
castI2S = CreateNativeFunction(voidTy, { int8PtrTy, int32Ty }, "__CastI2S", CastI2S);
|
||||
castU2S = CreateNativeFunction(voidTy, { int8PtrTy, int32Ty }, "__CastU2S", CastU2S);
|
||||
castF2S = CreateNativeFunction(voidTy, { int8PtrTy, doubleTy }, "__CastF2S", CastF2S);
|
||||
castV22S = CreateNativeFunction(voidTy, { int8PtrTy, doubleTy, doubleTy }, "__CastV22S", CastV22S);
|
||||
castV32S = CreateNativeFunction(voidTy, { int8PtrTy, doubleTy, doubleTy, doubleTy }, "__CastV32S", CastV32S);
|
||||
castP2S = CreateNativeFunction(voidTy, { int8PtrTy, int8PtrTy }, "__CastP2S", CastP2S);
|
||||
castS2I = CreateNativeFunction(int32Ty, { int8PtrTy }, "__CastS2I", CastS2I);
|
||||
castS2F = CreateNativeFunction(doubleTy, { int8PtrTy }, "__CastS2F", CastS2F);
|
||||
castS2N = CreateNativeFunction(int32Ty, { int8PtrTy }, "__CastS2N", CastS2N);
|
||||
castN2S = CreateNativeFunction(voidTy, { int8PtrTy, int32Ty }, "__CastN2S", CastN2S);
|
||||
castS2Co = CreateNativeFunction(int32Ty, { int8PtrTy }, "__CastS2Co", CastS2Co);
|
||||
castCo2S = CreateNativeFunction(voidTy, { int8PtrTy, int32Ty }, "__CastCo2S", CastCo2S);
|
||||
castS2So = CreateNativeFunction(int32Ty, { int8PtrTy }, "__CastS2So", CastS2So);
|
||||
castSo2S = CreateNativeFunction(voidTy, { int8PtrTy, int32Ty }, "__CastSo2S", CastSo2S);
|
||||
castSID2S = CreateNativeFunction(voidTy, { int8PtrTy, int32Ty }, "__CastSID2S", CastSID2S);
|
||||
castTID2S = CreateNativeFunction(voidTy, { int8PtrTy, int32Ty }, "__CastTID2S", CastTID2S);
|
||||
castB_S = CreateNativeFunction(int32Ty, { int8PtrTy }, "__CastB_S", CastB_S);
|
||||
dynCast = CreateNativeFunction(int8PtrTy, { int8PtrTy, int8PtrTy }, "__DynCast", DynCast);
|
||||
dynCastC = CreateNativeFunction(int8PtrTy, { int8PtrTy, int8PtrTy }, "__DynCastC", DynCastC);
|
||||
}
|
||||
|
||||
IRFunction* JitCompiler::CreateNativeFunction(IRType* returnType, std::vector<IRType*> args, const char* name, void* ptr)
|
||||
{
|
||||
IRFunctionType* functype = ircontext->getFunctionType(returnType, args);
|
||||
IRFunction* func = ircontext->createFunction(functype, name);
|
||||
ircontext->addGlobalMapping(func, ptr);
|
||||
return func;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,8 @@ void JitCompiler::EmitVMCall(IRValue* vmfunc, VMFunction* target)
|
|||
IRValue* paramsptr = OffsetPtr(vmframe, offsetParams);
|
||||
IRValue* scriptcall = Load(ToInt8PtrPtr(vmfunc, myoffsetof(VMScriptFunction, ScriptCall)));
|
||||
|
||||
IRInst* call = cc.CreateCall(cc.CreateBitCast(scriptcall, GetFunctionType5<int, VMFunction*, VMValue*, int, VMReturn*, int>()), { vmfunc, paramsptr, ConstValueD(B), GetCallReturns(), ConstValueD(C) });
|
||||
IRFunctionType* functype = ircontext->getFunctionType(int32Ty, { int8PtrTy, int8PtrTy, int32Ty, int8PtrTy, int32Ty });
|
||||
IRInst* call = cc.CreateCall(cc.CreateBitCast(scriptcall, functype), { vmfunc, paramsptr, ConstValueD(B), GetCallReturns(), ConstValueD(C) });
|
||||
call->comment = std::string("call ") + (target ? target->PrintableName.GetChars() : "VMCall");
|
||||
|
||||
LoadInOuts();
|
||||
|
@ -518,7 +519,7 @@ IRFunctionType* JitCompiler::GetFuncSignature()
|
|||
{
|
||||
if (ParamOpcodes[i]->op == OP_PARAMI)
|
||||
{
|
||||
args.push_back(ircontext->getInt32Ty());
|
||||
args.push_back(int32Ty);
|
||||
}
|
||||
else // OP_PARAM
|
||||
{
|
||||
|
@ -532,28 +533,28 @@ IRFunctionType* JitCompiler::GetFuncSignature()
|
|||
case REGT_INT | REGT_ADDROF:
|
||||
case REGT_POINTER | REGT_ADDROF:
|
||||
case REGT_FLOAT | REGT_ADDROF:
|
||||
args.push_back(ircontext->getInt8PtrTy());
|
||||
args.push_back(int8PtrTy);
|
||||
break;
|
||||
case REGT_INT:
|
||||
case REGT_INT | REGT_KONST:
|
||||
args.push_back(ircontext->getInt32Ty());
|
||||
args.push_back(int32Ty);
|
||||
break;
|
||||
case REGT_STRING:
|
||||
case REGT_STRING | REGT_KONST:
|
||||
args.push_back(ircontext->getInt8PtrTy());
|
||||
args.push_back(int8PtrTy);
|
||||
break;
|
||||
case REGT_FLOAT:
|
||||
case REGT_FLOAT | REGT_KONST:
|
||||
args.push_back(ircontext->getDoublePtrTy());
|
||||
args.push_back(doublePtrTy);
|
||||
break;
|
||||
case REGT_FLOAT | REGT_MULTIREG2:
|
||||
args.push_back(ircontext->getDoublePtrTy());
|
||||
args.push_back(ircontext->getDoublePtrTy());
|
||||
args.push_back(doublePtrTy);
|
||||
args.push_back(doublePtrTy);
|
||||
break;
|
||||
case REGT_FLOAT | REGT_MULTIREG3:
|
||||
args.push_back(ircontext->getDoublePtrTy());
|
||||
args.push_back(ircontext->getDoublePtrTy());
|
||||
args.push_back(ircontext->getDoublePtrTy());
|
||||
args.push_back(doublePtrTy);
|
||||
args.push_back(doublePtrTy);
|
||||
args.push_back(doublePtrTy);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -566,7 +567,7 @@ IRFunctionType* JitCompiler::GetFuncSignature()
|
|||
const VMOP *retval = pc + 1;
|
||||
int numret = C;
|
||||
|
||||
IRType* rettype = ircontext->getVoidTy();
|
||||
IRType* rettype = voidTy;
|
||||
|
||||
// Check if first return value can be placed in the function's real return value slot
|
||||
int startret = 1;
|
||||
|
@ -581,13 +582,13 @@ IRFunctionType* JitCompiler::GetFuncSignature()
|
|||
switch (type)
|
||||
{
|
||||
case REGT_INT:
|
||||
rettype = ircontext->getInt32Ty();
|
||||
rettype = int32Ty;
|
||||
break;
|
||||
case REGT_FLOAT:
|
||||
rettype = ircontext->getDoublePtrTy();
|
||||
rettype = doublePtrTy;
|
||||
break;
|
||||
case REGT_POINTER:
|
||||
rettype = ircontext->getInt8PtrTy();
|
||||
rettype = int8PtrTy;
|
||||
break;
|
||||
case REGT_STRING:
|
||||
default:
|
||||
|
@ -604,7 +605,7 @@ IRFunctionType* JitCompiler::GetFuncSignature()
|
|||
I_Error("Expected OP_RESULT to follow OP_CALL\n");
|
||||
}
|
||||
|
||||
args.push_back(ircontext->getInt8PtrTy());
|
||||
args.push_back(int8PtrTy);
|
||||
}
|
||||
|
||||
return ircontext->getFunctionType(rettype, args);
|
||||
|
|
|
@ -50,23 +50,13 @@ void JitCompiler::EmitIJMP()
|
|||
EmitThrowException(X_OTHER);
|
||||
}
|
||||
|
||||
static void ValidateCall(DObject *o, VMFunction *f, int b)
|
||||
{
|
||||
FScopeBarrier::ValidateCall(o->GetClass(), f, b - 1);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSCOPE()
|
||||
{
|
||||
auto continuebb = irfunc->createBasicBlock({});
|
||||
auto exceptionbb = EmitThrowExceptionLabel(X_READ_NIL);
|
||||
cc.CreateCondBr(cc.CreateICmpEQ(LoadD(A), ConstValueA(0)), exceptionbb, continuebb);
|
||||
cc.SetInsertPoint(continuebb);
|
||||
cc.CreateCall(GetNativeFunc<void, DObject*, VMFunction*, int>("__ValidateCall", ValidateCall), { LoadA(A), ConstA(C), ConstValueD(B) });
|
||||
}
|
||||
|
||||
static void SetString(VMReturn* ret, FString* str)
|
||||
{
|
||||
ret->SetString(*str);
|
||||
cc.CreateCall(validateCall, { LoadA(A), ConstA(C), ConstValueD(B) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitRET()
|
||||
|
@ -139,7 +129,7 @@ void JitCompiler::EmitRET()
|
|||
break;
|
||||
case REGT_STRING:
|
||||
{
|
||||
cc.CreateCall(GetNativeFunc<void, VMReturn*, FString*>("__SetString", SetString), { location, (regtype & REGT_KONST) ? ConstS(regnum) : LoadS(regnum) });
|
||||
cc.CreateCall(setReturnString, { location, (regtype & REGT_KONST) ? ConstS(regnum) : LoadS(regnum) });
|
||||
break;
|
||||
}
|
||||
case REGT_POINTER:
|
||||
|
@ -218,7 +208,7 @@ void JitCompiler::EmitBOUND()
|
|||
IRBasicBlock* exceptionbb = irfunc->createBasicBlock({});
|
||||
cc.CreateCondBr(cc.CreateICmpUGE(LoadD(A), ConstValueD(BC)), exceptionbb, continuebb);
|
||||
cc.SetInsertPoint(exceptionbb);
|
||||
cc.CreateCall(GetNativeFunc<void, int, int>("__ThrowArrayOutOfBounds", &JitCompiler::ThrowArrayOutOfBounds), { LoadD(A), ConstValueD(BC) });
|
||||
cc.CreateCall(throwArrayOutOfBounds, { LoadD(A), ConstValueD(BC) });
|
||||
exceptionbb->code.front()->lineNumber = sfunc->PCToLine(pc);
|
||||
cc.CreateBr(continuebb);
|
||||
cc.SetInsertPoint(continuebb);
|
||||
|
@ -230,7 +220,7 @@ void JitCompiler::EmitBOUND_K()
|
|||
IRBasicBlock* exceptionbb = irfunc->createBasicBlock({});
|
||||
cc.CreateCondBr(cc.CreateICmpUGE(LoadD(A), ConstD(BC)), exceptionbb, continuebb);
|
||||
cc.SetInsertPoint(exceptionbb);
|
||||
cc.CreateCall(GetNativeFunc<void, int, int>("__ThrowArrayOutOfBounds", &JitCompiler::ThrowArrayOutOfBounds), { LoadD(A), ConstD(BC) });
|
||||
cc.CreateCall(throwArrayOutOfBounds, { LoadD(A), ConstD(BC) });
|
||||
exceptionbb->code.front()->lineNumber = sfunc->PCToLine(pc);
|
||||
cc.CreateBr(continuebb);
|
||||
cc.SetInsertPoint(continuebb);
|
||||
|
@ -242,20 +232,8 @@ void JitCompiler::EmitBOUND_R()
|
|||
IRBasicBlock* exceptionbb = irfunc->createBasicBlock({});
|
||||
cc.CreateCondBr(cc.CreateICmpUGE(LoadD(A), LoadD(B)), exceptionbb, continuebb);
|
||||
cc.SetInsertPoint(exceptionbb);
|
||||
cc.CreateCall(GetNativeFunc<void, int, int>("__ThrowArrayOutOfBounds", &JitCompiler::ThrowArrayOutOfBounds), { LoadD(A), LoadD(BC) });
|
||||
cc.CreateCall(throwArrayOutOfBounds, { LoadD(A), LoadD(BC) });
|
||||
exceptionbb->code.front()->lineNumber = sfunc->PCToLine(pc);
|
||||
cc.CreateBr(continuebb);
|
||||
cc.SetInsertPoint(continuebb);
|
||||
}
|
||||
|
||||
void JitCompiler::ThrowArrayOutOfBounds(int index, int size)
|
||||
{
|
||||
if (index >= size)
|
||||
{
|
||||
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Max.index = %u, current index = %u\n", size, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Negative current index = %i\n", index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ void JitCompiler::EmitLKF()
|
|||
|
||||
void JitCompiler::EmitLKS()
|
||||
{
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, FString*>("__CallAssignString", &JitCompiler::CallAssignString), { LoadS(A), ConstS(BC) });
|
||||
cc.CreateCall(stringAssignmentOperator, { LoadS(A), ConstS(BC) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLKP()
|
||||
|
@ -31,25 +31,25 @@ void JitCompiler::EmitLKP()
|
|||
|
||||
void JitCompiler::EmitLK_R()
|
||||
{
|
||||
IRValue* base = ircontext->getConstantInt(ircontext->getInt32PtrTy(), (uint64_t)&konstd[C]);
|
||||
IRValue* base = ircontext->getConstantInt(int32PtrTy, (uint64_t)&konstd[C]);
|
||||
StoreD(Load(OffsetPtr(base, LoadD(B))), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLKF_R()
|
||||
{
|
||||
IRValue* base = ircontext->getConstantInt(ircontext->getDoublePtrTy(), (uint64_t)&konstf[C]);
|
||||
IRValue* base = ircontext->getConstantInt(doublePtrTy, (uint64_t)&konstf[C]);
|
||||
StoreF(Load(OffsetPtr(base, LoadD(B))), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLKS_R()
|
||||
{
|
||||
IRValue* base = ircontext->getConstantInt(ircontext->getInt8PtrTy()->getPointerTo(ircontext), (uint64_t)&konsts[C]);
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, FString*>("__CallAssignString", &JitCompiler::CallAssignString), { LoadS(A), Load(OffsetPtr(base, LoadD(B))) });
|
||||
IRValue* base = ircontext->getConstantInt(int8PtrPtrTy, (uint64_t)&konsts[C]);
|
||||
cc.CreateCall(stringAssignmentOperator, { LoadS(A), Load(OffsetPtr(base, LoadD(B))) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLKP_R()
|
||||
{
|
||||
IRValue* base = ircontext->getConstantInt(ircontext->getInt8PtrTy()->getPointerTo(ircontext), (uint64_t)&konsta[C]);
|
||||
IRValue* base = ircontext->getConstantInt(int8PtrPtrTy, (uint64_t)&konsta[C]);
|
||||
StoreA(Load(OffsetPtr(base, LoadD(B))), A);
|
||||
}
|
||||
|
||||
|
@ -174,13 +174,13 @@ void JitCompiler::EmitLDP_R()
|
|||
void JitCompiler::EmitLS()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, FString*>("__CallAssignString", &JitCompiler::CallAssignString), { LoadS(A), OffsetPtr(LoadA(B), ConstD(C)) });
|
||||
cc.CreateCall(stringAssignmentOperator, { LoadS(A), OffsetPtr(LoadA(B), ConstD(C)) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLS_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, FString*>("__CallAssignString", &JitCompiler::CallAssignString), { LoadS(A), OffsetPtr(LoadA(B), LoadD(C)) });
|
||||
cc.CreateCall(stringAssignmentOperator, { LoadS(A), OffsetPtr(LoadA(B), LoadD(C)) });
|
||||
}
|
||||
|
||||
#if 0 // Inline read barrier impl
|
||||
|
@ -219,21 +219,16 @@ void JitCompiler::EmitLO_R()
|
|||
|
||||
#else
|
||||
|
||||
static DObject *ReadBarrier(DObject *p)
|
||||
{
|
||||
return GC::ReadBarrier(p);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLO()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
StoreA(cc.CreateCall(GetNativeFunc<DObject*, DObject*>("__ReadBarrier", ReadBarrier), { OffsetPtr(LoadA(B), ConstD(C)) }), A);
|
||||
StoreA(cc.CreateCall(readBarrier, { OffsetPtr(LoadA(B), ConstD(C)) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLO_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
StoreA(cc.CreateCall(GetNativeFunc<DObject*, DObject*>("__ReadBarrier", ReadBarrier), { OffsetPtr(LoadA(B), LoadD(C)) }), A);
|
||||
StoreA(cc.CreateCall(readBarrier, { OffsetPtr(LoadA(B), LoadD(C)) }), A);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -284,21 +279,16 @@ void JitCompiler::EmitLV3_R()
|
|||
StoreF(Load(OffsetPtr(base, 2)), A + 2);
|
||||
}
|
||||
|
||||
static void SetString(FString *to, char **from)
|
||||
{
|
||||
*to = *from;
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLCS()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, char**>("__SetString", SetString), { LoadS(A), OffsetPtr(LoadA(B), ConstD(C)) });
|
||||
cc.CreateCall(stringAssignmentOperatorCStr, { LoadS(A), OffsetPtr(LoadA(B), ConstD(C)) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLCS_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, char**>("__SetString", SetString), { LoadS(A), OffsetPtr(LoadA(B), LoadD(C)) });
|
||||
cc.CreateCall(stringAssignmentOperatorCStr, { LoadS(A), OffsetPtr(LoadA(B), LoadD(C)) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLBIT()
|
||||
|
@ -307,6 +297,6 @@ void JitCompiler::EmitLBIT()
|
|||
IRValue* value = Load(LoadA(B));
|
||||
value = cc.CreateAnd(value, ircontext->getConstantInt(C));
|
||||
value = cc.CreateICmpNE(value, ircontext->getConstantInt(0));
|
||||
value = cc.CreateZExt(value, ircontext->getInt32Ty());
|
||||
value = cc.CreateZExt(value, int32Ty);
|
||||
StoreD(value, A);
|
||||
}
|
||||
|
|
|
@ -5,34 +5,14 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
// String instructions.
|
||||
|
||||
static void ConcatString(FString* to, FString* first, FString* second)
|
||||
{
|
||||
*to = *first + *second;
|
||||
}
|
||||
|
||||
void JitCompiler::EmitCONCAT()
|
||||
{
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, FString*, FString*>("__ConcatString", ConcatString), { LoadS(A), LoadS(B), LoadS(C) });
|
||||
}
|
||||
|
||||
static int StringLength(FString* str)
|
||||
{
|
||||
return static_cast<int>(str->Len());
|
||||
cc.CreateCall(stringPlusOperator, { LoadS(A), LoadS(B), LoadS(C) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLENS()
|
||||
{
|
||||
StoreD(cc.CreateCall(GetNativeFunc<int, FString*>("__StringLength", StringLength), { LoadS(B) }), A);
|
||||
}
|
||||
|
||||
static int StringCompareNoCase(FString* first, FString* second)
|
||||
{
|
||||
return first->CompareNoCase(*second);
|
||||
}
|
||||
|
||||
static int StringCompare(FString* first, FString* second)
|
||||
{
|
||||
return first->Compare(*second);
|
||||
StoreD(cc.CreateCall(stringLength, { LoadS(B) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitCMPS()
|
||||
|
@ -42,12 +22,7 @@ void JitCompiler::EmitCMPS()
|
|||
IRValue* arg0 = static_cast<bool>(A & CMP_BK) ? ConstS(B) : LoadS(B);
|
||||
IRValue* arg1 = static_cast<bool>(A & CMP_CK) ? ConstS(C) : LoadS(C);
|
||||
|
||||
IRValue* result;
|
||||
if (static_cast<bool>(A & CMP_APPROX))
|
||||
result = cc.CreateCall(GetNativeFunc<int, FString*, FString*>("__StringCompareNoCase", StringCompareNoCase), { arg0, arg1 });
|
||||
else
|
||||
result = cc.CreateCall(GetNativeFunc<int, FString*, FString*>("__StringCompare", StringCompare), { arg0, arg1 });
|
||||
|
||||
IRValue* result = cc.CreateCall(static_cast<bool>(A & CMP_APPROX) ? stringCompareNoCase : stringCompare, { arg0, arg1 });
|
||||
IRValue* zero = ConstValueD(0);
|
||||
|
||||
int method = A & CMP_METHOD_MASK;
|
||||
|
@ -686,18 +661,13 @@ void JitCompiler::EmitDIVF_KR()
|
|||
StoreF(cc.CreateFDiv(ConstF(B), LoadF(C)), A);
|
||||
}
|
||||
|
||||
static double DoubleModF(double a, double b)
|
||||
{
|
||||
return a - floor(a / b) * b;
|
||||
}
|
||||
|
||||
void JitCompiler::EmitMODF_RR()
|
||||
{
|
||||
IRBasicBlock* exceptionbb = EmitThrowExceptionLabel(X_DIVISION_BY_ZERO);
|
||||
IRBasicBlock* continuebb = irfunc->createBasicBlock({});
|
||||
cc.CreateCondBr(cc.CreateFCmpUEQ(LoadF(C), ConstValueF(0.0)), exceptionbb, continuebb);
|
||||
cc.SetInsertPoint(continuebb);
|
||||
StoreF(cc.CreateCall(GetNativeFunc<double, double, double>("__DoubleModF", DoubleModF), { LoadF(B), LoadF(C) }), A);
|
||||
StoreF(cc.CreateCall(doubleModF, { LoadF(B), LoadF(C) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitMODF_RK()
|
||||
|
@ -708,7 +678,7 @@ void JitCompiler::EmitMODF_RK()
|
|||
}
|
||||
else
|
||||
{
|
||||
StoreF(cc.CreateCall(GetNativeFunc<double, double, double>("__DoubleModF", DoubleModF), { LoadF(B), ConstF(C) }), A);
|
||||
StoreF(cc.CreateCall(doubleModF, { LoadF(B), ConstF(C) }), A);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,22 +688,22 @@ void JitCompiler::EmitMODF_KR()
|
|||
IRBasicBlock* continuebb = irfunc->createBasicBlock({});
|
||||
cc.CreateCondBr(cc.CreateFCmpUEQ(LoadF(C), ConstValueF(0.0)), exceptionbb, continuebb);
|
||||
cc.SetInsertPoint(continuebb);
|
||||
StoreF(cc.CreateCall(GetNativeFunc<double, double, double>("__DoubleModF", DoubleModF), { ConstF(B), LoadF(C) }), A);
|
||||
StoreF(cc.CreateCall(doubleModF, { ConstF(B), LoadF(C) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitPOWF_RR()
|
||||
{
|
||||
StoreF(cc.CreateCall(GetNativeFunc<double, double, double>("__g_pow", g_pow), { LoadF(B), LoadF(C) }), A);
|
||||
StoreF(cc.CreateCall(doublePow, { LoadF(B), LoadF(C) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitPOWF_RK()
|
||||
{
|
||||
StoreF(cc.CreateCall(GetNativeFunc<double, double, double>("__g_pow", g_pow), { LoadF(B), ConstF(C) }), A);
|
||||
StoreF(cc.CreateCall(doublePow, { LoadF(B), ConstF(C) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitPOWF_KR()
|
||||
{
|
||||
StoreF(cc.CreateCall(GetNativeFunc<double, double, double>("__g_pow", g_pow), { ConstF(B), LoadF(C) }), A);
|
||||
StoreF(cc.CreateCall(doublePow, { ConstF(B), LoadF(C) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitMINF_RR()
|
||||
|
@ -814,7 +784,7 @@ void JitCompiler::EmitMAXF_RK()
|
|||
|
||||
void JitCompiler::EmitATAN2()
|
||||
{
|
||||
StoreF(cc.CreateFMul(cc.CreateCall(GetNativeFunc<double, double, double>("__g_atan2", g_atan2), { LoadF(B), LoadF(C) }), ConstValueF(180 / M_PI)), A);
|
||||
StoreF(cc.CreateFMul(cc.CreateCall(doubleAtan2, { LoadF(B), LoadF(C) }), ConstValueF(180 / M_PI)), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitFLOP()
|
||||
|
@ -832,38 +802,36 @@ void JitCompiler::EmitFLOP()
|
|||
v = cc.CreateFMul(v, ConstValueF(M_PI / 180));
|
||||
}
|
||||
|
||||
typedef double(*FuncPtr)(double);
|
||||
const char* funcname = "";
|
||||
FuncPtr func = nullptr;
|
||||
IRFunction* func = nullptr;
|
||||
switch (C)
|
||||
{
|
||||
default: I_Error("Unknown OP_FLOP subfunction");
|
||||
case FLOP_ABS: func = fabs; funcname = "__fabs"; break;
|
||||
case FLOP_EXP: func = g_exp; funcname = "__g_exp"; break;
|
||||
case FLOP_LOG: func = g_log; funcname = "__g_log"; break;
|
||||
case FLOP_LOG10: func = g_log10; funcname = "__g_log10"; break;
|
||||
case FLOP_SQRT: func = g_sqrt; funcname = "__g_sqrt"; break;
|
||||
case FLOP_CEIL: func = ceil; funcname = "__ceil"; break;
|
||||
case FLOP_FLOOR: func = floor; funcname = "__floor"; break;
|
||||
case FLOP_ACOS: func = g_acos; funcname = "__g_acos"; break;
|
||||
case FLOP_ASIN: func = g_asin; funcname = "__g_asin"; break;
|
||||
case FLOP_ATAN: func = g_atan; funcname = "__g_atan"; break;
|
||||
case FLOP_COS: func = g_cos; funcname = "__g_cos"; break;
|
||||
case FLOP_SIN: func = g_sin; funcname = "__g_sin"; break;
|
||||
case FLOP_TAN: func = g_tan; funcname = "__g_tan"; break;
|
||||
case FLOP_ACOS_DEG: func = g_acos; funcname = "__g_acos"; break;
|
||||
case FLOP_ASIN_DEG: func = g_asin; funcname = "__g_asin"; break;
|
||||
case FLOP_ATAN_DEG: func = g_atan; funcname = "__g_atan"; break;
|
||||
case FLOP_COS_DEG: func = g_cosdeg; funcname = "__g_cosdeg"; break;
|
||||
case FLOP_SIN_DEG: func = g_sindeg; funcname = "__g_sindeg"; break;
|
||||
case FLOP_TAN_DEG: func = g_tan; funcname = "__g_tan"; break;
|
||||
case FLOP_COSH: func = g_cosh; funcname = "__g_cosh"; break;
|
||||
case FLOP_SINH: func = g_sinh; funcname = "__g_sinh"; break;
|
||||
case FLOP_TANH: func = g_tanh; funcname = "__g_tanh"; break;
|
||||
case FLOP_ROUND: func = round; funcname = "__round"; break;
|
||||
case FLOP_ABS: func = doubleFabs; break;
|
||||
case FLOP_EXP: func = doubleExp; break;
|
||||
case FLOP_LOG: func = doubleLog; break;
|
||||
case FLOP_LOG10: func = doubleLog10; break;
|
||||
case FLOP_SQRT: func = doubleSqrt; break;
|
||||
case FLOP_CEIL: func = doubleCeil; break;
|
||||
case FLOP_FLOOR: func = doubleFloor; break;
|
||||
case FLOP_ACOS: func = doubleAcos; break;
|
||||
case FLOP_ASIN: func = doubleAsin; break;
|
||||
case FLOP_ATAN: func = doubleAtan; break;
|
||||
case FLOP_COS: func = doubleCos; break;
|
||||
case FLOP_SIN: func = doubleSin; break;
|
||||
case FLOP_TAN: func = doubleTan; break;
|
||||
case FLOP_ACOS_DEG: func = doubleAcos; break;
|
||||
case FLOP_ASIN_DEG: func = doubleAsin; break;
|
||||
case FLOP_ATAN_DEG: func = doubleAtan; break;
|
||||
case FLOP_COS_DEG: func = doubleCosDeg; break;
|
||||
case FLOP_SIN_DEG: func = doubleSinDeg; break;
|
||||
case FLOP_TAN_DEG: func = doubleTan; break;
|
||||
case FLOP_COSH: func = doubleCosh; break;
|
||||
case FLOP_SINH: func = doubleSinh; break;
|
||||
case FLOP_TANH: func = doubleTanh; break;
|
||||
case FLOP_ROUND: func = doubleRound; break;
|
||||
}
|
||||
|
||||
IRValue* result = cc.CreateCall(GetNativeFunc<double, double>(funcname, func), { v });
|
||||
IRValue* result = cc.CreateCall(func, { v });
|
||||
|
||||
if (C == FLOP_ACOS_DEG || C == FLOP_ASIN_DEG || C == FLOP_ATAN_DEG)
|
||||
{
|
||||
|
@ -1066,7 +1034,7 @@ void JitCompiler::EmitLENV2()
|
|||
IRValue* x = LoadF(B);
|
||||
IRValue* y = LoadF(B + 1);
|
||||
IRValue* dotproduct = cc.CreateFAdd(cc.CreateFMul(x, x), cc.CreateFMul(y, y));
|
||||
IRValue* len = cc.CreateCall(GetNativeFunc<double, double>("__g_sqrt", g_sqrt), { dotproduct });
|
||||
IRValue* len = cc.CreateCall(doubleSqrt, { dotproduct });
|
||||
StoreF(len, A);
|
||||
}
|
||||
|
||||
|
@ -1168,7 +1136,7 @@ void JitCompiler::EmitLENV3()
|
|||
IRValue* y = LoadF(B + 1);
|
||||
IRValue* z = LoadF(B + 2);
|
||||
IRValue* dotproduct = cc.CreateFAdd(cc.CreateFAdd(cc.CreateFMul(x, x), cc.CreateFMul(y, y)), cc.CreateFMul(z, z));
|
||||
IRValue* len = cc.CreateCall(GetNativeFunc<double, double>("__g_sqrt", g_sqrt), { dotproduct });
|
||||
IRValue* len = cc.CreateCall(doubleSqrt, { dotproduct });
|
||||
StoreF(len, A);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
|
||||
#include "jitintern.h"
|
||||
#include "v_video.h"
|
||||
#include "s_soundinternal.h"
|
||||
#include "texturemanager.h"
|
||||
#include "palutil.h"
|
||||
|
||||
void JitCompiler::EmitMOVE()
|
||||
{
|
||||
|
@ -16,7 +12,7 @@ void JitCompiler::EmitMOVEF()
|
|||
|
||||
void JitCompiler::EmitMOVES()
|
||||
{
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, FString*>("__CallAssignString", &JitCompiler::CallAssignString), { LoadS(A), LoadS(B) });
|
||||
cc.CreateCall(stringAssignmentOperator, { LoadS(A), LoadS(B) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitMOVEA()
|
||||
|
@ -37,140 +33,111 @@ void JitCompiler::EmitMOVEV3()
|
|||
StoreF(LoadF(B + 2), A + 2);
|
||||
}
|
||||
|
||||
static void CastI2S(FString *a, int b) { a->Format("%d", b); }
|
||||
static void CastU2S(FString *a, int b) { a->Format("%u", b); }
|
||||
static void CastF2S(FString *a, double b) { a->Format("%.5f", b); }
|
||||
static void CastV22S(FString *a, double b, double b1) { a->Format("(%.5f, %.5f)", b, b1); }
|
||||
static void CastV32S(FString *a, double b, double b1, double b2) { a->Format("(%.5f, %.5f, %.5f)", b, b1, b2); }
|
||||
static void CastP2S(FString *a, void *b) { if (b == nullptr) *a = "null"; else a->Format("%p", b); }
|
||||
static int CastS2I(FString *b) { return (int)b->ToLong(); }
|
||||
static double CastS2F(FString *b) { return b->ToDouble(); }
|
||||
static int CastS2N(FString *b) { return b->Len() == 0 ? NAME_None : FName(*b).GetIndex(); }
|
||||
static void CastN2S(FString *a, int b) { FName name = FName(ENamedName(b)); *a = name.IsValidName() ? name.GetChars() : ""; }
|
||||
static int CastS2Co(FString *b) { return V_GetColor(nullptr, *b); }
|
||||
static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); }
|
||||
static int CastS2So(FString *b) { return FSoundID(*b); }
|
||||
static void CastSo2S(FString* a, int b) { *a = soundEngine->GetSoundName(b); }
|
||||
static void CastSID2S(FString* a, unsigned int b) { VM_CastSpriteIDToString(a, b); }
|
||||
static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetGameTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); }
|
||||
|
||||
void JitCompiler::EmitCAST()
|
||||
{
|
||||
switch (C)
|
||||
{
|
||||
case CAST_I2F:
|
||||
StoreF(cc.CreateSIToFP(LoadD(B), ircontext->getDoubleTy()), A);
|
||||
StoreF(cc.CreateSIToFP(LoadD(B), doubleTy), A);
|
||||
break;
|
||||
case CAST_U2F:
|
||||
StoreF(cc.CreateUIToFP(LoadD(B), ircontext->getDoubleTy()), A);
|
||||
StoreF(cc.CreateUIToFP(LoadD(B), doubleTy), A);
|
||||
break;
|
||||
case CAST_F2I:
|
||||
StoreD(cc.CreateFPToSI(LoadF(B), ircontext->getInt32Ty()), A);
|
||||
StoreD(cc.CreateFPToSI(LoadF(B), int32Ty), A);
|
||||
break;
|
||||
case CAST_F2U:
|
||||
StoreD(cc.CreateFPToUI(LoadF(B), ircontext->getInt32Ty()), A);
|
||||
StoreD(cc.CreateFPToUI(LoadF(B), int32Ty), A);
|
||||
break;
|
||||
case CAST_I2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, int>("__CastI2S", CastI2S), { LoadS(A), LoadD(B) });
|
||||
cc.CreateCall(castI2S, { LoadS(A), LoadD(B) });
|
||||
break;
|
||||
case CAST_U2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, int>("__CastU2S", CastU2S), { LoadS(A), LoadD(B) });
|
||||
cc.CreateCall(castU2S, { LoadS(A), LoadD(B) });
|
||||
break;
|
||||
case CAST_F2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, double>("__CastF2S", CastF2S), { LoadS(A), LoadF(B) });
|
||||
cc.CreateCall(castF2S, { LoadS(A), LoadF(B) });
|
||||
break;
|
||||
case CAST_V22S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, double, double>("__CastV22S", CastV22S), { LoadS(A), LoadF(B), LoadF(B + 1) });
|
||||
cc.CreateCall(castV22S, { LoadS(A), LoadF(B), LoadF(B + 1) });
|
||||
break;
|
||||
case CAST_V32S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, double, double, double>("__CastV32S", CastV32S), { LoadS(A), LoadF(B), LoadF(B + 1), LoadF(B + 2) });
|
||||
cc.CreateCall(castV32S, { LoadS(A), LoadF(B), LoadF(B + 1), LoadF(B + 2) });
|
||||
break;
|
||||
case CAST_P2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, void*>("__CastP2S", CastP2S), { LoadS(A), LoadA(B) });
|
||||
cc.CreateCall(castP2S, { LoadS(A), LoadA(B) });
|
||||
break;
|
||||
case CAST_S2I:
|
||||
StoreD(cc.CreateCall(GetNativeFunc<int, FString*>("__CastS2I", CastS2I), { LoadS(B) }), A);
|
||||
StoreD(cc.CreateCall(castS2I, { LoadS(B) }), A);
|
||||
break;
|
||||
case CAST_S2F:
|
||||
StoreF(cc.CreateCall(GetNativeFunc<double, FString*>("__CastS2F", CastS2F), { LoadS(B) }), A);
|
||||
StoreF(cc.CreateCall(castS2F, { LoadS(B) }), A);
|
||||
break;
|
||||
case CAST_S2N:
|
||||
StoreD(cc.CreateCall(GetNativeFunc<int, FString*>("__CastS2N", CastS2N), { LoadS(B) }), A);
|
||||
StoreD(cc.CreateCall(castS2N, { LoadS(B) }), A);
|
||||
break;
|
||||
case CAST_N2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, int>("__CastN2S", CastN2S), { LoadS(A), LoadD(B) });
|
||||
cc.CreateCall(castN2S, { LoadS(A), LoadD(B) });
|
||||
break;
|
||||
case CAST_S2Co:
|
||||
StoreD(cc.CreateCall(GetNativeFunc<int, FString*>("__CastS2Co", CastS2Co), { LoadS(B) }), A);
|
||||
StoreD(cc.CreateCall(castS2Co, { LoadS(B) }), A);
|
||||
break;
|
||||
case CAST_Co2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, int>("__CastCo2S", CastCo2S), { LoadS(A), LoadD(B) });
|
||||
cc.CreateCall(castCo2S, { LoadS(A), LoadD(B) });
|
||||
break;
|
||||
case CAST_S2So:
|
||||
StoreD(cc.CreateCall(GetNativeFunc<int, FString*>("__CastS2So", CastS2So), { LoadS(B) }), A);
|
||||
StoreD(cc.CreateCall(castS2So, { LoadS(B) }), A);
|
||||
break;
|
||||
case CAST_So2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, int>("__CastSo2S", CastSo2S), { LoadS(A), LoadD(B) });
|
||||
cc.CreateCall(castSo2S, { LoadS(A), LoadD(B) });
|
||||
break;
|
||||
case CAST_SID2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, unsigned int>("__CastSID2S", CastSID2S), { LoadS(A), LoadD(B) });
|
||||
cc.CreateCall(castSID2S, { LoadS(A), LoadD(B) });
|
||||
break;
|
||||
case CAST_TID2S:
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, int>("__CastTID2S", CastTID2S), { LoadS(A), LoadD(B) });
|
||||
cc.CreateCall(castTID2S, { LoadS(A), LoadD(B) });
|
||||
break;
|
||||
default:
|
||||
I_Error("Unknown OP_CAST type\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int CastB_S(FString *s) { return s->Len() > 0; }
|
||||
|
||||
void JitCompiler::EmitCASTB()
|
||||
{
|
||||
if (C == CASTB_I)
|
||||
{
|
||||
StoreD(cc.CreateZExt(cc.CreateICmpNE(LoadD(B), ConstValueD(0)), ircontext->getInt32Ty()), A);
|
||||
StoreD(cc.CreateZExt(cc.CreateICmpNE(LoadD(B), ConstValueD(0)), int32Ty), A);
|
||||
}
|
||||
else if (C == CASTB_F)
|
||||
{
|
||||
StoreD(cc.CreateZExt(cc.CreateFCmpUNE(LoadF(B), ConstValueF(0.0)), ircontext->getInt32Ty()), A);
|
||||
StoreD(cc.CreateZExt(cc.CreateFCmpUNE(LoadF(B), ConstValueF(0.0)), int32Ty), A);
|
||||
}
|
||||
else if (C == CASTB_A)
|
||||
{
|
||||
StoreD(cc.CreateZExt(cc.CreateICmpNE(LoadA(B), ConstValueA(0)), ircontext->getInt32Ty()), A);
|
||||
StoreD(cc.CreateZExt(cc.CreateICmpNE(LoadA(B), ConstValueA(0)), int32Ty), A);
|
||||
}
|
||||
else
|
||||
{
|
||||
StoreD(cc.CreateCall(GetNativeFunc<int, FString* >("__CastB_S", CastB_S), { LoadS(B) }), A);
|
||||
StoreD(cc.CreateCall(castB_S, { LoadS(B) }), A);
|
||||
}
|
||||
}
|
||||
|
||||
static DObject *DynCast(DObject *obj, PClass *cls)
|
||||
{
|
||||
return (obj && obj->IsKindOf(cls)) ? obj : nullptr;
|
||||
}
|
||||
|
||||
void JitCompiler::EmitDYNCAST_R()
|
||||
{
|
||||
StoreA(cc.CreateCall(GetNativeFunc<DObject*, DObject*, PClass*>("__DynCast", DynCast), { LoadA(B), LoadA(C) }), A);
|
||||
StoreA(cc.CreateCall(dynCast, { LoadA(B), LoadA(C) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitDYNCAST_K()
|
||||
{
|
||||
StoreA(cc.CreateCall(GetNativeFunc<DObject*, DObject*, PClass*>("__DynCast", DynCast), { LoadA(B), ConstA(C) }), A);
|
||||
}
|
||||
|
||||
static PClass *DynCastC(PClass *cls1, PClass *cls2)
|
||||
{
|
||||
return (cls1 && cls1->IsDescendantOf(cls2)) ? cls1 : nullptr;
|
||||
StoreA(cc.CreateCall(dynCast, { LoadA(B), ConstA(C) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitDYNCASTC_R()
|
||||
{
|
||||
StoreA(cc.CreateCall(GetNativeFunc<PClass*, PClass*, PClass*>("__DynCastC", DynCastC), { LoadA(B), LoadA(C) }), A);
|
||||
StoreA(cc.CreateCall(dynCastC, { LoadA(B), LoadA(C) }), A);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitDYNCASTC_K()
|
||||
{
|
||||
StoreA(cc.CreateCall(GetNativeFunc<PClass*, PClass*, PClass*>("__DynCastC", DynCastC), { LoadA(B), ConstA(C) }), A);
|
||||
StoreA(cc.CreateCall(dynCastC, { LoadA(B), ConstA(C) }), A);
|
||||
}
|
||||
|
|
|
@ -64,27 +64,25 @@ void JitCompiler::EmitSDP_R()
|
|||
void JitCompiler::EmitSS()
|
||||
{
|
||||
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, FString*>("__CallAssignString", &JitCompiler::CallAssignString), { OffsetPtr(LoadA(A), ConstD(C)), LoadS(B) });
|
||||
cc.CreateCall(stringAssignmentOperator, { OffsetPtr(LoadA(A), ConstD(C)), LoadS(B) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSS_R()
|
||||
{
|
||||
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||
cc.CreateCall(GetNativeFunc<void, FString*, FString*>("__CallAssignString", &JitCompiler::CallAssignString), { OffsetPtr(LoadA(A), LoadD(C)), LoadS(B) });
|
||||
cc.CreateCall(stringAssignmentOperator, { OffsetPtr(LoadA(A), LoadD(C)), LoadS(B) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSO()
|
||||
{
|
||||
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||
typedef void(*FuncPtr)(DObject*);
|
||||
cc.CreateCall(GetNativeFunc<void, DObject*>("__WriteBarrier", static_cast<FuncPtr>(GC::WriteBarrier)), { OffsetPtr(LoadA(A), ConstD(C)), LoadA(B) });
|
||||
cc.CreateCall(writeBarrier, { OffsetPtr(LoadA(A), ConstD(C)), LoadA(B) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSO_R()
|
||||
{
|
||||
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||
typedef void(*FuncPtr)(DObject*);
|
||||
cc.CreateCall(GetNativeFunc<void, DObject*>("__WriteBarrier", static_cast<FuncPtr>(GC::WriteBarrier)), { OffsetPtr(LoadA(A), LoadD(C)), LoadA(B) });
|
||||
cc.CreateCall(writeBarrier, { OffsetPtr(LoadA(A), LoadD(C)), LoadA(B) });
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSP()
|
||||
|
|
|
@ -34,8 +34,6 @@ public:
|
|||
|
||||
IRFunction* Codegen();
|
||||
|
||||
// VMScriptFunction* GetScriptFunction() { return sfunc; }
|
||||
|
||||
private:
|
||||
// Declare EmitXX functions for the opcodes:
|
||||
#define xx(op, name, mode, alt, kreg, ktype) void Emit##op();
|
||||
|
@ -59,9 +57,6 @@ private:
|
|||
void EmitThrowException(EVMAbortException reason);
|
||||
IRBasicBlock* EmitThrowExceptionLabel(EVMAbortException reason);
|
||||
|
||||
static void ThrowArrayOutOfBounds(int index, int size);
|
||||
static void ThrowException(int reason);
|
||||
|
||||
void Setup();
|
||||
void CreateRegisters();
|
||||
void IncrementVMCalls();
|
||||
|
@ -76,77 +71,9 @@ private:
|
|||
|
||||
IRFunctionType* GetFuncSignature();
|
||||
|
||||
template<typename T> IRType* GetIRType() { static_assert(std::is_pointer<T>::value, "Unsupported type"); return ircontext->getInt8PtrTy(); }
|
||||
template<> IRType* GetIRType<void>() { return ircontext->getVoidTy(); }
|
||||
template<> IRType* GetIRType<char>() { return ircontext->getInt8Ty(); }
|
||||
template<> IRType* GetIRType<unsigned char>() { return ircontext->getInt8Ty(); }
|
||||
template<> IRType* GetIRType<short>() { return ircontext->getInt16Ty(); }
|
||||
template<> IRType* GetIRType<unsigned short>() { return ircontext->getInt16Ty(); }
|
||||
template<> IRType* GetIRType<int>() { return ircontext->getInt32Ty(); }
|
||||
template<> IRType* GetIRType<unsigned int>() { return ircontext->getInt32Ty(); }
|
||||
template<> IRType* GetIRType<long long>() { return ircontext->getInt64Ty(); }
|
||||
template<> IRType* GetIRType<unsigned long long>() { return ircontext->getInt64Ty(); }
|
||||
template<> IRType* GetIRType<float>() { return ircontext->getFloatTy(); }
|
||||
template<> IRType* GetIRType<double>() { return ircontext->getDoubleTy(); }
|
||||
|
||||
template<typename RetType>
|
||||
IRFunctionType* GetFunctionType0() { return ircontext->getFunctionType(GetIRType<RetType>(), { }); }
|
||||
|
||||
template<typename RetType, typename P1>
|
||||
IRFunctionType* GetFunctionType1() { return ircontext->getFunctionType(GetIRType<RetType>(), { GetIRType<P1>() }); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2>
|
||||
IRFunctionType* GetFunctionType2() { return ircontext->getFunctionType(GetIRType<RetType>(), { GetIRType<P1>(), GetIRType<P2>() }); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3>
|
||||
IRFunctionType* GetFunctionType3() { return ircontext->getFunctionType(GetIRType<RetType>(), { GetIRType<P1>(), GetIRType<P2>(), GetIRType<P3>() }); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3, typename P4>
|
||||
IRFunctionType* GetFunctionType4() { return ircontext->getFunctionType(GetIRType<RetType>(), { GetIRType<P1>(), GetIRType<P2>(), GetIRType<P3>(), GetIRType<P4>() }); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||
IRFunctionType* GetFunctionType5() { return ircontext->getFunctionType(GetIRType<RetType>(), { GetIRType<P1>(), GetIRType<P2>(), GetIRType<P3>(), GetIRType<P4>(), GetIRType<P5>() }); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
|
||||
IRFunctionType* GetFunctionType6() { return ircontext->getFunctionType(GetIRType<RetType>(), { GetIRType<P1>(), GetIRType<P2>(), GetIRType<P3>(), GetIRType<P4>(), GetIRType<P5>(), GetIRType<P6>() }); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
|
||||
IRFunctionType* GetFunctionType7() { return ircontext->getFunctionType(GetIRType<RetType>(), { GetIRType<P1>(), GetIRType<P2>(), GetIRType<P3>(), GetIRType<P4>(), GetIRType<P5>(), GetIRType<P6>(), GetIRType<P7>() }); }
|
||||
|
||||
IRFunction* GetNativeFunc(const char* name, void* ptr, IRFunctionType* functype)
|
||||
{
|
||||
IRFunction* func = ircontext->getFunction(name);
|
||||
if (!func)
|
||||
{
|
||||
func = ircontext->createFunction(functype, name);
|
||||
ircontext->addGlobalMapping(func, ptr);
|
||||
}
|
||||
return func;
|
||||
}
|
||||
|
||||
template<typename RetType>
|
||||
IRFunction* GetNativeFunc(const char* name, RetType(*func)()) { return GetNativeFunc(name, func, GetFunctionType0<RetType>()); }
|
||||
|
||||
template<typename RetType, typename P1>
|
||||
IRFunction* GetNativeFunc(const char* name, RetType(*func)(P1 p1)) { return GetNativeFunc(name, func, GetFunctionType1<RetType, P1>()); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2>
|
||||
IRFunction* GetNativeFunc(const char* name, RetType(*func)(P1 p1, P2 p2)) { return GetNativeFunc(name, func, GetFunctionType2<RetType, P1, P2>()); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3>
|
||||
IRFunction* GetNativeFunc(const char* name, RetType(*func)(P1 p1, P2 p2, P3 p3)) { return GetNativeFunc(name, func, GetFunctionType3<RetType, P1, P2, P3>()); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3, typename P4>
|
||||
IRFunction* GetNativeFunc(const char* name, RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4)) { return GetNativeFunc(name, func, GetFunctionType4<RetType, P1, P2, P3, P4>()); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||
IRFunction* GetNativeFunc(const char* name, RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)) { return GetNativeFunc(name, func, GetFunctionType5<RetType, P1, P2, P3, P4, P5>()); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
|
||||
IRFunction* GetNativeFunc(const char* name, RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)) { return GetNativeFunc(name, func, GetFunctionType6<RetType, P1, P2, P3, P4, P5, P6>()); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
|
||||
IRFunction* GetNativeFunc(const char* name, RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)) { return GetNativeFunc(name, func, GetFunctionType7<RetType, P1, P2, P3, P4, P5, P6, P7>()); }
|
||||
void GetTypes();
|
||||
void CreateNativeFunctions();
|
||||
IRFunction* CreateNativeFunction(IRType* returnType, std::vector<IRType*> args, const char* name, void* ptr);
|
||||
|
||||
template <typename Func>
|
||||
void EmitComparisonOpcode(Func jmpFunc)
|
||||
|
@ -167,13 +94,13 @@ private:
|
|||
IRValue* LoadA(int index) { return cc.CreateLoad(regA[index]); }
|
||||
IRValue* LoadS(int index) { return cc.CreateLoad(regS[index]); }
|
||||
IRValue* ConstD(int index) { return ircontext->getConstantInt(konstd[index]); }
|
||||
IRValue* ConstF(int index) { return ircontext->getConstantFloat(ircontext->getDoubleTy(), konstf[index]); }
|
||||
IRValue* ConstA(int index) { return ircontext->getConstantInt(ircontext->getInt8PtrTy(), (uint64_t)konsta[index].v); }
|
||||
IRValue* ConstS(int index) { return ircontext->getConstantInt(ircontext->getInt8PtrTy(), (uint64_t)&konsts[index]); }
|
||||
IRValue* ConstF(int index) { return ircontext->getConstantFloat(doubleTy, konstf[index]); }
|
||||
IRValue* ConstA(int index) { return ircontext->getConstantInt(int8PtrTy, (uint64_t)konsta[index].v); }
|
||||
IRValue* ConstS(int index) { return ircontext->getConstantInt(int8PtrTy, (uint64_t)&konsts[index]); }
|
||||
IRValue* ConstValueD(int value) { return ircontext->getConstantInt(value); }
|
||||
IRValue* ConstValueF(double value) { return ircontext->getConstantFloat(ircontext->getDoubleTy(), value); }
|
||||
IRValue* ConstValueA(void* value) { return ircontext->getConstantInt(ircontext->getInt8PtrTy(), (uint64_t)value); }
|
||||
IRValue* ConstValueS(void* value) { return ircontext->getConstantInt(ircontext->getInt8PtrTy(), (uint64_t)value); }
|
||||
IRValue* ConstValueF(double value) { return ircontext->getConstantFloat(doubleTy, value); }
|
||||
IRValue* ConstValueA(void* value) { return ircontext->getConstantInt(int8PtrTy, (uint64_t)value); }
|
||||
IRValue* ConstValueS(void* value) { return ircontext->getConstantInt(int8PtrTy, (uint64_t)value); }
|
||||
void StoreD(IRValue* value, int index) { cc.CreateStore(value, regD[index]); }
|
||||
void StoreF(IRValue* value, int index) { cc.CreateStore(value, regF[index]); }
|
||||
void StoreA(IRValue* value, int index) { cc.CreateStore(value, regA[index]); }
|
||||
|
@ -181,30 +108,28 @@ private:
|
|||
|
||||
IRValue* OffsetPtr(IRValue* ptr, IRValue* offset) { return cc.CreateGEP(ptr, { offset }); }
|
||||
IRValue* OffsetPtr(IRValue* ptr, int offset) { return cc.CreateGEP(ptr, { ircontext->getConstantInt(offset) }); }
|
||||
IRValue* ToInt8Ptr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt8PtrTy()); }
|
||||
IRValue* ToInt8Ptr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt8PtrTy()); }
|
||||
IRValue* ToInt16Ptr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt16PtrTy()); }
|
||||
IRValue* ToInt32Ptr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt32PtrTy()); }
|
||||
IRValue* ToInt32Ptr(IRValue* ptr) { return cc.CreateBitCast(ptr, ircontext->getInt32PtrTy()); }
|
||||
IRValue* ToInt32Ptr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt32PtrTy()); }
|
||||
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* ToInt8PtrPtr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt8PtrTy()->getPointerTo(ircontext)); }
|
||||
IRValue* ToInt8PtrPtr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), ircontext->getInt8PtrTy()->getPointerTo(ircontext)); }
|
||||
IRValue* ToInt8PtrPtr(IRValue* ptr) { return cc.CreateBitCast(ptr, ircontext->getInt8PtrTy()->getPointerTo(ircontext)); }
|
||||
IRValue* Trunc8(IRValue* value) { return cc.CreateTrunc(value, ircontext->getInt8Ty()); }
|
||||
IRValue* Trunc16(IRValue* value) { return cc.CreateTrunc(value, ircontext->getInt16Ty()); }
|
||||
IRValue* FPTrunc(IRValue* value) { return cc.CreateFPTrunc(value, ircontext->getFloatTy()); }
|
||||
IRValue* ZExt(IRValue* value) { return cc.CreateZExt(value, ircontext->getInt32Ty()); }
|
||||
IRValue* SExt(IRValue* value) { return cc.CreateSExt(value, ircontext->getInt32Ty()); }
|
||||
IRValue* FPExt(IRValue* value) { return cc.CreateFPExt(value, ircontext->getDoubleTy()); }
|
||||
IRValue* ToInt8Ptr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), int8PtrTy); }
|
||||
IRValue* ToInt8Ptr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), int8PtrTy); }
|
||||
IRValue* ToInt16Ptr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), int16PtrTy); }
|
||||
IRValue* ToInt32Ptr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), int32PtrTy); }
|
||||
IRValue* ToInt32Ptr(IRValue* ptr) { return cc.CreateBitCast(ptr, int32PtrTy); }
|
||||
IRValue* ToInt32Ptr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), int32PtrTy); }
|
||||
IRValue* ToFloatPtr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), floatPtrTy); }
|
||||
IRValue* ToDoublePtr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), doublePtrTy); }
|
||||
IRValue* ToDoublePtr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), doublePtrTy); }
|
||||
IRValue* ToDoublePtr(IRValue* ptr) { return cc.CreateBitCast(ptr, doublePtrTy); }
|
||||
IRValue* ToInt8PtrPtr(IRValue* ptr, IRValue* offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), int8PtrPtrTy); }
|
||||
IRValue* ToInt8PtrPtr(IRValue* ptr, int offset) { return cc.CreateBitCast(OffsetPtr(ptr, offset), int8PtrPtrTy); }
|
||||
IRValue* ToInt8PtrPtr(IRValue* ptr) { return cc.CreateBitCast(ptr, int8PtrPtrTy); }
|
||||
IRValue* Trunc8(IRValue* value) { return cc.CreateTrunc(value, int8Ty); }
|
||||
IRValue* Trunc16(IRValue* value) { return cc.CreateTrunc(value, int16Ty); }
|
||||
IRValue* FPTrunc(IRValue* value) { return cc.CreateFPTrunc(value, floatTy); }
|
||||
IRValue* ZExt(IRValue* value) { return cc.CreateZExt(value, int32Ty); }
|
||||
IRValue* SExt(IRValue* value) { return cc.CreateSExt(value, int32Ty); }
|
||||
IRValue* FPExt(IRValue* value) { return cc.CreateFPExt(value, doubleTy); }
|
||||
void Store(IRValue* value, IRValue* ptr) { cc.CreateStore(value, ptr); }
|
||||
IRValue* Load(IRValue* ptr) { return cc.CreateLoad(ptr); }
|
||||
|
||||
static void CallAssignString(FString* to, FString* from) { *to = *from; }
|
||||
|
||||
VMScriptFunction* sfunc = nullptr;
|
||||
|
||||
IRContext* ircontext = nullptr;
|
||||
|
@ -242,4 +167,74 @@ private:
|
|||
int offsetExtra = 0;
|
||||
|
||||
TArray<JitLabel> labels;
|
||||
|
||||
IRType* voidTy = nullptr;
|
||||
IRType* int8Ty = nullptr;
|
||||
IRType* int8PtrTy = nullptr;
|
||||
IRType* int8PtrPtrTy = nullptr;
|
||||
IRType* int16Ty = nullptr;
|
||||
IRType* int16PtrTy = nullptr;
|
||||
IRType* int32Ty = nullptr;
|
||||
IRType* int32PtrTy = nullptr;
|
||||
IRType* int64Ty = nullptr;
|
||||
IRType* floatTy = nullptr;
|
||||
IRType* floatPtrTy = nullptr;
|
||||
IRType* doubleTy = nullptr;
|
||||
IRType* doublePtrTy = nullptr;
|
||||
|
||||
IRFunction* validateCall = nullptr;
|
||||
IRFunction* setReturnString = nullptr;
|
||||
IRFunction* createFullVMFrame = nullptr;
|
||||
IRFunction* popFullVMFrame = nullptr;
|
||||
IRFunction* throwException = nullptr;
|
||||
IRFunction* throwArrayOutOfBounds = nullptr;
|
||||
IRFunction* stringAssignmentOperator = nullptr;
|
||||
IRFunction* stringAssignmentOperatorCStr = nullptr;
|
||||
IRFunction* stringPlusOperator = nullptr;
|
||||
IRFunction* stringCompare = nullptr;
|
||||
IRFunction* stringCompareNoCase = nullptr;
|
||||
IRFunction* stringLength = nullptr;
|
||||
IRFunction* readBarrier = nullptr;
|
||||
IRFunction* writeBarrier = nullptr;
|
||||
IRFunction* doubleModF = nullptr;
|
||||
IRFunction* doublePow = nullptr;
|
||||
IRFunction* doubleAtan2 = nullptr;
|
||||
IRFunction* doubleFabs = nullptr;
|
||||
IRFunction* doubleExp = nullptr;
|
||||
IRFunction* doubleLog = nullptr;
|
||||
IRFunction* doubleLog10 = nullptr;
|
||||
IRFunction* doubleSqrt = nullptr;
|
||||
IRFunction* doubleCeil = nullptr;
|
||||
IRFunction* doubleFloor = nullptr;
|
||||
IRFunction* doubleAcos = nullptr;
|
||||
IRFunction* doubleAsin = nullptr;
|
||||
IRFunction* doubleAtan = nullptr;
|
||||
IRFunction* doubleCos = nullptr;
|
||||
IRFunction* doubleSin = nullptr;
|
||||
IRFunction* doubleTan = nullptr;
|
||||
IRFunction* doubleCosDeg = nullptr;
|
||||
IRFunction* doubleSinDeg = nullptr;
|
||||
IRFunction* doubleCosh = nullptr;
|
||||
IRFunction* doubleSinh = nullptr;
|
||||
IRFunction* doubleTanh = nullptr;
|
||||
IRFunction* doubleRound = nullptr;
|
||||
IRFunction* castI2S = nullptr;
|
||||
IRFunction* castU2S = nullptr;
|
||||
IRFunction* castF2S = nullptr;
|
||||
IRFunction* castV22S = nullptr;
|
||||
IRFunction* castV32S = nullptr;
|
||||
IRFunction* castP2S = nullptr;
|
||||
IRFunction* castS2I = nullptr;
|
||||
IRFunction* castS2F = nullptr;
|
||||
IRFunction* castS2N = nullptr;
|
||||
IRFunction* castN2S = nullptr;
|
||||
IRFunction* castS2Co = nullptr;
|
||||
IRFunction* castCo2S = nullptr;
|
||||
IRFunction* castS2So = nullptr;
|
||||
IRFunction* castSo2S = nullptr;
|
||||
IRFunction* castSID2S = nullptr;
|
||||
IRFunction* castTID2S = nullptr;
|
||||
IRFunction* castB_S = nullptr;
|
||||
IRFunction* dynCast = nullptr;
|
||||
IRFunction* dynCastC = nullptr;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue