A64: Implement FCMP, FCMPE

This commit is contained in:
MerryMage 2018-02-02 22:25:51 +00:00
parent 75b8a76630
commit 93fcbdf1e2
4 changed files with 67 additions and 4 deletions

View file

@ -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

View file

@ -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")

View file

@ -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 <boost/optional.hpp>
#include "frontend/A64/translate/impl/impl.h"
namespace Dynarmic::A64 {
static boost::optional<size_t> 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

View file

@ -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);