diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 199cebfe..1df2971c 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -666,7 +666,7 @@ INST(NEG_2, "NEG (vector)", "0Q101 INST(SQXTUN_2, "SQXTUN, SQXTUN2", "0Q101110zz100001001010nnnnnddddd") INST(SHLL, "SHLL, SHLL2", "0Q101110zz100001001110nnnnnddddd") INST(UQXTN_2, "UQXTN, UQXTN2", "0Q101110zz100001010010nnnnnddddd") -//INST(FCVTXN_2, "FCVTXN, FCVTXN2", "0Q1011100z100001011010nnnnnddddd") +INST(FCVTXN_2, "FCVTXN, FCVTXN2", "0Q1011100z100001011010nnnnnddddd") //INST(FRINTA_1, "FRINTA (vector)", "0Q10111001111001100010nnnnnddddd") INST(FRINTA_2, "FRINTA (vector)", "0Q1011100z100001100010nnnnnddddd") //INST(FRINTX_1, "FRINTX (vector)", "0Q10111001111001100110nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index d65318ed..c117b885 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -748,7 +748,7 @@ struct TranslatorVisitor final { bool NEG_2(bool Q, Imm<2> size, Vec Vn, Vec Vd); bool SQXTUN_2(bool Q, Imm<2> size, Vec Vn, Vec Vd); bool UQXTN_2(bool Q, Imm<2> size, Vec Vn, Vec Vd); - bool FCVTXN_2(bool Q, bool sz, Vec Vn, Reg Rd); + bool FCVTXN_2(bool Q, bool sz, Vec Vn, Vec Vd); bool FRINTN_1(bool Q, Vec Vn, Vec Vd); bool FRINTN_2(bool Q, bool sz, Vec Vn, Vec Vd); bool FRINTM_1(bool Q, Vec Vn, Vec Vd); 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 2dba56e5..c734d662 100644 --- a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp @@ -397,6 +397,26 @@ 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::FCVTXN_2(bool Q, bool sz, Vec Vn, Vec Vd) { + if (!sz) { + return UnallocatedEncoding(); + } + + const size_t part = Q ? 1 : 0; + const auto operand = ir.GetQ(Vn); + auto result = ir.ZeroVector(); + + for (size_t e = 0; e < 2; ++e) { + const IR::U64 element = ir.VectorGetElement(64, operand, e); + const IR::U32 converted = ir.FPDoubleToSingle(element, FP::RoundingMode::ToOdd); + + result = ir.VectorSetElement(32, result, e, converted); + } + + Vpart(64, Vd, part, result); + return true; +} + bool TranslatorVisitor::FCVTZS_int_4(bool Q, bool sz, Vec Vn, Vec Vd) { return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsZero); }