From 9912836b59b189cdcbf5c3517b6bece9f0f30a2d Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 13 Jul 2018 18:37:10 -0400 Subject: [PATCH] A64: Implement scalar double/single-precision variants of FACGE, FACGT, FCMEQ, FCMGE, FCMGT --- src/frontend/A64/decoder/a64.inc | 10 ++-- .../translate/impl/simd_scalar_three_same.cpp | 60 +++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index c608f387..06f90427 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -341,21 +341,21 @@ INST(DUP_elt_1, "DUP (element)", "01011 //INST(FMULX_vec_1, "FMULX", "01011110010mmmmm000111nnnnnddddd") //INST(FMULX_vec_2, "FMULX", "010111100z1mmmmm110111nnnnnddddd") //INST(FCMEQ_reg_1, "FCMEQ (register)", "01011110010mmmmm001001nnnnnddddd") -//INST(FCMEQ_reg_2, "FCMEQ (register)", "010111100z1mmmmm111001nnnnnddddd") +INST(FCMEQ_reg_2, "FCMEQ (register)", "010111100z1mmmmm111001nnnnnddddd") //INST(FRECPS_1, "FRECPS", "01011110010mmmmm001111nnnnnddddd") //INST(FRECPS_2, "FRECPS", "010111100z1mmmmm111111nnnnnddddd") //INST(FRSQRTS_1, "FRSQRTS", "01011110110mmmmm001111nnnnnddddd") //INST(FRSQRTS_2, "FRSQRTS", "010111101z1mmmmm111111nnnnnddddd") //INST(FCMGE_reg_1, "FCMGE (register)", "01111110010mmmmm001001nnnnnddddd") -//INST(FCMGE_reg_2, "FCMGE (register)", "011111100z1mmmmm111001nnnnnddddd") +INST(FCMGE_reg_2, "FCMGE (register)", "011111100z1mmmmm111001nnnnnddddd") //INST(FACGE_1, "FACGE", "01111110010mmmmm001011nnnnnddddd") -//INST(FACGE_2, "FACGE", "011111100z1mmmmm111011nnnnnddddd") +INST(FACGE_2, "FACGE", "011111100z1mmmmm111011nnnnnddddd") //INST(FABD_1, "FABD", "01111110110mmmmm000101nnnnnddddd") INST(FABD_2, "FABD", "011111101z1mmmmm110101nnnnnddddd") //INST(FCMGT_reg_1, "FCMGT (register)", "01111110110mmmmm001001nnnnnddddd") -//INST(FCMGT_reg_2, "FCMGT (register)", "011111101z1mmmmm111001nnnnnddddd") +INST(FCMGT_reg_2, "FCMGT (register)", "011111101z1mmmmm111001nnnnnddddd") //INST(FACGT_1, "FACGT", "01111110110mmmmm001011nnnnnddddd") -//INST(FACGT_2, "FACGT", "011111101z1mmmmm111011nnnnnddddd") +INST(FACGT_2, "FACGT", "011111101z1mmmmm111011nnnnnddddd") // Data Processing - FP and SIMD - Scalar two register misc //INST(FCVTNS_1, "FCVTNS (vector)", "0101111001111001101010nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_scalar_three_same.cpp b/src/frontend/A64/translate/impl/simd_scalar_three_same.cpp index d85e8150..c3aba19c 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_three_same.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_three_same.cpp @@ -60,6 +60,46 @@ bool ScalarCompare(TranslatorVisitor& v, Imm<2> size, boost::optional Vm, V v.V_scalar(datasize, Vd, v.ir.VectorGetElement(esize, result, 0)); return true; } + +enum class FPComparisonType { + EQ, + GE, + AbsoluteGE, + GT, + AbsoluteGT +}; + +bool ScalarFPCompareRegister(TranslatorVisitor& v, bool sz, Vec Vm, Vec Vn, Vec Vd, FPComparisonType type) { + const size_t esize = sz ? 64 : 32; + const size_t datasize = esize; + + const IR::U128 operand1 = v.V(datasize, Vn); + const IR::U128 operand2 = v.V(datasize, Vm); + const IR::U128 result = [&] { + switch (type) { + case FPComparisonType::EQ: + return v.ir.FPVectorEqual(esize, operand1, operand2); + case FPComparisonType::GE: + return v.ir.FPVectorGreaterEqual(esize, operand1, operand2); + case FPComparisonType::AbsoluteGE: + return v.ir.FPVectorGreaterEqual(esize, + v.ir.FPVectorAbs(esize, operand1), + v.ir.FPVectorAbs(esize, operand2)); + case FPComparisonType::GT: + return v.ir.FPVectorGreater(esize, operand1, operand2); + case FPComparisonType::AbsoluteGT: + return v.ir.FPVectorGreater(esize, + v.ir.FPVectorAbs(esize, operand1), + v.ir.FPVectorAbs(esize, operand2)); + } + + UNREACHABLE(); + return IR::U128{}; + }(); + + v.V_scalar(datasize, Vd, v.ir.VectorGetElement(esize, result, 0)); + return true; +} } // Anonymous namespace bool TranslatorVisitor::ADD_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { @@ -142,6 +182,26 @@ bool TranslatorVisitor::FABD_2(bool sz, Vec Vm, Vec Vn, Vec Vd) { return true; } +bool TranslatorVisitor::FACGE_2(bool sz, Vec Vm, Vec Vn, Vec Vd) { + return ScalarFPCompareRegister(*this, sz, Vm, Vn, Vd, FPComparisonType::AbsoluteGE); +} + +bool TranslatorVisitor::FACGT_2(bool sz, Vec Vm, Vec Vn, Vec Vd) { + return ScalarFPCompareRegister(*this, sz, Vm, Vn, Vd, FPComparisonType::AbsoluteGT); +} + +bool TranslatorVisitor::FCMEQ_reg_2(bool sz, Vec Vm, Vec Vn, Vec Vd) { + return ScalarFPCompareRegister(*this, sz, Vm, Vn, Vd, FPComparisonType::EQ); +} + +bool TranslatorVisitor::FCMGE_reg_2(bool sz, Vec Vm, Vec Vn, Vec Vd) { + return ScalarFPCompareRegister(*this, sz, Vm, Vn, Vd, FPComparisonType::GE); +} + +bool TranslatorVisitor::FCMGT_reg_2(bool sz, Vec Vm, Vec Vn, Vec Vd) { + return ScalarFPCompareRegister(*this, sz, Vm, Vn, Vd, FPComparisonType::GT); +} + bool TranslatorVisitor::SSHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { if (size != 0b11) { return ReservedValue();