mirror of https://github.com/ZDoom/gzdoom.git
- fix CALL_K and disable CALL
This commit is contained in:
parent
ced793b791
commit
afc3c6b562
|
@ -105,6 +105,9 @@ public:
|
||||||
}
|
}
|
||||||
else if (sfunc->Code[i].op == OP_PARAM)
|
else if (sfunc->Code[i].op == OP_PARAM)
|
||||||
{
|
{
|
||||||
|
if (!!(B & REGT_MULTIREG3) || !!(B & REGT_MULTIREG2))
|
||||||
|
return false;
|
||||||
|
|
||||||
switch (B)
|
switch (B)
|
||||||
{
|
{
|
||||||
case REGT_STRING:
|
case REGT_STRING:
|
||||||
|
@ -117,6 +120,9 @@ public:
|
||||||
}
|
}
|
||||||
else if (sfunc->Code[i].op == OP_RESULT)
|
else if (sfunc->Code[i].op == OP_RESULT)
|
||||||
{
|
{
|
||||||
|
if (!!(B & REGT_MULTIREG3) || !!(B & REGT_MULTIREG2))
|
||||||
|
return false;
|
||||||
|
|
||||||
if ((B & REGT_TYPE) == REGT_STRING)
|
if ((B & REGT_TYPE) == REGT_STRING)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +219,7 @@ private:
|
||||||
//EMIT_OP(IJMP);
|
//EMIT_OP(IJMP);
|
||||||
EMIT_OP(PARAM);
|
EMIT_OP(PARAM);
|
||||||
EMIT_OP(PARAMI);
|
EMIT_OP(PARAMI);
|
||||||
EMIT_OP(CALL);
|
//EMIT_OP(CALL);
|
||||||
EMIT_OP(CALL_K);
|
EMIT_OP(CALL_K);
|
||||||
EMIT_OP(VTBL);
|
EMIT_OP(VTBL);
|
||||||
EMIT_OP(SCOPE);
|
EMIT_OP(SCOPE);
|
||||||
|
@ -1003,6 +1009,7 @@ private:
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
||||||
int index = NumParam++;
|
int index = NumParam++;
|
||||||
|
ParamOpcodes.Push(pc);
|
||||||
|
|
||||||
X86Gp stackPtr, tmp;
|
X86Gp stackPtr, tmp;
|
||||||
X86Xmm tmp2;
|
X86Xmm tmp2;
|
||||||
|
@ -1021,8 +1028,6 @@ private:
|
||||||
stackPtr = cc.newIntPtr();
|
stackPtr = cc.newIntPtr();
|
||||||
cc.mov(stackPtr, frameD);
|
cc.mov(stackPtr, frameD);
|
||||||
cc.add(stackPtr, C * sizeof(int32_t));
|
cc.add(stackPtr, C * sizeof(int32_t));
|
||||||
cc.mov(x86::dword_ptr(stackPtr), regD[C]);
|
|
||||||
|
|
||||||
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), stackPtr);
|
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), stackPtr);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
||||||
break;
|
break;
|
||||||
|
@ -1041,13 +1046,13 @@ private:
|
||||||
stackPtr = cc.newIntPtr();
|
stackPtr = cc.newIntPtr();
|
||||||
cc.mov(stackPtr, frameA);
|
cc.mov(stackPtr, frameA);
|
||||||
cc.add(stackPtr, C * sizeof(void*));
|
cc.add(stackPtr, C * sizeof(void*));
|
||||||
cc.mov(x86::ptr(stackPtr), regA[C]);
|
|
||||||
|
|
||||||
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), stackPtr);
|
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), stackPtr);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
||||||
break;
|
break;
|
||||||
case REGT_POINTER | REGT_KONST:
|
case REGT_POINTER | REGT_KONST:
|
||||||
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), ToMemAddress(konsta[C].v));
|
tmp = cc.newIntPtr();
|
||||||
|
cc.mov(tmp, ToMemAddress(konsta[C].v));
|
||||||
|
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), tmp);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
||||||
break;
|
break;
|
||||||
case REGT_FLOAT:
|
case REGT_FLOAT:
|
||||||
|
@ -1058,6 +1063,7 @@ private:
|
||||||
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C]);
|
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C]);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
||||||
index = NumParam++;
|
index = NumParam++;
|
||||||
|
ParamOpcodes.Push(pc);
|
||||||
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C + 1]);
|
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C + 1]);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
||||||
break;
|
break;
|
||||||
|
@ -1065,9 +1071,11 @@ private:
|
||||||
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C]);
|
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C]);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
||||||
index = NumParam++;
|
index = NumParam++;
|
||||||
|
ParamOpcodes.Push(pc);
|
||||||
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C + 1]);
|
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C + 1]);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
||||||
index = NumParam++;
|
index = NumParam++;
|
||||||
|
ParamOpcodes.Push(pc);
|
||||||
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C + 2]);
|
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), regF[C + 2]);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
||||||
break;
|
break;
|
||||||
|
@ -1075,8 +1083,6 @@ private:
|
||||||
stackPtr = cc.newIntPtr();
|
stackPtr = cc.newIntPtr();
|
||||||
cc.mov(stackPtr, frameF);
|
cc.mov(stackPtr, frameF);
|
||||||
cc.add(stackPtr, C * sizeof(double));
|
cc.add(stackPtr, C * sizeof(double));
|
||||||
cc.movsd(x86::qword_ptr(stackPtr), regF[C]);
|
|
||||||
|
|
||||||
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), stackPtr);
|
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), stackPtr);
|
||||||
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
||||||
break;
|
break;
|
||||||
|
@ -1092,11 +1098,13 @@ private:
|
||||||
I_FatalError("Unknown REGT value passed to EmitPARAM\n");
|
I_FatalError("Unknown REGT value passed to EmitPARAM\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitPARAMI()
|
void EmitPARAMI()
|
||||||
{
|
{
|
||||||
int index = NumParam++;
|
int index = NumParam++;
|
||||||
|
ParamOpcodes.Push(pc);
|
||||||
cc.mov(asmjit::x86::dword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, i)), (int)ABCs);
|
cc.mov(asmjit::x86::dword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, i)), (int)ABCs);
|
||||||
cc.mov(asmjit::x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_INT);
|
cc.mov(asmjit::x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_INT);
|
||||||
}
|
}
|
||||||
|
@ -1117,12 +1125,24 @@ private:
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
||||||
if (NumParam != B)
|
if (NumParam < B)
|
||||||
I_FatalError("OP_CALL parameter count does not match the number of preceding OP_PARAM instructions");
|
I_FatalError("OP_CALL parameter count does not match the number of preceding OP_PARAM instructions");
|
||||||
NumParam = 0;
|
|
||||||
|
|
||||||
|
StoreInOuts(B);
|
||||||
FillReturns(pc + 1, C);
|
FillReturns(pc + 1, C);
|
||||||
|
|
||||||
|
X86Gp paramsptr;
|
||||||
|
if (B != NumParam)
|
||||||
|
{
|
||||||
|
paramsptr = cc.newIntPtr();
|
||||||
|
cc.mov(paramsptr, params);
|
||||||
|
cc.add(paramsptr, (NumParam - B) * sizeof(VMValue));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
paramsptr = params;
|
||||||
|
}
|
||||||
|
|
||||||
auto result = cc.newInt32();
|
auto result = cc.newInt32();
|
||||||
auto call = cc.call(ToMemAddress(&JitCompiler::DoCall), FuncSignature7<int, void*, void*, int, int, void*, void*, void*>());
|
auto call = cc.call(ToMemAddress(&JitCompiler::DoCall), FuncSignature7<int, void*, void*, int, int, void*, void*, void*>());
|
||||||
call->setRet(0, result);
|
call->setRet(0, result);
|
||||||
|
@ -1130,7 +1150,7 @@ private:
|
||||||
call->setArg(1, ptr);
|
call->setArg(1, ptr);
|
||||||
call->setArg(2, asmjit::Imm(B));
|
call->setArg(2, asmjit::Imm(B));
|
||||||
call->setArg(3, asmjit::Imm(C));
|
call->setArg(3, asmjit::Imm(C));
|
||||||
call->setArg(4, params);
|
call->setArg(4, paramsptr);
|
||||||
call->setArg(5, callReturns);
|
call->setArg(5, callReturns);
|
||||||
call->setArg(6, exceptInfo);
|
call->setArg(6, exceptInfo);
|
||||||
|
|
||||||
|
@ -1146,17 +1166,43 @@ private:
|
||||||
|
|
||||||
LoadReturns(pc - B, B, true);
|
LoadReturns(pc - B, B, true);
|
||||||
LoadReturns(pc + 1, C, false);
|
LoadReturns(pc + 1, C, false);
|
||||||
|
|
||||||
|
NumParam -= B;
|
||||||
|
ParamOpcodes.Resize(ParamOpcodes.Size() - B);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadReturns(const VMOP *retval, int numret, const VMOP *argval, int numarg)
|
void StoreInOuts(int b)
|
||||||
{
|
{
|
||||||
// Put the stored returns back into asmjit virtual registers:
|
using namespace asmjit;
|
||||||
|
|
||||||
// Put any inout arguments back into asmjit virtual registers:
|
for (unsigned int i = ParamOpcodes.Size() - b; i < ParamOpcodes.Size(); i++)
|
||||||
for (int i = 0; i < numarg; ++i)
|
|
||||||
{
|
{
|
||||||
int type = argval[i].b;
|
asmjit::X86Gp stackPtr;
|
||||||
int regnum = argval[i].c;
|
switch (ParamOpcodes[i]->b)
|
||||||
|
{
|
||||||
|
case REGT_INT | REGT_ADDROF:
|
||||||
|
stackPtr = cc.newIntPtr();
|
||||||
|
cc.mov(stackPtr, frameD);
|
||||||
|
cc.add(stackPtr, C * sizeof(int32_t));
|
||||||
|
cc.mov(x86::dword_ptr(stackPtr), regD[C]);
|
||||||
|
break;
|
||||||
|
//case REGT_STRING | REGT_ADDROF:
|
||||||
|
// break;
|
||||||
|
case REGT_POINTER | REGT_ADDROF:
|
||||||
|
stackPtr = cc.newIntPtr();
|
||||||
|
cc.mov(stackPtr, frameA);
|
||||||
|
cc.add(stackPtr, C * sizeof(void*));
|
||||||
|
cc.mov(x86::ptr(stackPtr), regA[C]);
|
||||||
|
break;
|
||||||
|
case REGT_FLOAT | REGT_ADDROF:
|
||||||
|
stackPtr = cc.newIntPtr();
|
||||||
|
cc.mov(stackPtr, frameF);
|
||||||
|
cc.add(stackPtr, C * sizeof(double));
|
||||||
|
cc.movsd(x86::qword_ptr(stackPtr), regF[C]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3350,7 +3396,8 @@ private:
|
||||||
asmjit::X86Gp frameF;
|
asmjit::X86Gp frameF;
|
||||||
asmjit::X86Gp frameA;
|
asmjit::X86Gp frameA;
|
||||||
asmjit::X86Gp params;
|
asmjit::X86Gp params;
|
||||||
int NumParam = 0; // Actually part of vmframe (f->NumParam), but we are going to assume that the backend never reuses parameters
|
int NumParam = 0; // Actually part of vmframe (f->NumParam), but nobody seems to read that?
|
||||||
|
TArray<const VMOP *> ParamOpcodes;
|
||||||
asmjit::X86Gp callReturns;
|
asmjit::X86Gp callReturns;
|
||||||
|
|
||||||
const int *konstd;
|
const int *konstd;
|
||||||
|
|
Loading…
Reference in New Issue