diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 7bf4af15..00a3ee8e 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -595,11 +595,11 @@ INST(XTN, "XTN, XTN2", "0Q001 //INST(SCVTF_int_3, "SCVTF (vector, integer)", "0Q00111001111001110110nnnnnddddd") INST(SCVTF_int_4, "SCVTF (vector, integer)", "0Q0011100z100001110110nnnnnddddd") //INST(FCMGT_zero_3, "FCMGT (zero)", "0Q00111011111000110010nnnnnddddd") -//INST(FCMGT_zero_4, "FCMGT (zero)", "0Q0011101z100000110010nnnnnddddd") +INST(FCMGT_zero_4, "FCMGT (zero)", "0Q0011101z100000110010nnnnnddddd") //INST(FCMEQ_zero_3, "FCMEQ (zero)", "0Q00111011111000110110nnnnnddddd") INST(FCMEQ_zero_4, "FCMEQ (zero)", "0Q0011101z100000110110nnnnnddddd") //INST(FCMLT_3, "FCMLT (zero)", "0Q00111011111000111010nnnnnddddd") -//INST(FCMLT_4, "FCMLT (zero)", "0Q0011101z100000111010nnnnnddddd") +INST(FCMLT_4, "FCMLT (zero)", "0Q0011101z100000111010nnnnnddddd") INST(FABS_1, "FABS (vector)", "0Q00111011111000111110nnnnnddddd") INST(FABS_2, "FABS (vector)", "0Q0011101z100000111110nnnnnddddd") //INST(FRINTP_1, "FRINTP (vector)", "0Q00111011111001100010nnnnnddddd") @@ -645,9 +645,9 @@ INST(FNEG_2, "FNEG (vector)", "0Q101 //INST(FRINTI_1, "FRINTI (vector)", "0Q10111011111001100110nnnnnddddd") //INST(FRINTI_2, "FRINTI (vector)", "0Q1011101z100001100110nnnnnddddd") //INST(FCMGE_zero_3, "FCMGE (zero)", "0Q10111011111000110010nnnnnddddd") -//INST(FCMGE_zero_4, "FCMGE (zero)", "0Q1011101z100000110010nnnnnddddd") +INST(FCMGE_zero_4, "FCMGE (zero)", "0Q1011101z100000110010nnnnnddddd") //INST(FCMLE_3, "FCMLE (zero)", "0Q10111011111000110110nnnnnddddd") -//INST(FCMLE_4, "FCMLE (zero)", "0Q1011101z100000110110nnnnnddddd") +INST(FCMLE_4, "FCMLE (zero)", "0Q1011101z100000110110nnnnnddddd") //INST(FCVTPU_3, "FCVTPU (vector)", "0Q10111011111001101010nnnnnddddd") //INST(FCVTPU_4, "FCVTPU (vector)", "0Q1011101z100001101010nnnnnddddd") //INST(FCVTZU_int_3, "FCVTZU (vector, integer)", "0Q10111011111001101110nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp index ea359b08..9719d865 100644 --- a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp @@ -49,6 +49,38 @@ bool CompareAgainstZero(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec V v.V(datasize, Vd, result); return true; } + +bool FPCompareAgainstZero(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, ComparisonType type) { + if (sz && !Q) { + return v.ReservedValue(); + } + + const size_t esize = sz ? 64 : 32; + const size_t datasize = Q ? 128 : 64; + + 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(datasize, Vd, result); + return true; +} } // Anonymous namespace bool TranslatorVisitor::CNT(bool Q, Imm<2> size, Vec Vn, Vec Vd) { @@ -143,18 +175,23 @@ bool TranslatorVisitor::FABS_2(bool Q, bool sz, Vec Vn, Vec Vd) { } bool TranslatorVisitor::FCMEQ_zero_4(bool Q, bool sz, Vec Vn, Vec Vd) { - if (sz && !Q) { - return ReservedValue(); - } + return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::EQ); +} - const size_t esize = sz ? 64 : 32; - const size_t datasize = Q ? 128 : 64; +bool TranslatorVisitor::FCMGE_zero_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::GE); +} - const IR::U128 operand = V(datasize, Vn); - const IR::U128 result = ir.FPVectorEqual(esize, operand, ir.ZeroVector()); +bool TranslatorVisitor::FCMGT_zero_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::GT); +} - V(datasize, Vd, result); - return true; +bool TranslatorVisitor::FCMLE_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::LE); +} + +bool TranslatorVisitor::FCMLT_4(bool Q, bool sz, Vec Vn, Vec Vd) { + return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::LT); } bool TranslatorVisitor::FNEG_1(bool Q, Vec Vn, Vec Vd) {