diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 5865c4cf..01de3f09 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -941,5 +941,5 @@ 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(FNMADD_float, "FNMADD", "00011111yy1mmmmm0aaaaannnnnddddd") +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 32e9f3d4..ae609f7e 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 @@ -51,4 +51,18 @@ bool TranslatorVisitor::FMSUB_float(Imm<2> type, Vec Vm, Vec Va, Vec Vn, Vec Vd) return true; } +bool TranslatorVisitor::FNMADD_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(ir.FPNeg(operanda), ir.FPNeg(operand1), operand2, true); + V_scalar(*datasize, Vd, result); + return true; +} + } // namespace Dynarmic::A64