mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-03-08 10:16:28 +00:00
VFP: Implement VMLA, VMLS, VNMLA, VNMLS
This commit is contained in:
@@ -74,6 +74,46 @@ bool ArmTranslatorVisitor::vfp2_VMUL(Cond cond, bool D, size_t Vn, size_t Vd, bo
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
|
||||
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
|
||||
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
|
||||
|
||||
ExtReg d = ToExtReg(sz, Vd, D);
|
||||
ExtReg n = ToExtReg(sz, Vn, N);
|
||||
ExtReg m = ToExtReg(sz, Vm, M);
|
||||
// VMLA.{F32,F64} <{S,D}d>, <{S,D}n>, <{S,D}m>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto a = ir.GetExtendedRegister(n);
|
||||
auto b = ir.GetExtendedRegister(m);
|
||||
auto c = ir.GetExtendedRegister(d);
|
||||
auto result = sz
|
||||
? ir.FPAdd64(c, ir.FPMul64(a, b, true), true)
|
||||
: ir.FPAdd32(c, ir.FPMul32(a, b, true), true);
|
||||
ir.SetExtendedRegister(d, result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
|
||||
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
|
||||
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
|
||||
|
||||
ExtReg d = ToExtReg(sz, Vd, D);
|
||||
ExtReg n = ToExtReg(sz, Vn, N);
|
||||
ExtReg m = ToExtReg(sz, Vm, M);
|
||||
// VMLS.{F32,F64} <{S,D}d>, <{S,D}n>, <{S,D}m>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto a = ir.GetExtendedRegister(n);
|
||||
auto b = ir.GetExtendedRegister(m);
|
||||
auto c = ir.GetExtendedRegister(d);
|
||||
auto result = sz
|
||||
? ir.FPAdd64(c, ir.FPNeg64(ir.FPMul64(a, b, true)), true)
|
||||
: ir.FPAdd32(c, ir.FPNeg32(ir.FPMul32(a, b, true)), true);
|
||||
ir.SetExtendedRegister(d, result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
|
||||
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
|
||||
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
|
||||
@@ -93,6 +133,46 @@ bool ArmTranslatorVisitor::vfp2_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, b
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VNMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
|
||||
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
|
||||
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
|
||||
|
||||
ExtReg d = ToExtReg(sz, Vd, D);
|
||||
ExtReg n = ToExtReg(sz, Vn, N);
|
||||
ExtReg m = ToExtReg(sz, Vm, M);
|
||||
// VNMLA.{F32,F64} <{S,D}d>, <{S,D}n>, <{S,D}m>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto a = ir.GetExtendedRegister(n);
|
||||
auto b = ir.GetExtendedRegister(m);
|
||||
auto c = ir.GetExtendedRegister(d);
|
||||
auto result = sz
|
||||
? ir.FPAdd64(ir.FPNeg64(c), ir.FPNeg64(ir.FPMul64(a, b, true)), true)
|
||||
: ir.FPAdd32(ir.FPNeg32(c), ir.FPNeg32(ir.FPMul32(a, b, true)), true);
|
||||
ir.SetExtendedRegister(d, result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VNMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
|
||||
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
|
||||
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
|
||||
|
||||
ExtReg d = ToExtReg(sz, Vd, D);
|
||||
ExtReg n = ToExtReg(sz, Vn, N);
|
||||
ExtReg m = ToExtReg(sz, Vm, M);
|
||||
// VNMLS.{F32,F64} <{S,D}d>, <{S,D}n>, <{S,D}m>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto a = ir.GetExtendedRegister(n);
|
||||
auto b = ir.GetExtendedRegister(m);
|
||||
auto c = ir.GetExtendedRegister(d);
|
||||
auto result = sz
|
||||
? ir.FPAdd64(ir.FPNeg64(c), ir.FPMul64(a, b, true), true)
|
||||
: ir.FPAdd32(ir.FPNeg32(c), ir.FPMul32(a, b, true), true);
|
||||
ir.SetExtendedRegister(d, result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
|
||||
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
|
||||
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
|
||||
|
||||
Reference in New Issue
Block a user