mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +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:
|
||||
|
||||
switch (sfunc->Code[i].op)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case OP_IJMP:
|
||||
case OP_TAIL:
|
||||
case OP_TAIL_K:
|
||||
if (sfunc->Code[i].op == OP_IJMP)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Partially implemented functions:
|
||||
|
||||
|
|
|
@ -138,12 +138,14 @@ void JitCompiler::EmitCALL_K()
|
|||
|
||||
void JitCompiler::EmitTAIL()
|
||||
{
|
||||
I_FatalError("EmitTAIL not implemented\n");
|
||||
EmitDoTail(regA[A]);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -160,8 +162,7 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
|
|||
if (B != NumParam)
|
||||
{
|
||||
paramsptr = cc.newIntPtr();
|
||||
cc.mov(paramsptr, params);
|
||||
cc.add(paramsptr, (int)((NumParam - B) * sizeof(VMValue)));
|
||||
cc.lea(paramsptr, x86::ptr(params, (int)((NumParam - B) * sizeof(VMValue))));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -196,6 +197,48 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
|
|||
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)
|
||||
{
|
||||
using namespace asmjit;
|
||||
|
|
|
@ -43,6 +43,7 @@ private:
|
|||
void EmitOpcode();
|
||||
|
||||
void EmitDoCall(asmjit::X86Gp ptr);
|
||||
void EmitDoTail(asmjit::X86Gp ptr);
|
||||
void StoreInOuts(int b);
|
||||
void LoadInOuts(int b);
|
||||
void LoadReturns(const VMOP *retval, int numret);
|
||||
|
|
Loading…
Reference in a new issue