From dd4ac86f8ec7eab60adab40a2ca458789e07c93c Mon Sep 17 00:00:00 2001 From: MerryMage Date: Thu, 26 Jul 2018 12:46:12 +0100 Subject: [PATCH] A64: Implement FCVT{N,M,A,P}{U,S} (vector), FCVTZU (vector, integer), single/double variant --- src/frontend/A64/decoder/a64.inc | 18 +++--- .../translate/impl/simd_two_register_misc.cpp | 61 ++++++++++++++++--- 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 6a433754..55996b8e 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -587,11 +587,11 @@ INST(SQXTN_2, "SQXTN, SQXTN2", "0Q001 //INST(FRINTM_1, "FRINTM (vector)", "0Q00111001111001100110nnnnnddddd") //INST(FRINTM_2, "FRINTM (vector)", "0Q0011100z100001100110nnnnnddddd") //INST(FCVTNS_3, "FCVTNS (vector)", "0Q00111001111001101010nnnnnddddd") -//INST(FCVTNS_4, "FCVTNS (vector)", "0Q0011100z100001101010nnnnnddddd") +INST(FCVTNS_4, "FCVTNS (vector)", "0Q0011100z100001101010nnnnnddddd") //INST(FCVTMS_3, "FCVTMS (vector)", "0Q00111001111001101110nnnnnddddd") -//INST(FCVTMS_4, "FCVTMS (vector)", "0Q0011100z100001101110nnnnnddddd") +INST(FCVTMS_4, "FCVTMS (vector)", "0Q0011100z100001101110nnnnnddddd") //INST(FCVTAS_3, "FCVTAS (vector)", "0Q00111001111001110010nnnnnddddd") -//INST(FCVTAS_4, "FCVTAS (vector)", "0Q0011100z100001110010nnnnnddddd") +INST(FCVTAS_4, "FCVTAS (vector)", "0Q0011100z100001110010nnnnnddddd") //INST(SCVTF_int_3, "SCVTF (vector, integer)", "0Q00111001111001110110nnnnnddddd") INST(SCVTF_int_4, "SCVTF (vector, integer)", "0Q0011100z100001110110nnnnnddddd") //INST(FCMGT_zero_3, "FCMGT (zero)", "0Q00111011111000110010nnnnnddddd") @@ -607,7 +607,7 @@ INST(FABS_2, "FABS (vector)", "0Q001 //INST(FRINTZ_1, "FRINTZ (vector)", "0Q00111011111001100110nnnnnddddd") //INST(FRINTZ_2, "FRINTZ (vector)", "0Q0011101z100001100110nnnnnddddd") //INST(FCVTPS_3, "FCVTPS (vector)", "0Q00111011111001101010nnnnnddddd") -//INST(FCVTPS_4, "FCVTPS (vector)", "0Q0011101z100001101010nnnnnddddd") +INST(FCVTPS_4, "FCVTPS (vector)", "0Q0011101z100001101010nnnnnddddd") //INST(FCVTZS_int_3, "FCVTZS (vector, integer)", "0Q00111011111001101110nnnnnddddd") INST(FCVTZS_int_4, "FCVTZS (vector, integer)", "0Q0011101z100001101110nnnnnddddd") //INST(URECPE, "URECPE", "0Q0011101z100001110010nnnnnddddd") @@ -631,11 +631,11 @@ INST(UQXTN_2, "UQXTN, UQXTN2", "0Q101 //INST(FRINTX_1, "FRINTX (vector)", "0Q10111001111001100110nnnnnddddd") //INST(FRINTX_2, "FRINTX (vector)", "0Q1011100z100001100110nnnnnddddd") //INST(FCVTNU_3, "FCVTNU (vector)", "0Q10111001111001101010nnnnnddddd") -//INST(FCVTNU_4, "FCVTNU (vector)", "0Q1011100z100001101010nnnnnddddd") +INST(FCVTNU_4, "FCVTNU (vector)", "0Q1011100z100001101010nnnnnddddd") //INST(FCVTMU_3, "FCVTMU (vector)", "0Q10111001111001101110nnnnnddddd") -//INST(FCVTMU_4, "FCVTMU (vector)", "0Q1011100z100001101110nnnnnddddd") +INST(FCVTMU_4, "FCVTMU (vector)", "0Q1011100z100001101110nnnnnddddd") //INST(FCVTAU_3, "FCVTAU (vector)", "0Q10111001111001110010nnnnnddddd") -//INST(FCVTAU_4, "FCVTAU (vector)", "0Q1011100z100001110010nnnnnddddd") +INST(FCVTAU_4, "FCVTAU (vector)", "0Q1011100z100001110010nnnnnddddd") //INST(UCVTF_int_3, "UCVTF (vector, integer)", "0Q10111001111001110110nnnnnddddd") INST(UCVTF_int_4, "UCVTF (vector, integer)", "0Q1011100z100001110110nnnnnddddd") INST(NOT, "NOT", "0Q10111000100000010110nnnnnddddd") @@ -649,9 +649,9 @@ INST(FCMGE_zero_4, "FCMGE (zero)", "0Q101 //INST(FCMLE_3, "FCMLE (zero)", "0Q10111011111000110110nnnnnddddd") INST(FCMLE_4, "FCMLE (zero)", "0Q1011101z100000110110nnnnnddddd") //INST(FCVTPU_3, "FCVTPU (vector)", "0Q10111011111001101010nnnnnddddd") -//INST(FCVTPU_4, "FCVTPU (vector)", "0Q1011101z100001101010nnnnnddddd") +INST(FCVTPU_4, "FCVTPU (vector)", "0Q1011101z100001101010nnnnnddddd") //INST(FCVTZU_int_3, "FCVTZU (vector, integer)", "0Q10111011111001101110nnnnnddddd") -//INST(FCVTZU_int_4, "FCVTZU (vector, integer)", "0Q1011101z100001101110nnnnnddddd") +INST(FCVTZU_int_4, "FCVTZU (vector, integer)", "0Q1011101z100001101110nnnnnddddd") //INST(URSQRTE, "URSQRTE", "0Q1011101z100001110010nnnnnddddd") //INST(FRSQRTE_3, "FRSQRTE", "0Q10111011111001110110nnnnnddddd") INST(FRSQRTE_4, "FRSQRTE", "0Q1011101z100001110110nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp index 723d5941..9fadd80c 100644 --- a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp @@ -4,6 +4,7 @@ * General Public License version 2 or any later version. */ +#include "common/fp/rounding_mode.h" #include "frontend/A64/translate/impl/impl.h" namespace Dynarmic::A64 { @@ -107,6 +108,23 @@ bool IntegerConvertToFloat(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd return true; } +bool FloatConvertToInteger(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, Signedness signedness, FP::RoundingMode rounding_mode) { + if (sz && !Q) { + return v.ReservedValue(); + } + + const size_t datasize = Q ? 128 : 64; + const size_t esize = sz ? 64 : 32; + + const IR::U128 operand = v.V(datasize, Vn); + const IR::U128 result = signedness == Signedness::Signed + ? v.ir.FPVectorToSignedFixed(esize, operand, 0, rounding_mode) + : v.ir.FPVectorToUnsignedFixed(esize, operand, 0, rounding_mode); + + v.V(datasize, Vd, result); + return true; +} + bool SaturatedNarrow(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, IR::U128 (IR::IREmitter::*fn)(size_t, const IR::U128&)) { if (size == 0b11) { return v.ReservedValue(); @@ -234,19 +252,44 @@ bool TranslatorVisitor::FCMLT_4(bool Q, bool sz, Vec Vn, Vec Vd) { return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::LT); } +bool TranslatorVisitor::FCVTNS_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::ToNearest_TieEven); +} + +bool TranslatorVisitor::FCVTMS_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsMinusInfinity); +} + +bool TranslatorVisitor::FCVTAS_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::ToNearest_TieAwayFromZero); +} + +bool TranslatorVisitor::FCVTPS_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsPlusInfinity); +} + bool TranslatorVisitor::FCVTZS_int_4(bool Q, bool sz, Vec Vn, Vec Vd) { - if (sz && !Q) { - return ReservedValue(); - } + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsZero); +} - const size_t datasize = Q ? 128 : 64; - const size_t esize = sz ? 64 : 32; +bool TranslatorVisitor::FCVTNU_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::ToNearest_TieEven); +} - const IR::U128 operand = V(datasize, Vn); - const IR::U128 result = ir.FPVectorToSignedFixed(esize, operand, 0, FP::RoundingMode::TowardsZero); +bool TranslatorVisitor::FCVTMU_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsMinusInfinity); +} - V(datasize, Vd, result); - return true; +bool TranslatorVisitor::FCVTAU_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::ToNearest_TieAwayFromZero); +} + +bool TranslatorVisitor::FCVTPU_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsPlusInfinity); +} + +bool TranslatorVisitor::FCVTZU_int_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsZero); } bool TranslatorVisitor::FRECPE_4(bool Q, bool sz, Vec Vn, Vec Vd) {