mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-06 22:48:25 +01:00
VFP: Implement VMOV (all variants)
This commit is contained in:
parent
aba705f6b9
commit
a2c2db277b
11 changed files with 301 additions and 27 deletions
|
|
@ -192,6 +192,123 @@ bool ArmTranslatorVisitor::vfp2_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, bo
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D) {
|
||||
ExtReg d = ToExtReg(true, Vd, D);
|
||||
if (t == Reg::PC)
|
||||
return UnpredictableInstruction();
|
||||
// VMOV.32 <Dd[0]>, <Rt>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto d_f64 = ir.GetExtendedRegister(d);
|
||||
auto t_u32 = ir.GetRegister(t);
|
||||
|
||||
auto d_u64 = ir.TransferFromFP64(d_f64);
|
||||
auto result = ir.Pack2x32To1x64(t_u32, ir.MostSignificantWord(d_u64).result);
|
||||
|
||||
ir.SetExtendedRegister(d, ir.TransferToFP64(result));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_f64_u32(Cond cond, size_t Vn, Reg t, bool N) {
|
||||
ExtReg n = ToExtReg(true, Vn, N);
|
||||
if (t == Reg::PC)
|
||||
return UnpredictableInstruction();
|
||||
// VMOV.32 <Rt>, <Dn[0]>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto n_f64 = ir.GetExtendedRegister(n);
|
||||
ir.SetRegister(t, ir.LeastSignificantWord(ir.TransferFromFP64(n_f64)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_u32_f32(Cond cond, size_t Vn, Reg t, bool N) {
|
||||
ExtReg n = ToExtReg(false, Vn, N);
|
||||
if (t == Reg::PC)
|
||||
return UnpredictableInstruction();
|
||||
// VMOV <Sn>, <Rt>
|
||||
if (ConditionPassed(cond)) {
|
||||
ir.SetExtendedRegister(n, ir.TransferToFP32(ir.GetRegister(t)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_f32_u32(Cond cond, size_t Vn, Reg t, bool N) {
|
||||
ExtReg n = ToExtReg(false, Vn, N);
|
||||
if (t == Reg::PC)
|
||||
return UnpredictableInstruction();
|
||||
// VMOV <Rt>, <Sn>
|
||||
if (ConditionPassed(cond)) {
|
||||
ir.SetRegister(t, ir.TransferFromFP32(ir.GetExtendedRegister(n)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_2u32_2f32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) {
|
||||
ExtReg m = ToExtReg(false, Vm, M);
|
||||
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31)
|
||||
return UnpredictableInstruction();
|
||||
// VMOV <Sm>, <Sm1>, <Rt>, <Rt2>
|
||||
if (ConditionPassed(cond)) {
|
||||
ir.SetExtendedRegister(m, ir.TransferToFP32(ir.GetRegister(t)));
|
||||
ir.SetExtendedRegister(m+1, ir.TransferToFP32(ir.GetRegister(t2)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_2f32_2u32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) {
|
||||
ExtReg m = ToExtReg(false, Vm, M);
|
||||
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31)
|
||||
return UnpredictableInstruction();
|
||||
if (t == t2)
|
||||
return UnpredictableInstruction();
|
||||
// VMOV <Rt>, <Rt2>, <Sm>, <Sm1>
|
||||
if (ConditionPassed(cond)) {
|
||||
ir.SetRegister(t, ir.TransferFromFP32(ir.GetExtendedRegister(m)));
|
||||
ir.SetRegister(t2, ir.TransferFromFP32(ir.GetExtendedRegister(m+1)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_2u32_f64(Cond cond, Reg t2, Reg t, bool M, size_t Vm) {
|
||||
ExtReg m = ToExtReg(true, Vm, M);
|
||||
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31)
|
||||
return UnpredictableInstruction();
|
||||
// VMOV<c> <Dm>, <Rt>, <Rt2>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto value = ir.Pack2x32To1x64(ir.GetRegister(t), ir.GetRegister(t2));
|
||||
ir.SetExtendedRegister(m, ir.TransferToFP64(value));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) {
|
||||
ExtReg m = ToExtReg(true, Vm, M);
|
||||
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31)
|
||||
return UnpredictableInstruction();
|
||||
if (t == t2)
|
||||
return UnpredictableInstruction();
|
||||
// VMOV<c> <Rt>, <Rt2>, <Dm>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto value = ir.TransferFromFP64(ir.GetExtendedRegister(m));
|
||||
ir.SetRegister(t, ir.LeastSignificantWord(value));
|
||||
ir.SetRegister(t2, ir.MostSignificantWord(value).result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, 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 m = ToExtReg(sz, Vm, M);
|
||||
// VMOV.{F32,F64} <{S,D}d>, <{S,D}m>
|
||||
if (ConditionPassed(cond)) {
|
||||
ir.SetExtendedRegister(d, ir.GetExtendedRegister(m));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::vfp2_VABS(Cond cond, bool D, size_t Vd, bool sz, 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue