From d7ac5a664f9a174e9427d894ecf3b9bf214a2077 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 23 Mar 2019 12:49:45 -0400 Subject: [PATCH] A64: Handle half-precision floating point in FCVTL Like FCVTN, now that we have half-precision floating point conversion functions available, we can go ahead and use those to eliminate the interpreter fallback. --- .../translate/impl/simd_two_register_misc.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) 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 d8f3160d..92d9553f 100644 --- a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp @@ -342,19 +342,24 @@ bool TranslatorVisitor::FCMLT_4(bool Q, bool sz, Vec Vn, Vec Vd) { } bool TranslatorVisitor::FCVTL(bool Q, bool sz, Vec Vn, Vec Vd) { - // Half-precision not handled directly. - if (!sz) { - return InterpretThisInstruction(); - } + const size_t esize = sz ? 32 : 16; + const size_t datasize = 64; + const size_t num_elements = datasize / esize; const IR::U128 part = Vpart(64, Vn, Q); const auto rounding_mode = ir.current_location->FPCR().RMode(); IR::U128 result = ir.ZeroVector(); - for (size_t i = 0; i < 2; i++) { - const IR::U64 element = ir.FPSingleToDouble(ir.VectorGetElement(32, part, i), rounding_mode); + for (size_t i = 0; i < num_elements; i++) { + IR::U16U32U64 element = ir.VectorGetElement(esize, part, i); - result = ir.VectorSetElement(64, result, i, element); + if (esize == 16) { + element = ir.FPHalfToSingle(element, rounding_mode); + } else if (esize == 32) { + element = ir.FPSingleToDouble(element, rounding_mode); + } + + result = ir.VectorSetElement(2 * esize, result, i, element); } V(128, Vd, result);