- use the ParamOpcodes array for finding the OP_PARAM's used by a call

This commit is contained in:
Magnus Norddahl 2018-09-17 00:31:25 +02:00
parent da040e818c
commit d032914c3d
2 changed files with 43 additions and 31 deletions

View file

@ -189,8 +189,8 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
cc.ret(vReg); cc.ret(vReg);
cc.bind(noexception); cc.bind(noexception);
LoadReturns(pc - B, B, true); LoadInOuts(B);
LoadReturns(pc + 1, C, false); LoadReturns(pc + 1, C);
NumParam -= B; NumParam -= B;
ParamOpcodes.Resize(ParamOpcodes.Size() - B); ParamOpcodes.Resize(ParamOpcodes.Size() - B);
@ -232,41 +232,51 @@ void JitCompiler::StoreInOuts(int b)
} }
} }
void JitCompiler::LoadReturns(const VMOP *retval, int numret, bool inout) void JitCompiler::LoadInOuts(int b)
{
for (unsigned int i = ParamOpcodes.Size() - b; i < ParamOpcodes.Size(); i++)
{
const VMOP &param = *ParamOpcodes[i];
if (param.op == OP_PARAM && (param.b & REGT_ADDROF))
{
LoadCallResult(param);
}
}
}
void JitCompiler::LoadReturns(const VMOP *retval, int numret)
{ {
for (int i = 0; i < numret; ++i) for (int i = 0; i < numret; ++i)
{ {
if (!inout && retval[i].op != OP_RESULT) if (retval[i].op != OP_RESULT)
I_FatalError("Expected OP_RESULT to follow OP_CALL\n"); I_FatalError("Expected OP_RESULT to follow OP_CALL\n");
else if (inout && retval[i].op != OP_PARAMI)
continue;
else if (inout && retval[i].op != OP_PARAM)
I_FatalError("Expected OP_PARAM to precede OP_CALL\n");
int type = retval[i].b; LoadCallResult(retval[i]);
int regnum = retval[i].c; }
}
if (inout && !(type & REGT_ADDROF)) void JitCompiler::LoadCallResult(const VMOP &opdata)
continue; {
int type = opdata.b;
int regnum = opdata.c;
switch (type & REGT_TYPE) switch (type & REGT_TYPE)
{ {
case REGT_INT: case REGT_INT:
cc.mov(regD[regnum], asmjit::x86::dword_ptr(frameD, regnum * sizeof(int32_t))); cc.mov(regD[regnum], asmjit::x86::dword_ptr(frameD, regnum * sizeof(int32_t)));
break; break;
case REGT_FLOAT: case REGT_FLOAT:
cc.movsd(regF[regnum], asmjit::x86::qword_ptr(frameF, regnum * sizeof(double))); cc.movsd(regF[regnum], asmjit::x86::qword_ptr(frameF, regnum * sizeof(double)));
break; break;
case REGT_STRING: case REGT_STRING:
// We don't have to do anything in this case. String values are never moved to virtual registers. // We don't have to do anything in this case. String values are never moved to virtual registers.
break; break;
case REGT_POINTER: case REGT_POINTER:
cc.mov(regA[regnum], asmjit::x86::ptr(frameA, regnum * sizeof(void*))); cc.mov(regA[regnum], asmjit::x86::ptr(frameA, regnum * sizeof(void*)));
break; break;
default: default:
I_FatalError("Unknown OP_RESULT type encountered in LoadReturns\n"); I_FatalError("Unknown OP_RESULT/OP_PARAM type encountered in LoadCallResult\n");
break; break;
}
} }
} }

View file

@ -44,8 +44,10 @@ private:
void EmitDoCall(asmjit::X86Gp ptr); void EmitDoCall(asmjit::X86Gp ptr);
void StoreInOuts(int b); void StoreInOuts(int b);
void LoadReturns(const VMOP *retval, int numret, bool inout); void LoadInOuts(int b);
void LoadReturns(const VMOP *retval, int numret);
void FillReturns(const VMOP *retval, int numret); void FillReturns(const VMOP *retval, int numret);
void LoadCallResult(const VMOP &opdata);
static int DoCall(VMFrameStack *stack, VMFunction *call, int b, int c, VMValue *param, VMReturn *returns, JitExceptionInfo *exceptinfo); static int DoCall(VMFrameStack *stack, VMFunction *call, int b, int c, VMValue *param, VMReturn *returns, JitExceptionInfo *exceptinfo);
template <typename Func> template <typename Func>