diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 1eb5fc55..bfadf3be 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -893,8 +893,8 @@ INST(EOR_asimd, "EOR (vector)", "0Q101 // Data Processing - FP and SIMD - Conversion between floating point and integer //INST(FCVTNS_float, "FCVTNS (scalar)", "z0011110yy100000000000nnnnnddddd") //INST(FCVTNU_float, "FCVTNU (scalar)", "z0011110yy100001000000nnnnnddddd") -//INST(SCVTF_float_int, "SCVTF (scalar, integer)", "z0011110yy100010000000nnnnnddddd") -//INST(UCVTF_float_int, "UCVTF (scalar, integer)", "z0011110yy100011000000nnnnnddddd") +INST(SCVTF_float_int, "SCVTF (scalar, integer)", "z0011110yy100010000000nnnnnddddd") +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") 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 2b90af38..a153a11a 100644 --- a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp +++ b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp @@ -22,6 +22,60 @@ static boost::optional GetDataSize(Imm<2> type) { return boost::none; } +bool TranslatorVisitor::SCVTF_float_int(bool sf, Imm<2> type, Reg Rn, Vec Vd) { + const size_t intsize = sf ? 64 : 32; + const auto fltsize = GetDataSize(type); + if (!fltsize || *fltsize == 16) { + return UnallocatedEncoding(); + } + + const IR::U32U64 intval = X(intsize, Rn); + IR::U32U64 fltval; + + if (intsize == 32 && *fltsize == 32) { + fltval = ir.FPS32ToSingle(intval, false, true); + } else if (intsize == 32 && *fltsize == 64) { + fltval = ir.FPS32ToDouble(intval, false, true); + } else if (intsize == 64 && *fltsize == 32) { + return InterpretThisInstruction(); + } else if (intsize == 64 && *fltsize == 64) { + return InterpretThisInstruction(); + } else { + UNREACHABLE(); + } + + V_scalar(*fltsize, Vd, fltval); + + return true; +} + +bool TranslatorVisitor::UCVTF_float_int(bool sf, Imm<2> type, Reg Rn, Vec Vd) { + const size_t intsize = sf ? 64 : 32; + const auto fltsize = GetDataSize(type); + if (!fltsize || *fltsize == 16) { + return UnallocatedEncoding(); + } + + const IR::U32U64 intval = X(intsize, Rn); + IR::U32U64 fltval; + + if (intsize == 32 && *fltsize == 32) { + fltval = ir.FPU32ToSingle(intval, false, true); + } else if (intsize == 32 && *fltsize == 64) { + fltval = ir.FPU32ToDouble(intval, false, true); + } else if (intsize == 64 && *fltsize == 32) { + return InterpretThisInstruction(); + } else if (intsize == 64 && *fltsize == 64) { + return InterpretThisInstruction(); + } else { + UNREACHABLE(); + } + + V_scalar(*fltsize, Vd, fltval); + + 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);