- backend update from GZDoom.

Mainly quaternion math and sound system cleanup.
This commit is contained in:
Christoph Oelckers 2022-11-24 16:56:46 +01:00
parent f1bfaac301
commit 2ffdf3d0e1
25 changed files with 919 additions and 259 deletions

View file

@ -1606,6 +1606,62 @@ void JitCompiler::EmitEQV4_K()
I_Error("EQV4_K is not used.");
}
// Quaternion ops
void FuncMULQQ(void *result, double ax, double ay, double az, double aw, double bx, double by, double bz, double bw)
{
*reinterpret_cast<DQuaternion*>(result) = DQuaternion(ax, ay, az, aw) * DQuaternion(bx, by, bz, bw);
}
void FuncMULQV3(void *result, double ax, double ay, double az, double aw, double bx, double by, double bz)
{
*reinterpret_cast<DVector3*>(result) = DQuaternion(ax, ay, az, aw) * DVector3(bx, by, bz);
}
void JitCompiler::EmitMULQQ_RR()
{
auto stack = GetTemporaryVectorStackStorage();
auto tmp = newTempIntPtr();
cc.lea(tmp, stack);
auto call = CreateCall<void, void*, double, double, double, double, double, double, double, double>(FuncMULQQ);
call->setArg(0, tmp);
call->setArg(1, regF[B + 0]);
call->setArg(2, regF[B + 1]);
call->setArg(3, regF[B + 2]);
call->setArg(4, regF[B + 3]);
call->setArg(5, regF[C + 0]);
call->setArg(6, regF[C + 1]);
call->setArg(7, regF[C + 2]);
call->setArg(8, regF[C + 3]);
cc.movsd(regF[A + 0], asmjit::x86::qword_ptr(tmp, 0));
cc.movsd(regF[A + 1], asmjit::x86::qword_ptr(tmp, 8));
cc.movsd(regF[A + 2], asmjit::x86::qword_ptr(tmp, 16));
cc.movsd(regF[A + 3], asmjit::x86::qword_ptr(tmp, 24));
}
void JitCompiler::EmitMULQV3_RR()
{
auto stack = GetTemporaryVectorStackStorage();
auto tmp = newTempIntPtr();
cc.lea(tmp, stack);
auto call = CreateCall<void, void*, double, double, double, double, double, double, double>(FuncMULQV3);
call->setArg(0, tmp);
call->setArg(1, regF[B + 0]);
call->setArg(2, regF[B + 1]);
call->setArg(3, regF[B + 2]);
call->setArg(4, regF[B + 3]);
call->setArg(5, regF[C + 0]);
call->setArg(6, regF[C + 1]);
call->setArg(7, regF[C + 2]);
cc.movsd(regF[A + 0], asmjit::x86::qword_ptr(tmp, 0));
cc.movsd(regF[A + 1], asmjit::x86::qword_ptr(tmp, 8));
cc.movsd(regF[A + 2], asmjit::x86::qword_ptr(tmp, 16));
}
/////////////////////////////////////////////////////////////////////////////
// Pointer math.

View file

@ -60,8 +60,8 @@ static int CastS2N(FString *b) { return b->Len() == 0 ? NAME_None : FName(*b).Ge
static void CastN2S(FString *a, int b) { FName name = FName(ENamedName(b)); *a = name.IsValidName() ? name.GetChars() : ""; }
static int CastS2Co(FString *b) { return V_GetColor(*b); }
static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); }
static int CastS2So(FString *b) { return FSoundID(*b); }
static void CastSo2S(FString* a, int b) { *a = soundEngine->GetSoundName(b); }
static int CastS2So(FString *b) { return S_FindSound(*b).index(); }
static void CastSo2S(FString* a, int b) { *a = soundEngine->GetSoundName(FSoundID::fromInt(b)); }
static void CastSID2S(FString* a, unsigned int b) { VM_CastSpriteIDToString(a, b); }
static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetGameTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); }

View file

@ -186,7 +186,13 @@ private:
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)) { return cc.call(asmjit::imm_ptr(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6)>(func))), asmjit::FuncSignature6<RetType, P1, P2, P3, P4, P5, P6>()); }
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
asmjit::CCFuncCall *CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)) { return cc.call(asmjit::imm_ptr(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6, P7)>(func))), asmjit::FuncSignature7<RetType, P1, P2, P3, P4, P5, P6, P7>()); }
asmjit::CCFuncCall* CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)) { return cc.call(asmjit::imm_ptr(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6, P7)>(func))), asmjit::FuncSignature7<RetType, P1, P2, P3, P4, P5, P6, P7>()); }
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
asmjit::CCFuncCall* CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)) { return cc.call(asmjit::imm_ptr(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6, P7, P8)>(func))), asmjit::FuncSignature8<RetType, P1, P2, P3, P4, P5, P6, P7, P8>()); }
template<typename RetType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
asmjit::CCFuncCall* CreateCall(RetType(*func)(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9)) { return cc.call(asmjit::imm_ptr(reinterpret_cast<void*>(static_cast<RetType(*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)>(func))), asmjit::FuncSignature9<RetType, P1, P2, P3, P4, P5, P6, P7, P8, P9>()); }
FString regname;
size_t tmpPosInt32, tmpPosInt64, tmpPosIntPtr, tmpPosXmmSd, tmpPosXmmSs, tmpPosXmmPd, resultPosInt32, resultPosIntPtr, resultPosXmmSd;
@ -305,6 +311,19 @@ private:
TArray<OpcodeLabel> labels;
// Get temporary storage enough for DVector4 which is required by operation such as MULQQ and MULQV3
bool vectorStackAllocated = false;
asmjit::X86Mem vectorStack;
asmjit::X86Mem GetTemporaryVectorStackStorage()
{
if (!vectorStackAllocated)
{
vectorStack = cc.newStack(sizeof(DVector4), alignof(DVector4), "tmpDVector4");
vectorStackAllocated = true;
}
return vectorStack;
}
const VMOP *pc;
VM_UBYTE op;
};