diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 373171d9..204cb12a 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -581,7 +581,7 @@ INST(ABS_2, "ABS", "0Q001 INST(XTN, "XTN, XTN2", "0Q001110zz100001001010nnnnnddddd") INST(SQXTN_2, "SQXTN, SQXTN2", "0Q001110zz100001010010nnnnnddddd") //INST(FCVTN, "FCVTN, FCVTN2", "0Q0011100z100001011010nnnnnddddd") -//INST(FCVTL, "FCVTL, FCVTL2", "0Q0011100z100001011110nnnnnddddd") +INST(FCVTL, "FCVTL, FCVTL2", "0Q0011100z100001011110nnnnnddddd") //INST(FRINTN_1, "FRINTN (vector)", "0Q00111001111001100010nnnnnddddd") INST(FRINTN_2, "FRINTN (vector)", "0Q0011100z100001100010nnnnnddddd") //INST(FRINTM_1, "FRINTM (vector)", "0Q00111001111001100110nnnnnddddd") 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 f2b37fd2..be02db13 100644 --- a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp @@ -267,6 +267,25 @@ bool TranslatorVisitor::FCMLT_4(bool Q, bool sz, Vec Vn, Vec Vd) { return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::LT); } +bool TranslatorVisitor::FCVTL(bool Q, bool sz, Vec Vn, Vec Vd) { + // Half-precision not handled directly. + if (!sz) { + return InterpretThisInstruction(); + } + + const IR::U128 part = Vpart(64, Vn, Q); + IR::U128 result = ir.ZeroVector(); + + for (size_t i = 0; i < 2; i++) { + const IR::U64 element = ir.FPSingleToDouble(ir.VectorGetElement(32, part, i), true); + + result = ir.VectorSetElement(64, result, i, element); + } + + V(128, Vd, result); + return true; +} + 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); }