diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 838c15e4..3a7f58ad 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -939,7 +939,7 @@ INST(FNMUL_float, "FNMUL (scalar)", "00011 INST(FCSEL_float, "FCSEL", "00011110yy1mmmmmcccc11nnnnnddddd") // Data Processing - FP and SIMD - Floating point data processing three register -//INST(FMADD_float, "FMADD", "00011111yy0mmmmm0aaaaannnnnddddd") +INST(FMADD_float, "FMADD", "00011111yy0mmmmm0aaaaannnnnddddd") //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 new file mode 100644 index 00000000..9b30fff4 --- /dev/null +++ b/src/frontend/A64/translate/impl/floating_point_data_processing_three_register.cpp @@ -0,0 +1,40 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include + +#include "frontend/A64/translate/impl/impl.h" + +namespace Dynarmic::A64 { + +static boost::optional GetDataSize(Imm<2> type) { + switch (type.ZeroExtend()) { + case 0b00: + return 32; + case 0b01: + return 64; + case 0b11: + // FP16Ext, unimplemented. + return boost::none; + } + return boost::none; +} + +bool TranslatorVisitor::FMADD_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, operand1, operand2, true); + V_scalar(*datasize, Vd, result); + return true; +} + +} // namespace Dynarmic::A64