diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 3a7f58ad..5865c4cf 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -940,6 +940,6 @@ INST(FCSEL_float, "FCSEL", "00011 // Data Processing - FP and SIMD - Floating point data processing three register INST(FMADD_float, "FMADD", "00011111yy0mmmmm0aaaaannnnnddddd") -//INST(FMSUB_float, "FMSUB", "00011111yy0mmmmm1aaaaannnnnddddd") +INST(FMSUB_float, "FMSUB", "00011111yy0mmmmm1aaaaannnnnddddd") //INST(FNMADD_float, "FNMADD", "00011111yy1mmmmm0aaaaannnnnddddd") //INST(FNMSUB_float, "FNMSUB", "00011111yy1mmmmm1aaaaannnnnddddd") diff --git a/src/frontend/A64/translate/impl/floating_point_data_processing_three_register.cpp b/src/frontend/A64/translate/impl/floating_point_data_processing_three_register.cpp index 9b30fff4..32e9f3d4 100644 --- a/src/frontend/A64/translate/impl/floating_point_data_processing_three_register.cpp +++ b/src/frontend/A64/translate/impl/floating_point_data_processing_three_register.cpp @@ -37,4 +37,18 @@ bool TranslatorVisitor::FMADD_float(Imm<2> type, Vec Vm, Vec Va, Vec Vn, Vec Vd) return true; } +bool TranslatorVisitor::FMSUB_float(Imm<2> type, Vec Vm, Vec Va, Vec Vn, Vec Vd) { + const auto datasize = GetDataSize(type); + if (!datasize || *datasize == 16) { + return UnallocatedEncoding(); + } + + const IR::U32U64 operanda = V_scalar(*datasize, Va); + const IR::U32U64 operand1 = V_scalar(*datasize, Vn); + const IR::U32U64 operand2 = V_scalar(*datasize, Vm); + const IR::U32U64 result = ir.FPMulAdd(operanda, ir.FPNeg(operand1), operand2, true); + V_scalar(*datasize, Vd, result); + return true; +} + } // namespace Dynarmic::A64