From f7f83b76b729382f12e78464ff67119a55855a3c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 15 Jul 2018 19:50:32 -0400 Subject: [PATCH] simd_scalar_two_register_misc: Implement scalar double/single-precision variants of FCM{EQ, GE, GT, LE, LT} (zero) --- src/frontend/A64/decoder/a64.inc | 10 ++-- .../impl/simd_scalar_two_register_misc.cpp | 57 +++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 9b9eb30b..d1f7a1ec 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -367,11 +367,11 @@ INST(FACGT_2, "FACGT", "01111 //INST(SCVTF_int_1, "SCVTF (vector, integer)", "0101111001111001110110nnnnnddddd") INST(SCVTF_int_2, "SCVTF (vector, integer)", "010111100z100001110110nnnnnddddd") //INST(FCMGT_zero_1, "FCMGT (zero)", "0101111011111000110010nnnnnddddd") -//INST(FCMGT_zero_2, "FCMGT (zero)", "010111101z100000110010nnnnnddddd") +INST(FCMGT_zero_2, "FCMGT (zero)", "010111101z100000110010nnnnnddddd") //INST(FCMEQ_zero_1, "FCMEQ (zero)", "0101111011111000110110nnnnnddddd") -//INST(FCMEQ_zero_2, "FCMEQ (zero)", "010111101z100000110110nnnnnddddd") +INST(FCMEQ_zero_2, "FCMEQ (zero)", "010111101z100000110110nnnnnddddd") //INST(FCMLT_1, "FCMLT (zero)", "0101111011111000111010nnnnnddddd") -//INST(FCMLT_2, "FCMLT (zero)", "010111101z100000111010nnnnnddddd") +INST(FCMLT_2, "FCMLT (zero)", "010111101z100000111010nnnnnddddd") //INST(FCVTPS_1, "FCVTPS (vector)", "0101111011111001101010nnnnnddddd") //INST(FCVTPS_2, "FCVTPS (vector)", "010111101z100001101010nnnnnddddd") //INST(FCVTZS_int_1, "FCVTZS (vector, integer)", "0101111011111001101110nnnnnddddd") @@ -389,9 +389,9 @@ INST(SCVTF_int_2, "SCVTF (vector, integer)", "01011 //INST(UCVTF_int_1, "UCVTF (vector, integer)", "0111111001111001110110nnnnnddddd") INST(UCVTF_int_2, "UCVTF (vector, integer)", "011111100z100001110110nnnnnddddd") //INST(FCMGE_zero_1, "FCMGE (zero)", "0111111011111000110010nnnnnddddd") -//INST(FCMGE_zero_2, "FCMGE (zero)", "011111101z100000110010nnnnnddddd") +INST(FCMGE_zero_2, "FCMGE (zero)", "011111101z100000110010nnnnnddddd") //INST(FCMLE_1, "FCMLE (zero)", "0111111011111000110110nnnnnddddd") -//INST(FCMLE_2, "FCMLE (zero)", "011111101z100000110110nnnnnddddd") +INST(FCMLE_2, "FCMLE (zero)", "011111101z100000110110nnnnnddddd") //INST(FCVTPU_1, "FCVTPU (vector)", "0111111011111001101010nnnnnddddd") //INST(FCVTPU_2, "FCVTPU (vector)", "011111101z100001101010nnnnnddddd") //INST(FCVTZU_int_1, "FCVTZU (vector, integer)", "0111111011111001101110nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp b/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp index fd770dbe..d15dbab3 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp @@ -7,6 +7,43 @@ #include "frontend/A64/translate/impl/impl.h" namespace Dynarmic::A64 { +namespace { +enum class ComparisonType { + EQ, + GE, + GT, + LE, + LT +}; + +bool ScalarFPCompareAgainstZero(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, ComparisonType type) { + const size_t esize = sz ? 64 : 32; + const size_t datasize = esize; + + const IR::U128 operand = v.V(datasize, Vn); + const IR::U128 zero = v.ir.ZeroVector(); + const IR::U128 result = [&] { + switch (type) { + case ComparisonType::EQ: + return v.ir.FPVectorEqual(esize, operand, zero); + case ComparisonType::GE: + return v.ir.FPVectorGreaterEqual(esize, operand, zero); + case ComparisonType::GT: + return v.ir.FPVectorGreater(esize, operand, zero); + case ComparisonType::LE: + return v.ir.FPVectorGreaterEqual(esize, zero, operand); + case ComparisonType::LT: + return v.ir.FPVectorGreater(esize, zero, operand); + } + + UNREACHABLE(); + return IR::U128{}; + }(); + + v.V_scalar(datasize, Vd, v.ir.VectorGetElement(esize, result, 0)); + return true; +} +} // Anonymous namespace bool TranslatorVisitor::ABS_1(Imm<2> size, Vec Vn, Vec Vd) { if (size != 0b11) { @@ -21,6 +58,26 @@ bool TranslatorVisitor::ABS_1(Imm<2> size, Vec Vn, Vec Vd) { return true; } +bool TranslatorVisitor::FCMEQ_zero_2(bool sz, Vec Vn, Vec Vd) { + return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::EQ); +} + +bool TranslatorVisitor::FCMGE_zero_2(bool sz, Vec Vn, Vec Vd) { + return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::GE); +} + +bool TranslatorVisitor::FCMGT_zero_2(bool sz, Vec Vn, Vec Vd) { + return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::GT); +} + +bool TranslatorVisitor::FCMLE_2(bool sz, Vec Vn, Vec Vd) { + return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::LE); +} + +bool TranslatorVisitor::FCMLT_2(bool sz, Vec Vn, Vec Vd) { + return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::LT); +} + bool TranslatorVisitor::NEG_1(Imm<2> size, Vec Vn, Vec Vd) { if (size != 0b11) { return ReservedValue();