diff --git a/src/frontend/A64/translate/impl/floating_point_compare.cpp b/src/frontend/A64/translate/impl/floating_point_compare.cpp index f8a73260..5e8708ec 100644 --- a/src/frontend/A64/translate/impl/floating_point_compare.cpp +++ b/src/frontend/A64/translate/impl/floating_point_compare.cpp @@ -9,8 +9,8 @@ #include "frontend/A64/translate/impl/impl.h" namespace Dynarmic::A64 { - -static boost::optional GetDataSize(Imm<2> type) { +namespace { +boost::optional GetDataSize(Imm<2> type) { switch (type.ZeroExtend()) { case 0b00: return 32; @@ -23,42 +23,32 @@ static boost::optional GetDataSize(Imm<2> type) { return boost::none; } -bool TranslatorVisitor::FCMP_float(Imm<2> type, Vec Vm, Vec Vn, bool cmp_with_zero) { - auto datasize = GetDataSize(type); +bool FPCompare(TranslatorVisitor& v, Imm<2> type, Vec Vm, Vec Vn, bool exc_on_qnan, bool cmp_with_zero) { + const auto datasize = GetDataSize(type); if (!datasize) { - return UnallocatedEncoding(); + return v.UnallocatedEncoding(); } - const IR::U32U64 operand1 = V_scalar(*datasize, Vn); + const IR::U32U64 operand1 = v.V_scalar(*datasize, Vn); IR::U32U64 operand2; if (cmp_with_zero) { - operand2 = I(*datasize, 0); + operand2 = v.I(*datasize, 0); } else { - operand2 = V_scalar(*datasize, Vm); + operand2 = v.V_scalar(*datasize, Vm); } - auto nzcv = ir.FPCompare(operand1, operand2, false, true); - ir.SetNZCV(nzcv); + const auto nzcv = v.ir.FPCompare(operand1, operand2, exc_on_qnan, true); + v.ir.SetNZCV(nzcv); return true; } +} // Anonymous namespace + +bool TranslatorVisitor::FCMP_float(Imm<2> type, Vec Vm, Vec Vn, bool cmp_with_zero) { + return FPCompare(*this, type, Vm, Vn, false, cmp_with_zero); +} bool TranslatorVisitor::FCMPE_float(Imm<2> type, Vec Vm, Vec Vn, bool cmp_with_zero) { - auto datasize = GetDataSize(type); - if (!datasize) { - return UnallocatedEncoding(); - } - - const IR::U32U64 operand1 = V_scalar(*datasize, Vn); - IR::U32U64 operand2; - if (cmp_with_zero) { - operand2 = I(*datasize, 0); - } else { - operand2 = V_scalar(*datasize, Vm); - } - - auto nzcv = ir.FPCompare(operand1, operand2, true, true); - ir.SetNZCV(nzcv); - return true; + return FPCompare(*this, type, Vm, Vn, true, cmp_with_zero); } } // namespace Dynarmic::A64 diff --git a/src/frontend/A64/translate/impl/floating_point_conditional_compare.cpp b/src/frontend/A64/translate/impl/floating_point_conditional_compare.cpp index 24d420de..88c1a5a0 100644 --- a/src/frontend/A64/translate/impl/floating_point_conditional_compare.cpp +++ b/src/frontend/A64/translate/impl/floating_point_conditional_compare.cpp @@ -9,7 +9,7 @@ #include "frontend/A64/translate/impl/impl.h" namespace Dynarmic::A64 { - +namespace { static boost::optional GetDataSize(Imm<2> type) { switch (type.ZeroExtend()) { case 0b00: @@ -22,36 +22,29 @@ static boost::optional GetDataSize(Imm<2> type) { return boost::none; } -bool TranslatorVisitor::FCCMP_float(Imm<2> type, Vec Vm, Cond cond, Vec Vn, Imm<4> nzcv) { +bool FPCompare(TranslatorVisitor& v, Imm<2> type, Vec Vm, Cond cond, Vec Vn, Imm<4> nzcv, bool exc_on_qnan) { const auto datasize = GetDataSize(type); if (!datasize || *datasize == 16) { - return UnallocatedEncoding(); + return v.UnallocatedEncoding(); } const u32 flags = nzcv.ZeroExtend() << 28; - const IR::U32U64 operand1 = V_scalar(*datasize, Vn); - const IR::U32U64 operand2 = V_scalar(*datasize, Vm); + const IR::U32U64 operand1 = v.V_scalar(*datasize, Vn); + const IR::U32U64 operand2 = v.V_scalar(*datasize, Vm); - const IR::NZCV then_flags = ir.FPCompare(operand1, operand2, false, true); - const IR::NZCV else_flags = ir.NZCVFromPackedFlags(ir.Imm32(flags)); - ir.SetNZCV(ir.ConditionalSelect(cond, then_flags, else_flags)); + const IR::NZCV then_flags = v.ir.FPCompare(operand1, operand2, exc_on_qnan, true); + const IR::NZCV else_flags = v.ir.NZCVFromPackedFlags(v.ir.Imm32(flags)); + v.ir.SetNZCV(v.ir.ConditionalSelect(cond, then_flags, else_flags)); return true; } +} // Anonymous namespace + +bool TranslatorVisitor::FCCMP_float(Imm<2> type, Vec Vm, Cond cond, Vec Vn, Imm<4> nzcv) { + return FPCompare(*this, type, Vm, cond, Vn, nzcv, false); +} bool TranslatorVisitor::FCCMPE_float(Imm<2> type, Vec Vm, Cond cond, Vec Vn, Imm<4> nzcv) { - const auto datasize = GetDataSize(type); - if (!datasize || *datasize == 16) { - return UnallocatedEncoding(); - } - const u32 flags = nzcv.ZeroExtend() << 28; - - const IR::U32U64 operand1 = V_scalar(*datasize, Vn); - const IR::U32U64 operand2 = V_scalar(*datasize, Vm); - - const IR::NZCV then_flags = ir.FPCompare(operand1, operand2, true, true); - const IR::NZCV else_flags = ir.NZCVFromPackedFlags(ir.Imm32(flags)); - ir.SetNZCV(ir.ConditionalSelect(cond, then_flags, else_flags)); - return true; + return FPCompare(*this, type, Vm, cond, Vn, nzcv, true); } } // namespace Dynarmic::A64