diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 235e6d09..67ecc0a6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,6 +74,7 @@ add_library(dynarmic frontend/A64/translate/impl/data_processing_register.cpp frontend/A64/translate/impl/data_processing_shift.cpp frontend/A64/translate/impl/exception_generating.cpp + frontend/A64/translate/impl/floating_point_compare.cpp frontend/A64/translate/impl/floating_point_data_processing_two_register.cpp frontend/A64/translate/impl/impl.cpp frontend/A64/translate/impl/impl.h diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 309fba19..c426481c 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -929,8 +929,8 @@ INST(EOR_asimd, "EOR (vector)", "0Q101 //INST(FRINTI_float, "FRINTI (scalar)", "00011110yy100111110000nnnnnddddd") // Data Processing - FP and SIMD - Floating point compare -//INST(FCMP_float, "FCMP", "00011110yy1mmmmm001000nnnnn0-000") -//INST(FCMPE_float, "FCMPE", "00011110yy1mmmmm001000nnnnn1-000") +INST(FCMP_float, "FCMP", "00011110yy1mmmmm001000nnnnn0o000") +INST(FCMPE_float, "FCMPE", "00011110yy1mmmmm001000nnnnn1o000") // Data Processing - FP and SIMD - Floating point immediate //INST(FMOV_float_imm, "FMOV (scalar, immediate)", "00011110yy1iiiiiiii10000000ddddd") diff --git a/src/frontend/A64/translate/impl/floating_point_compare.cpp b/src/frontend/A64/translate/impl/floating_point_compare.cpp new file mode 100644 index 00000000..6921d7a9 --- /dev/null +++ b/src/frontend/A64/translate/impl/floating_point_compare.cpp @@ -0,0 +1,62 @@ +/* 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::FCMP_float(Imm<2> type, Vec Vm, Vec Vn, bool cmp_with_zero) { + auto datasize = GetDataSize(type); + if (!datasize) { + return UnallocatedEncoding(); + } + + const IR::U32U64 operand1 = V_scalar(*datasize, Vn); + IR::U32U64 operand2; + if (cmp_with_zero) { + operand2 = I(*datasize, 0); + } else { + operand2 = V_scalar(*datasize, Vm); + } + + ir.FPCompare(operand1, operand2, false, true); + return true; +} + +bool TranslatorVisitor::FCMPE_float(Imm<2> type, Vec Vm, Vec Vn, bool cmp_with_zero) { + auto datasize = GetDataSize(type); + if (!datasize) { + return UnallocatedEncoding(); + } + + const IR::U32U64 operand1 = V_scalar(*datasize, Vn); + IR::U32U64 operand2; + if (cmp_with_zero) { + operand2 = I(*datasize, 0); + } else { + operand2 = V_scalar(*datasize, Vm); + } + + ir.FPCompare(operand1, operand2, true, true); + return true; +} + +} // namespace Dynarmic::A64 diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index 5b1aea66..0dfec6d1 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -983,8 +983,8 @@ struct TranslatorVisitor final { bool FRINTI_float(Imm<2> type, Vec Vn, Vec Vd); // Data Processing - FP and SIMD - Floating point compare - bool FCMP_float(Imm<2> type, Vec Vm, Vec Vn); - bool FCMPE_float(Imm<2> type, Vec Vm, Vec Vn); + bool FCMP_float(Imm<2> type, Vec Vm, Vec Vn, bool cmp_with_zero); + bool FCMPE_float(Imm<2> type, Vec Vm, Vec Vn, bool cmp_with_zero); // Data Processing - FP and SIMD - Floating point immediate bool FMOV_float_imm(Imm<2> type, Imm<8> imm8, Vec Vd);