From 25a7256ee194a29bee5c4b18fad6573f66eaa4ed Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 22 Mar 2019 10:07:03 -0400 Subject: [PATCH] A64: Enable FMOV (general) for half-precision floating point This just transfers values between vector registers and general-purpose registers with no conversions performed, so this is trivial to add support for half-precision to. --- .../floating_point_conversion_integer.cpp | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp index 62b3dc20..15fabe05 100644 --- a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp +++ b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp @@ -62,32 +62,31 @@ bool TranslatorVisitor::FMOV_float_gen(bool sf, Imm<2> type, Imm<1> rmode_0, Imm // opcode<2:1> == 0b11 // rmode<1> == 0b0 - const size_t intsize = sf ? 64 : 32; - size_t fltsize; - switch (type.ZeroExtend()) { - case 0b00: - fltsize = 32; - break; - case 0b01: - fltsize = 64; - break; - case 0b10: - if (rmode_0 != 1) { - return UnallocatedEncoding(); - } - fltsize = 128; - break; - default: - case 0b11: - fltsize = 16; + if (type == 0b10 && rmode_0 != 1) { return UnallocatedEncoding(); } + const size_t intsize = sf ? 64 : 32; + size_t fltsize = [type] { + switch (type.ZeroExtend()) { + case 0b00: + return 32; + case 0b01: + return 64; + case 0b10: + return 128; + case 0b11: + return 16; + default: + UNREACHABLE(); + return 0; + } + }(); + bool integer_to_float; size_t part; switch (rmode_0.ZeroExtend()) { case 0b0: - // fltsize != 16 is always true for now (late 2018), until half-float support is implemented. if (fltsize != 16 && fltsize != intsize) { return UnallocatedEncoding(); } @@ -106,11 +105,11 @@ bool TranslatorVisitor::FMOV_float_gen(bool sf, Imm<2> type, Imm<1> rmode_0, Imm } if (integer_to_float) { - IR::U32U64 intval = X(intsize, static_cast(n)); + const IR::U16U32U64 intval = X(fltsize, static_cast(n)); Vpart_scalar(fltsize, static_cast(d), part, intval); } else { - IR::UAny fltval = Vpart_scalar(fltsize, static_cast(n), part); - IR::U32U64 intval = ZeroExtend(fltval, intsize); + const IR::UAny fltval = Vpart_scalar(fltsize, static_cast(n), part); + const IR::U32U64 intval = ZeroExtend(fltval, intsize); X(intsize, static_cast(d), intval); }