Revert "AsmJit update"
This reverts commit 747b3dfcfe.
# Conflicts:
# libraries/asmjit/asmjit/core/compiler.h
This had to be reverted because it breaks exception handling which is a critical problem.
With the updated code any exception thrown inside code that had a JITed call stack would crash.
This commit is contained in:
parent
2e7af1338c
commit
523fd0bf3a
166 changed files with 45117 additions and 51918 deletions
|
|
@ -17,13 +17,6 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
|
||||
using namespace asmjit;
|
||||
StringLogger logger;
|
||||
|
||||
// Keep annotations to make it easier to process the debug log in case of error.
|
||||
logger.setFlags(
|
||||
FormatOptions::kFlagDebugRA |
|
||||
FormatOptions::kFlagRegCasts |
|
||||
FormatOptions::kFlagAnnotations);
|
||||
|
||||
try
|
||||
{
|
||||
ThrowingErrorHandler errorHandler;
|
||||
|
|
@ -58,11 +51,11 @@ void JitDumpLog(FILE *file, VMScriptFunction *sfunc)
|
|||
JitCompiler compiler(&code, sfunc);
|
||||
compiler.Codegen();
|
||||
|
||||
fwrite(logger.data(), logger.dataSize(), 1, file);
|
||||
fwrite(logger.getString(), logger.getLength(), 1, file);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
fwrite(logger.data(), logger.dataSize(), 1, file);
|
||||
fwrite(logger.getString(), logger.getLength(), 1, file);
|
||||
|
||||
FString err;
|
||||
err.Format("Unexpected JIT error: %s\n", e.what());
|
||||
|
|
@ -76,7 +69,7 @@ void JitDumpLog(FILE *file, VMScriptFunction *sfunc)
|
|||
static void OutputJitLog(const asmjit::StringLogger &logger)
|
||||
{
|
||||
// Write line by line since I_FatalError seems to cut off long strings
|
||||
const char *pos = logger.data();
|
||||
const char *pos = logger.getString();
|
||||
const char *end = pos;
|
||||
while (*end)
|
||||
{
|
||||
|
|
@ -101,7 +94,7 @@ static const char *OpNames[NUM_OPS] =
|
|||
#undef xx
|
||||
};
|
||||
|
||||
asmjit::FuncNode *JitCompiler::Codegen()
|
||||
asmjit::CCFunc *JitCompiler::Codegen()
|
||||
{
|
||||
Setup();
|
||||
|
||||
|
|
@ -136,7 +129,7 @@ asmjit::FuncNode *JitCompiler::Codegen()
|
|||
cc.comment(lineinfo.GetChars(), lineinfo.Len());
|
||||
}
|
||||
|
||||
labels[i].cursor = cc.cursor();
|
||||
labels[i].cursor = cc.getCursor();
|
||||
ResetTemp();
|
||||
EmitOpcode();
|
||||
|
||||
|
|
@ -148,7 +141,7 @@ asmjit::FuncNode *JitCompiler::Codegen()
|
|||
cc.endFunc();
|
||||
cc.finalize();
|
||||
|
||||
auto code = cc.code();
|
||||
auto code = cc.getCode ();
|
||||
for (unsigned int j = 0; j < LineInfo.Size (); j++)
|
||||
{
|
||||
auto info = LineInfo[j];
|
||||
|
|
@ -158,7 +151,7 @@ asmjit::FuncNode *JitCompiler::Codegen()
|
|||
continue;
|
||||
}
|
||||
|
||||
info.InstructionIndex = code->labelOffset(info.Label);
|
||||
info.InstructionIndex = code->getLabelOffset (info.Label);
|
||||
|
||||
LineInfo[j] = info;
|
||||
}
|
||||
|
|
@ -184,7 +177,7 @@ void JitCompiler::EmitOpcode()
|
|||
|
||||
void JitCompiler::BindLabels()
|
||||
{
|
||||
asmjit::BaseNode *cursor = cc.cursor();
|
||||
asmjit::CBNode *cursor = cc.getCursor();
|
||||
unsigned int size = labels.Size();
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
{
|
||||
|
|
@ -202,7 +195,7 @@ void JitCompiler::CheckVMFrame()
|
|||
{
|
||||
if (!vmframeAllocated)
|
||||
{
|
||||
auto cursor = cc.cursor();
|
||||
auto cursor = cc.getCursor();
|
||||
cc.setCursor(vmframeCursor);
|
||||
|
||||
auto vmstack = cc.newStack(sfunc->StackSize, 16, "vmstack");
|
||||
|
|
@ -214,11 +207,11 @@ void JitCompiler::CheckVMFrame()
|
|||
}
|
||||
}
|
||||
|
||||
asmjit::x86::Gp JitCompiler::GetCallReturns()
|
||||
asmjit::X86Gp JitCompiler::GetCallReturns()
|
||||
{
|
||||
if (!callReturnsAllocated)
|
||||
{
|
||||
auto cursor = cc.cursor();
|
||||
auto cursor = cc.getCursor();
|
||||
cc.setCursor(callReturnsCursor);
|
||||
auto stackalloc = cc.newStack(sizeof(VMReturn) * MAX_RETURNS, alignof(VMReturn), "stackalloc");
|
||||
callReturns = cc.newIntPtr("callReturns");
|
||||
|
|
@ -252,14 +245,14 @@ void JitCompiler::Setup()
|
|||
ret = cc.newIntPtr("ret"); // VMReturn *ret
|
||||
numret = cc.newInt32("numret"); // int numret
|
||||
|
||||
func = cc.addFunc(FuncSignatureT<int, VMFunction *, void *, int, void *, int>());
|
||||
func = cc.addFunc(FuncSignature5<int, VMFunction *, void *, int, void *, int>());
|
||||
cc.setArg(0, unusedFunc);
|
||||
cc.setArg(1, args);
|
||||
cc.setArg(2, numargs);
|
||||
cc.setArg(3, ret);
|
||||
cc.setArg(4, numret);
|
||||
|
||||
callReturnsCursor = cc.cursor();
|
||||
callReturnsCursor = cc.getCursor();
|
||||
|
||||
konstd = sfunc->KonstD;
|
||||
konstf = sfunc->KonstF;
|
||||
|
|
@ -299,7 +292,7 @@ void JitCompiler::SetupSimpleFrame()
|
|||
|
||||
// This is a simple frame with no constructors or destructors. Allocate it on the stack ourselves.
|
||||
|
||||
vmframeCursor = cc.cursor();
|
||||
vmframeCursor = cc.getCursor();
|
||||
|
||||
int argsPos = 0;
|
||||
int regd = 0, regf = 0, rega = 0;
|
||||
|
|
@ -367,7 +360,7 @@ void JitCompiler::SetupFullVMFrame()
|
|||
stack = cc.newIntPtr("stack");
|
||||
auto allocFrame = CreateCall<VMFrameStack *, VMScriptFunction *, VMValue *, int>(CreateFullVMFrame);
|
||||
allocFrame->setRet(0, stack);
|
||||
allocFrame->setArg(0, imm(sfunc));
|
||||
allocFrame->setArg(0, imm_ptr(sfunc));
|
||||
allocFrame->setArg(1, args);
|
||||
allocFrame->setArg(2, numargs);
|
||||
|
||||
|
|
@ -408,7 +401,7 @@ void JitCompiler::IncrementVMCalls()
|
|||
// VMCalls[0]++
|
||||
auto vmcallsptr = newTempIntPtr();
|
||||
auto vmcalls = newTempInt32();
|
||||
cc.mov(vmcallsptr, asmjit::imm(VMCalls));
|
||||
cc.mov(vmcallsptr, asmjit::imm_ptr(VMCalls));
|
||||
cc.mov(vmcalls, asmjit::x86::dword_ptr(vmcallsptr));
|
||||
cc.add(vmcalls, (int)1);
|
||||
cc.mov(asmjit::x86::dword_ptr(vmcallsptr), vmcalls);
|
||||
|
|
@ -467,7 +460,7 @@ void JitCompiler::EmitThrowException(EVMAbortException reason)
|
|||
asmjit::Label JitCompiler::EmitThrowExceptionLabel(EVMAbortException reason)
|
||||
{
|
||||
auto label = cc.newLabel();
|
||||
auto cursor = cc.cursor();
|
||||
auto cursor = cc.getCursor();
|
||||
cc.bind(label);
|
||||
EmitThrowException(reason);
|
||||
cc.setCursor(cursor);
|
||||
|
|
@ -480,7 +473,7 @@ asmjit::Label JitCompiler::EmitThrowExceptionLabel(EVMAbortException reason)
|
|||
return label;
|
||||
}
|
||||
|
||||
asmjit::x86::Gp JitCompiler::CheckRegD(int r0, int r1)
|
||||
asmjit::X86Gp JitCompiler::CheckRegD(int r0, int r1)
|
||||
{
|
||||
if (r0 != r1)
|
||||
{
|
||||
|
|
@ -494,7 +487,7 @@ asmjit::x86::Gp JitCompiler::CheckRegD(int r0, int r1)
|
|||
}
|
||||
}
|
||||
|
||||
asmjit::x86::Xmm JitCompiler::CheckRegF(int r0, int r1)
|
||||
asmjit::X86Xmm JitCompiler::CheckRegF(int r0, int r1)
|
||||
{
|
||||
if (r0 != r1)
|
||||
{
|
||||
|
|
@ -508,7 +501,7 @@ asmjit::x86::Xmm JitCompiler::CheckRegF(int r0, int r1)
|
|||
}
|
||||
}
|
||||
|
||||
asmjit::x86::Xmm JitCompiler::CheckRegF(int r0, int r1, int r2)
|
||||
asmjit::X86Xmm JitCompiler::CheckRegF(int r0, int r1, int r2)
|
||||
{
|
||||
if (r0 != r1 && r0 != r2)
|
||||
{
|
||||
|
|
@ -522,7 +515,7 @@ asmjit::x86::Xmm JitCompiler::CheckRegF(int r0, int r1, int r2)
|
|||
}
|
||||
}
|
||||
|
||||
asmjit::x86::Xmm JitCompiler::CheckRegF(int r0, int r1, int r2, int r3)
|
||||
asmjit::X86Xmm JitCompiler::CheckRegF(int r0, int r1, int r2, int r3)
|
||||
{
|
||||
if (r0 != r1 && r0 != r2 && r0 != r3)
|
||||
{
|
||||
|
|
@ -536,7 +529,7 @@ asmjit::x86::Xmm JitCompiler::CheckRegF(int r0, int r1, int r2, int r3)
|
|||
}
|
||||
}
|
||||
|
||||
asmjit::x86::Gp JitCompiler::CheckRegS(int r0, int r1)
|
||||
asmjit::X86Gp JitCompiler::CheckRegS(int r0, int r1)
|
||||
{
|
||||
if (r0 != r1)
|
||||
{
|
||||
|
|
@ -550,7 +543,7 @@ asmjit::x86::Gp JitCompiler::CheckRegS(int r0, int r1)
|
|||
}
|
||||
}
|
||||
|
||||
asmjit::x86::Gp JitCompiler::CheckRegA(int r0, int r1)
|
||||
asmjit::X86Gp JitCompiler::CheckRegA(int r0, int r1)
|
||||
{
|
||||
if (r0 != r1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,14 +61,14 @@ void JitCompiler::EmitCALL_K()
|
|||
else
|
||||
{
|
||||
auto ptr = newTempIntPtr();
|
||||
cc.mov(ptr, asmjit::imm(target));
|
||||
cc.mov(ptr, asmjit::imm_ptr(target));
|
||||
EmitVMCall(ptr, target);
|
||||
}
|
||||
|
||||
pc += C; // Skip RESULTs
|
||||
}
|
||||
|
||||
void JitCompiler::EmitVMCall(asmjit::x86::Gp vmfunc, VMFunction *target)
|
||||
void JitCompiler::EmitVMCall(asmjit::X86Gp vmfunc, VMFunction *target)
|
||||
{
|
||||
using namespace asmjit;
|
||||
|
||||
|
|
@ -83,14 +83,14 @@ void JitCompiler::EmitVMCall(asmjit::x86::Gp vmfunc, VMFunction *target)
|
|||
|
||||
FillReturns(pc + 1, C);
|
||||
|
||||
x86::Gp paramsptr = newTempIntPtr();
|
||||
X86Gp paramsptr = newTempIntPtr();
|
||||
cc.lea(paramsptr, x86::ptr(vmframe, offsetParams));
|
||||
|
||||
auto scriptcall = newTempIntPtr();
|
||||
cc.mov(scriptcall, x86::ptr(vmfunc, myoffsetof(VMScriptFunction, ScriptCall)));
|
||||
|
||||
auto result = newResultInt32();
|
||||
auto call = cc.call(scriptcall, FuncSignatureT<int, VMFunction *, VMValue*, int, VMReturn*, int>());
|
||||
auto call = cc.call(scriptcall, FuncSignature5<int, VMFunction *, VMValue*, int, VMReturn*, int>());
|
||||
call->setRet(0, result);
|
||||
call->setArg(0, vmfunc);
|
||||
call->setArg(1, paramsptr);
|
||||
|
|
@ -109,9 +109,9 @@ int JitCompiler::StoreCallParams()
|
|||
{
|
||||
using namespace asmjit;
|
||||
|
||||
x86::Gp stackPtr = newTempIntPtr();
|
||||
x86::Gp tmp = newTempIntPtr();
|
||||
x86::Xmm tmp2 = newTempXmmSd();
|
||||
X86Gp stackPtr = newTempIntPtr();
|
||||
X86Gp tmp = newTempIntPtr();
|
||||
X86Xmm tmp2 = newTempXmmSd();
|
||||
|
||||
int numparams = 0;
|
||||
for (unsigned int i = 0; i < ParamOpcodes.Size(); i++)
|
||||
|
|
@ -150,7 +150,7 @@ int JitCompiler::StoreCallParams()
|
|||
cc.mov(x86::ptr(vmframe, offsetParams + slot * sizeof(VMValue) + myoffsetof(VMValue, a)), regS[bc]);
|
||||
break;
|
||||
case REGT_STRING | REGT_KONST:
|
||||
cc.mov(tmp, asmjit::imm(&konsts[bc]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konsts[bc]));
|
||||
cc.mov(x86::ptr(vmframe, offsetParams + slot * sizeof(VMValue) + myoffsetof(VMValue, sp)), tmp);
|
||||
break;
|
||||
case REGT_POINTER:
|
||||
|
|
@ -162,7 +162,7 @@ int JitCompiler::StoreCallParams()
|
|||
cc.mov(x86::ptr(vmframe, offsetParams + slot * sizeof(VMValue) + myoffsetof(VMValue, a)), stackPtr);
|
||||
break;
|
||||
case REGT_POINTER | REGT_KONST:
|
||||
cc.mov(tmp, asmjit::imm(konsta[bc].v));
|
||||
cc.mov(tmp, asmjit::imm_ptr(konsta[bc].v));
|
||||
cc.mov(x86::ptr(vmframe, offsetParams + slot * sizeof(VMValue) + myoffsetof(VMValue, a)), tmp);
|
||||
break;
|
||||
case REGT_FLOAT:
|
||||
|
|
@ -193,7 +193,7 @@ int JitCompiler::StoreCallParams()
|
|||
cc.mov(x86::ptr(vmframe, offsetParams + slot * sizeof(VMValue) + myoffsetof(VMValue, a)), stackPtr);
|
||||
break;
|
||||
case REGT_FLOAT | REGT_KONST:
|
||||
cc.mov(tmp, asmjit::imm(konstf + bc));
|
||||
cc.mov(tmp, asmjit::imm_ptr(konstf + bc));
|
||||
cc.movsd(tmp2, asmjit::x86::qword_ptr(tmp));
|
||||
cc.movsd(x86::qword_ptr(vmframe, offsetParams + slot * sizeof(VMValue) + myoffsetof(VMValue, f)), tmp2);
|
||||
break;
|
||||
|
|
@ -330,7 +330,7 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
|
|||
assert(ParamOpcodes.Size() > 0);
|
||||
const VMOP *param = ParamOpcodes[0];
|
||||
const int bc = param->i16u;
|
||||
asmjit::x86::Gp *reg = nullptr;
|
||||
asmjit::X86Gp *reg = nullptr;
|
||||
|
||||
switch (param->a & REGT_TYPE)
|
||||
{
|
||||
|
|
@ -345,14 +345,14 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
|
|||
cc.jz(label);
|
||||
}
|
||||
|
||||
asmjit::BaseNode *cursorBefore = cc.cursor();
|
||||
auto call = cc.call(imm(target->DirectNativeCall), CreateFuncSignature());
|
||||
asmjit::CBNode *cursorBefore = cc.getCursor();
|
||||
auto call = cc.call(imm_ptr(target->DirectNativeCall), CreateFuncSignature());
|
||||
call->setInlineComment(target->PrintableName.GetChars());
|
||||
asmjit::BaseNode *cursorAfter = cc.cursor();
|
||||
asmjit::CBNode *cursorAfter = cc.getCursor();
|
||||
cc.setCursor(cursorBefore);
|
||||
|
||||
x86::Gp tmp;
|
||||
x86::Xmm tmp2;
|
||||
X86Gp tmp;
|
||||
X86Xmm tmp2;
|
||||
|
||||
int numparams = 0;
|
||||
for (unsigned int i = 0; i < ParamOpcodes.Size(); i++)
|
||||
|
|
@ -384,7 +384,7 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
|
|||
break;
|
||||
case REGT_STRING | REGT_KONST:
|
||||
tmp = newTempIntPtr();
|
||||
cc.mov(tmp, imm(&konsts[bc]));
|
||||
cc.mov(tmp, imm_ptr(&konsts[bc]));
|
||||
call->setArg(slot, tmp);
|
||||
break;
|
||||
case REGT_POINTER:
|
||||
|
|
@ -392,7 +392,7 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
|
|||
break;
|
||||
case REGT_POINTER | REGT_KONST:
|
||||
tmp = newTempIntPtr();
|
||||
cc.mov(tmp, imm(konsta[bc].v));
|
||||
cc.mov(tmp, imm_ptr(konsta[bc].v));
|
||||
call->setArg(slot, tmp);
|
||||
break;
|
||||
case REGT_FLOAT:
|
||||
|
|
@ -411,7 +411,7 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
|
|||
case REGT_FLOAT | REGT_KONST:
|
||||
tmp = newTempIntPtr();
|
||||
tmp2 = newTempXmmSd();
|
||||
cc.mov(tmp, asmjit::imm(konstf + bc));
|
||||
cc.mov(tmp, asmjit::imm_ptr(konstf + bc));
|
||||
cc.movsd(tmp2, asmjit::x86::qword_ptr(tmp));
|
||||
call->setArg(slot, tmp2);
|
||||
break;
|
||||
|
|
@ -580,7 +580,7 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature()
|
|||
{
|
||||
if (ParamOpcodes[i]->op == OP_PARAMI)
|
||||
{
|
||||
args.Push(Type::IdOfT<int>::kTypeId);
|
||||
args.Push(TypeIdOf<int>::kTypeId);
|
||||
key += "i";
|
||||
}
|
||||
else // OP_PARAM
|
||||
|
|
@ -595,33 +595,33 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature()
|
|||
case REGT_INT | REGT_ADDROF:
|
||||
case REGT_POINTER | REGT_ADDROF:
|
||||
case REGT_FLOAT | REGT_ADDROF:
|
||||
args.Push(Type::IdOfT<void*>::kTypeId);
|
||||
args.Push(TypeIdOf<void*>::kTypeId);
|
||||
key += "v";
|
||||
break;
|
||||
case REGT_INT:
|
||||
case REGT_INT | REGT_KONST:
|
||||
args.Push(Type::IdOfT<int>::kTypeId);
|
||||
args.Push(TypeIdOf<int>::kTypeId);
|
||||
key += "i";
|
||||
break;
|
||||
case REGT_STRING:
|
||||
case REGT_STRING | REGT_KONST:
|
||||
args.Push(Type::IdOfT<void*>::kTypeId);
|
||||
args.Push(TypeIdOf<void*>::kTypeId);
|
||||
key += "s";
|
||||
break;
|
||||
case REGT_FLOAT:
|
||||
case REGT_FLOAT | REGT_KONST:
|
||||
args.Push(Type::IdOfT<double>::kTypeId);
|
||||
args.Push(TypeIdOf<double>::kTypeId);
|
||||
key += "f";
|
||||
break;
|
||||
case REGT_FLOAT | REGT_MULTIREG2:
|
||||
args.Push(Type::IdOfT<double>::kTypeId);
|
||||
args.Push(Type::IdOfT<double>::kTypeId);
|
||||
args.Push(TypeIdOf<double>::kTypeId);
|
||||
args.Push(TypeIdOf<double>::kTypeId);
|
||||
key += "ff";
|
||||
break;
|
||||
case REGT_FLOAT | REGT_MULTIREG3:
|
||||
args.Push(Type::IdOfT<double>::kTypeId);
|
||||
args.Push(Type::IdOfT<double>::kTypeId);
|
||||
args.Push(Type::IdOfT<double>::kTypeId);
|
||||
args.Push(TypeIdOf<double>::kTypeId);
|
||||
args.Push(TypeIdOf<double>::kTypeId);
|
||||
args.Push(TypeIdOf<double>::kTypeId);
|
||||
key += "fff";
|
||||
break;
|
||||
|
||||
|
|
@ -635,7 +635,7 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature()
|
|||
const VMOP *retval = pc + 1;
|
||||
int numret = C;
|
||||
|
||||
uint32_t rettype = Type::IdOfT<void>::kTypeId;
|
||||
uint32_t rettype = TypeIdOf<void>::kTypeId;
|
||||
|
||||
// Check if first return value can be placed in the function's real return value slot
|
||||
int startret = 1;
|
||||
|
|
@ -650,15 +650,15 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature()
|
|||
switch (type)
|
||||
{
|
||||
case REGT_INT:
|
||||
rettype = Type::IdOfT<int>::kTypeId;
|
||||
rettype = TypeIdOf<int>::kTypeId;
|
||||
key += "ri";
|
||||
break;
|
||||
case REGT_FLOAT:
|
||||
rettype = Type::IdOfT<double>::kTypeId;
|
||||
rettype = TypeIdOf<double>::kTypeId;
|
||||
key += "rf";
|
||||
break;
|
||||
case REGT_POINTER:
|
||||
rettype = Type::IdOfT<void*>::kTypeId;
|
||||
rettype = TypeIdOf<void*>::kTypeId;
|
||||
key += "rv";
|
||||
break;
|
||||
case REGT_STRING:
|
||||
|
|
@ -676,7 +676,7 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature()
|
|||
I_Error("Expected OP_RESULT to follow OP_CALL\n");
|
||||
}
|
||||
|
||||
args.Push(Type::IdOfT<void*>::kTypeId);
|
||||
args.Push(TypeIdOf<void*>::kTypeId);
|
||||
key += "v";
|
||||
}
|
||||
|
||||
|
|
@ -685,6 +685,6 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature()
|
|||
if (!cachedArgs) cachedArgs.reset(new TArray<uint8_t>(args));
|
||||
|
||||
FuncSignature signature;
|
||||
signature.init(CallConv::kIdHost, FuncSignature::kNoVarArgs, rettype, cachedArgs->Data(), cachedArgs->Size());
|
||||
signature.init(CallConv::kIdHost, rettype, cachedArgs->Data(), cachedArgs->Size());
|
||||
return signature;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ void JitCompiler::EmitSCOPE()
|
|||
cc.jz(label);
|
||||
|
||||
auto f = newTempIntPtr();
|
||||
cc.mov(f, asmjit::imm(konsta[C].v));
|
||||
cc.mov(f, asmjit::imm_ptr(konsta[C].v));
|
||||
|
||||
typedef int(*FuncPtr)(DObject*, VMFunction*, int);
|
||||
auto call = CreateCall<void, DObject*, VMFunction*, int>(ValidateCall);
|
||||
|
|
@ -77,7 +77,7 @@ void JitCompiler::EmitRET()
|
|||
if (B == REGT_NIL)
|
||||
{
|
||||
EmitPopFrame();
|
||||
x86::Gp vReg = newTempInt32();
|
||||
X86Gp vReg = newTempInt32();
|
||||
cc.mov(vReg, 0);
|
||||
cc.ret(vReg);
|
||||
}
|
||||
|
|
@ -86,8 +86,8 @@ void JitCompiler::EmitRET()
|
|||
int a = A;
|
||||
int retnum = a & ~RET_FINAL;
|
||||
|
||||
x86::Gp reg_retnum = newTempInt32();
|
||||
x86::Gp location = newTempIntPtr();
|
||||
X86Gp reg_retnum = newTempInt32();
|
||||
X86Gp location = newTempIntPtr();
|
||||
Label L_endif = cc.newLabel();
|
||||
|
||||
cc.mov(reg_retnum, retnum);
|
||||
|
|
@ -161,7 +161,7 @@ void JitCompiler::EmitRET()
|
|||
cc.add(ptr, (int)(retnum * sizeof(VMReturn)));
|
||||
auto call = CreateCall<void, VMReturn*, FString*>(SetString);
|
||||
call->setArg(0, ptr);
|
||||
if (regtype & REGT_KONST) call->setArg(1, asmjit::imm(&konsts[regnum]));
|
||||
if (regtype & REGT_KONST) call->setArg(1, asmjit::imm_ptr(&konsts[regnum]));
|
||||
else call->setArg(1, regS[regnum]);
|
||||
break;
|
||||
}
|
||||
|
|
@ -171,7 +171,7 @@ void JitCompiler::EmitRET()
|
|||
if (regtype & REGT_KONST)
|
||||
{
|
||||
auto ptr = newTempIntPtr();
|
||||
cc.mov(ptr, asmjit::imm(konsta[regnum].v));
|
||||
cc.mov(ptr, asmjit::imm_ptr(konsta[regnum].v));
|
||||
cc.mov(x86::qword_ptr(location), ptr);
|
||||
}
|
||||
else
|
||||
|
|
@ -184,7 +184,7 @@ void JitCompiler::EmitRET()
|
|||
if (regtype & REGT_KONST)
|
||||
{
|
||||
auto ptr = newTempIntPtr();
|
||||
cc.mov(ptr, asmjit::imm(konsta[regnum].v));
|
||||
cc.mov(ptr, asmjit::imm_ptr(konsta[regnum].v));
|
||||
cc.mov(x86::dword_ptr(location), ptr);
|
||||
}
|
||||
else
|
||||
|
|
@ -218,8 +218,8 @@ void JitCompiler::EmitRETI()
|
|||
int a = A;
|
||||
int retnum = a & ~RET_FINAL;
|
||||
|
||||
x86::Gp reg_retnum = newTempInt32();
|
||||
x86::Gp location = newTempIntPtr();
|
||||
X86Gp reg_retnum = newTempInt32();
|
||||
X86Gp location = newTempIntPtr();
|
||||
Label L_endif = cc.newLabel();
|
||||
|
||||
cc.mov(reg_retnum, retnum);
|
||||
|
|
@ -251,7 +251,7 @@ void JitCompiler::EmitTHROW()
|
|||
|
||||
void JitCompiler::EmitBOUND()
|
||||
{
|
||||
auto cursor = cc.cursor();
|
||||
auto cursor = cc.getCursor();
|
||||
auto label = cc.newLabel();
|
||||
cc.bind(label);
|
||||
auto call = CreateCall<void, int, int>(&JitCompiler::ThrowArrayOutOfBounds);
|
||||
|
|
@ -270,7 +270,7 @@ void JitCompiler::EmitBOUND()
|
|||
|
||||
void JitCompiler::EmitBOUND_K()
|
||||
{
|
||||
auto cursor = cc.cursor();
|
||||
auto cursor = cc.getCursor();
|
||||
auto label = cc.newLabel();
|
||||
cc.bind(label);
|
||||
auto call = CreateCall<void, int, int>(&JitCompiler::ThrowArrayOutOfBounds);
|
||||
|
|
@ -289,7 +289,7 @@ void JitCompiler::EmitBOUND_K()
|
|||
|
||||
void JitCompiler::EmitBOUND_R()
|
||||
{
|
||||
auto cursor = cc.cursor();
|
||||
auto cursor = cc.getCursor();
|
||||
auto label = cc.newLabel();
|
||||
cc.bind(label);
|
||||
auto call = CreateCall<void, int, int>(&JitCompiler::ThrowArrayOutOfBounds);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ void JitCompiler::EmitLK()
|
|||
void JitCompiler::EmitLKF()
|
||||
{
|
||||
auto base = newTempIntPtr();
|
||||
cc.mov(base, asmjit::imm(konstf + BC));
|
||||
cc.mov(base, asmjit::imm_ptr(konstf + BC));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(base));
|
||||
}
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ void JitCompiler::EmitLKS()
|
|||
{
|
||||
auto call = CreateCall<void, FString*, FString*>(&JitCompiler::CallAssignString);
|
||||
call->setArg(0, regS[A]);
|
||||
call->setArg(1, asmjit::imm(konsts + BC));
|
||||
call->setArg(1, asmjit::imm_ptr(konsts + BC));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLKP()
|
||||
|
|
@ -36,26 +36,26 @@ void JitCompiler::EmitLKP()
|
|||
void JitCompiler::EmitLK_R()
|
||||
{
|
||||
auto base = newTempIntPtr();
|
||||
cc.mov(base, asmjit::imm(konstd + C));
|
||||
cc.mov(regD[A], asmjit::x86::ptr(base, regD[B].cloneAs(base), 2));
|
||||
cc.mov(base, asmjit::imm_ptr(konstd + C));
|
||||
cc.mov(regD[A], asmjit::x86::ptr(base, regD[B], 2));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLKF_R()
|
||||
{
|
||||
auto base = newTempIntPtr();
|
||||
cc.mov(base, asmjit::imm(konstf + C));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(base, regD[B].cloneAs(base), 3));
|
||||
cc.mov(base, asmjit::imm_ptr(konstf + C));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(base, regD[B], 3));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLKS_R()
|
||||
{
|
||||
auto base = newTempIntPtr();
|
||||
cc.mov(base, asmjit::imm(konsts + C));
|
||||
cc.mov(base, asmjit::imm_ptr(konsts + C));
|
||||
auto ptr = newTempIntPtr();
|
||||
if (cc.is64Bit())
|
||||
cc.lea(ptr, asmjit::x86::ptr(base, regD[B].cloneAs(base), 3));
|
||||
cc.lea(ptr, asmjit::x86::ptr(base, regD[B], 3));
|
||||
else
|
||||
cc.lea(ptr, asmjit::x86::ptr(base, regD[B].cloneAs(base), 2));
|
||||
cc.lea(ptr, asmjit::x86::ptr(base, regD[B], 2));
|
||||
auto call = CreateCall<void, FString*, FString*>(&JitCompiler::CallAssignString);
|
||||
call->setArg(0, regS[A]);
|
||||
call->setArg(1, ptr);
|
||||
|
|
@ -64,11 +64,11 @@ void JitCompiler::EmitLKS_R()
|
|||
void JitCompiler::EmitLKP_R()
|
||||
{
|
||||
auto base = newTempIntPtr();
|
||||
cc.mov(base, asmjit::imm(konsta + C));
|
||||
cc.mov(base, asmjit::imm_ptr(konsta + C));
|
||||
if (cc.is64Bit())
|
||||
cc.mov(regA[A], asmjit::x86::ptr(base, regD[B].cloneAs(base), 3));
|
||||
cc.mov(regA[A], asmjit::x86::ptr(base, regD[B], 3));
|
||||
else
|
||||
cc.mov(regA[A], asmjit::x86::ptr(base, regD[B].cloneAs(base), 2));
|
||||
cc.mov(regA[A], asmjit::x86::ptr(base, regD[B], 2));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLFP()
|
||||
|
|
@ -107,7 +107,7 @@ void JitCompiler::EmitLB()
|
|||
void JitCompiler::EmitLB_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.movsx(regD[A], asmjit::x86::byte_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.movsx(regD[A], asmjit::x86::byte_ptr(regA[B], regD[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLH()
|
||||
|
|
@ -119,7 +119,7 @@ void JitCompiler::EmitLH()
|
|||
void JitCompiler::EmitLH_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.movsx(regD[A], asmjit::x86::word_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.movsx(regD[A], asmjit::x86::word_ptr(regA[B], regD[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLW()
|
||||
|
|
@ -131,7 +131,7 @@ void JitCompiler::EmitLW()
|
|||
void JitCompiler::EmitLW_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.mov(regD[A], asmjit::x86::dword_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.mov(regD[A], asmjit::x86::dword_ptr(regA[B], regD[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLBU()
|
||||
|
|
@ -143,19 +143,19 @@ void JitCompiler::EmitLBU()
|
|||
void JitCompiler::EmitLBU_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.movzx(regD[A], asmjit::x86::byte_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.movzx(regD[A].r8Lo(), asmjit::x86::byte_ptr(regA[B], regD[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLHU()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.movzx(regD[A], asmjit::x86::word_ptr(regA[B], konstd[C]));
|
||||
cc.movzx(regD[A].r16(), asmjit::x86::word_ptr(regA[B], konstd[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLHU_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.movzx(regD[A], asmjit::x86::word_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.movzx(regD[A].r16(), asmjit::x86::word_ptr(regA[B], regD[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLSP()
|
||||
|
|
@ -169,7 +169,7 @@ void JitCompiler::EmitLSP_R()
|
|||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.xorpd(regF[A], regF[A]);
|
||||
cc.cvtss2sd(regF[A], asmjit::x86::dword_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.cvtss2sd(regF[A], asmjit::x86::dword_ptr(regA[B], regD[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLDP()
|
||||
|
|
@ -181,7 +181,7 @@ void JitCompiler::EmitLDP()
|
|||
void JitCompiler::EmitLDP_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(regA[B], regD[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLS()
|
||||
|
|
@ -198,7 +198,7 @@ void JitCompiler::EmitLS_R()
|
|||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
auto ptr = newTempIntPtr();
|
||||
cc.lea(ptr, asmjit::x86::ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.lea(ptr, asmjit::x86::ptr(regA[B], regD[C]));
|
||||
auto call = CreateCall<void, FString*, FString*>(&JitCompiler::CallAssignString);
|
||||
call->setArg(0, regS[A]);
|
||||
call->setArg(1, ptr);
|
||||
|
|
@ -234,7 +234,7 @@ void JitCompiler::EmitLO_R()
|
|||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
|
||||
cc.mov(regA[A], asmjit::x86::ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.mov(regA[A], asmjit::x86::ptr(regA[B], regD[C]));
|
||||
EmitReadBarrier();
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ void JitCompiler::EmitLO_R()
|
|||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
|
||||
auto ptr = newTempIntPtr();
|
||||
cc.mov(ptr, asmjit::x86::ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.mov(ptr, asmjit::x86::ptr(regA[B], regD[C]));
|
||||
|
||||
auto result = newResultIntPtr();
|
||||
auto call = CreateCall<DObject*, DObject*>(ReadBarrier);
|
||||
|
|
@ -284,7 +284,7 @@ void JitCompiler::EmitLP()
|
|||
void JitCompiler::EmitLP_R()
|
||||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
cc.mov(regA[A], asmjit::x86::ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.mov(regA[A], asmjit::x86::ptr(regA[B], regD[C]));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitLV2()
|
||||
|
|
@ -300,7 +300,7 @@ void JitCompiler::EmitLV2_R()
|
|||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.lea(tmp, asmjit::x86::qword_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.lea(tmp, asmjit::x86::qword_ptr(regA[B], regD[C]));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.movsd(regF[A + 1], asmjit::x86::qword_ptr(tmp, 8));
|
||||
}
|
||||
|
|
@ -319,7 +319,7 @@ void JitCompiler::EmitLV3_R()
|
|||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.lea(tmp, asmjit::x86::qword_ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.lea(tmp, asmjit::x86::qword_ptr(regA[B], regD[C]));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.movsd(regF[A + 1], asmjit::x86::qword_ptr(tmp, 8));
|
||||
cc.movsd(regF[A + 2], asmjit::x86::qword_ptr(tmp, 16));
|
||||
|
|
@ -344,7 +344,7 @@ void JitCompiler::EmitLCS_R()
|
|||
{
|
||||
EmitNullPointerThrow(B, X_READ_NIL);
|
||||
auto ptr = newTempIntPtr();
|
||||
cc.lea(ptr, asmjit::x86::ptr(regA[B], regD[C].cloneAs(regA[B])));
|
||||
cc.lea(ptr, asmjit::x86::ptr(regA[B], regD[C]));
|
||||
auto call = CreateCall<void, FString*, char**>(SetString);
|
||||
call->setArg(0, regS[A]);
|
||||
call->setArg(1, ptr);
|
||||
|
|
@ -356,5 +356,5 @@ void JitCompiler::EmitLBIT()
|
|||
cc.movsx(regD[A], asmjit::x86::byte_ptr(regA[B]));
|
||||
cc.and_(regD[A], C);
|
||||
cc.cmp(regD[A], 0);
|
||||
cc.setne(regD[A].r8());
|
||||
cc.setne(regD[A]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,10 +51,10 @@ void JitCompiler::EmitCMPS()
|
|||
auto result = newResultInt32();
|
||||
call->setRet(0, result);
|
||||
|
||||
if (static_cast<bool>(A & CMP_BK)) call->setArg(0, asmjit::imm(&konsts[B]));
|
||||
if (static_cast<bool>(A & CMP_BK)) call->setArg(0, asmjit::imm_ptr(&konsts[B]));
|
||||
else call->setArg(0, regS[B]);
|
||||
|
||||
if (static_cast<bool>(A & CMP_CK)) call->setArg(1, asmjit::imm(&konsts[C]));
|
||||
if (static_cast<bool>(A & CMP_CK)) call->setArg(1, asmjit::imm_ptr(&konsts[C]));
|
||||
else call->setArg(1, regS[C]);
|
||||
|
||||
int method = A & CMP_METHOD_MASK;
|
||||
|
|
@ -84,7 +84,7 @@ void JitCompiler::EmitSLL_RR()
|
|||
auto rc = CheckRegD(C, A);
|
||||
if (A != B)
|
||||
cc.mov(regD[A], regD[B]);
|
||||
cc.shl(regD[A], rc.r8());
|
||||
cc.shl(regD[A], rc);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSLL_RI()
|
||||
|
|
@ -98,7 +98,7 @@ void JitCompiler::EmitSLL_KR()
|
|||
{
|
||||
auto rc = CheckRegD(C, A);
|
||||
cc.mov(regD[A], konstd[B]);
|
||||
cc.shl(regD[A], rc.r8());
|
||||
cc.shl(regD[A], rc);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSRL_RR()
|
||||
|
|
@ -106,7 +106,7 @@ void JitCompiler::EmitSRL_RR()
|
|||
auto rc = CheckRegD(C, A);
|
||||
if (A != B)
|
||||
cc.mov(regD[A], regD[B]);
|
||||
cc.shr(regD[A], rc.r8());
|
||||
cc.shr(regD[A], rc);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSRL_RI()
|
||||
|
|
@ -120,7 +120,7 @@ void JitCompiler::EmitSRL_KR()
|
|||
{
|
||||
auto rc = CheckRegD(C, A);
|
||||
cc.mov(regD[A], konstd[B]);
|
||||
cc.shr(regD[A], rc.r8());
|
||||
cc.shr(regD[A], rc);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSRA_RR()
|
||||
|
|
@ -128,7 +128,7 @@ void JitCompiler::EmitSRA_RR()
|
|||
auto rc = CheckRegD(C, A);
|
||||
if (A != B)
|
||||
cc.mov(regD[A], regD[B]);
|
||||
cc.sar(regD[A], rc.r8());
|
||||
cc.sar(regD[A], rc);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitSRA_RI()
|
||||
|
|
@ -142,7 +142,7 @@ void JitCompiler::EmitSRA_KR()
|
|||
{
|
||||
auto rc = CheckRegD(C, A);
|
||||
cc.mov(regD[A], konstd[B]);
|
||||
cc.sar(regD[A], rc.r8());
|
||||
cc.sar(regD[A], rc);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitADD_RR()
|
||||
|
|
@ -228,7 +228,7 @@ void JitCompiler::EmitDIV_RK()
|
|||
auto konstTmp = newTempIntPtr();
|
||||
cc.mov(tmp0, regD[B]);
|
||||
cc.cdq(tmp1, tmp0);
|
||||
cc.mov(konstTmp, asmjit::imm(&konstd[C]));
|
||||
cc.mov(konstTmp, asmjit::imm_ptr(&konstd[C]));
|
||||
cc.idiv(tmp1, tmp0, asmjit::x86::ptr(konstTmp));
|
||||
cc.mov(regD[A], tmp0);
|
||||
}
|
||||
|
|
@ -277,7 +277,7 @@ void JitCompiler::EmitDIVU_RK()
|
|||
auto konstTmp = newTempIntPtr();
|
||||
cc.mov(tmp0, regD[B]);
|
||||
cc.mov(tmp1, 0);
|
||||
cc.mov(konstTmp, asmjit::imm(&konstd[C]));
|
||||
cc.mov(konstTmp, asmjit::imm_ptr(&konstd[C]));
|
||||
cc.div(tmp1, tmp0, asmjit::x86::ptr(konstTmp));
|
||||
cc.mov(regD[A], tmp0);
|
||||
}
|
||||
|
|
@ -326,7 +326,7 @@ void JitCompiler::EmitMOD_RK()
|
|||
auto konstTmp = newTempIntPtr();
|
||||
cc.mov(tmp0, regD[B]);
|
||||
cc.cdq(tmp1, tmp0);
|
||||
cc.mov(konstTmp, asmjit::imm(&konstd[C]));
|
||||
cc.mov(konstTmp, asmjit::imm_ptr(&konstd[C]));
|
||||
cc.idiv(tmp1, tmp0, asmjit::x86::ptr(konstTmp));
|
||||
cc.mov(regD[A], tmp1);
|
||||
}
|
||||
|
|
@ -375,7 +375,7 @@ void JitCompiler::EmitMODU_RK()
|
|||
auto konstTmp = newTempIntPtr();
|
||||
cc.mov(tmp0, regD[B]);
|
||||
cc.mov(tmp1, 0);
|
||||
cc.mov(konstTmp, asmjit::imm(&konstd[C]));
|
||||
cc.mov(konstTmp, asmjit::imm_ptr(&konstd[C]));
|
||||
cc.div(tmp1, tmp0, asmjit::x86::ptr(konstTmp));
|
||||
cc.mov(regD[A], tmp1);
|
||||
}
|
||||
|
|
@ -586,7 +586,7 @@ void JitCompiler::EmitLT_KR()
|
|||
{
|
||||
EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) {
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstd[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstd[B]));
|
||||
cc.cmp(asmjit::x86::ptr(tmp), regD[C]);
|
||||
if (check) cc.jl(fail);
|
||||
else cc.jnl(fail);
|
||||
|
|
@ -615,7 +615,7 @@ void JitCompiler::EmitLE_KR()
|
|||
{
|
||||
EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) {
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstd[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstd[B]));
|
||||
cc.cmp(asmjit::x86::ptr(tmp), regD[C]);
|
||||
if (check) cc.jle(fail);
|
||||
else cc.jnle(fail);
|
||||
|
|
@ -644,7 +644,7 @@ void JitCompiler::EmitLTU_KR()
|
|||
{
|
||||
EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) {
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstd[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstd[B]));
|
||||
cc.cmp(asmjit::x86::ptr(tmp), regD[C]);
|
||||
if (check) cc.jb(fail);
|
||||
else cc.jnb(fail);
|
||||
|
|
@ -673,7 +673,7 @@ void JitCompiler::EmitLEU_KR()
|
|||
{
|
||||
EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) {
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstd[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstd[B]));
|
||||
cc.cmp(asmjit::x86::ptr(tmp), regD[C]);
|
||||
if (check) cc.jbe(fail);
|
||||
else cc.jnbe(fail);
|
||||
|
|
@ -696,7 +696,7 @@ void JitCompiler::EmitADDF_RK()
|
|||
auto tmp = newTempIntPtr();
|
||||
if (A != B)
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.addsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
|
||||
|
|
@ -713,7 +713,7 @@ void JitCompiler::EmitSUBF_RK()
|
|||
auto tmp = newTempIntPtr();
|
||||
if (A != B)
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.subsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
|
||||
|
|
@ -721,7 +721,7 @@ void JitCompiler::EmitSUBF_KR()
|
|||
{
|
||||
auto rc = CheckRegF(C, A);
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstf[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[B]));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.subsd(regF[A], rc);
|
||||
}
|
||||
|
|
@ -739,7 +739,7 @@ void JitCompiler::EmitMULF_RK()
|
|||
auto tmp = newTempIntPtr();
|
||||
if (A != B)
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.mulsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
|
||||
|
|
@ -766,7 +766,7 @@ void JitCompiler::EmitDIVF_RK()
|
|||
{
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.divsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
}
|
||||
|
|
@ -775,7 +775,7 @@ void JitCompiler::EmitDIVF_KR()
|
|||
{
|
||||
auto rc = CheckRegF(C, A);
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstf[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[B]));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.divsd(regF[A], rc);
|
||||
}
|
||||
|
|
@ -810,7 +810,7 @@ void JitCompiler::EmitMODF_RK()
|
|||
else
|
||||
{
|
||||
auto tmpPtr = newTempIntPtr();
|
||||
cc.mov(tmpPtr, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmpPtr, asmjit::imm_ptr(&konstf[C]));
|
||||
|
||||
auto tmp = newTempXmmSd();
|
||||
cc.movsd(tmp, asmjit::x86::qword_ptr(tmpPtr));
|
||||
|
|
@ -859,7 +859,7 @@ void JitCompiler::EmitPOWF_RK()
|
|||
{
|
||||
auto tmp = newTempIntPtr();
|
||||
auto tmp2 = newTempXmmSd();
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.movsd(tmp2, asmjit::x86::qword_ptr(tmp));
|
||||
|
||||
auto result = newResultXmmSd();
|
||||
|
|
@ -874,7 +874,7 @@ void JitCompiler::EmitPOWF_KR()
|
|||
{
|
||||
auto tmp = newTempIntPtr();
|
||||
auto tmp2 = newTempXmmSd();
|
||||
cc.mov(tmp, asmjit::imm(&konstf[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[B]));
|
||||
cc.movsd(tmp2, asmjit::x86::qword_ptr(tmp));
|
||||
|
||||
auto result = newResultXmmSd();
|
||||
|
|
@ -897,7 +897,7 @@ void JitCompiler::EmitMINF_RK()
|
|||
{
|
||||
auto rb = CheckRegF(B, A);
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.minpd(regF[A], rb); // minsd requires SSE 4.1
|
||||
}
|
||||
|
|
@ -914,7 +914,7 @@ void JitCompiler::EmitMAXF_RK()
|
|||
{
|
||||
auto rb = CheckRegF(B, A);
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.movsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.maxpd(regF[A], rb); // maxsd requires SSE 4.1
|
||||
}
|
||||
|
|
@ -930,7 +930,7 @@ void JitCompiler::EmitATAN2()
|
|||
|
||||
static const double constant = 180 / M_PI;
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&constant));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&constant));
|
||||
cc.mulsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
|
||||
|
|
@ -938,7 +938,7 @@ void JitCompiler::EmitFLOP()
|
|||
{
|
||||
if (C == FLOP_NEG)
|
||||
{
|
||||
auto mask = cc.newDoubleConst(asmjit::ConstPool::kScopeLocal, -0.0);
|
||||
auto mask = cc.newDoubleConst(asmjit::kConstScopeLocal, -0.0);
|
||||
auto maskXmm = newTempXmmSd();
|
||||
cc.movsd(maskXmm, mask);
|
||||
if (A != B)
|
||||
|
|
@ -954,7 +954,7 @@ void JitCompiler::EmitFLOP()
|
|||
{
|
||||
static const double constant = M_PI / 180;
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&constant));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&constant));
|
||||
cc.mulsd(v, asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
|
||||
|
|
@ -998,7 +998,7 @@ void JitCompiler::EmitFLOP()
|
|||
{
|
||||
static const double constant = 180 / M_PI;
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&constant));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&constant));
|
||||
cc.mulsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
}
|
||||
|
|
@ -1025,10 +1025,10 @@ void JitCompiler::EmitEQF_R()
|
|||
auto tmp = newTempXmmSd();
|
||||
|
||||
const int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF;
|
||||
auto absMask = cc.newDoubleConst(asmjit::ConstPool::kScopeLocal, reinterpret_cast<const double&>(absMaskInt));
|
||||
auto absMask = cc.newDoubleConst(asmjit::kConstScopeLocal, reinterpret_cast<const double&>(absMaskInt));
|
||||
auto absMaskXmm = newTempXmmPd();
|
||||
|
||||
auto epsilon = cc.newDoubleConst(asmjit::ConstPool::kScopeLocal, VM_EPSILON);
|
||||
auto epsilon = cc.newDoubleConst(asmjit::kConstScopeLocal, VM_EPSILON);
|
||||
auto epsilonXmm = newTempXmmSd();
|
||||
|
||||
cc.movsd(tmp, regF[B]);
|
||||
|
|
@ -1051,7 +1051,7 @@ void JitCompiler::EmitEQF_K()
|
|||
bool approx = static_cast<bool>(A & CMP_APPROX);
|
||||
if (!approx) {
|
||||
auto konstTmp = newTempIntPtr();
|
||||
cc.mov(konstTmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(konstTmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.ucomisd(regF[B], x86::qword_ptr(konstTmp));
|
||||
if (check) {
|
||||
cc.jp(success);
|
||||
|
|
@ -1067,13 +1067,13 @@ void JitCompiler::EmitEQF_K()
|
|||
auto subTmp = newTempXmmSd();
|
||||
|
||||
const int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF;
|
||||
auto absMask = cc.newDoubleConst(ConstPool::kScopeLocal, reinterpret_cast<const double&>(absMaskInt));
|
||||
auto absMask = cc.newDoubleConst(kConstScopeLocal, reinterpret_cast<const double&>(absMaskInt));
|
||||
auto absMaskXmm = newTempXmmPd();
|
||||
|
||||
auto epsilon = cc.newDoubleConst(ConstPool::kScopeLocal, VM_EPSILON);
|
||||
auto epsilon = cc.newDoubleConst(kConstScopeLocal, VM_EPSILON);
|
||||
auto epsilonXmm = newTempXmmSd();
|
||||
|
||||
cc.mov(konstTmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(konstTmp, asmjit::imm_ptr(&konstf[C]));
|
||||
|
||||
cc.movsd(subTmp, regF[B]);
|
||||
cc.subsd(subTmp, x86::qword_ptr(konstTmp));
|
||||
|
|
@ -1106,7 +1106,7 @@ void JitCompiler::EmitLTF_RK()
|
|||
|
||||
auto constTmp = newTempIntPtr();
|
||||
auto xmmTmp = newTempXmmSd();
|
||||
cc.mov(constTmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(constTmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.movsd(xmmTmp, asmjit::x86::qword_ptr(constTmp));
|
||||
|
||||
cc.ucomisd(xmmTmp, regF[B]);
|
||||
|
|
@ -1121,7 +1121,7 @@ void JitCompiler::EmitLTF_KR()
|
|||
if (static_cast<bool>(A & CMP_APPROX)) I_Error("CMP_APPROX not implemented for LTF_KR.\n");
|
||||
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstf[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[B]));
|
||||
|
||||
cc.ucomisd(regF[C], asmjit::x86::qword_ptr(tmp));
|
||||
if (check) cc.ja(fail);
|
||||
|
|
@ -1147,7 +1147,7 @@ void JitCompiler::EmitLEF_RK()
|
|||
|
||||
auto constTmp = newTempIntPtr();
|
||||
auto xmmTmp = newTempXmmSd();
|
||||
cc.mov(constTmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(constTmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.movsd(xmmTmp, asmjit::x86::qword_ptr(constTmp));
|
||||
|
||||
cc.ucomisd(xmmTmp, regF[B]);
|
||||
|
|
@ -1162,7 +1162,7 @@ void JitCompiler::EmitLEF_KR()
|
|||
if (static_cast<bool>(A & CMP_APPROX)) I_Error("CMP_APPROX not implemented for LEF_KR.\n");
|
||||
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(&konstf[B]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[B]));
|
||||
|
||||
cc.ucomisd(regF[C], asmjit::x86::qword_ptr(tmp));
|
||||
if (check) cc.jae(fail);
|
||||
|
|
@ -1175,7 +1175,7 @@ void JitCompiler::EmitLEF_KR()
|
|||
|
||||
void JitCompiler::EmitNEGV2()
|
||||
{
|
||||
auto mask = cc.newDoubleConst(asmjit::ConstPool::kScopeLocal, -0.0);
|
||||
auto mask = cc.newDoubleConst(asmjit::kConstScopeLocal, -0.0);
|
||||
auto maskXmm = newTempXmmSd();
|
||||
cc.movsd(maskXmm, mask);
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
|
|
@ -1230,7 +1230,7 @@ void JitCompiler::EmitMULVF2_RK()
|
|||
auto tmp = newTempIntPtr();
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
cc.movsd(regF[A + 1], regF[B + 1]);
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.mulsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.mulsd(regF[A + 1], asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
|
|
@ -1249,7 +1249,7 @@ void JitCompiler::EmitDIVVF2_RK()
|
|||
auto tmp = newTempIntPtr();
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
cc.movsd(regF[A + 1], regF[B + 1]);
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.divsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.divsd(regF[A + 1], asmjit::x86::qword_ptr(tmp));
|
||||
}
|
||||
|
|
@ -1284,7 +1284,7 @@ void JitCompiler::EmitEQV2_K()
|
|||
|
||||
void JitCompiler::EmitNEGV3()
|
||||
{
|
||||
auto mask = cc.newDoubleConst(asmjit::ConstPool::kScopeLocal, -0.0);
|
||||
auto mask = cc.newDoubleConst(asmjit::kConstScopeLocal, -0.0);
|
||||
auto maskXmm = newTempXmmSd();
|
||||
cc.movsd(maskXmm, mask);
|
||||
cc.movsd(regF[A], regF[B]);
|
||||
|
|
@ -1389,7 +1389,7 @@ void JitCompiler::EmitMULVF3_RK()
|
|||
cc.movsd(regF[A], regF[B]);
|
||||
cc.movsd(regF[A + 1], regF[B + 1]);
|
||||
cc.movsd(regF[A + 2], regF[B + 2]);
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.mulsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.mulsd(regF[A + 1], asmjit::x86::qword_ptr(tmp));
|
||||
cc.mulsd(regF[A + 2], asmjit::x86::qword_ptr(tmp));
|
||||
|
|
@ -1412,7 +1412,7 @@ void JitCompiler::EmitDIVVF3_RK()
|
|||
cc.movsd(regF[A], regF[B]);
|
||||
cc.movsd(regF[A + 1], regF[B + 1]);
|
||||
cc.movsd(regF[A + 2], regF[B + 2]);
|
||||
cc.mov(tmp, asmjit::imm(&konstf[C]));
|
||||
cc.mov(tmp, asmjit::imm_ptr(&konstf[C]));
|
||||
cc.divsd(regF[A], asmjit::x86::qword_ptr(tmp));
|
||||
cc.divsd(regF[A + 1], asmjit::x86::qword_ptr(tmp));
|
||||
cc.divsd(regF[A + 2], asmjit::x86::qword_ptr(tmp));
|
||||
|
|
@ -1461,7 +1461,7 @@ void JitCompiler::EmitADDA_RR()
|
|||
cc.je(label);
|
||||
|
||||
auto tmpptr = newTempIntPtr();
|
||||
cc.mov(tmpptr.r32(), regD[C]);
|
||||
cc.mov(tmpptr, regD[C]);
|
||||
cc.add(tmp, tmpptr);
|
||||
|
||||
cc.bind(label);
|
||||
|
|
@ -1488,9 +1488,8 @@ void JitCompiler::EmitADDA_RK()
|
|||
void JitCompiler::EmitSUBA()
|
||||
{
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp.r32(), regD[C]);
|
||||
cc.sub(tmp, regA[B]);
|
||||
cc.neg(tmp);
|
||||
cc.mov(tmp, regA[B]);
|
||||
cc.sub(tmp, regD[C]);
|
||||
cc.mov(regA[A], tmp);
|
||||
}
|
||||
|
||||
|
|
@ -1507,14 +1506,14 @@ void JitCompiler::EmitEQA_K()
|
|||
{
|
||||
EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) {
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp, asmjit::imm(konsta[C].v));
|
||||
cc.mov(tmp, asmjit::imm_ptr(konsta[C].v));
|
||||
cc.cmp(regA[B], tmp);
|
||||
if (check) cc.je(fail);
|
||||
else cc.jne(fail);
|
||||
});
|
||||
}
|
||||
|
||||
void JitCompiler::CallSqrt(const asmjit::x86::Xmm &a, const asmjit::x86::Xmm &b)
|
||||
void JitCompiler::CallSqrt(const asmjit::X86Xmm &a, const asmjit::X86Xmm &b)
|
||||
{
|
||||
auto result = newResultXmmSd();
|
||||
auto call = CreateCall<double, double>(g_sqrt);
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetTexture(*(FTextu
|
|||
|
||||
void JitCompiler::EmitCAST()
|
||||
{
|
||||
asmjit::x86::Gp tmp, resultD;
|
||||
asmjit::x86::Xmm resultF;
|
||||
asmjit::FuncCallNode *call = nullptr;
|
||||
asmjit::X86Gp tmp, resultD;
|
||||
asmjit::X86Xmm resultF;
|
||||
asmjit::CCFuncCall *call = nullptr;
|
||||
|
||||
switch (C)
|
||||
{
|
||||
|
|
@ -185,7 +185,7 @@ void JitCompiler::EmitCASTB()
|
|||
if (C == CASTB_I)
|
||||
{
|
||||
cc.cmp(regD[B], (int)0);
|
||||
cc.setne(regD[A].r8());
|
||||
cc.setne(regD[A]);
|
||||
cc.movzx(regD[A], regD[A].r8Lo()); // not sure if this is needed
|
||||
}
|
||||
else if (C == CASTB_F)
|
||||
|
|
@ -196,13 +196,13 @@ void JitCompiler::EmitCASTB()
|
|||
cc.mov(one, 1);
|
||||
cc.xor_(regD[A], regD[A]);
|
||||
cc.ucomisd(regF[B], zero);
|
||||
cc.setp(regD[A].r8());
|
||||
cc.setp(regD[A]);
|
||||
cc.cmovne(regD[A], one);
|
||||
}
|
||||
else if (C == CASTB_A)
|
||||
{
|
||||
cc.test(regA[B], regA[B]);
|
||||
cc.setne(regD[A].r8());
|
||||
cc.setne(regD[A]);
|
||||
cc.movzx(regD[A], regD[A].r8Lo()); // not sure if this is needed
|
||||
}
|
||||
else
|
||||
|
|
@ -234,7 +234,7 @@ void JitCompiler::EmitDYNCAST_K()
|
|||
{
|
||||
auto result = newResultIntPtr();
|
||||
auto c = newTempIntPtr();
|
||||
cc.mov(c, asmjit::imm(konsta[C].o));
|
||||
cc.mov(c, asmjit::imm_ptr(konsta[C].o));
|
||||
auto call = CreateCall<DObject*, DObject*, PClass*>(DynCast);
|
||||
call->setRet(0, result);
|
||||
call->setArg(0, regA[B]);
|
||||
|
|
@ -262,7 +262,7 @@ void JitCompiler::EmitDYNCASTC_K()
|
|||
using namespace asmjit;
|
||||
auto result = newResultIntPtr();
|
||||
auto c = newTempIntPtr();
|
||||
cc.mov(c, asmjit::imm(konsta[C].o));
|
||||
cc.mov(c, asmjit::imm_ptr(konsta[C].o));
|
||||
typedef PClass*(*FuncPtr)(PClass*, PClass*);
|
||||
auto call = CreateCall<PClass*, PClass*, PClass*>(DynCastC);
|
||||
call->setRet(0, result);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ asmjit::CodeInfo GetHostCodeInfo()
|
|||
if (firstCall)
|
||||
{
|
||||
asmjit::JitRuntime rt;
|
||||
codeInfo = rt.codeInfo();
|
||||
codeInfo = rt.getCodeInfo();
|
||||
firstCall = false;
|
||||
}
|
||||
|
||||
|
|
@ -56,12 +56,13 @@ static void *AllocJitMemory(size_t size)
|
|||
}
|
||||
else
|
||||
{
|
||||
const size_t bytesToAllocate = asmjit::Support::alignUp(MAX(size_t(1024 * 1024), size), VirtMem::info().pageGranularity);
|
||||
void *p;
|
||||
if (VirtMem::alloc(&p, bytesToAllocate, VirtMem::kAccessReadWrite | VirtMem::kAccessExecute) != asmjit::kErrorOk)
|
||||
const size_t bytesToAllocate = MAX(size_t(1024 * 1024), size);
|
||||
size_t allocatedSize = 0;
|
||||
void *p = OSUtils::allocVirtualMemory(bytesToAllocate, &allocatedSize, OSUtils::kVMWritable | OSUtils::kVMExecutable);
|
||||
if (!p)
|
||||
return nullptr;
|
||||
JitBlocks.Push((uint8_t*)p);
|
||||
JitBlockSize = bytesToAllocate;
|
||||
JitBlockSize = allocatedSize;
|
||||
JitBlockPos = size;
|
||||
return p;
|
||||
}
|
||||
|
|
@ -79,15 +80,19 @@ static void *AllocJitMemory(size_t size)
|
|||
#define UWOP_SAVE_XMM128_FAR 9
|
||||
#define UWOP_PUSH_MACHFRAME 10
|
||||
|
||||
static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::FuncNode *func)
|
||||
static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
|
||||
{
|
||||
using namespace asmjit;
|
||||
FuncFrame frame = func->frame();
|
||||
FuncFrameLayout layout;
|
||||
Error error = layout.init(func->getDetail(), func->getFrameInfo());
|
||||
if (error != kErrorOk)
|
||||
I_Error("FuncFrameLayout.init failed");
|
||||
|
||||
// We need a dummy assembler for instruction size calculations
|
||||
// We need a dummy emitter for instruction size calculations
|
||||
CodeHolder code;
|
||||
code.init(GetHostCodeInfo());
|
||||
x86::Assembler assembler(&code);
|
||||
X86Assembler assembler(&code);
|
||||
X86Emitter *emitter = assembler.asEmitter();
|
||||
|
||||
// Build UNWIND_CODE codes:
|
||||
|
||||
|
|
@ -96,26 +101,26 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::FuncNode *func)
|
|||
|
||||
// Note: this must match exactly what X86Internal::emitProlog does
|
||||
|
||||
x86::Gp zsp = assembler.zsp(); // ESP|RSP register.
|
||||
x86::Gp zbp = assembler.zsp(); // EBP|RBP register.
|
||||
zbp.setId(x86::Gp::kIdBp);
|
||||
x86::Gp gpReg = assembler.zsp(); // General purpose register (temporary).
|
||||
x86::Gp saReg = assembler.zsp(); // Stack-arguments base register.
|
||||
uint32_t gpSaved = frame.savedRegs(x86::Reg::kGroupGp);
|
||||
X86Gp zsp = emitter->zsp(); // ESP|RSP register.
|
||||
X86Gp zbp = emitter->zsp(); // EBP|RBP register.
|
||||
zbp.setId(X86Gp::kIdBp);
|
||||
X86Gp gpReg = emitter->zsp(); // General purpose register (temporary).
|
||||
X86Gp saReg = emitter->zsp(); // Stack-arguments base register.
|
||||
uint32_t gpSaved = layout.getSavedRegs(X86Reg::kKindGp);
|
||||
|
||||
if (frame.hasPreservedFP())
|
||||
if (layout.hasPreservedFP())
|
||||
{
|
||||
// Emit: 'push zbp'
|
||||
// 'mov zbp, zsp'.
|
||||
gpSaved &= ~Support::bitMask(x86::Gp::kIdBp);
|
||||
assembler.push(zbp);
|
||||
gpSaved &= ~Utils::mask(X86Gp::kIdBp);
|
||||
emitter->push(zbp);
|
||||
|
||||
opoffset = (uint32_t)assembler.offset();
|
||||
opoffset = (uint32_t)assembler.getOffset();
|
||||
opcode = UWOP_PUSH_NONVOL;
|
||||
opinfo = x86::Gp::kIdBp;
|
||||
opinfo = X86Gp::kIdBp;
|
||||
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
|
||||
|
||||
assembler.mov(zbp, zsp);
|
||||
emitter->mov(zbp, zsp);
|
||||
}
|
||||
|
||||
if (gpSaved)
|
||||
|
|
@ -125,48 +130,48 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::FuncNode *func)
|
|||
if (!(i & 0x1)) continue;
|
||||
// Emit: 'push gp' sequence.
|
||||
gpReg.setId(regId);
|
||||
assembler.push(gpReg);
|
||||
emitter->push(gpReg);
|
||||
|
||||
opoffset = (uint32_t)assembler.offset();
|
||||
opoffset = (uint32_t)assembler.getOffset();
|
||||
opcode = UWOP_PUSH_NONVOL;
|
||||
opinfo = regId;
|
||||
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t saRegId = frame.saRegId();
|
||||
if (saRegId != BaseReg::kIdBad && saRegId != x86::Gp::kIdSp)
|
||||
uint32_t stackArgsRegId = layout.getStackArgsRegId();
|
||||
if (stackArgsRegId != Globals::kInvalidRegId && stackArgsRegId != X86Gp::kIdSp)
|
||||
{
|
||||
saReg.setId(saRegId);
|
||||
if (!(frame.hasPreservedFP() && saRegId == x86::Gp::kIdBp))
|
||||
saReg.setId(stackArgsRegId);
|
||||
if (!(layout.hasPreservedFP() && stackArgsRegId == X86Gp::kIdBp))
|
||||
{
|
||||
// Emit: 'mov saReg, zsp'.
|
||||
assembler.mov(saReg, zsp);
|
||||
emitter->mov(saReg, zsp);
|
||||
}
|
||||
}
|
||||
|
||||
if (frame.hasDynamicAlignment())
|
||||
if (layout.hasDynamicAlignment())
|
||||
{
|
||||
// Emit: 'and zsp, StackAlignment'.
|
||||
assembler.and_(zsp, -static_cast<int32_t>(frame.finalStackAlignment()));
|
||||
emitter->and_(zsp, -static_cast<int32_t>(layout.getStackAlignment()));
|
||||
}
|
||||
|
||||
if (frame.hasStackAdjustment())
|
||||
if (layout.hasStackAdjustment())
|
||||
{
|
||||
// Emit: 'sub zsp, StackAdjustment'.
|
||||
assembler.sub(zsp, frame.stackAdjustment());
|
||||
emitter->sub(zsp, layout.getStackAdjustment());
|
||||
|
||||
uint32_t stackadjust = frame.stackAdjustment();
|
||||
uint32_t stackadjust = layout.getStackAdjustment();
|
||||
if (stackadjust <= 128)
|
||||
{
|
||||
opoffset = (uint32_t)assembler.offset();
|
||||
opoffset = (uint32_t)assembler.getOffset();
|
||||
opcode = UWOP_ALLOC_SMALL;
|
||||
opinfo = stackadjust / 8 - 1;
|
||||
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
|
||||
}
|
||||
else if (stackadjust <= 512 * 1024 - 8)
|
||||
{
|
||||
opoffset = (uint32_t)assembler.offset();
|
||||
opoffset = (uint32_t)assembler.getOffset();
|
||||
opcode = UWOP_ALLOC_LARGE;
|
||||
opinfo = 0;
|
||||
codes.Push(stackadjust / 8);
|
||||
|
|
@ -174,7 +179,7 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::FuncNode *func)
|
|||
}
|
||||
else
|
||||
{
|
||||
opoffset = (uint32_t)assembler.offset();
|
||||
opoffset = (uint32_t)assembler.getOffset();
|
||||
opcode = UWOP_ALLOC_LARGE;
|
||||
opinfo = 1;
|
||||
codes.Push((uint16_t)(stackadjust >> 16));
|
||||
|
|
@ -183,22 +188,21 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::FuncNode *func)
|
|||
}
|
||||
}
|
||||
|
||||
if (frame.hasDynamicAlignment() && frame.hasDAOffset())
|
||||
if (layout.hasDynamicAlignment() && layout.hasDsaSlotUsed())
|
||||
{
|
||||
// Emit: 'mov [zsp + dsaSlot], saReg'.
|
||||
x86::Mem saMem = x86::ptr(zsp, int32_t(frame.daOffset()));
|
||||
assembler.mov(saMem, saReg);
|
||||
X86Mem saMem = x86::ptr(zsp, layout._dsaSlot);
|
||||
emitter->mov(saMem, saReg);
|
||||
}
|
||||
|
||||
uint32_t xmmSaved = frame.savedRegs(x86::Reg::kGroupVec);
|
||||
uint32_t xmmSaved = layout.getSavedRegs(X86Reg::kKindVec);
|
||||
if (xmmSaved)
|
||||
{
|
||||
int vecOffset = frame.nonGpSaveOffset();
|
||||
x86::Mem vecBase = x86::ptr(zsp, vecOffset);
|
||||
x86::Reg vecReg = x86::xmm(0);
|
||||
bool avx = frame.isAvxEnabled();
|
||||
bool aligned = frame.hasAlignedVecSR();
|
||||
uint32_t vecInst = aligned ? (avx ? x86::Inst::kIdVmovaps : x86::Inst::kIdMovaps) : (avx ? x86::Inst::kIdVmovups : x86::Inst::kIdMovups);
|
||||
X86Mem vecBase = x86::ptr(zsp, layout.getVecStackOffset());
|
||||
X86Reg vecReg = x86::xmm(0);
|
||||
bool avx = layout.isAvxEnabled();
|
||||
bool aligned = layout.hasAlignedVecSR();
|
||||
uint32_t vecInst = aligned ? (avx ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps) : (avx ? X86Inst::kIdVmovups : X86Inst::kIdMovups);
|
||||
uint32_t vecSize = 16;
|
||||
for (uint32_t i = xmmSaved, regId = 0; i; i >>= 1, regId++)
|
||||
{
|
||||
|
|
@ -206,24 +210,24 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::FuncNode *func)
|
|||
|
||||
// Emit 'movaps|movups [zsp + X], xmm0..15'.
|
||||
vecReg.setId(regId);
|
||||
assembler.emit(vecInst, vecBase, vecReg);
|
||||
emitter->emit(vecInst, vecBase, vecReg);
|
||||
vecBase.addOffsetLo32(static_cast<int32_t>(vecSize));
|
||||
|
||||
if (vecBase.offsetLo32() / vecSize < (1 << 16))
|
||||
if (vecBase.getOffsetLo32() / vecSize < (1 << 16))
|
||||
{
|
||||
opoffset = (uint32_t)assembler.offset();
|
||||
opoffset = (uint32_t)assembler.getOffset();
|
||||
opcode = UWOP_SAVE_XMM128;
|
||||
opinfo = regId;
|
||||
codes.Push(vecBase.offsetLo32() / vecSize);
|
||||
codes.Push(vecBase.getOffsetLo32() / vecSize);
|
||||
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
|
||||
}
|
||||
else
|
||||
{
|
||||
opoffset = (uint32_t)assembler.offset();
|
||||
opoffset = (uint32_t)assembler.getOffset();
|
||||
opcode = UWOP_SAVE_XMM128_FAR;
|
||||
opinfo = regId;
|
||||
codes.Push((uint16_t)(vecBase.offsetLo32() >> 16));
|
||||
codes.Push((uint16_t)vecBase.offsetLo32());
|
||||
codes.Push((uint16_t)(vecBase.getOffsetLo32() >> 16));
|
||||
codes.Push((uint16_t)vecBase.getOffsetLo32());
|
||||
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
|
||||
}
|
||||
}
|
||||
|
|
@ -232,7 +236,7 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::FuncNode *func)
|
|||
// Build the UNWIND_INFO structure:
|
||||
|
||||
uint16_t version = 1, flags = 0, frameRegister = 0, frameOffset = 0;
|
||||
uint16_t sizeOfProlog = (uint16_t)assembler.offset();
|
||||
uint16_t sizeOfProlog = (uint16_t)assembler.getOffset();
|
||||
uint16_t countOfCodes = (uint16_t)codes.Size();
|
||||
|
||||
TArray<uint16_t> info;
|
||||
|
|
@ -252,14 +256,10 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
|
|||
{
|
||||
using namespace asmjit;
|
||||
|
||||
FuncNode *func = compiler->Codegen();
|
||||
if (code->flatten() != kErrorOk)
|
||||
return nullptr;
|
||||
if (code->resolveUnresolvedLinks() != kErrorOk)
|
||||
return nullptr;
|
||||
CCFunc *func = compiler->Codegen();
|
||||
|
||||
size_t estimatedCodeSize = Support::alignUp(code->codeSize(), 16);
|
||||
if (estimatedCodeSize == 0)
|
||||
size_t codeSize = code->getCodeSize();
|
||||
if (codeSize == 0)
|
||||
return nullptr;
|
||||
|
||||
#ifdef _WIN64
|
||||
|
|
@ -271,24 +271,24 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
|
|||
size_t functionTableSize = 0;
|
||||
#endif
|
||||
|
||||
uint8_t *p = (uint8_t *)AllocJitMemory(estimatedCodeSize + unwindInfoSize + functionTableSize);
|
||||
codeSize = (codeSize + 15) / 16 * 16;
|
||||
|
||||
uint8_t *p = (uint8_t *)AllocJitMemory(codeSize + unwindInfoSize + functionTableSize);
|
||||
if (!p)
|
||||
return nullptr;
|
||||
|
||||
if (code->relocateToBase((uintptr_t)p) != kErrorOk)
|
||||
size_t relocSize = code->relocate(p);
|
||||
if (relocSize == 0)
|
||||
return nullptr;
|
||||
|
||||
size_t codeSize = code->codeSize();
|
||||
for (Section* section : code->sections())
|
||||
memcpy(p + size_t(section->offset()), section->data(), size_t(section->bufferSize()));
|
||||
|
||||
size_t unwindStart = Support::alignUp(codeSize, 16);
|
||||
size_t unwindStart = relocSize;
|
||||
unwindStart = (unwindStart + 15) / 16 * 16;
|
||||
JitBlockPos -= codeSize - unwindStart;
|
||||
|
||||
#ifdef _WIN64
|
||||
uint8_t *baseaddr = JitBlocks.Last();
|
||||
uint8_t *startaddr = p;
|
||||
uint8_t *endaddr = p + codeSize;
|
||||
uint8_t *endaddr = p + relocSize;
|
||||
uint8_t *unwindptr = p + unwindStart;
|
||||
memcpy(unwindptr, &unwindInfo[0], unwindInfoSize);
|
||||
|
||||
|
|
@ -403,7 +403,7 @@ static void WriteCIE(TArray<uint8_t> &stream, const TArray<uint8_t> &cieInstruct
|
|||
unsigned int lengthPos = stream.Size();
|
||||
WriteUInt32(stream, 0); // Length
|
||||
WriteUInt32(stream, 0); // CIE ID
|
||||
|
||||
|
||||
WriteUInt8(stream, 1); // CIE Version
|
||||
WriteUInt8(stream, 'z');
|
||||
WriteUInt8(stream, 'R'); // fde encoding
|
||||
|
|
@ -428,7 +428,7 @@ static void WriteFDE(TArray<uint8_t> &stream, const TArray<uint8_t> &fdeInstruct
|
|||
WriteUInt32(stream, 0); // Length
|
||||
uint32_t offsetToCIE = stream.Size() - cieLocation;
|
||||
WriteUInt32(stream, offsetToCIE);
|
||||
|
||||
|
||||
functionStart = stream.Size();
|
||||
WriteUInt64(stream, 0); // func start
|
||||
WriteUInt64(stream, 0); // func size
|
||||
|
|
@ -486,7 +486,7 @@ static void WriteRegisterStackLocation(TArray<uint8_t> &instructions, int dwarfR
|
|||
WriteULEB128(instructions, stackLocation);
|
||||
}
|
||||
|
||||
static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::FuncNode *func, unsigned int &functionStart)
|
||||
static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::CCFunc *func, unsigned int &functionStart)
|
||||
{
|
||||
using namespace asmjit;
|
||||
|
||||
|
|
@ -499,67 +499,71 @@ static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::FuncNode *func, unsigned int
|
|||
//
|
||||
// The CFI_Parser<A>::decodeFDE parser on the other side..
|
||||
// https://github.com/llvm-mirror/libunwind/blob/master/src/DwarfParser.hpp
|
||||
|
||||
|
||||
// Asmjit -> DWARF register id
|
||||
int dwarfRegId[16];
|
||||
dwarfRegId[x86::Gp::kIdAx] = 0;
|
||||
dwarfRegId[x86::Gp::kIdDx] = 1;
|
||||
dwarfRegId[x86::Gp::kIdCx] = 2;
|
||||
dwarfRegId[x86::Gp::kIdBx] = 3;
|
||||
dwarfRegId[x86::Gp::kIdSi] = 4;
|
||||
dwarfRegId[x86::Gp::kIdDi] = 5;
|
||||
dwarfRegId[x86::Gp::kIdBp] = 6;
|
||||
dwarfRegId[x86::Gp::kIdSp] = 7;
|
||||
dwarfRegId[x86::Gp::kIdR8] = 8;
|
||||
dwarfRegId[x86::Gp::kIdR9] = 9;
|
||||
dwarfRegId[x86::Gp::kIdR10] = 10;
|
||||
dwarfRegId[x86::Gp::kIdR11] = 11;
|
||||
dwarfRegId[x86::Gp::kIdR12] = 12;
|
||||
dwarfRegId[x86::Gp::kIdR13] = 13;
|
||||
dwarfRegId[x86::Gp::kIdR14] = 14;
|
||||
dwarfRegId[x86::Gp::kIdR15] = 15;
|
||||
dwarfRegId[X86Gp::kIdAx] = 0;
|
||||
dwarfRegId[X86Gp::kIdDx] = 1;
|
||||
dwarfRegId[X86Gp::kIdCx] = 2;
|
||||
dwarfRegId[X86Gp::kIdBx] = 3;
|
||||
dwarfRegId[X86Gp::kIdSi] = 4;
|
||||
dwarfRegId[X86Gp::kIdDi] = 5;
|
||||
dwarfRegId[X86Gp::kIdBp] = 6;
|
||||
dwarfRegId[X86Gp::kIdSp] = 7;
|
||||
dwarfRegId[X86Gp::kIdR8] = 8;
|
||||
dwarfRegId[X86Gp::kIdR9] = 9;
|
||||
dwarfRegId[X86Gp::kIdR10] = 10;
|
||||
dwarfRegId[X86Gp::kIdR11] = 11;
|
||||
dwarfRegId[X86Gp::kIdR12] = 12;
|
||||
dwarfRegId[X86Gp::kIdR13] = 13;
|
||||
dwarfRegId[X86Gp::kIdR14] = 14;
|
||||
dwarfRegId[X86Gp::kIdR15] = 15;
|
||||
int dwarfRegRAId = 16;
|
||||
int dwarfRegXmmId = 17;
|
||||
|
||||
|
||||
TArray<uint8_t> cieInstructions;
|
||||
TArray<uint8_t> fdeInstructions;
|
||||
|
||||
uint8_t returnAddressReg = dwarfRegRAId;
|
||||
int stackOffset = 8; // Offset from RSP to the Canonical Frame Address (CFA) - stack position where the CALL return address is stored
|
||||
|
||||
WriteDefineCFA(cieInstructions, dwarfRegId[x86::Gp::kIdSp], stackOffset);
|
||||
WriteDefineCFA(cieInstructions, dwarfRegId[X86Gp::kIdSp], stackOffset);
|
||||
WriteRegisterStackLocation(cieInstructions, returnAddressReg, stackOffset);
|
||||
|
||||
FuncFrameLayout layout;
|
||||
Error error = layout.init(func->getDetail(), func->getFrameInfo());
|
||||
if (error != kErrorOk)
|
||||
I_Error("FuncFrameLayout.init failed");
|
||||
|
||||
FuncFrame frame = func->frame();
|
||||
|
||||
// We need a dummy assembler for instruction size calculations
|
||||
// We need a dummy emitter for instruction size calculations
|
||||
CodeHolder code;
|
||||
code.init(GetHostCodeInfo());
|
||||
x86::Assembler assembler(&code);
|
||||
X86Assembler assembler(&code);
|
||||
X86Emitter *emitter = assembler.asEmitter();
|
||||
uint64_t lastOffset = 0;
|
||||
|
||||
// Note: the following code must match exactly what X86Internal::emitProlog does
|
||||
|
||||
x86::Gp zsp = assembler.zsp(); // ESP|RSP register.
|
||||
x86::Gp zbp = assembler.zsp(); // EBP|RBP register.
|
||||
zbp.setId(x86::Gp::kIdBp);
|
||||
x86::Gp gpReg = assembler.zsp(); // General purpose register (temporary).
|
||||
x86::Gp saReg = assembler.zsp(); // Stack-arguments base register.
|
||||
uint32_t gpSaved = frame.savedRegs(x86::Reg::kGroupGp);
|
||||
X86Gp zsp = emitter->zsp(); // ESP|RSP register.
|
||||
X86Gp zbp = emitter->zsp(); // EBP|RBP register.
|
||||
zbp.setId(X86Gp::kIdBp);
|
||||
X86Gp gpReg = emitter->zsp(); // General purpose register (temporary).
|
||||
X86Gp saReg = emitter->zsp(); // Stack-arguments base register.
|
||||
uint32_t gpSaved = layout.getSavedRegs(X86Reg::kKindGp);
|
||||
|
||||
if (frame.hasPreservedFP())
|
||||
if (layout.hasPreservedFP())
|
||||
{
|
||||
// Emit: 'push zbp'
|
||||
// 'mov zbp, zsp'.
|
||||
gpSaved &= ~Support::bitMask(x86::Gp::kIdBp);
|
||||
assembler.push(zbp);
|
||||
gpSaved &= ~Utils::mask(X86Gp::kIdBp);
|
||||
emitter->push(zbp);
|
||||
|
||||
stackOffset += 8;
|
||||
WriteAdvanceLoc(fdeInstructions, assembler.offset(), lastOffset);
|
||||
WriteAdvanceLoc(fdeInstructions, assembler.getOffset(), lastOffset);
|
||||
WriteDefineStackOffset(fdeInstructions, stackOffset);
|
||||
WriteRegisterStackLocation(fdeInstructions, dwarfRegId[x86::Gp::kIdBp], stackOffset);
|
||||
WriteRegisterStackLocation(fdeInstructions, dwarfRegId[X86Gp::kIdBp], stackOffset);
|
||||
|
||||
assembler.mov(zbp, zsp);
|
||||
emitter->mov(zbp, zsp);
|
||||
}
|
||||
|
||||
if (gpSaved)
|
||||
|
|
@ -569,60 +573,58 @@ static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::FuncNode *func, unsigned int
|
|||
if (!(i & 0x1)) continue;
|
||||
// Emit: 'push gp' sequence.
|
||||
gpReg.setId(regId);
|
||||
assembler.push(gpReg);
|
||||
emitter->push(gpReg);
|
||||
|
||||
stackOffset += 8;
|
||||
WriteAdvanceLoc(fdeInstructions, assembler.offset(), lastOffset);
|
||||
WriteAdvanceLoc(fdeInstructions, assembler.getOffset(), lastOffset);
|
||||
WriteDefineStackOffset(fdeInstructions, stackOffset);
|
||||
WriteRegisterStackLocation(fdeInstructions, dwarfRegId[regId], stackOffset);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t saRegId = frame.saRegId();
|
||||
if (saRegId != BaseReg::kIdBad && saRegId != x86::Gp::kIdSp)
|
||||
uint32_t stackArgsRegId = layout.getStackArgsRegId();
|
||||
if (stackArgsRegId != Globals::kInvalidRegId && stackArgsRegId != X86Gp::kIdSp)
|
||||
{
|
||||
saReg.setId(saRegId);
|
||||
if (frame.hasPreservedFP()) {
|
||||
if (saRegId != x86::Gp::kIdBp)
|
||||
assembler.mov(saReg, zbp);
|
||||
}
|
||||
else {
|
||||
assembler.mov(saReg, zsp);
|
||||
saReg.setId(stackArgsRegId);
|
||||
if (!(layout.hasPreservedFP() && stackArgsRegId == X86Gp::kIdBp))
|
||||
{
|
||||
// Emit: 'mov saReg, zsp'.
|
||||
emitter->mov(saReg, zsp);
|
||||
}
|
||||
}
|
||||
|
||||
if (frame.hasDynamicAlignment())
|
||||
if (layout.hasDynamicAlignment())
|
||||
{
|
||||
// Emit: 'and zsp, StackAlignment'.
|
||||
assembler.and_(zsp, -static_cast<int32_t>(frame.finalStackAlignment()));
|
||||
emitter->and_(zsp, -static_cast<int32_t>(layout.getStackAlignment()));
|
||||
}
|
||||
|
||||
if (frame.hasStackAdjustment())
|
||||
if (layout.hasStackAdjustment())
|
||||
{
|
||||
// Emit: 'sub zsp, StackAdjustment'.
|
||||
assembler.sub(zsp, frame.stackAdjustment());
|
||||
emitter->sub(zsp, layout.getStackAdjustment());
|
||||
|
||||
stackOffset += frame.stackAdjustment();
|
||||
WriteAdvanceLoc(fdeInstructions, assembler.offset(), lastOffset);
|
||||
stackOffset += layout.getStackAdjustment();
|
||||
WriteAdvanceLoc(fdeInstructions, assembler.getOffset(), lastOffset);
|
||||
WriteDefineStackOffset(fdeInstructions, stackOffset);
|
||||
}
|
||||
|
||||
if (frame.hasDynamicAlignment() && frame.hasDAOffset())
|
||||
if (layout.hasDynamicAlignment() && layout.hasDsaSlotUsed())
|
||||
{
|
||||
// Emit: 'mov [zsp + dsaSlot], saReg'.
|
||||
x86::Mem saMem = x86::ptr(zsp, int32_t(frame.daOffset()));
|
||||
assembler.mov(saMem, saReg);
|
||||
X86Mem saMem = x86::ptr(zsp, layout._dsaSlot);
|
||||
emitter->mov(saMem, saReg);
|
||||
}
|
||||
|
||||
uint32_t xmmSaved = frame.savedRegs(x86::Reg::kGroupVec);
|
||||
uint32_t xmmSaved = layout.getSavedRegs(X86Reg::kKindVec);
|
||||
if (xmmSaved)
|
||||
{
|
||||
int vecOffset = frame.nonGpSaveOffset();
|
||||
x86::Mem vecBase = x86::ptr(zsp, vecOffset);
|
||||
x86::Reg vecReg = x86::xmm(0);
|
||||
bool avx = frame.isAvxEnabled();
|
||||
bool aligned = frame.hasAlignedVecSR();
|
||||
uint32_t vecInst = aligned ? (avx ? x86::Inst::kIdVmovaps : x86::Inst::kIdMovaps) : (avx ? x86::Inst::kIdVmovups : x86::Inst::kIdMovups);
|
||||
int vecOffset = layout.getVecStackOffset();
|
||||
X86Mem vecBase = x86::ptr(zsp, layout.getVecStackOffset());
|
||||
X86Reg vecReg = x86::xmm(0);
|
||||
bool avx = layout.isAvxEnabled();
|
||||
bool aligned = layout.hasAlignedVecSR();
|
||||
uint32_t vecInst = aligned ? (avx ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps) : (avx ? X86Inst::kIdVmovups : X86Inst::kIdMovups);
|
||||
uint32_t vecSize = 16;
|
||||
for (uint32_t i = xmmSaved, regId = 0; i; i >>= 1, regId++)
|
||||
{
|
||||
|
|
@ -630,10 +632,10 @@ static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::FuncNode *func, unsigned int
|
|||
|
||||
// Emit 'movaps|movups [zsp + X], xmm0..15'.
|
||||
vecReg.setId(regId);
|
||||
assembler.emit(vecInst, vecBase, vecReg);
|
||||
emitter->emit(vecInst, vecBase, vecReg);
|
||||
vecBase.addOffsetLo32(static_cast<int32_t>(vecSize));
|
||||
|
||||
WriteAdvanceLoc(fdeInstructions, assembler.offset(), lastOffset);
|
||||
WriteAdvanceLoc(fdeInstructions, assembler.getOffset(), lastOffset);
|
||||
WriteRegisterStackLocation(fdeInstructions, dwarfRegXmmId + regId, stackOffset - vecOffset);
|
||||
vecOffset += static_cast<int32_t>(vecSize);
|
||||
}
|
||||
|
|
@ -650,37 +652,33 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
|
|||
{
|
||||
using namespace asmjit;
|
||||
|
||||
FuncNode *func = compiler->Codegen();
|
||||
if (code->flatten() != kErrorOk)
|
||||
return nullptr;
|
||||
if (code->resolveUnresolvedLinks() != kErrorOk)
|
||||
return nullptr;
|
||||
CCFunc *func = compiler->Codegen();
|
||||
|
||||
size_t estimatedCodeSize = Support::alignUp(code->codeSize(), 16);
|
||||
if (estimatedCodeSize == 0)
|
||||
size_t codeSize = code->getCodeSize();
|
||||
if (codeSize == 0)
|
||||
return nullptr;
|
||||
|
||||
unsigned int fdeFunctionStart = 0;
|
||||
TArray<uint8_t> unwindInfo = CreateUnwindInfoUnix(func, fdeFunctionStart);
|
||||
size_t unwindInfoSize = unwindInfo.Size();
|
||||
|
||||
uint8_t *p = (uint8_t *)AllocJitMemory(estimatedCodeSize + unwindInfoSize);
|
||||
codeSize = (codeSize + 15) / 16 * 16;
|
||||
|
||||
uint8_t *p = (uint8_t *)AllocJitMemory(codeSize + unwindInfoSize);
|
||||
if (!p)
|
||||
return nullptr;
|
||||
|
||||
if (code->relocateToBase((uintptr_t)p) != kErrorOk)
|
||||
size_t relocSize = code->relocate(p);
|
||||
if (relocSize == 0)
|
||||
return nullptr;
|
||||
|
||||
size_t codeSize = code->codeSize();
|
||||
for (Section* section : code->sections())
|
||||
memcpy(p + size_t(section->offset()), section->data(), size_t(section->bufferSize()));
|
||||
|
||||
size_t unwindStart = Support::alignUp(codeSize, 16);
|
||||
size_t unwindStart = relocSize;
|
||||
unwindStart = (unwindStart + 15) / 16 * 16;
|
||||
JitBlockPos -= codeSize - unwindStart;
|
||||
|
||||
uint8_t *baseaddr = JitBlocks.Last();
|
||||
uint8_t *startaddr = p;
|
||||
uint8_t *endaddr = p + codeSize;
|
||||
uint8_t *endaddr = p + relocSize;
|
||||
uint8_t *unwindptr = p + unwindStart;
|
||||
memcpy(unwindptr, &unwindInfo[0], unwindInfoSize);
|
||||
|
||||
|
|
@ -704,7 +702,7 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
|
|||
uint64_t length64 = *((uint64_t *)(entry + 4));
|
||||
if (length64 == 0)
|
||||
break;
|
||||
|
||||
|
||||
uint64_t offset = *((uint64_t *)(entry + 12));
|
||||
if (offset != 0)
|
||||
{
|
||||
|
|
@ -752,7 +750,7 @@ void JitRelease()
|
|||
#endif
|
||||
for (auto p : JitBlocks)
|
||||
{
|
||||
asmjit::VirtMem::release(p, 1024 * 1024);
|
||||
asmjit::OSUtils::releaseVirtualMemory(p, 1024 * 1024);
|
||||
}
|
||||
JitDebugInfo.Clear();
|
||||
JitFrames.Clear();
|
||||
|
|
|
|||
|
|
@ -133,8 +133,8 @@ void JitCompiler::EmitSV2_R()
|
|||
{
|
||||
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp.r32(), regD[C]);
|
||||
cc.add(tmp, regA[A]);
|
||||
cc.mov(tmp, regA[A]);
|
||||
cc.add(tmp, regD[C]);
|
||||
cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]);
|
||||
cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]);
|
||||
}
|
||||
|
|
@ -154,8 +154,8 @@ void JitCompiler::EmitSV3_R()
|
|||
{
|
||||
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.mov(tmp.r32(), regD[C]);
|
||||
cc.add(tmp, regA[A]);
|
||||
cc.mov(tmp, regA[A]);
|
||||
cc.add(tmp, regD[C]);
|
||||
cc.movsd(asmjit::x86::qword_ptr(tmp), regF[B]);
|
||||
cc.movsd(asmjit::x86::qword_ptr(tmp, 8), regF[B + 1]);
|
||||
cc.movsd(asmjit::x86::qword_ptr(tmp, 16), regF[B + 2]);
|
||||
|
|
@ -166,11 +166,11 @@ void JitCompiler::EmitSBIT()
|
|||
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||
auto tmp1 = newTempInt32();
|
||||
auto tmp2 = newTempInt32();
|
||||
cc.movzx(tmp1, asmjit::x86::byte_ptr(regA[A]));
|
||||
cc.mov(tmp1, asmjit::x86::byte_ptr(regA[A]));
|
||||
cc.mov(tmp2, tmp1);
|
||||
cc.or_(tmp1, (int)C);
|
||||
cc.and_(tmp2, ~(int)C);
|
||||
cc.test(regD[B], regD[B]);
|
||||
cc.cmove(tmp1, tmp2);
|
||||
cc.mov(asmjit::x86::byte_ptr(regA[A]), tmp1.r8());
|
||||
cc.mov(asmjit::x86::byte_ptr(regA[A]), tmp1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "stats.h"
|
||||
|
||||
// To do: get cmake to define these..
|
||||
#define ASMJIT_BUILD_EMBED
|
||||
#define ASMJIT_STATIC
|
||||
|
||||
#include <asmjit/asmjit.h>
|
||||
|
|
@ -36,7 +37,7 @@ class JitCompiler
|
|||
public:
|
||||
JitCompiler(asmjit::CodeHolder *code, VMScriptFunction *sfunc) : cc(code), sfunc(sfunc) { }
|
||||
|
||||
asmjit::FuncNode *Codegen();
|
||||
asmjit::CCFunc *Codegen();
|
||||
VMScriptFunction *GetScriptFunction() { return sfunc; }
|
||||
|
||||
TArray<JitLineInfo> LineInfo;
|
||||
|
|
@ -60,7 +61,7 @@ private:
|
|||
void EmitPopFrame();
|
||||
|
||||
void EmitNativeCall(VMNativeFunction *target);
|
||||
void EmitVMCall(asmjit::x86::Gp ptr, VMFunction *target);
|
||||
void EmitVMCall(asmjit::X86Gp ptr, VMFunction *target);
|
||||
void EmitVtbl(const VMOP *op);
|
||||
|
||||
int StoreCallParams();
|
||||
|
|
@ -119,10 +120,10 @@ private:
|
|||
auto tmp = newTempXmmSd();
|
||||
|
||||
const int64_t absMaskInt = 0x7FFFFFFFFFFFFFFF;
|
||||
auto absMask = cc.newDoubleConst(asmjit::ConstPool::kScopeLocal, reinterpret_cast<const double&>(absMaskInt));
|
||||
auto absMask = cc.newDoubleConst(asmjit::kConstScopeLocal, reinterpret_cast<const double&>(absMaskInt));
|
||||
auto absMaskXmm = newTempXmmPd();
|
||||
|
||||
auto epsilon = cc.newDoubleConst(asmjit::ConstPool::kScopeLocal, VM_EPSILON);
|
||||
auto epsilon = cc.newDoubleConst(asmjit::kConstScopeLocal, VM_EPSILON);
|
||||
auto epsilonXmm = newTempXmmSd();
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
|
|
@ -160,37 +161,37 @@ private:
|
|||
return (uint64_t)(ptrdiff_t)d;
|
||||
}
|
||||
|
||||
void CallSqrt(const asmjit::x86::Xmm &a, const asmjit::x86::Xmm &b);
|
||||
void CallSqrt(const asmjit::X86Xmm &a, const asmjit::X86Xmm &b);
|
||||
|
||||
static void CallAssignString(FString* to, FString* from) {
|
||||
*to = *from;
|
||||
}
|
||||
|
||||
template<typename RetType, typename P1>
|
||||
asmjit::FuncCallNode *CreateCall(RetType(*func)(P1 p1)) { return cc.call(asmjit::imm(reinterpret_cast<void*>(static_cast<RetType(*)(P1)>(func))), asmjit::FuncSignatureT<RetType, P1>()); }
|
||||
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1)) { return cc.call(asmjit::imm_ptr(reinterpret_cast<void*>(static_cast<RetType(*)(P1)>(func))), asmjit::FuncSignature1<RetType, P1>()); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2>
|
||||
asmjit::FuncCallNode *CreateCall(RetType(*func)(P1 p1, P2 p2)) { return cc.call(asmjit::imm(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2)>(func))), asmjit::FuncSignatureT<RetType, P1, P2>()); }
|
||||
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2)) { return cc.call(asmjit::imm_ptr(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2)>(func))), asmjit::FuncSignature2<RetType, P1, P2>()); }
|
||||
|
||||
template<typename RetType, typename P1, typename P2, typename P3>
|
||||
asmjit::FuncCallNode *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3)) { return cc.call(asmjit::imm(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3)>(func))), asmjit::FuncSignatureT<RetType, P1, P2, P3>()); }
|
||||
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3)) { return cc.call(asmjit::imm_ptr(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::FuncCallNode *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4)) { return cc.call(asmjit::imm(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4)>(func))), asmjit::FuncSignatureT<RetType, P1, P2, P3, P4>()); }
|
||||
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4)) { return cc.call(asmjit::imm_ptr(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::FuncCallNode *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)) { return cc.call(asmjit::imm(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5)>(func))), asmjit::FuncSignatureT<RetType, P1, P2, P3, P4, P5>()); }
|
||||
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)) { return cc.call(asmjit::imm_ptr(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::FuncCallNode *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)) { return cc.call(asmjit::imm(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6)>(func))), asmjit::FuncSignatureT<RetType, P1, P2, P3, P4, P5, P6>()); }
|
||||
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)) { return cc.call(asmjit::imm_ptr(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::FuncCallNode *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)) { return cc.call(asmjit::imm(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6, P7)>(func))), asmjit::FuncSignatureT<RetType, P1, P2, P3, P4, P5, P6, P7>()); }
|
||||
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)) { return cc.call(asmjit::imm_ptr(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6, P7)>(func))), asmjit::FuncSignature7<RetType, P1, P2, P3, P4, P5, P6, P7>()); }
|
||||
|
||||
FString regname;
|
||||
size_t tmpPosInt32, tmpPosInt64, tmpPosIntPtr, tmpPosXmmSd, tmpPosXmmSs, tmpPosXmmPd, resultPosInt32, resultPosIntPtr, resultPosXmmSd;
|
||||
std::vector<asmjit::x86::Gp> regTmpInt32, regTmpInt64, regTmpIntPtr, regResultInt32, regResultIntPtr;
|
||||
std::vector<asmjit::x86::Xmm> regTmpXmmSd, regTmpXmmSs, regTmpXmmPd, regResultXmmSd;
|
||||
std::vector<asmjit::X86Gp> regTmpInt32, regTmpInt64, regTmpIntPtr, regResultInt32, regResultIntPtr;
|
||||
std::vector<asmjit::X86Xmm> regTmpXmmSd, regTmpXmmSs, regTmpXmmPd, regResultXmmSd;
|
||||
|
||||
void ResetTemp()
|
||||
{
|
||||
|
|
@ -216,16 +217,16 @@ private:
|
|||
return tmpVector[tmpPos++];
|
||||
}
|
||||
|
||||
asmjit::x86::Gp newTempInt32() { return newTempRegister(regTmpInt32, tmpPosInt32, "tmpDword", [&](const char *name) { return cc.newInt32(name); }); }
|
||||
asmjit::x86::Gp newTempInt64() { return newTempRegister(regTmpInt64, tmpPosInt64, "tmpQword", [&](const char *name) { return cc.newInt64(name); }); }
|
||||
asmjit::x86::Gp newTempIntPtr() { return newTempRegister(regTmpIntPtr, tmpPosIntPtr, "tmpPtr", [&](const char *name) { return cc.newIntPtr(name); }); }
|
||||
asmjit::x86::Xmm newTempXmmSd() { return newTempRegister(regTmpXmmSd, tmpPosXmmSd, "tmpXmmSd", [&](const char *name) { return cc.newXmmSd(name); }); }
|
||||
asmjit::x86::Xmm newTempXmmSs() { return newTempRegister(regTmpXmmSs, tmpPosXmmSs, "tmpXmmSs", [&](const char *name) { return cc.newXmmSs(name); }); }
|
||||
asmjit::x86::Xmm newTempXmmPd() { return newTempRegister(regTmpXmmPd, tmpPosXmmPd, "tmpXmmPd", [&](const char *name) { return cc.newXmmPd(name); }); }
|
||||
asmjit::X86Gp newTempInt32() { return newTempRegister(regTmpInt32, tmpPosInt32, "tmpDword", [&](const char *name) { return cc.newInt32(name); }); }
|
||||
asmjit::X86Gp newTempInt64() { return newTempRegister(regTmpInt64, tmpPosInt64, "tmpQword", [&](const char *name) { return cc.newInt64(name); }); }
|
||||
asmjit::X86Gp newTempIntPtr() { return newTempRegister(regTmpIntPtr, tmpPosIntPtr, "tmpPtr", [&](const char *name) { return cc.newIntPtr(name); }); }
|
||||
asmjit::X86Xmm newTempXmmSd() { return newTempRegister(regTmpXmmSd, tmpPosXmmSd, "tmpXmmSd", [&](const char *name) { return cc.newXmmSd(name); }); }
|
||||
asmjit::X86Xmm newTempXmmSs() { return newTempRegister(regTmpXmmSs, tmpPosXmmSs, "tmpXmmSs", [&](const char *name) { return cc.newXmmSs(name); }); }
|
||||
asmjit::X86Xmm newTempXmmPd() { return newTempRegister(regTmpXmmPd, tmpPosXmmPd, "tmpXmmPd", [&](const char *name) { return cc.newXmmPd(name); }); }
|
||||
|
||||
asmjit::x86::Gp newResultInt32() { return newTempRegister(regResultInt32, resultPosInt32, "resultDword", [&](const char *name) { return cc.newInt32(name); }); }
|
||||
asmjit::x86::Gp newResultIntPtr() { return newTempRegister(regResultIntPtr, resultPosIntPtr, "resultPtr", [&](const char *name) { return cc.newIntPtr(name); }); }
|
||||
asmjit::x86::Xmm newResultXmmSd() { return newTempRegister(regResultXmmSd, resultPosXmmSd, "resultXmmSd", [&](const char *name) { return cc.newXmmSd(name); }); }
|
||||
asmjit::X86Gp newResultInt32() { return newTempRegister(regResultInt32, resultPosInt32, "resultDword", [&](const char *name) { return cc.newInt32(name); }); }
|
||||
asmjit::X86Gp newResultIntPtr() { return newTempRegister(regResultIntPtr, resultPosIntPtr, "resultPtr", [&](const char *name) { return cc.newIntPtr(name); }); }
|
||||
asmjit::X86Xmm newResultXmmSd() { return newTempRegister(regResultXmmSd, resultPosXmmSd, "resultXmmSd", [&](const char *name) { return cc.newXmmSd(name); }); }
|
||||
|
||||
void EmitReadBarrier();
|
||||
|
||||
|
|
@ -236,22 +237,22 @@ private:
|
|||
static void ThrowArrayOutOfBounds(int index, int size);
|
||||
static void ThrowException(int reason);
|
||||
|
||||
asmjit::x86::Gp CheckRegD(int r0, int r1);
|
||||
asmjit::x86::Xmm CheckRegF(int r0, int r1);
|
||||
asmjit::x86::Xmm CheckRegF(int r0, int r1, int r2);
|
||||
asmjit::x86::Xmm CheckRegF(int r0, int r1, int r2, int r3);
|
||||
asmjit::x86::Gp CheckRegS(int r0, int r1);
|
||||
asmjit::x86::Gp CheckRegA(int r0, int r1);
|
||||
asmjit::X86Gp CheckRegD(int r0, int r1);
|
||||
asmjit::X86Xmm CheckRegF(int r0, int r1);
|
||||
asmjit::X86Xmm CheckRegF(int r0, int r1, int r2);
|
||||
asmjit::X86Xmm CheckRegF(int r0, int r1, int r2, int r3);
|
||||
asmjit::X86Gp CheckRegS(int r0, int r1);
|
||||
asmjit::X86Gp CheckRegA(int r0, int r1);
|
||||
|
||||
asmjit::x86::Compiler cc;
|
||||
asmjit::X86Compiler cc;
|
||||
VMScriptFunction *sfunc;
|
||||
|
||||
asmjit::FuncNode *func = nullptr;
|
||||
asmjit::x86::Gp args;
|
||||
asmjit::x86::Gp numargs;
|
||||
asmjit::x86::Gp ret;
|
||||
asmjit::x86::Gp numret;
|
||||
asmjit::x86::Gp stack;
|
||||
asmjit::CCFunc *func = nullptr;
|
||||
asmjit::X86Gp args;
|
||||
asmjit::X86Gp numargs;
|
||||
asmjit::X86Gp ret;
|
||||
asmjit::X86Gp numret;
|
||||
asmjit::X86Gp stack;
|
||||
|
||||
int offsetParams;
|
||||
int offsetF;
|
||||
|
|
@ -263,29 +264,29 @@ private:
|
|||
TArray<const VMOP *> ParamOpcodes;
|
||||
|
||||
void CheckVMFrame();
|
||||
asmjit::x86::Gp GetCallReturns();
|
||||
asmjit::X86Gp GetCallReturns();
|
||||
|
||||
bool vmframeAllocated = false;
|
||||
asmjit::BaseNode *vmframeCursor = nullptr;
|
||||
asmjit::x86::Gp vmframe;
|
||||
asmjit::CBNode *vmframeCursor = nullptr;
|
||||
asmjit::X86Gp vmframe;
|
||||
|
||||
bool callReturnsAllocated = false;
|
||||
asmjit::BaseNode *callReturnsCursor = nullptr;
|
||||
asmjit::x86::Gp callReturns;
|
||||
asmjit::CBNode *callReturnsCursor = nullptr;
|
||||
asmjit::X86Gp callReturns;
|
||||
|
||||
const int *konstd;
|
||||
const double *konstf;
|
||||
const FString *konsts;
|
||||
const FVoidObj *konsta;
|
||||
|
||||
TArray<asmjit::x86::Gp> regD;
|
||||
TArray<asmjit::x86::Xmm> regF;
|
||||
TArray<asmjit::x86::Gp> regA;
|
||||
TArray<asmjit::x86::Gp> regS;
|
||||
TArray<asmjit::X86Gp> regD;
|
||||
TArray<asmjit::X86Xmm> regF;
|
||||
TArray<asmjit::X86Gp> regA;
|
||||
TArray<asmjit::X86Gp> regS;
|
||||
|
||||
struct OpcodeLabel
|
||||
{
|
||||
asmjit::BaseNode *cursor = nullptr;
|
||||
asmjit::CBNode *cursor = nullptr;
|
||||
asmjit::Label label;
|
||||
bool inUse = false;
|
||||
};
|
||||
|
|
@ -326,7 +327,7 @@ public:
|
|||
class ThrowingErrorHandler : public asmjit::ErrorHandler
|
||||
{
|
||||
public:
|
||||
void handleError(asmjit::Error err, const char *message, asmjit::BaseEmitter *origin) override
|
||||
bool handleError(asmjit::Error err, const char *message, asmjit::CodeEmitter *origin) override
|
||||
{
|
||||
throw AsmJitException(err, message);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue