mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-02 08:53:42 +00:00
- implement PARAM and PARAMI
This commit is contained in:
parent
6f55c76f05
commit
4d1cb258d6
1 changed files with 140 additions and 16 deletions
|
@ -71,9 +71,9 @@ public:
|
||||||
if (!opcodeFunc)
|
if (!opcodeFunc)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
auto pc = sfunc->Code + i;
|
||||||
if (sfunc->Code[i].op == OP_RET)
|
if (sfunc->Code[i].op == OP_RET)
|
||||||
{
|
{
|
||||||
auto pc = sfunc->Code + i;
|
|
||||||
if (B != REGT_NIL)
|
if (B != REGT_NIL)
|
||||||
{
|
{
|
||||||
int regtype = B;
|
int regtype = B;
|
||||||
|
@ -83,7 +83,6 @@ public:
|
||||||
}
|
}
|
||||||
else if (sfunc->Code[i].op == OP_CAST)
|
else if (sfunc->Code[i].op == OP_CAST)
|
||||||
{
|
{
|
||||||
auto pc = sfunc->Code + i;
|
|
||||||
switch (C)
|
switch (C)
|
||||||
{
|
{
|
||||||
case CAST_I2F:
|
case CAST_I2F:
|
||||||
|
@ -97,10 +96,21 @@ public:
|
||||||
}
|
}
|
||||||
else if (sfunc->Code[i].op == OP_CASTB)
|
else if (sfunc->Code[i].op == OP_CASTB)
|
||||||
{
|
{
|
||||||
auto pc = sfunc->Code + i;
|
|
||||||
if (C == CASTB_S)
|
if (C == CASTB_S)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (sfunc->Code[i].op == OP_PARAM)
|
||||||
|
{
|
||||||
|
switch (B)
|
||||||
|
{
|
||||||
|
case REGT_STRING:
|
||||||
|
case REGT_STRING | REGT_ADDROF:
|
||||||
|
case REGT_STRING | REGT_KONST:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -192,8 +202,8 @@ private:
|
||||||
EMIT_OP(TESTN);
|
EMIT_OP(TESTN);
|
||||||
EMIT_OP(JMP);
|
EMIT_OP(JMP);
|
||||||
//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);
|
||||||
|
@ -978,8 +988,110 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
//void EmitIJMP() {} // pc += dA + BC -- BC is a signed offset. The target instruction must be a JMP.
|
//void EmitIJMP() {} // pc += dA + BC -- BC is a signed offset. The target instruction must be a JMP.
|
||||||
//void EmitPARAM() {} // push parameter encoded in BC for function call (B=regtype, C=regnum)
|
|
||||||
//void EmitPARAMI() {} // push immediate, signed integer for function call
|
void EmitPARAM()
|
||||||
|
{
|
||||||
|
using namespace asmjit;
|
||||||
|
|
||||||
|
int index = NumParam++;
|
||||||
|
|
||||||
|
X86Gp stackPtr, tmp;
|
||||||
|
X86Xmm tmp2;
|
||||||
|
|
||||||
|
switch (B)
|
||||||
|
{
|
||||||
|
case REGT_NIL:
|
||||||
|
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), (int64_t)0);
|
||||||
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_NIL);
|
||||||
|
break;
|
||||||
|
case REGT_INT:
|
||||||
|
cc.mov(x86::dword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, i)), regD[C]);
|
||||||
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_INT);
|
||||||
|
break;
|
||||||
|
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]);
|
||||||
|
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
case REGT_INT | REGT_KONST:
|
||||||
|
cc.mov(x86::dword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, i)), konstd[C]);
|
||||||
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_INT);
|
||||||
|
break;
|
||||||
|
//case REGT_STRING:
|
||||||
|
//case REGT_STRING | REGT_ADDROF:
|
||||||
|
//case REGT_STRING | REGT_KONST:
|
||||||
|
case REGT_POINTER:
|
||||||
|
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), regA[C]);
|
||||||
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
||||||
|
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]);
|
||||||
|
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
case REGT_POINTER | REGT_KONST:
|
||||||
|
cc.mov(x86::ptr(params, index * sizeof(VMValue) + offsetof(VMValue, a)), ToMemAddress(konsta[C].v));
|
||||||
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_POINTER);
|
||||||
|
break;
|
||||||
|
case REGT_FLOAT:
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
case REGT_FLOAT | REGT_MULTIREG2:
|
||||||
|
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);
|
||||||
|
index = NumParam++;
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
case REGT_FLOAT | REGT_MULTIREG3:
|
||||||
|
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);
|
||||||
|
index = NumParam++;
|
||||||
|
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);
|
||||||
|
index = NumParam++;
|
||||||
|
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);
|
||||||
|
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]);
|
||||||
|
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
case REGT_FLOAT | REGT_KONST:
|
||||||
|
tmp = cc.newIntPtr();
|
||||||
|
tmp2 = cc.newXmmSd();
|
||||||
|
cc.mov(tmp, ToMemAddress(konstf + C));
|
||||||
|
cc.movsd(tmp2, asmjit::x86::qword_ptr(tmp));
|
||||||
|
cc.movsd(x86::qword_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, f)), tmp2);
|
||||||
|
cc.mov(x86::byte_ptr(params, index * sizeof(VMValue) + offsetof(VMValue, Type)), (int)REGT_FLOAT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
I_FatalError("Unknown REGT value passed to EmitPARAM\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitPARAMI()
|
||||||
|
{
|
||||||
|
int index = NumParam++;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
//void EmitCALL() {} // Call function pkA with parameter count B and expected result count C
|
//void EmitCALL() {} // Call function pkA with parameter count B and expected result count C
|
||||||
//void EmitCALL_K() {}
|
//void EmitCALL_K() {}
|
||||||
|
|
||||||
|
@ -2735,7 +2847,7 @@ private:
|
||||||
cc.comment(funcname.GetChars(), funcname.Len());
|
cc.comment(funcname.GetChars(), funcname.Len());
|
||||||
|
|
||||||
stack = cc.newIntPtr("stack"); // VMFrameStack *stack
|
stack = cc.newIntPtr("stack"); // VMFrameStack *stack
|
||||||
vmregs = cc.newIntPtr("vmregs"); // void *vmregs
|
vmregs = cc.newIntPtr("vmregs"); // VMRegisters *vmregs
|
||||||
ret = cc.newIntPtr("ret"); // VMReturn *ret
|
ret = cc.newIntPtr("ret"); // VMReturn *ret
|
||||||
numret = cc.newInt32("numret"); // int numret
|
numret = cc.newInt32("numret"); // int numret
|
||||||
exceptInfo = cc.newIntPtr("exceptinfo"); // JitExceptionInfo *exceptInfo
|
exceptInfo = cc.newIntPtr("exceptinfo"); // JitExceptionInfo *exceptInfo
|
||||||
|
@ -2757,32 +2869,39 @@ private:
|
||||||
regA.Resize(sfunc->NumRegA);
|
regA.Resize(sfunc->NumRegA);
|
||||||
//regS.Resize(sfunc->NumRegS);
|
//regS.Resize(sfunc->NumRegS);
|
||||||
|
|
||||||
X86Gp initreg = cc.newIntPtr();
|
frameD = cc.newIntPtr();
|
||||||
|
frameF = cc.newIntPtr();
|
||||||
|
//frameS = cc.newIntPtr();
|
||||||
|
frameA = cc.newIntPtr();
|
||||||
|
params = cc.newIntPtr();
|
||||||
|
cc.mov(frameD, x86::ptr(vmregs, offsetof(VMRegisters, d)));
|
||||||
|
cc.mov(frameF, x86::ptr(vmregs, offsetof(VMRegisters, f)));
|
||||||
|
//cc.mov(frameS, x86::ptr(vmregs, offsetof(VMRegisters, s)));
|
||||||
|
cc.mov(frameA, x86::ptr(vmregs, offsetof(VMRegisters, a)));
|
||||||
|
cc.mov(params, x86::ptr(vmregs, offsetof(VMRegisters, param)));
|
||||||
|
|
||||||
if (sfunc->NumRegD > 0)
|
if (sfunc->NumRegD > 0)
|
||||||
{
|
{
|
||||||
cc.mov(initreg, x86::ptr(vmregs, 0));
|
|
||||||
for (int i = 0; i < sfunc->NumRegD; i++)
|
for (int i = 0; i < sfunc->NumRegD; i++)
|
||||||
{
|
{
|
||||||
FString regname;
|
FString regname;
|
||||||
regname.Format("regD%d", i);
|
regname.Format("regD%d", i);
|
||||||
regD[i] = cc.newInt32(regname.GetChars());
|
regD[i] = cc.newInt32(regname.GetChars());
|
||||||
cc.mov(regD[i], x86::dword_ptr(initreg, i * sizeof(int32_t)));
|
cc.mov(regD[i], x86::dword_ptr(frameD, i * sizeof(int32_t)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sfunc->NumRegF > 0)
|
if (sfunc->NumRegF > 0)
|
||||||
{
|
{
|
||||||
cc.mov(initreg, x86::ptr(vmregs, sizeof(void*)));
|
|
||||||
for (int i = 0; i < sfunc->NumRegF; i++)
|
for (int i = 0; i < sfunc->NumRegF; i++)
|
||||||
{
|
{
|
||||||
FString regname;
|
FString regname;
|
||||||
regname.Format("regF%d", i);
|
regname.Format("regF%d", i);
|
||||||
regF[i] = cc.newXmmSd(regname.GetChars());
|
regF[i] = cc.newXmmSd(regname.GetChars());
|
||||||
cc.movsd(regF[i], x86::qword_ptr(initreg, i * sizeof(double)));
|
cc.movsd(regF[i], x86::qword_ptr(frameF, i * sizeof(double)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*if (sfunc->NumRegS > 0)
|
/*if (sfunc->NumRegS > 0)
|
||||||
{
|
{
|
||||||
cc.mov(initreg, x86::ptr(vmregs, sizeof(void*) * 2));
|
|
||||||
for (int i = 0; i < sfunc->NumRegS; i++)
|
for (int i = 0; i < sfunc->NumRegS; i++)
|
||||||
{
|
{
|
||||||
FString regname;
|
FString regname;
|
||||||
|
@ -2792,13 +2911,12 @@ private:
|
||||||
}*/
|
}*/
|
||||||
if (sfunc->NumRegA > 0)
|
if (sfunc->NumRegA > 0)
|
||||||
{
|
{
|
||||||
cc.mov(initreg, x86::ptr(vmregs, sizeof(void*) * 3));
|
|
||||||
for (int i = 0; i < sfunc->NumRegA; i++)
|
for (int i = 0; i < sfunc->NumRegA; i++)
|
||||||
{
|
{
|
||||||
FString regname;
|
FString regname;
|
||||||
regname.Format("regA%d", i);
|
regname.Format("regA%d", i);
|
||||||
regA[i] = cc.newIntPtr(regname.GetChars());
|
regA[i] = cc.newIntPtr(regname.GetChars());
|
||||||
cc.mov(regA[i], x86::ptr(initreg, i * sizeof(void*)));
|
cc.mov(regA[i], x86::ptr(frameA, i * sizeof(void*)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2968,6 +3086,12 @@ private:
|
||||||
asmjit::X86Gp numret;
|
asmjit::X86Gp numret;
|
||||||
asmjit::X86Gp exceptInfo;
|
asmjit::X86Gp exceptInfo;
|
||||||
|
|
||||||
|
asmjit::X86Gp frameD;
|
||||||
|
asmjit::X86Gp frameF;
|
||||||
|
asmjit::X86Gp frameA;
|
||||||
|
asmjit::X86Gp params;
|
||||||
|
int NumParam = 0; // Actually part of vmframe (f->NumParam), but we are going to assume that the backend never reuses parameters
|
||||||
|
|
||||||
const int *konstd;
|
const int *konstd;
|
||||||
const double *konstf;
|
const double *konstf;
|
||||||
const FString *konsts;
|
const FString *konsts;
|
||||||
|
|
Loading…
Reference in a new issue