mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 23:32:02 +00:00
- implement OP_TAIL and OP_TAIL_K
This commit is contained in:
parent
d032914c3d
commit
f61df60240
3 changed files with 49 additions and 12 deletions
|
@ -146,15 +146,8 @@ bool JitCompiler::CanJit(VMScriptFunction *sfunc)
|
||||||
{
|
{
|
||||||
// Functions not implemented at all yet:
|
// Functions not implemented at all yet:
|
||||||
|
|
||||||
switch (sfunc->Code[i].op)
|
if (sfunc->Code[i].op == OP_IJMP)
|
||||||
{
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case OP_IJMP:
|
|
||||||
case OP_TAIL:
|
|
||||||
case OP_TAIL_K:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Partially implemented functions:
|
// Partially implemented functions:
|
||||||
|
|
||||||
|
|
|
@ -138,12 +138,14 @@ void JitCompiler::EmitCALL_K()
|
||||||
|
|
||||||
void JitCompiler::EmitTAIL()
|
void JitCompiler::EmitTAIL()
|
||||||
{
|
{
|
||||||
I_FatalError("EmitTAIL not implemented\n");
|
EmitDoTail(regA[A]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitTAIL_K()
|
void JitCompiler::EmitTAIL_K()
|
||||||
{
|
{
|
||||||
I_FatalError("EmitTAIL_K not implemented\n");
|
auto ptr = cc.newIntPtr();
|
||||||
|
cc.mov(ptr, ToMemAddress(konsta[A].o));
|
||||||
|
EmitDoTail(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
|
void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
|
||||||
|
@ -160,8 +162,7 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
|
||||||
if (B != NumParam)
|
if (B != NumParam)
|
||||||
{
|
{
|
||||||
paramsptr = cc.newIntPtr();
|
paramsptr = cc.newIntPtr();
|
||||||
cc.mov(paramsptr, params);
|
cc.lea(paramsptr, x86::ptr(params, (int)((NumParam - B) * sizeof(VMValue))));
|
||||||
cc.add(paramsptr, (int)((NumParam - B) * sizeof(VMValue)));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -196,6 +197,48 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
|
||||||
ParamOpcodes.Resize(ParamOpcodes.Size() - B);
|
ParamOpcodes.Resize(ParamOpcodes.Size() - B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitCompiler::EmitDoTail(asmjit::X86Gp ptr)
|
||||||
|
{
|
||||||
|
// Whereas the CALL instruction uses its third operand to specify how many return values
|
||||||
|
// it expects, TAIL ignores its third operand and uses whatever was passed to this Exec call.
|
||||||
|
|
||||||
|
// Note: this is not a true tail call, but then again, it isn't in the vmexec implementation either..
|
||||||
|
|
||||||
|
using namespace asmjit;
|
||||||
|
|
||||||
|
if (NumParam < B)
|
||||||
|
I_FatalError("OP_TAIL parameter count does not match the number of preceding OP_PARAM instructions");
|
||||||
|
|
||||||
|
StoreInOuts(B); // Is REGT_ADDROF even allowed for (true) tail calls?
|
||||||
|
|
||||||
|
X86Gp paramsptr;
|
||||||
|
if (B != NumParam)
|
||||||
|
{
|
||||||
|
paramsptr = cc.newIntPtr();
|
||||||
|
cc.lea(paramsptr, x86::ptr(params, (int)((NumParam - B) * sizeof(VMValue))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
paramsptr = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = cc.newInt32();
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<const void*>(&JitCompiler::DoCall)), FuncSignature7<int, void*, void*, int, int, void*, void*, void*>());
|
||||||
|
call->setRet(0, result);
|
||||||
|
call->setArg(0, stack);
|
||||||
|
call->setArg(1, ptr);
|
||||||
|
call->setArg(2, asmjit::Imm(B));
|
||||||
|
call->setArg(3, numret);
|
||||||
|
call->setArg(4, paramsptr);
|
||||||
|
call->setArg(5, ret);
|
||||||
|
call->setArg(6, exceptInfo);
|
||||||
|
|
||||||
|
cc.ret(result);
|
||||||
|
|
||||||
|
NumParam -= B;
|
||||||
|
ParamOpcodes.Resize(ParamOpcodes.Size() - B);
|
||||||
|
}
|
||||||
|
|
||||||
void JitCompiler::StoreInOuts(int b)
|
void JitCompiler::StoreInOuts(int b)
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
|
@ -43,6 +43,7 @@ private:
|
||||||
void EmitOpcode();
|
void EmitOpcode();
|
||||||
|
|
||||||
void EmitDoCall(asmjit::X86Gp ptr);
|
void EmitDoCall(asmjit::X86Gp ptr);
|
||||||
|
void EmitDoTail(asmjit::X86Gp ptr);
|
||||||
void StoreInOuts(int b);
|
void StoreInOuts(int b);
|
||||||
void LoadInOuts(int b);
|
void LoadInOuts(int b);
|
||||||
void LoadReturns(const VMOP *retval, int numret);
|
void LoadReturns(const VMOP *retval, int numret);
|
||||||
|
|
Loading…
Reference in a new issue