diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 5fdc85bd..01a7d1b5 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -881,7 +881,7 @@ INST(SCVTF_float_int, "SCVTF (scalar, integer)", "z0011 INST(UCVTF_float_int, "UCVTF (scalar, integer)", "z0011110yy100011000000nnnnnddddd") //INST(FCVTAS_float, "FCVTAS (scalar)", "z0011110yy100100000000nnnnnddddd") //INST(FCVTAU_float, "FCVTAU (scalar)", "z0011110yy100101000000nnnnnddddd") -//INST(FMOV_float_gen, "FMOV (general)", "z0011110yy10-11-000000nnnnnddddd") +INST(FMOV_float_gen, "FMOV (general)", "z0011110yy10r11o000000nnnnnddddd") //INST(FCVTPS_float, "FCVTPS (scalar)", "z0011110yy101000000000nnnnnddddd") //INST(FCVTPU_float, "FCVTPU (scalar)", "z0011110yy101001000000nnnnnddddd") //INST(FCVTMS_float, "FCVTMS (scalar)", "z0011110yy110000000000nnnnnddddd") 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 a153a11a..d6ed8dfc 100644 --- a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp +++ b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp @@ -76,6 +76,65 @@ bool TranslatorVisitor::UCVTF_float_int(bool sf, Imm<2> type, Reg Rn, Vec Vd) { return true; } +bool TranslatorVisitor::FMOV_float_gen(bool sf, Imm<2> type, Imm<1> rmode_0, Imm<1> opc_0, size_t n, size_t d) { + // NOTE: + // 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; + return UnallocatedEncoding(); + } + + bool integer_to_float; + size_t part; + switch (rmode_0.ZeroExtend()) { + case 0b0: + if (fltsize != 16 && fltsize != intsize) { + return UnallocatedEncoding(); + } + integer_to_float = opc_0 == 0b1; + part = 0; + break; + default: + case 0b1: + if (intsize != 64 || fltsize != 128) { + return UnallocatedEncoding(); + } + integer_to_float = opc_0 == 0b1; + part = 1; + fltsize = 64; + break; + } + + if (integer_to_float) { + IR::U32U64 intval = X(intsize, static_cast(n)); + Vpart(fltsize, static_cast(d), part, intval); + } else { + IR::UAny fltval = Vpart(fltsize, static_cast(n), part); + IR::U32U64 intval = ZeroExtend(fltval, intsize); + X(intsize, static_cast(d), intval); + } + + return true; +} + bool TranslatorVisitor::FCVTZS_float_int(bool sf, Imm<2> type, Vec Vn, Reg Rd) { const size_t intsize = sf ? 64 : 32; const auto fltsize = GetDataSize(type); diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index a20ebc42..1f1e8371 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -938,7 +938,7 @@ struct TranslatorVisitor final { bool UCVTF_float_int(bool sf, Imm<2> type, Reg Rn, Vec Vd); bool FCVTAS_float(bool sf, Imm<2> type, Vec Vn, Reg Rd); bool FCVTAU_float(bool sf, Imm<2> type, Vec Vn, Reg Rd); - bool FMOV_float_gen(bool sf, Imm<2> type, Vec Vn, Vec Vd); + bool FMOV_float_gen(bool sf, Imm<2> type, Imm<1> rmode_0, Imm<1> opc_0, size_t n, size_t d); bool FCVTPS_float(bool sf, Imm<2> type, Vec Vn, Reg Rd); bool FCVTPU_float(bool sf, Imm<2> type, Vec Vn, Reg Rd); bool FCVTMS_float(bool sf, Imm<2> type, Vec Vn, Reg Rd);