diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 88735d28..63b40dc1 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -583,9 +583,9 @@ INST(SQXTN_2, "SQXTN, SQXTN2", "0Q001 //INST(FCVTN, "FCVTN, FCVTN2", "0Q0011100z100001011010nnnnnddddd") //INST(FCVTL, "FCVTL, FCVTL2", "0Q0011100z100001011110nnnnnddddd") //INST(FRINTN_1, "FRINTN (vector)", "0Q00111001111001100010nnnnnddddd") -//INST(FRINTN_2, "FRINTN (vector)", "0Q0011100z100001100010nnnnnddddd") +INST(FRINTN_2, "FRINTN (vector)", "0Q0011100z100001100010nnnnnddddd") //INST(FRINTM_1, "FRINTM (vector)", "0Q00111001111001100110nnnnnddddd") -//INST(FRINTM_2, "FRINTM (vector)", "0Q0011100z100001100110nnnnnddddd") +INST(FRINTM_2, "FRINTM (vector)", "0Q0011100z100001100110nnnnnddddd") //INST(FCVTNS_3, "FCVTNS (vector)", "0Q00111001111001101010nnnnnddddd") INST(FCVTNS_4, "FCVTNS (vector)", "0Q0011100z100001101010nnnnnddddd") //INST(FCVTMS_3, "FCVTMS (vector)", "0Q00111001111001101110nnnnnddddd") @@ -603,9 +603,9 @@ INST(FCMLT_4, "FCMLT (zero)", "0Q001 INST(FABS_1, "FABS (vector)", "0Q00111011111000111110nnnnnddddd") INST(FABS_2, "FABS (vector)", "0Q0011101z100000111110nnnnnddddd") //INST(FRINTP_1, "FRINTP (vector)", "0Q00111011111001100010nnnnnddddd") -//INST(FRINTP_2, "FRINTP (vector)", "0Q0011101z100001100010nnnnnddddd") +INST(FRINTP_2, "FRINTP (vector)", "0Q0011101z100001100010nnnnnddddd") //INST(FRINTZ_1, "FRINTZ (vector)", "0Q00111011111001100110nnnnnddddd") -//INST(FRINTZ_2, "FRINTZ (vector)", "0Q0011101z100001100110nnnnnddddd") +INST(FRINTZ_2, "FRINTZ (vector)", "0Q0011101z100001100110nnnnnddddd") //INST(FCVTPS_3, "FCVTPS (vector)", "0Q00111011111001101010nnnnnddddd") INST(FCVTPS_4, "FCVTPS (vector)", "0Q0011101z100001101010nnnnnddddd") //INST(FCVTZS_int_3, "FCVTZS (vector, integer)", "0Q00111011111001101110nnnnnddddd") @@ -627,9 +627,9 @@ INST(SHLL, "SHLL, SHLL2", "0Q101 INST(UQXTN_2, "UQXTN, UQXTN2", "0Q101110zz100001010010nnnnnddddd") //INST(FCVTXN_2, "FCVTXN, FCVTXN2", "0Q1011100z100001011010nnnnnddddd") //INST(FRINTA_1, "FRINTA (vector)", "0Q10111001111001100010nnnnnddddd") -//INST(FRINTA_2, "FRINTA (vector)", "0Q1011100z100001100010nnnnnddddd") +INST(FRINTA_2, "FRINTA (vector)", "0Q1011100z100001100010nnnnnddddd") //INST(FRINTX_1, "FRINTX (vector)", "0Q10111001111001100110nnnnnddddd") -//INST(FRINTX_2, "FRINTX (vector)", "0Q1011100z100001100110nnnnnddddd") +INST(FRINTX_2, "FRINTX (vector)", "0Q1011100z100001100110nnnnnddddd") //INST(FCVTNU_3, "FCVTNU (vector)", "0Q10111001111001101010nnnnnddddd") INST(FCVTNU_4, "FCVTNU (vector)", "0Q1011100z100001101010nnnnnddddd") //INST(FCVTMU_3, "FCVTMU (vector)", "0Q10111001111001101110nnnnnddddd") @@ -643,7 +643,7 @@ INST(RBIT_asimd, "RBIT (vector)", "0Q101 INST(FNEG_1, "FNEG (vector)", "0Q10111011111000111110nnnnnddddd") INST(FNEG_2, "FNEG (vector)", "0Q1011101z100000111110nnnnnddddd") //INST(FRINTI_1, "FRINTI (vector)", "0Q10111011111001100110nnnnnddddd") -//INST(FRINTI_2, "FRINTI (vector)", "0Q1011101z100001100110nnnnnddddd") +INST(FRINTI_2, "FRINTI (vector)", "0Q1011101z100001100110nnnnnddddd") //INST(FCMGE_zero_3, "FCMGE (zero)", "0Q10111011111000110010nnnnnddddd") INST(FCMGE_zero_4, "FCMGE (zero)", "0Q1011101z100000110010nnnnnddddd") //INST(FCMLE_3, "FCMLE (zero)", "0Q10111011111000110110nnnnnddddd") 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 9fadd80c..f2b37fd2 100644 --- a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp @@ -125,6 +125,21 @@ bool FloatConvertToInteger(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd return true; } +bool FloatRoundToIntegral(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, FP::RoundingMode rounding_mode, bool exact) { + 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 = v.ir.FPVectorRoundInt(esize, operand, rounding_mode, exact); + + 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(); @@ -292,6 +307,35 @@ 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::FRINTN_2(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatRoundToIntegral(*this, Q, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieEven, false); +} + +bool TranslatorVisitor::FRINTM_2(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatRoundToIntegral(*this, Q, sz, Vn, Vd, FP::RoundingMode::TowardsMinusInfinity, false); +} + +bool TranslatorVisitor::FRINTP_2(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatRoundToIntegral(*this, Q, sz, Vn, Vd, FP::RoundingMode::TowardsPlusInfinity, false); +} + +bool TranslatorVisitor::FRINTZ_2(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatRoundToIntegral(*this, Q, sz, Vn, Vd, FP::RoundingMode::TowardsZero, false); +} + +bool TranslatorVisitor::FRINTA_2(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatRoundToIntegral(*this, Q, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieAwayFromZero, false); +} + +bool TranslatorVisitor::FRINTX_2(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatRoundToIntegral(*this, Q, sz, Vn, Vd, ir.current_location->FPCR().RMode(), true); +} + +bool TranslatorVisitor::FRINTI_2(bool Q, bool sz, Vec Vn, Vec Vd) { + return FloatRoundToIntegral(*this, Q, sz, Vn, Vd,ir.current_location->FPCR().RMode(), false); +} + + bool TranslatorVisitor::FRECPE_4(bool Q, bool sz, Vec Vn, Vec Vd) { if (sz && !Q) { return ReservedValue();