Fixed JIT error with Conjugate/Inverse
These need to be compiler intrinsics since faux types aren't supported with self.
This commit is contained in:
parent
486be3a5b6
commit
e7d0991798
8 changed files with 54 additions and 39 deletions
|
|
@ -172,6 +172,8 @@ xx(Sum)
|
|||
xx(Unit)
|
||||
xx(Angle)
|
||||
xx(PlusZ)
|
||||
xx(Conjugate)
|
||||
xx(Inverse)
|
||||
xx(ToVector)
|
||||
xx(Size)
|
||||
xx(Push)
|
||||
|
|
|
|||
|
|
@ -9063,7 +9063,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
else if (Self->IsQuaternion())
|
||||
{
|
||||
// Reuse vector built-ins for quaternion
|
||||
if (MethodName == NAME_Length || MethodName == NAME_LengthSquared || MethodName == NAME_Unit)
|
||||
if (MethodName == NAME_Length || MethodName == NAME_LengthSquared || MethodName == NAME_Unit || MethodName == NAME_Conjugate || MethodName == NAME_Inverse)
|
||||
{
|
||||
if (ArgList.Size() > 0)
|
||||
{
|
||||
|
|
@ -10361,6 +10361,9 @@ FxExpression *FxVectorBuiltin::Resolve(FCompileContext &ctx)
|
|||
ValueType = TypeFloat64;
|
||||
break;
|
||||
|
||||
case NAME_Conjugate:
|
||||
case NAME_Inverse:
|
||||
assert(Self->IsQuaternion());
|
||||
case NAME_Unit:
|
||||
ValueType = Self->ValueType;
|
||||
break;
|
||||
|
|
@ -10413,6 +10416,18 @@ ExpEmit FxVectorBuiltin::Emit(VMFunctionBuilder *build)
|
|||
build->Emit(vecSize == 2 ? OP_DIVVF2_RR : vecSize == 3 ? OP_DIVVF3_RR : OP_DIVVF4_RR, to.RegNum, op.RegNum, len.RegNum);
|
||||
len.Free(build);
|
||||
}
|
||||
else if (Function == NAME_Conjugate)
|
||||
{
|
||||
build->Emit(OP_CONJQ, to.RegNum, op.RegNum);
|
||||
}
|
||||
else if (Function == NAME_Inverse)
|
||||
{
|
||||
ExpEmit len(build, REGT_FLOAT);
|
||||
build->Emit(OP_DOTV4_RR, len.RegNum, op.RegNum, op.RegNum);
|
||||
build->Emit(OP_CONJQ, to.RegNum, op.RegNum);
|
||||
build->Emit(OP_DIVVF4_RR, to.RegNum, to.RegNum, len.RegNum);
|
||||
len.Free(build);
|
||||
}
|
||||
else if (Function == NAME_Angle)
|
||||
{
|
||||
build->Emit(OP_ATAN2, to.RegNum, op.RegNum + 1, op.RegNum);
|
||||
|
|
|
|||
|
|
@ -1396,40 +1396,6 @@ DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, SLerp, QuatSLerp)
|
|||
ACTION_RETURN_QUAT(quat);
|
||||
}
|
||||
|
||||
void QuatConjugate(
|
||||
double x, double y, double z, double w,
|
||||
DQuaternion* pquat
|
||||
)
|
||||
{
|
||||
*pquat = DQuaternion(x, y, z, w).Conjugate();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, Conjugate, QuatConjugate)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DQuaternion);
|
||||
|
||||
DQuaternion quat;
|
||||
QuatConjugate(self->X, self->Y, self->Z, self->W, &quat);
|
||||
ACTION_RETURN_QUAT(quat);
|
||||
}
|
||||
|
||||
void QuatInverse(
|
||||
double x, double y, double z, double w,
|
||||
DQuaternion* pquat
|
||||
)
|
||||
{
|
||||
*pquat = DQuaternion(x, y, z, w).Inverse();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, Inverse, QuatInverse)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DQuaternion);
|
||||
|
||||
DQuaternion quat;
|
||||
QuatInverse(self->X, self->Y, self->Z, self->W, &quat);
|
||||
ACTION_RETURN_QUAT(quat);
|
||||
}
|
||||
|
||||
PFunction * FindFunctionPointer(PClass * cls, int fn_name)
|
||||
{
|
||||
auto fn = dyn_cast<PFunction>(cls->FindSymbol(ENamedName(fn_name), true));
|
||||
|
|
|
|||
|
|
@ -1617,6 +1617,11 @@ void FuncMULQV3(void *result, double ax, double ay, double az, double aw, double
|
|||
*reinterpret_cast<DVector3*>(result) = DQuaternion(ax, ay, az, aw) * DVector3(bx, by, bz);
|
||||
}
|
||||
|
||||
void FuncCONJQ(void* result, double x, double y, double z, double w)
|
||||
{
|
||||
*reinterpret_cast<DQuaternion*>(result) = DQuaternion(-x, -y, -z, w);
|
||||
}
|
||||
|
||||
void JitCompiler::EmitMULQQ_RR()
|
||||
{
|
||||
auto stack = GetTemporaryVectorStackStorage();
|
||||
|
|
@ -1661,6 +1666,25 @@ void JitCompiler::EmitMULQV3_RR()
|
|||
cc.movsd(regF[A + 2], asmjit::x86::qword_ptr(tmp, 16));
|
||||
}
|
||||
|
||||
void JitCompiler::EmitCONJQ()
|
||||
{
|
||||
auto stack = GetTemporaryVectorStackStorage();
|
||||
auto tmp = newTempIntPtr();
|
||||
cc.lea(tmp, stack);
|
||||
|
||||
auto call = CreateCall<void, void*, double, double, double, double>(FuncCONJQ);
|
||||
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]);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Pointer math.
|
||||
|
|
|
|||
|
|
@ -1908,6 +1908,13 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret)
|
|||
reinterpret_cast<DQuaternion&>(reg.f[A]) = q1 * q2;
|
||||
}
|
||||
NEXTOP;
|
||||
OP(CONJQ):
|
||||
ASSERTF(a + 3); ASSERTF(B + 3);
|
||||
{
|
||||
const DQuaternion& q = reinterpret_cast<DQuaternion&>(reg.f[B]);
|
||||
reinterpret_cast<DQuaternion&>(reg.f[A]) = q.Conjugate();
|
||||
}
|
||||
NEXTOP;
|
||||
OP(ADDA_RR):
|
||||
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
||||
c = reg.d[C];
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ xx(EQV4_K, beqv4, CVRK, NOP, 0, 0) // this will never be used.
|
|||
// Quaternion math
|
||||
xx(MULQQ_RR, mulqq, RVRVRV, NOP, 0, 0) // qA = qB * qC
|
||||
xx(MULQV3_RR, mulqv3, RVRVRV, NOP, 0, 0) // qA = qB * vC
|
||||
xx(CONJQ, conjq, RVRVRV, NOP, 0, 0) // qA = qB.Conjugate
|
||||
|
||||
// Pointer math.
|
||||
xx(ADDA_RR, add, RPRPRI, NOP, 0, 0) // pA = pB + dkC
|
||||
|
|
|
|||
|
|
@ -292,11 +292,11 @@ public:
|
|||
return TVector3(r.X, r.Y, r.Z);
|
||||
}
|
||||
|
||||
TQuaternion<vec_t> Conjugate()
|
||||
TQuaternion<vec_t> Conjugate() const
|
||||
{
|
||||
return TQuaternion(-X, -Y, -Z, +W);
|
||||
}
|
||||
TQuaternion<vec_t> Inverse()
|
||||
TQuaternion<vec_t> Inverse() const
|
||||
{
|
||||
return Conjugate() / LengthSquared();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -977,11 +977,11 @@ struct QuatStruct native unsafe(internal)
|
|||
native static Quat NLerp(Quat from, Quat to, double t);
|
||||
native static Quat FromAngles(double yaw, double pitch, double roll);
|
||||
native static Quat AxisAngle(Vector3 xyz, double angle);
|
||||
native Quat Conjugate();
|
||||
native Quat Inverse();
|
||||
// native double Length();
|
||||
// native double LengthSquared();
|
||||
// native Quat Unit();
|
||||
// native Quat Conjugate();
|
||||
// native Quat Inverse();
|
||||
}
|
||||
|
||||
struct ScriptSavedPos
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue