From 5200bf41cfe6604388a9da2f54de90cdbfc66768 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 16 Jul 2018 13:55:19 +0100 Subject: [PATCH] A64: Implement FRINTN (scalar) --- src/frontend/A64/decoder/a64.inc | 2 +- ...ting_point_data_processing_one_register.cpp | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 8a9faa1b..c929ee3a 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -905,7 +905,7 @@ INST(FABS_float, "FABS (scalar)", "00011 INST(FNEG_float, "FNEG (scalar)", "00011110yy100001010000nnnnnddddd") INST(FSQRT_float, "FSQRT (scalar)", "00011110yy100001110000nnnnnddddd") INST(FCVT_float, "FCVT", "00011110yy10001oo10000nnnnnddddd") -//INST(FRINTN_float, "FRINTN (scalar)", "00011110yy100100010000nnnnnddddd") +INST(FRINTN_float, "FRINTN (scalar)", "00011110yy100100010000nnnnnddddd") //INST(FRINTP_float, "FRINTP (scalar)", "00011110yy100100110000nnnnnddddd") //INST(FRINTM_float, "FRINTM (scalar)", "00011110yy100101010000nnnnnddddd") //INST(FRINTZ_float, "FRINTZ (scalar)", "00011110yy100101110000nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/floating_point_data_processing_one_register.cpp b/src/frontend/A64/translate/impl/floating_point_data_processing_one_register.cpp index 7cb71085..fe1c1f2c 100644 --- a/src/frontend/A64/translate/impl/floating_point_data_processing_one_register.cpp +++ b/src/frontend/A64/translate/impl/floating_point_data_processing_one_register.cpp @@ -152,16 +152,24 @@ bool TranslatorVisitor::FCVT_float(Imm<2> type, Imm<2> opc, Vec Vn, Vec Vd) { return true; } -bool TranslatorVisitor::FRINTA_float(Imm<2> type, Vec Vn, Vec Vd) { +bool FloatingPointRoundToIntegral(TranslatorVisitor& v, Imm<2> type, Vec Vn, Vec Vd, FP::RoundingMode rounding_mode, bool exact) { const boost::optional datasize = GetDataSize(type); if (!datasize || *datasize == 16) { - return UnallocatedEncoding(); + return v.UnallocatedEncoding(); } - const IR::U32U64 operand = V_scalar(*datasize, Vn); - const IR::U32U64 result = ir.FPRoundInt(operand, FP::RoundingMode::ToNearest_TieAwayFromZero, false); - V_scalar(*datasize, Vd, result); + const IR::U32U64 operand = v.V_scalar(*datasize, Vn); + const IR::U32U64 result = v.ir.FPRoundInt(operand, rounding_mode, exact); + v.V_scalar(*datasize, Vd, result); return true; } +bool TranslatorVisitor::FRINTN_float(Imm<2> type, Vec Vn, Vec Vd) { + return FloatingPointRoundToIntegral(*this, type, Vn, Vd, FP::RoundingMode::ToNearest_TieEven, false); +} + +bool TranslatorVisitor::FRINTA_float(Imm<2> type, Vec Vn, Vec Vd) { + return FloatingPointRoundToIntegral(*this, type, Vn, Vd, FP::RoundingMode::ToNearest_TieAwayFromZero, false); +} + } // namespace Dynarmic::A64